From 383d08978d9b22367d2d7a263be6b878a8480f11 Mon Sep 17 00:00:00 2001 From: navjotcis <33522186+navjotcis@users.noreply.github.com> Date: Tue, 15 Sep 2020 22:28:25 +0530 Subject: [PATCH] Revert "removed the inset sent query and using the comman helper_sent.inset method for data insertion" --- .gitignore | 4 - .readthedocs.yml | 9 - .travis.yml | 1 - COPYING | 2 +- LICENSE | 51 +- README.md | 8 +- android_instruction.rst | 4 +- build/README.md | 2 + build/changelang.sh | 16 + build/compiletest.py | 23 + build/mergepullrequest.sh | 11 + build/osx.sh | 26 + build/updatetranslations.sh | 22 + buildscripts/winbuild.sh | 165 - checkdeps.py | 4 +- docs/_static/custom.css | 4 - docs/conf.py | 119 +- docs/contribute.dir/develop.dir/fabric.rst | 2 +- docs/contribute.dir/develop.dir/opsec.rst | 4 +- docs/contribute.dir/develop.dir/overview.rst | 10 +- docs/contribute.dir/processes.rst | 6 +- docs/index.rst | 12 +- docs/requirements.txt | 2 - fabfile/README.md | 4 +- packages/README.md | 2 +- packages/pyinstaller/bitmessagemain.spec | 90 +- pybitmessage | 1 - setup.cfg | 5 +- setup.py | 19 +- .../platform/python-for-android-new-toolchain | 1 - src/addresses.py | 42 +- src/alice.png | Bin 669 -> 0 bytes src/api.py | 129 +- src/bitmessagecli.py | 8 +- src/bitmessagecurses/__init__.py | 814 ++--- .../recipes/bitmsghash/__init__.py | 50 - .../recipes/kivymd/__init__.py | 41 - .../kivymd/kivymd-fix-dev-compatibility.patch | 36 - src/bitmessagekivy/identiconGeneration.py | 93 - src/bitmessagekivy/kivy_helper_search.py | 72 +- src/bitmessagekivy/main.kv | 1598 ++-------- src/bitmessagekivy/mpybit.py | 2836 ++--------------- src/bitmessagekivy/uikivysignaler.py | 28 - src/bitmessagemain.py | 213 +- src/bitmessageqt/__init__.py | 642 +++- src/bitmessageqt/about.ui | 2 +- src/bitmessageqt/dialogs.py | 13 +- src/bitmessageqt/networkstatus.py | 2 +- src/bitmessageqt/safehtmlparser.py | 102 +- src/bitmessageqt/settings.py | 1185 +++---- src/bitmessageqt/settings.ui | 414 +-- src/bitmessageqt/support.py | 4 +- src/bitmsghash/bitmsghash.cpp | 2 +- src/bmconfigparser.py | 44 +- src/bob.png | Bin 640 -> 0 bytes src/build_osx.py | 31 +- src/buildozer.spec | 60 +- src/class_addressGenerator.py | 79 +- src/class_objectProcessor.py | 146 +- src/class_objectProcessorQueue.py | 24 + src/class_singleCleaner.py | 166 +- src/class_singleWorker.py | 119 +- src/class_smtpDeliver.py | 33 +- src/class_smtpServer.py | 108 +- src/class_sqlThread.py | 290 +- src/dave.png | Bin 650 -> 0 bytes src/debug.py | 94 +- src/defaults.py | 22 +- src/depends.py | 28 +- src/eve.png | Bin 651 -> 0 bytes src/fallback/__init__.py | 16 +- src/helper_ackPayload.py | 32 +- src/helper_bitcoin.py | 18 +- src/helper_bootstrap.py | 84 + src/helper_generic.py | 114 - src/helper_inbox.py | 7 +- src/helper_msgcoding.py | 21 +- src/helper_random.py | 10 +- src/helper_search.py | 25 +- src/helper_sent.py | 13 +- src/helper_sql.py | 38 +- src/helper_startup.py | 76 +- src/helper_threading.py | 46 + src/highlevelcrypto.py | 54 +- src/image.svg | Bin 704 -> 0 bytes src/images/3.zip | Bin 3043 -> 0 bytes src/images/account_multiple.png | Bin 9798 -> 0 bytes src/images/addressbookadd.png | Bin 7765 -> 0 bytes src/images/avatar.png | Bin 27865 -> 0 bytes src/images/back-button.png | Bin 52318 -> 0 bytes src/images/black_cross.png | Bin 5201 -> 0 bytes src/images/copy_text.png | Bin 2701 -> 0 bytes src/images/down-arrow.png | Bin 2384 -> 0 bytes src/images/drawer_logo1.png | Bin 2041 -> 0 bytes src/images/left_arrow.png | Bin 2444 -> 0 bytes src/images/loader.gif | Bin 13527 -> 0 bytes src/images/loader.zip | Bin 15918 -> 0 bytes src/images/red.png | Bin 57642 -> 0 bytes src/images/right-arrow.png | Bin 3145 -> 0 bytes src/images/search.png | Bin 2982 -> 0 bytes src/images/search_mail.png | Bin 10555 -> 0 bytes src/images/text_images/!.png | Bin 5035 -> 0 bytes src/images/text_images/0.png | Bin 7321 -> 0 bytes src/images/text_images/1.png | Bin 5027 -> 0 bytes src/images/text_images/2.png | Bin 6916 -> 0 bytes src/images/text_images/3.png | Bin 7265 -> 0 bytes src/images/text_images/4.png | Bin 5891 -> 0 bytes src/images/text_images/5.png | Bin 6831 -> 0 bytes src/images/text_images/6.png | Bin 7644 -> 0 bytes src/images/text_images/7.png | Bin 5941 -> 0 bytes src/images/text_images/8.png | Bin 7777 -> 0 bytes src/images/text_images/9.png | Bin 7733 -> 0 bytes src/images/text_images/A.png | Bin 6857 -> 0 bytes src/images/text_images/B.png | Bin 6533 -> 0 bytes src/images/text_images/C.png | Bin 7662 -> 0 bytes src/images/text_images/D.png | Bin 6381 -> 0 bytes src/images/text_images/E.png | Bin 5009 -> 0 bytes src/images/text_images/F.png | Bin 4972 -> 0 bytes src/images/text_images/G.png | Bin 7593 -> 0 bytes src/images/text_images/H.png | Bin 5054 -> 0 bytes src/images/text_images/I.png | Bin 4713 -> 0 bytes src/images/text_images/J.png | Bin 5841 -> 0 bytes src/images/text_images/K.png | Bin 6719 -> 0 bytes src/images/text_images/L.png | Bin 4878 -> 0 bytes src/images/text_images/M.png | Bin 6569 -> 0 bytes src/images/text_images/N.png | Bin 6509 -> 0 bytes src/images/text_images/O.png | Bin 7912 -> 0 bytes src/images/text_images/P.png | Bin 5914 -> 0 bytes src/images/text_images/Q.png | Bin 8271 -> 0 bytes src/images/text_images/R.png | Bin 6404 -> 0 bytes src/images/text_images/S.png | Bin 7826 -> 0 bytes src/images/text_images/T.png | Bin 4793 -> 0 bytes src/images/text_images/U.png | Bin 6113 -> 0 bytes src/images/text_images/V.png | Bin 6761 -> 0 bytes src/images/text_images/W.png | Bin 7805 -> 0 bytes src/images/text_images/X.png | Bin 7367 -> 0 bytes src/images/text_images/Y.png | Bin 6459 -> 0 bytes src/images/text_images/Z.png | Bin 6166 -> 0 bytes src/images/transparent.png | Bin 24650 -> 0 bytes src/images/white.png | Bin 82182 -> 0 bytes src/inventory.py | 2 +- src/kivymd/LICENSE | 21 + src/kivymd/__init__.py | 6 + src/kivymd/accordion.py | 254 ++ src/kivymd/backgroundcolorbehavior.py | 23 + src/kivymd/bottomsheet.py | 211 ++ src/kivymd/button.py | 453 +++ src/kivymd/card.py | 58 + src/kivymd/color_definitions.py | 360 +++ src/kivymd/date_picker.py | 325 ++ src/kivymd/dialog.py | 176 + src/kivymd/elevationbehavior.py | 187 ++ .../fonts/Material-Design-Iconic-Font.ttf | Bin 0 -> 99212 bytes src/kivymd/fonts/Roboto-Bold.ttf | Bin 0 -> 163448 bytes src/kivymd/fonts/Roboto-Italic.ttf | Bin 0 -> 132440 bytes src/kivymd/fonts/Roboto-Light.ttf | Bin 0 -> 140276 bytes src/kivymd/fonts/Roboto-LightItalic.ttf | Bin 0 -> 133172 bytes src/kivymd/fonts/Roboto-Medium.ttf | Bin 0 -> 137308 bytes src/kivymd/fonts/Roboto-MediumItalic.ttf | Bin 0 -> 134312 bytes src/kivymd/fonts/Roboto-Regular.ttf | Bin 0 -> 145348 bytes src/kivymd/fonts/Roboto-Thin.ttf | Bin 0 -> 130044 bytes src/kivymd/fonts/Roboto-ThinItalic.ttf | Bin 0 -> 132860 bytes src/kivymd/grid.py | 168 + src/kivymd/icon_definitions.py | 1569 +++++++++ src/kivymd/images/kivymd_512.png | Bin 0 -> 30694 bytes src/kivymd/images/kivymd_logo.png | Bin 0 -> 42074 bytes src/kivymd/images/quad_shadow-0.png | Bin 0 -> 29962 bytes src/kivymd/images/quad_shadow-1.png | Bin 0 -> 30186 bytes src/kivymd/images/quad_shadow-2.png | Bin 0 -> 19289 bytes src/kivymd/images/quad_shadow.atlas | 1 + src/kivymd/images/rec_shadow-0.png | Bin 0 -> 46593 bytes src/kivymd/images/rec_shadow-1.png | Bin 0 -> 43957 bytes src/kivymd/images/rec_shadow.atlas | 1 + src/kivymd/images/rec_st_shadow-0.png | Bin 0 -> 30721 bytes src/kivymd/images/rec_st_shadow-1.png | Bin 0 -> 32265 bytes src/kivymd/images/rec_st_shadow-2.png | Bin 0 -> 28526 bytes src/kivymd/images/rec_st_shadow.atlas | 1 + src/kivymd/images/round_shadow-0.png | Bin 0 -> 39635 bytes src/kivymd/images/round_shadow-1.png | Bin 0 -> 40767 bytes src/kivymd/images/round_shadow-2.png | Bin 0 -> 26510 bytes src/kivymd/images/round_shadow.atlas | 1 + src/kivymd/label.py | 94 + src/kivymd/list.py | 531 +++ src/kivymd/material_resources.py | 50 + src/kivymd/menu.py | 192 ++ src/kivymd/navigationdrawer.py | 76 + src/kivymd/progressbar.py | 79 + src/kivymd/ripplebehavior.py | 169 + src/kivymd/selectioncontrols.py | 240 ++ src/kivymd/slider.py | 247 ++ src/kivymd/slidingpanel.py | 92 + src/kivymd/snackbar.py | 115 + src/kivymd/spinner.py | 149 + src/kivymd/tabs.py | 303 ++ src/kivymd/textfields.py | 215 ++ src/kivymd/theme_picker.py | 422 +++ src/kivymd/theming.py | 350 ++ src/kivymd/time_picker.py | 84 + src/kivymd/toolbar.py | 98 + src/kivymd/vendor/__init__.py | 1 + src/kivymd/vendor/circleLayout/LICENSE | 22 + src/kivymd/vendor/circleLayout/README.md | 21 + src/kivymd/vendor/circleLayout/__init__.py | 196 ++ src/kivymd/vendor/circularTimePicker/LICENSE | 22 + .../vendor/circularTimePicker/README.md | 43 + .../vendor/circularTimePicker/__init__.py | 770 +++++ src/knownnodes.py | 91 +- src/l10n.py | 52 +- src/main.py | 4 +- src/message_data_reader.py | 136 + src/messagetypes/__init__.py | 20 +- src/messagetypes/message.py | 19 +- src/messagetypes/vote.py | 18 +- src/multiqueue.py | 4 +- src/namecoin.py | 38 +- src/navigationdrawer/__init__.py | 82 + src/network/__init__.py | 20 - src/network/addrthread.py | 44 +- src/network/advanceddispatcher.py | 41 +- src/network/announcethread.py | 36 +- src/network/assemble.py | 31 - src/network/asyncore_pollchoose.py | 164 +- src/network/bmobject.py | 57 +- src/network/bmproto.py | 162 +- src/network/connectionchooser.py | 26 +- src/network/connectionpool.py | 172 +- src/network/constants.py | 17 - src/network/dandelion.py | 32 +- src/network/downloadthread.py | 38 +- src/network/{http_old.py => http-old.py} | 13 +- src/network/http.py | 41 +- src/network/httpd.py | 75 +- src/network/https.py | 23 +- src/network/invthread.py | 68 +- src/network/networkthread.py | 17 +- src/network/node.py | 4 - src/network/objectracker.py | 59 +- src/network/proxy.py | 26 +- src/network/receivequeuethread.py | 45 +- src/network/socks4a.py | 9 +- src/network/socks5.py | 37 +- src/network/stats.py | 60 +- src/network/tcp.py | 89 +- src/network/threads.py | 49 - src/network/tls.py | 120 +- src/network/udp.py | 46 +- src/network/uploadthread.py | 48 +- src/nohup.out | 3 - src/openclpow.py | 61 +- src/paths.py | 120 +- src/plugins/__init__.py | 7 - src/plugins/indicator_libmessaging.py | 13 +- src/plugins/menu_qrcode.py | 8 +- src/plugins/notification_notify2.py | 8 +- src/plugins/plugin.py | 26 +- src/plugins/proxyconfig_stem.py | 140 - src/plugins/sound_canberra.py | 9 +- src/plugins/sound_gstreamer.py | 5 +- src/plugins/sound_playfile.py | 8 +- src/proofofwork.py | 14 +- src/protocol.py | 179 +- src/pyelliptic/__init__.py | 25 +- src/pyelliptic/arithmetic.py | 28 +- src/pyelliptic/cipher.py | 20 +- src/pyelliptic/ecc.py | 28 +- src/pyelliptic/eccblind.py | 210 -- src/pyelliptic/hash.py | 13 +- src/pyelliptic/openssl.py | 350 +- src/qidenticon.py | 24 +- src/queues.py | 43 +- src/{network => }/randomtrackingdict.py | 30 +- src/semaphores.py | 3 - src/shared.py | 129 +- src/shutdown.py | 26 +- src/singleinstance.py | 22 +- src/singleton.py | 15 - src/socks/BUGS | 25 + src/socks/LICENSE | 22 + src/socks/README | 201 ++ src/socks/__init__.py | 476 +++ src/state.py | 92 +- src/storage/filesystem.py | 176 +- src/storage/sqlite.py | 98 +- src/storage/storage.py | 51 +- src/suravata.py | 32 - src/tests/core.py | 100 +- src/tests/test_api.py | 2 +- src/tests/test_blindsig.py | 52 - src/tests/test_config.py | 9 +- src/tests/test_logger.py | 69 - src/tests/test_networkgroup.py | 39 - src/threads.py | 46 - src/tr.py | 47 +- src/upnp.py | 35 +- 294 files changed, 14111 insertions(+), 10312 deletions(-) delete mode 100644 .readthedocs.yml create mode 100644 build/README.md create mode 100755 build/changelang.sh create mode 100755 build/compiletest.py create mode 100755 build/mergepullrequest.sh create mode 100755 build/osx.sh create mode 100755 build/updatetranslations.sh delete mode 100755 buildscripts/winbuild.sh delete mode 100644 docs/_static/custom.css delete mode 100644 docs/requirements.txt delete mode 120000 pybitmessage delete mode 160000 src/.buildozer/android/platform/python-for-android-new-toolchain delete mode 100644 src/alice.png delete mode 100644 src/bitmessagekivy/android/python-for-android/recipes/bitmsghash/__init__.py delete mode 100644 src/bitmessagekivy/android/python-for-android/recipes/kivymd/__init__.py delete mode 100644 src/bitmessagekivy/android/python-for-android/recipes/kivymd/kivymd-fix-dev-compatibility.patch delete mode 100644 src/bitmessagekivy/identiconGeneration.py delete mode 100644 src/bitmessagekivy/uikivysignaler.py delete mode 100644 src/bob.png create mode 100644 src/class_objectProcessorQueue.py delete mode 100644 src/dave.png delete mode 100644 src/eve.png create mode 100644 src/helper_bootstrap.py delete mode 100644 src/helper_generic.py create mode 100644 src/helper_threading.py delete mode 100644 src/image.svg delete mode 100644 src/images/3.zip delete mode 100644 src/images/account_multiple.png delete mode 100644 src/images/addressbookadd.png delete mode 100644 src/images/avatar.png delete mode 100644 src/images/back-button.png delete mode 100644 src/images/black_cross.png delete mode 100644 src/images/copy_text.png delete mode 100644 src/images/down-arrow.png delete mode 100644 src/images/drawer_logo1.png delete mode 100644 src/images/left_arrow.png delete mode 100644 src/images/loader.gif delete mode 100644 src/images/loader.zip delete mode 100644 src/images/red.png delete mode 100644 src/images/right-arrow.png delete mode 100644 src/images/search.png delete mode 100644 src/images/search_mail.png delete mode 100644 src/images/text_images/!.png delete mode 100644 src/images/text_images/0.png delete mode 100644 src/images/text_images/1.png delete mode 100644 src/images/text_images/2.png delete mode 100644 src/images/text_images/3.png delete mode 100644 src/images/text_images/4.png delete mode 100644 src/images/text_images/5.png delete mode 100644 src/images/text_images/6.png delete mode 100644 src/images/text_images/7.png delete mode 100644 src/images/text_images/8.png delete mode 100644 src/images/text_images/9.png delete mode 100644 src/images/text_images/A.png delete mode 100644 src/images/text_images/B.png delete mode 100644 src/images/text_images/C.png delete mode 100644 src/images/text_images/D.png delete mode 100644 src/images/text_images/E.png delete mode 100644 src/images/text_images/F.png delete mode 100644 src/images/text_images/G.png delete mode 100644 src/images/text_images/H.png delete mode 100644 src/images/text_images/I.png delete mode 100644 src/images/text_images/J.png delete mode 100644 src/images/text_images/K.png delete mode 100644 src/images/text_images/L.png delete mode 100644 src/images/text_images/M.png delete mode 100644 src/images/text_images/N.png delete mode 100644 src/images/text_images/O.png delete mode 100644 src/images/text_images/P.png delete mode 100644 src/images/text_images/Q.png delete mode 100644 src/images/text_images/R.png delete mode 100644 src/images/text_images/S.png delete mode 100644 src/images/text_images/T.png delete mode 100644 src/images/text_images/U.png delete mode 100644 src/images/text_images/V.png delete mode 100644 src/images/text_images/W.png delete mode 100644 src/images/text_images/X.png delete mode 100644 src/images/text_images/Y.png delete mode 100644 src/images/text_images/Z.png delete mode 100644 src/images/transparent.png delete mode 100644 src/images/white.png create mode 100644 src/kivymd/LICENSE create mode 100644 src/kivymd/__init__.py create mode 100644 src/kivymd/accordion.py create mode 100644 src/kivymd/backgroundcolorbehavior.py create mode 100644 src/kivymd/bottomsheet.py create mode 100644 src/kivymd/button.py create mode 100644 src/kivymd/card.py create mode 100644 src/kivymd/color_definitions.py create mode 100644 src/kivymd/date_picker.py create mode 100644 src/kivymd/dialog.py create mode 100644 src/kivymd/elevationbehavior.py create mode 100644 src/kivymd/fonts/Material-Design-Iconic-Font.ttf create mode 100644 src/kivymd/fonts/Roboto-Bold.ttf create mode 100644 src/kivymd/fonts/Roboto-Italic.ttf create mode 100644 src/kivymd/fonts/Roboto-Light.ttf create mode 100644 src/kivymd/fonts/Roboto-LightItalic.ttf create mode 100644 src/kivymd/fonts/Roboto-Medium.ttf create mode 100644 src/kivymd/fonts/Roboto-MediumItalic.ttf create mode 100644 src/kivymd/fonts/Roboto-Regular.ttf create mode 100644 src/kivymd/fonts/Roboto-Thin.ttf create mode 100644 src/kivymd/fonts/Roboto-ThinItalic.ttf create mode 100644 src/kivymd/grid.py create mode 100644 src/kivymd/icon_definitions.py create mode 100644 src/kivymd/images/kivymd_512.png create mode 100644 src/kivymd/images/kivymd_logo.png create mode 100644 src/kivymd/images/quad_shadow-0.png create mode 100644 src/kivymd/images/quad_shadow-1.png create mode 100644 src/kivymd/images/quad_shadow-2.png create mode 100644 src/kivymd/images/quad_shadow.atlas create mode 100644 src/kivymd/images/rec_shadow-0.png create mode 100644 src/kivymd/images/rec_shadow-1.png create mode 100644 src/kivymd/images/rec_shadow.atlas create mode 100644 src/kivymd/images/rec_st_shadow-0.png create mode 100644 src/kivymd/images/rec_st_shadow-1.png create mode 100644 src/kivymd/images/rec_st_shadow-2.png create mode 100644 src/kivymd/images/rec_st_shadow.atlas create mode 100644 src/kivymd/images/round_shadow-0.png create mode 100644 src/kivymd/images/round_shadow-1.png create mode 100644 src/kivymd/images/round_shadow-2.png create mode 100644 src/kivymd/images/round_shadow.atlas create mode 100644 src/kivymd/label.py create mode 100644 src/kivymd/list.py create mode 100644 src/kivymd/material_resources.py create mode 100644 src/kivymd/menu.py create mode 100644 src/kivymd/navigationdrawer.py create mode 100644 src/kivymd/progressbar.py create mode 100644 src/kivymd/ripplebehavior.py create mode 100644 src/kivymd/selectioncontrols.py create mode 100644 src/kivymd/slider.py create mode 100644 src/kivymd/slidingpanel.py create mode 100644 src/kivymd/snackbar.py create mode 100644 src/kivymd/spinner.py create mode 100644 src/kivymd/tabs.py create mode 100644 src/kivymd/textfields.py create mode 100644 src/kivymd/theme_picker.py create mode 100644 src/kivymd/theming.py create mode 100644 src/kivymd/time_picker.py create mode 100644 src/kivymd/toolbar.py create mode 100644 src/kivymd/vendor/__init__.py create mode 100644 src/kivymd/vendor/circleLayout/LICENSE create mode 100644 src/kivymd/vendor/circleLayout/README.md create mode 100644 src/kivymd/vendor/circleLayout/__init__.py create mode 100644 src/kivymd/vendor/circularTimePicker/LICENSE create mode 100644 src/kivymd/vendor/circularTimePicker/README.md create mode 100644 src/kivymd/vendor/circularTimePicker/__init__.py create mode 100644 src/message_data_reader.py create mode 100644 src/navigationdrawer/__init__.py delete mode 100644 src/network/assemble.py delete mode 100644 src/network/constants.py rename src/network/{http_old.py => http-old.py} (80%) delete mode 100644 src/network/threads.py delete mode 100644 src/nohup.out delete mode 100644 src/plugins/proxyconfig_stem.py delete mode 100644 src/pyelliptic/eccblind.py rename src/{network => }/randomtrackingdict.py (85%) delete mode 100644 src/semaphores.py create mode 100644 src/socks/BUGS create mode 100644 src/socks/LICENSE create mode 100644 src/socks/README create mode 100644 src/socks/__init__.py delete mode 100644 src/suravata.py delete mode 100644 src/tests/test_blindsig.py delete mode 100644 src/tests/test_logger.py delete mode 100644 src/tests/test_networkgroup.py delete mode 100644 src/threads.py diff --git a/.gitignore b/.gitignore index b8c4a56a..2bcb5340 100644 --- a/.gitignore +++ b/.gitignore @@ -17,8 +17,4 @@ dist *.egg-info docs/_*/* docs/autodoc/ -build/sphinx/ pyan/ -.buildozer/ -bin/ -src/images/default_identicon/ \ No newline at end of file diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index 474ae9ab..00000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: 2 - -python: - version: 2.7 - install: - - requirements: docs/requirements.txt - - method: setuptools - path: . - system_packages: true diff --git a/.travis.yml b/.travis.yml index d7141188..1edba418 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ addons: packages: - build-essential - libcap-dev - - tor install: - pip install -r requirements.txt - ln -s src pybitmessage # tests environment diff --git a/COPYING b/COPYING index 078bf213..2e0ae6c1 100644 --- a/COPYING +++ b/COPYING @@ -1,5 +1,5 @@ Copyright (c) 2012-2016 Jonathan Warren -Copyright (c) 2012-2020 The Bitmessage Developers +Copyright (c) 2012-2019 The Bitmessage Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/LICENSE b/LICENSE index c2eeff82..3be738c0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) Copyright (c) 2012-2016 Jonathan Warren -Copyright (c) 2012-2020 The Bitmessage Developers +Copyright (c) 2012-2019 The Bitmessage Developers 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 @@ -22,7 +22,7 @@ SOFTWARE. ===== qidenticon.py identicon python implementation with QPixmap output by sendiulo -qidenticon.py is Licensed under FreeBSD License. +qidenticon.py is Licesensed under FreeBSD License. (http://www.freebsd.org/copyright/freebsd-license.html) Copyright 2013 "Sendiulo". All rights reserved. @@ -36,7 +36,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR I ===== based on identicon.py identicon python implementation. by Shin Adachi -identicon.py is Licensed under FreeBSD License. +identicon.py is Licesensed under FreeBSD License. (http://www.freebsd.org/copyright/freebsd-license.html) Copyright 1994-2009 Shin Adachi. All rights reserved. @@ -47,48 +47,3 @@ Redistribution and use in source and binary forms, with or without modification, 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 COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -===== based on asyncore_pollchoose.py asyncore_pollchoose python implementation. by Sam Rushing - -Copyright 1996 by Sam Rushing. All Rights Reserved - -Permission to use, copy, modify, and distribute this software and -its documentation for any purpose and without fee is hereby -granted, provided that the above copyright notice appear in all -copies and that both that copyright notice and this permission -notice appear in supporting documentation, and that the name of Sam -Rushing not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, 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. - -===== based on namecoin.py namecoin.py python implementation by Daniel Kraft - -Copyright (C) 2013 by Daniel Kraft - -This file is part of the Bitmessage project. - -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/README.md b/README.md index 17049e7a..c3dcb540 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,12 @@ Development ---------- Bitmessage is a collaborative project. You are welcome to submit pull requests although if you plan to put a non-trivial amount of work into coding new -features, it is recommended that you first describe your ideas in the -separate issue. +features, it is recommended that you first solicit feedback on the DevTalk +pseudo-mailing list: +BM-2D9QKN4teYRvoq2fyzpiftPh9WP9qggtzh -Feel welcome to join chan "bitmessage", BM-2cWy7cvHoq3f1rYMerRJp8PT653jjSuEdY +Feel welcome to join chan "bitmessage", BM-2cWy7cvHoq3f1rYMerRJp8PT653jjSuEdY +which is on preview here: https://beamstat.com/chan/bitmessage References ---------- diff --git a/android_instruction.rst b/android_instruction.rst index e6c7797d..fab55b55 100644 --- a/android_instruction.rst +++ b/android_instruction.rst @@ -1,6 +1,6 @@ PyBitmessage(Android) -This sample aims to be as close to a real world example of a mobile. It has a more refined design and also provides a practical example of how a mobile app would interact and communicate with its addresses. +This sample aims to be as close to a real world example of a mobile. It has a more refined design and also provides a practical example of how a mobile app would interact and communicate with its adresses. Steps for trying out this sample: @@ -13,7 +13,7 @@ This sample uses the kivy as Kivy is an open source, cross-platform Python frame Kivy is written in Python and Cython, supports various input devices and has an extensive widget library. With the same codebase, you can target Windows, OS X, Linux, Android and iOS. All Kivy widgets are built with multitouch support. -Kivy in support take Buildozer which is a tool that automates the entire build process. It downloads and sets up all the prerequisite for python-for-android, including the android SDK and NDK, then builds an apk that can be automatically pushed to the device. +Kivy in support take Buildozer which is a tool that automates the entire build process. It downloads and sets up all the prequisites for python-for-android, including the android SDK and NDK, then builds an apk that can be automatically pushed to the device. Buildozer currently works only in Linux, and is an alpha release, but it already works well and can significantly simplify the apk build. diff --git a/build/README.md b/build/README.md new file mode 100644 index 00000000..248d2c41 --- /dev/null +++ b/build/README.md @@ -0,0 +1,2 @@ +This directory contains scripts that are helpful for developers when building +or maintaining PyBitmessage. diff --git a/build/changelang.sh b/build/changelang.sh new file mode 100755 index 00000000..915c5dea --- /dev/null +++ b/build/changelang.sh @@ -0,0 +1,16 @@ +export LANG=de_DE.UTF-8 +export LANGUAGE=de_DE +export LC_CTYPE="de_DE.UTF-8" +export LC_NUMERIC=de_DE.UTF-8 +export LC_TIME=de_DE.UTF-8 +export LC_COLLATE="de_DE.UTF-8" +export LC_MONETARY=de_DE.UTF-8 +export LC_MESSAGES="de_DE.UTF-8" +export LC_PAPER=de_DE.UTF-8 +export LC_NAME=de_DE.UTF-8 +export LC_ADDRESS=de_DE.UTF-8 +export LC_TELEPHONE=de_DE.UTF-8 +export LC_MEASUREMENT=de_DE.UTF-8 +export LC_IDENTIFICATION=de_DE.UTF-8 +export LC_ALL= +python2.7 src/bitmessagemain.py diff --git a/build/compiletest.py b/build/compiletest.py new file mode 100755 index 00000000..fdbf7db1 --- /dev/null +++ b/build/compiletest.py @@ -0,0 +1,23 @@ +#!/usr/bin/python2.7 + +import ctypes +import fnmatch +import os +import sys +import traceback + +matches = [] +for root, dirnames, filenames in os.walk('src'): + for filename in fnmatch.filter(filenames, '*.py'): + matches.append(os.path.join(root, filename)) + +for filename in matches: + source = open(filename, 'r').read() + '\n' + try: + compile(source, filename, 'exec') + except Exception as e: + if 'win' in sys.platform: + ctypes.windll.user32.MessageBoxA(0, traceback.format_exc(), "Exception in " + filename, 1) + else: + print "Exception in %s: %s" % (filename, traceback.format_exc()) + sys.exit(1) diff --git a/build/mergepullrequest.sh b/build/mergepullrequest.sh new file mode 100755 index 00000000..35e87566 --- /dev/null +++ b/build/mergepullrequest.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "You must specify pull request number" + exit +fi + +git pull +git checkout v0.6 +git fetch origin pull/"$1"/head:"$1" +git merge --ff-only "$1" diff --git a/build/osx.sh b/build/osx.sh new file mode 100755 index 00000000..e58a49f4 --- /dev/null +++ b/build/osx.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# OS X Build script wrapper around the py2app script. +# This build can only be generated on OS X. +# Requires all build dependencies for Bitmessage +# Especially important is OpenSSL installed through brew + +export ARCHFLAGS="-arch i386 -arch x86_64" + +if [[ -z "$1" ]]; then + echo "Please supply a version number for this release as the first argument." + exit +fi + +echo "Creating OS X packages for Bitmessage." + +export PYBITMESSAGEVERSION=$1 + +cd src && python2.7 build_osx.py py2app + +if [[ $? = "0" ]]; then + hdiutil create -fs HFS+ -volname "Bitmessage" -srcfolder dist/Bitmessage.app dist/bitmessage-v$1.dmg +else + echo "Problem creating Bitmessage.app, stopping." + exit +fi diff --git a/build/updatetranslations.sh b/build/updatetranslations.sh new file mode 100755 index 00000000..ba5a3fdb --- /dev/null +++ b/build/updatetranslations.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +if [ ! -f "$1" ]; then + echo "$1 not found, please specify the file name for source" + exit +fi + +srcdir=`mktemp -d` + +unzip "$1" -d $srcdir + +for i in $srcdir/*ts; do + o=`basename $i|cut -b3-` + o="${o,,}" + o="${o//@/_}" + echo "$i -> $o" + mv "$i" "$HOME/src/PyBitmessage/src/translations/$o" +done + +rm -rf -- $srcdir + +lrelease-qt4 "$HOME/src/PyBitmessage/src/translations/bitmessage.pro" diff --git a/buildscripts/winbuild.sh b/buildscripts/winbuild.sh deleted file mode 100755 index 5b4fc37f..00000000 --- a/buildscripts/winbuild.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/bash - -# INIT -MACHINE_TYPE=`uname -m` -BASE_DIR=$(pwd) -PYTHON_VERSION=2.7.17 -PYQT_VERSION=4-4.11.4-gpl-Py2.7-Qt4.8.7 -OPENSSL_VERSION=1_0_2t -SRCPATH=~/Downloads - -#Functions -function download_sources_32 { - if [ ! -d ${SRCPATH} ]; then - mkdir -p ${SRCPATH} - fi - wget -P ${SRCPATH} -c -nc --content-disposition \ - https://www.python.org/ftp/python/${PYTHON_VERSION}/python-${PYTHON_VERSION}.msi \ - https://download.microsoft.com/download/1/1/1/1116b75a-9ec3-481a-a3c8-1777b5381140/vcredist_x86.exe \ - https://github.com/Bitmessage/ThirdPartyLibraries/blob/master/PyQt${PYQT_VERSION}-x32.exe?raw=true \ - https://github.com/Bitmessage/ThirdPartyLibraries/blob/master/Win32OpenSSL-${OPENSSL_VERSION}.exe?raw=true \ - https://github.com/Bitmessage/ThirdPartyLibraries/blob/master/pyopencl-2015.1-cp27-none-win32.whl?raw=true -} - -function download_sources_64 { - if [ ! -d ${SRCPATH} ]; then - mkdir -p ${SRCPATH} - fi - wget -P ${SRCPATH} -c -nc --content-disposition \ - http://www.python.org/ftp/python/${PYTHON_VERSION}/python-${PYTHON_VERSION}.amd64.msi \ - https://download.microsoft.com/download/d/2/4/d242c3fb-da5a-4542-ad66-f9661d0a8d19/vcredist_x64.exe \ - https://github.com/Bitmessage/ThirdPartyLibraries/blob/master/PyQt${PYQT_VERSION}-x64.exe?raw=true \ - https://github.com/Bitmessage/ThirdPartyLibraries/blob/master/Win64OpenSSL-${OPENSSL_VERSION}.exe?raw=true \ - https://github.com/Bitmessage/ThirdPartyLibraries/blob/master/pyopencl-2015.1-cp27-none-win_amd64.whl?raw=true -} - -function download_sources { - if [ ${MACHINE_TYPE} == 'x86_64' ]; then - download_sources_64 - else - download_sources_32 - fi -} - -function install_wine { - echo "Setting up wine" - if [ ${MACHINE_TYPE} == 'x86_64' ]; then - export WINEPREFIX=${HOME}/.wine64 WINEARCH=win64 - else - export WINEPREFIX=${HOME}/.wine32 WINEARCH=win32 - fi - rm -rf ${WINEPREFIX} - rm -rf packages/pyinstaller/{build,dist} -} - -function install_python(){ - cd ${SRCPATH} - if [ ${MACHINE_TYPE} == 'x86_64' ]; then - echo "Installing Python ${PYTHON_VERSION} 64b" - wine msiexec -i python-${PYTHON_VERSION}.amd64.msi /q /norestart - echo "Installing vcredist for 64 bit" - wine vcredist_x64.exe /q /norestart - else - echo "Installing Python ${PYTHON_VERSION} 32b" - wine msiexec -i python-${PYTHON_VERSION}.msi /q /norestart - # MSVCR 2008 required for Windows XP - cd ${SRCPATH} - echo "Installing vc_redist (2008) for 32 bit " - wine vcredist_x86.exe /Q - fi - echo "Upgrading pip" - wine python -m pip install --upgrade pip -} - -function install_pyqt(){ - if [ ${MACHINE_TYPE} == 'x86_64' ]; then - echo "Installing PyQt-${PYQT_VERSION} 64b" - wine PyQt${PYQT_VERSION}-x64.exe /S /WX - else - echo "Installing PyQt-${PYQT_VERSION} 32b" - wine PyQt${PYQT_VERSION}-x32.exe /S /WX - fi -} - -function install_openssl(){ - if [ ${MACHINE_TYPE} == 'x86_64' ]; then - echo "Installing OpenSSL ${OPENSSL_VERSION} 64b" - wine Win64OpenSSL-${OPENSSL_VERSION}.exe /q /norestart /silent /verysilent /sp- /suppressmsgboxes - else - echo "Installing OpenSSL ${OPENSSL_VERSION} 32b" - wine Win32OpenSSL-${OPENSSL_VERSION}.exe /q /norestart /silent /verysilent /sp- /suppressmsgboxes - fi -} - -function install_pyinstaller() -{ - cd ${BASE_DIR} - echo "Installing PyInstaller" - if [ ${MACHINE_TYPE} == 'x86_64' ]; then - wine python -m pip install pyinstaller - else - # 3.2.1 is the last version to work on XP - # see https://github.com/pyinstaller/pyinstaller/issues/2931 - wine python -m pip install -I pyinstaller==3.2.1 - fi -} - -function install_msgpack() -{ - cd ${BASE_DIR} - echo "Installing msgpack" - wine python -m pip install msgpack-python -} - -function install_pyopencl() -{ - cd ${SRCPATH} - echo "Installing PyOpenCL" - if [ ${MACHINE_TYPE} == 'x86_64' ]; then - wine python -m pip install pyopencl-2015.1-cp27-none-win_amd64.whl - else - wine python -m pip install pyopencl-2015.1-cp27-none-win32.whl - fi -} - - -function build_dll(){ - cd ${BASE_DIR} - cd src/bitmsghash - if [ ${MACHINE_TYPE} == 'x86_64' ]; then - echo "Create dll" - x86_64-w64-mingw32-g++ -D_WIN32 -Wall -O3 -march=native -I$HOME/.wine64/drive_c/OpenSSL-Win64/include -I/usr/x86_64-w64-mingw32/include -L$HOME/.wine64/drive_c/OpenSSL-Win64/lib -c bitmsghash.cpp - x86_64-w64-mingw32-g++ -static-libgcc -shared bitmsghash.o -D_WIN32 -O3 -march=native -I$HOME/.wine64/drive_c/OpenSSL-Win64/include -L$HOME/.wine64/drive_c/OpenSSL-Win64 -L/usr/lib/x86_64-linux-gnu/wine -fPIC -shared -lcrypt32 -leay32 -lwsock32 -o bitmsghash64.dll -Wl,--out-implib,bitmsghash.a - else - echo "Create dll" - i686-w64-mingw32-g++ -D_WIN32 -Wall -m32 -O3 -march=native -I$HOME/.wine32/drive_c/OpenSSL-Win32/include -I/usr/i686-w64-mingw32/include -L$HOME/.wine32/drive_c/OpenSSL-Win32/lib -c bitmsghash.cpp - i686-w64-mingw32-g++ -static-libgcc -shared bitmsghash.o -D_WIN32 -O3 -march=native -I$HOME/.wine32/drive_c/OpenSSL-Win32/include -L$HOME/.wine32/drive_c/OpenSSL-Win32/lib/MinGW -fPIC -shared -lcrypt32 -leay32 -lwsock32 -o bitmsghash32.dll -Wl,--out-implib,bitmsghash.a - fi -} - -function build_exe(){ - cd ${BASE_DIR} - cd packages/pyinstaller - wine pyinstaller bitmessagemain.spec -} - -# prepare on ubuntu -# dpkg --add-architecture i386 -# apt update -# apt -y install wget wine-stable wine-development winetricks mingw-w64 wine32 wine64 xvfb - - -download_sources -if [ "$1" == "--download-only" ]; then - exit -fi - -install_wine -install_python -install_pyqt -install_openssl -install_pyopencl -install_msgpack -install_pyinstaller -build_dll -build_exe diff --git a/checkdeps.py b/checkdeps.py index c3dedc1d..03782037 100755 --- a/checkdeps.py +++ b/checkdeps.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2 """ -Check dependencies and give recommendations about how to satisfy them +Check dependendies and give recommendations about how to satisfy them Limitations: @@ -164,7 +164,7 @@ if (not compiler or prereqs) and OPSYS in PACKAGE_MANAGER: if not compiler: compilerToPackages() prereqToPackages() - if prereqs and mandatory: + if mandatory: sys.exit(1) else: print("All the dependencies satisfied, you can install PyBitmessage") diff --git a/docs/_static/custom.css b/docs/_static/custom.css deleted file mode 100644 index 5192985c..00000000 --- a/docs/_static/custom.css +++ /dev/null @@ -1,4 +0,0 @@ -/* Hide "On GitHub" section from versions menu */ -li.wy-breadcrumbs-aside > a.fa { - display: none; -} diff --git a/docs/conf.py b/docs/conf.py index 3464e056..a4dae7c7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,24 +2,35 @@ """ Configuration file for the Sphinx documentation builder. -For a full list of options see the documentation: +This file does only contain a selection of the most common options. For a +full list see the documentation: http://www.sphinx-doc.org/en/master/config + +-- Path setup -------------------------------------------------------------- + +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. """ import os import sys +from sphinx.apidoc import main +from mock import Mock as MagicMock + +sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('../src')) +sys.path.insert(0, os.path.abspath('../src/pyelliptic')) -from importlib import import_module - -import version # noqa:E402 +import version # -- Project information ----------------------------------------------------- project = u'PyBitmessage' -copyright = u'2019, The Bitmessage Team' # pylint: disable=redefined-builtin +copyright = u'2018, The Bitmessage Team' # pylint: disable=redefined-builtin author = u'The Bitmessage Team' # The short X.Y version @@ -39,18 +50,15 @@ release = version # ones. extensions = [ 'sphinx.ext.autodoc', - 'sphinx.ext.coverage', # FIXME: unused - 'sphinx.ext.imgmath', # legacy unused + # 'sphinx.ext.doctest', # Currently disabled due to bad doctests 'sphinx.ext.intersphinx', - 'sphinx.ext.linkcode', - 'sphinx.ext.napoleon', 'sphinx.ext.todo', - 'sphinxcontrib.apidoc', + 'sphinx.ext.coverage', + 'sphinx.ext.imgmath', + 'sphinx.ext.viewcode', 'm2r', ] -default_role = 'obj' - # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -67,29 +75,23 @@ master_doc = 'index' # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -# language = None +language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path . -exclude_patterns = ['_build'] +exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' -# Don't prepend every class or function name with full module path -add_module_names = False - -# A list of ignored prefixes for module index sorting. -modindex_common_prefix = ['pybitmessage.'] - # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -102,10 +104,6 @@ html_theme = 'sphinx_rtd_theme' # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] -html_css_files = [ - 'custom.css', -] - # Custom sidebar templates, must be a dictionary that maps document names # to template names. # @@ -116,7 +114,10 @@ html_css_files = [ # # html_sidebars = {} -html_show_sourcelink = False +# Deal with long lines in source view +html_theme_options = { + 'page_width': '1366px', +} # -- Options for HTMLHelp output --------------------------------------------- @@ -198,74 +199,10 @@ epub_exclude_files = ['search.html'] # -- Extension configuration ------------------------------------------------- -autodoc_mock_imports = [ - 'debug', - 'pybitmessage.bitmessagekivy', - 'pybitmessage.bitmessageqt.addressvalidator', - 'pybitmessage.helper_startup', - 'pybitmessage.network.httpd', - 'pybitmessage.network.https', - 'ctypes', - 'dialog', - 'gi', - 'kivy', - 'logging', - 'msgpack', - 'numpy', - 'pkg_resources', - 'pycanberra', - 'pyopencl', - 'PyQt4', - 'pyxdg', - 'qrcode', - 'stem', -] -autodoc_member_order = 'bysource' - -# Apidoc settings -apidoc_module_dir = '../pybitmessage' -apidoc_output_dir = 'autodoc' -apidoc_excluded_paths = [ - 'bitmessagekivy', 'build_osx.py', - 'bitmessageqt/addressvalidator.py', 'bitmessageqt/migrationwizard.py', - 'bitmessageqt/newaddresswizard.py', 'helper_startup.py', - 'kivymd', 'main.py', 'navigationdrawer', 'network/http*', - 'pybitmessage', 'tests', 'version.py' -] -apidoc_module_first = True -apidoc_separate_modules = True -apidoc_toc_file = False -apidoc_extra_args = ['-a'] - -# Napoleon settings -napoleon_google_docstring = True - - -# linkcode function -def linkcode_resolve(domain, info): - """This generates source URL's for sphinx.ext.linkcode""" - if domain != 'py' or not info['module']: - return - try: - home = os.path.abspath(import_module('pybitmessage').__path__[0]) - mod = import_module(info['module']).__file__ - except ImportError: - return - repo = 'https://github.com/Bitmessage/PyBitmessage/blob/v0.6/src%s' - path = mod.replace(home, '') - if path != mod: - # put the link only for top level definitions - if len(info['fullname'].split('.')) > 1: - return - if path.endswith('.pyc'): - path = path[:-1] - return repo % path - - # -- Options for intersphinx extension --------------------------------------- # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/2.7/': None} +intersphinx_mapping = {'https://docs.python.org/': None} # -- Options for todo extension ---------------------------------------------- diff --git a/docs/contribute.dir/develop.dir/fabric.rst b/docs/contribute.dir/develop.dir/fabric.rst index 8003f33a..434ccf7b 100644 --- a/docs/contribute.dir/develop.dir/fabric.rst +++ b/docs/contribute.dir/develop.dir/fabric.rst @@ -1,2 +1,2 @@ -.. mdinclude:: ../../../fabfile/README.md +.. mdinclude:: fabfile/README.md diff --git a/docs/contribute.dir/develop.dir/opsec.rst b/docs/contribute.dir/develop.dir/opsec.rst index 1af43668..87bf4f49 100644 --- a/docs/contribute.dir/develop.dir/opsec.rst +++ b/docs/contribute.dir/develop.dir/opsec.rst @@ -21,12 +21,12 @@ If we are to make bold claims about protecting your privacy we should demonstrat - looking to audit - warrant canary -Digital footprint +Digital foootprint ------------------ Your internet use can reveal metadata you wouldn't expect. This can be connected with other information about you if you're not careful. - * Use separate addresses for different purposes + * Use separate addresses for different puprose * Don't make the same mistakes all the time * Your language use is unique. The more you type, the more you fingerprint yourself. The words you know and use often vs the words you don't know or use often. diff --git a/docs/contribute.dir/develop.dir/overview.rst b/docs/contribute.dir/develop.dir/overview.rst index 8bbc8299..e83d884b 100644 --- a/docs/contribute.dir/develop.dir/overview.rst +++ b/docs/contribute.dir/develop.dir/overview.rst @@ -11,17 +11,17 @@ Bitmessage makes use of fabric_ to define tasks such as building documentation o Code style and linters ---------------------- -We aim to be PEP8 compliant but we recognize that we have a long way still to go. Currently we have style and lint exceptions specified at the most specific place we can. We are ignoring certain issues project-wide in order to avoid alert-blindness, avoid style and lint regressions and to allow continuous integration to hook into the output from the tools. While it is hoped that all new changes pass the checks, fixing some existing violations are mini-projects in themselves. Current thinking on ignorable violations is reflected in the options and comments in setup.cfg. Module and line-level lint warnings represent refactoring opportunities. +We aim to be PEP8 compliant but we recognise that we have a long way still to go. Currently we have style and lint exceptions specified at the most specific place we can. We are ignoring certain issues project-wide in order to avoid alert-blindess, avoid style and lint regressions and to allow continuous integration to hook into the output from the tools. While it is hoped that all new changes pass the checks, fixing some existing violations are mini-projects in themselves. Current thinking on ignorable violations is reflected in the options and comments in setup.cfg. Module and line-level lint warnings represent refactoring opportunities. Pull requests ------------- -There is a template at PULL_REQUEST_TEMPLATE.md that appears in the pull-request description. Please replace this text with something appropriate to your changes based on the ideas in the template. +There is a template at PULL_REQUEST_TEMPLATE.md that appears in the pull-request description. Please replace this text with something appropriate to your changes based off the ideas in the template. Bike-shedding ------------- -Beyond having well-documented, Pythonic code with static analysis tool checks, extensive test coverage and powerful devops tools, what else can we have? Without violating any linters there is room for making arbitrary decisions solely for the sake of project consistency. These are the stuff of the pedant's PR comments. Rather than have such conversations in PR comments, we can lay out the result of discussion here. +Beyond having well-documented, Pythonic code with static analysis tool checks, extensive test coverage and powerful devops tools, what else can we have? Without violating any linters there is room for making arbirary decisions solely for the sake of project consistency. These are the stuff of the pedant's PR comments. Rather than have such conversations in PR comments, we can lay out the result of discussion here. I'm putting up a strawman for each topic here, mostly based on my memory of reading related Stack Overflow articles etc. If contributors feel strongly (and we don't have anything better to do) then maybe we can convince each other to update this section. @@ -49,7 +49,7 @@ British vs American spelling Dependency graph ---------------- -These images are not very useful right now but the aim is to tweak the settings of one or more of them to be informative, and/or divide them up into smaller graphs. +These images are not very useful right now but the aim is to tweak the settings of one or more of them to be informative, and/or divide them up into smaller grapghs. To re-build them, run `fab build_docs:dep_graphs=true`. Note that the dot graph takes a lot of time. @@ -62,7 +62,7 @@ To re-build them, run `fab build_docs:dep_graphs=true`. Note that the dot graph .. figure:: ../../../../_static/deps-sfdp.png :alt: SFDP graph of dependencies :width: 100 pc - + :index:`SFDP` graph of dependencies .. figure:: ../../../../_static/deps-dot.png diff --git a/docs/contribute.dir/processes.rst b/docs/contribute.dir/processes.rst index eb913325..8f0385d4 100644 --- a/docs/contribute.dir/processes.rst +++ b/docs/contribute.dir/processes.rst @@ -1,8 +1,8 @@ Processes ========= -In order to keep the Bitmessage project running, the team runs a number of systems and accounts that form the -development pipeline and continuous delivery process. We are always striving to improve this process. Towards +In other to keep the Bitmessage project running the team run a number of systems and accounts that form the +development pipeline and continuous delivery process. We are always striving to improve the process. Towards that end it is documented here. @@ -20,7 +20,7 @@ Our official Github_ account is Bitmessage. Our issue tracker is here as well. BitMessage ---------- -We eat our own dog food! You can send us bug reports via the [chan] bitmessage BM-2cWy7cvHoq3f1rYMerRJp8PT653jjSuEdY +We eat our own dog food! You can send us bug reports via the Bitmessage chan at xxx .. _website: https://bitmessage.org diff --git a/docs/index.rst b/docs/index.rst index cc8c9523..9dddfa28 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,20 +1,12 @@ .. mdinclude:: ../README.md -Documentation -------------- -.. toctree:: - :maxdepth: 3 - - autodoc/pybitmessage - -Legacy pages ------------- .. toctree:: :maxdepth: 2 + overview usage contribute - + Indices and tables ------------------ diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 55219ec5..00000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -m2r -sphinxcontrib-apidoc diff --git a/fabfile/README.md b/fabfile/README.md index 5e90147c..643aed8e 100644 --- a/fabfile/README.md +++ b/fabfile/README.md @@ -1,6 +1,6 @@ # Fabric -[Fabric](https://www.fabfile.org) is a Python library for performing devops tasks. You can think of it a bit like a +[Fabric](https://www.fabfile.org) is a Python library for performing devops tasks. You can thing of it a bit like a makefile on steroids for Python. Its api abstracts away the clunky way you would run shell commands in Python, check return values and manage stdio. Tasks may be targetted at particular hosts or group of hosts. @@ -46,7 +46,7 @@ Furthermore, you can use -- to run arbitrary shell commands rather than tasks: There are a number of advantages that should benefit us: - * Common tasks can be written in Python and executed consistently + * Common tasks can be writen in Python and executed consistently * Common tasks are now under source control * All developers can run the same commands, if the underlying command sequence for a task changes (after review, obv) the user does not have to care diff --git a/packages/README.md b/packages/README.md index 2905ec20..ed2df3cc 100644 --- a/packages/README.md +++ b/packages/README.md @@ -15,7 +15,7 @@ OSX: https://github.com/Bitmessage/PyBitmessage/releases -Works on OSX 10.7.5 or higher +Wors on OSX 10.7.5 or higher Arch linux: diff --git a/packages/pyinstaller/bitmessagemain.spec b/packages/pyinstaller/bitmessagemain.spec index 92e52f6a..06cf6e76 100644 --- a/packages/pyinstaller/bitmessagemain.spec +++ b/packages/pyinstaller/bitmessagemain.spec @@ -1,89 +1,65 @@ import ctypes import os import time -import sys - -if ctypes.sizeof(ctypes.c_voidp) == 4: - arch=32 -else: - arch=64 - -sslName = 'OpenSSL-Win%s' % ("32" if arch == 32 else "64") -site_root = os.path.abspath(HOMEPATH) -spec_root = os.path.abspath(SPECPATH) -cdrivePath = site_root[0:3] -srcPath = os.path.join(spec_root[:-20], "src") -qtBase = "PyQt4" -openSSLPath = os.path.join(cdrivePath, sslName) -msvcrDllPath = os.path.join(cdrivePath, "windows", "system32") -pythonDllPath = os.path.join(cdrivePath, "Python27") -outPath = os.path.join(spec_root, "bitmessagemain") - -importPath = srcPath -sys.path.insert(0,importPath) -os.chdir(sys.path[0]) -from version import softwareVersion +srcPath = "C:\\src\\PyBitmessage\\src\\" +qtPath = "C:\\Qt-4.8.7\\" +openSSLPath = "C:\\OpenSSL-1.0.2j\\bin\\" +outPath = "C:\\src\\PyInstaller-3.2.1\\bitmessagemain" today = time.strftime("%Y%m%d") snapshot = False os.rename(os.path.join(srcPath, '__init__.py'), os.path.join(srcPath, '__init__.py.backup')) # -*- mode: python -*- -a = Analysis( - [os.path.join(srcPath, 'bitmessagemain.py')], +a = Analysis([srcPath + 'bitmessagemain.py'], pathex=[outPath], - hiddenimports=['bitmessageqt.languagebox', 'pyopencl','numpy', 'win32com' , 'setuptools.msvc' ,'_cffi_backend'], + hiddenimports=[], hookspath=None, - runtime_hooks=None - ) + runtime_hooks=None) os.rename(os.path.join(srcPath, '__init__.py.backup'), os.path.join(srcPath, '__init__.py')) def addTranslations(): import os extraDatas = [] - for file_ in os.listdir(os.path.join(srcPath, 'translations')): - if file_[-3:] != ".qm": + for file in os.listdir(srcPath + 'translations'): + if file[-3:] != ".qm": continue - extraDatas.append((os.path.join('translations', file_), - os.path.join(srcPath, 'translations', file_), 'DATA')) - for libdir in sys.path: - qtdir = os.path.join(libdir, qtBase, 'translations') - if os.path.isdir(qtdir): - break - if not os.path.isdir(qtdir): - return extraDatas - for file_ in os.listdir(qtdir): - if file_[0:3] != "qt_" or file_[5:8] != ".qm": + extraDatas.append((os.path.join('translations', file), os.path.join(srcPath, 'translations', file), 'DATA')) + for file in os.listdir(qtPath + 'translations'): + if file[0:3] != "qt_" or file[5:8] != ".qm": continue - extraDatas.append((os.path.join('translations', file_), - os.path.join(qtdir, file_), 'DATA')) + extraDatas.append((os.path.join('translations', file), os.path.join(qtPath, 'translations', file), 'DATA')) return extraDatas def addUIs(): import os extraDatas = [] - for file_ in os.listdir(os.path.join(srcPath, 'bitmessageqt')): - if file_[-3:] != ".ui": + for file in os.listdir(srcPath + 'bitmessageqt'): + if file[-3:] != ".ui": continue - extraDatas.append((os.path.join('ui', file_), os.path.join(srcPath, - 'bitmessageqt', file_), 'DATA')) + extraDatas.append((os.path.join('ui', file), os.path.join(srcPath, 'bitmessageqt', file), 'DATA')) return extraDatas # append the translations directory a.datas += addTranslations() a.datas += addUIs() +if ctypes.sizeof(ctypes.c_voidp) == 4: + arch=32 +else: + arch=64 -a.binaries += [('libeay32.dll', os.path.join(openSSLPath, 'libeay32.dll'), 'BINARY'), - ('python27.dll', os.path.join(pythonDllPath, 'python27.dll'), 'BINARY'), - (os.path.join('bitmsghash', 'bitmsghash%i.dll' % (arch)), os.path.join(srcPath, 'bitmsghash', 'bitmsghash%i.dll' % (arch)), 'BINARY'), - (os.path.join('bitmsghash', 'bitmsghash.cl'), os.path.join(srcPath, 'bitmsghash', 'bitmsghash.cl'), 'BINARY'), - (os.path.join('sslkeys', 'cert.pem'), os.path.join(srcPath, 'sslkeys', 'cert.pem'), 'BINARY'), - (os.path.join('sslkeys', 'key.pem'), os.path.join(srcPath, 'sslkeys', 'key.pem'), 'BINARY') - ] +a.binaries += [('libeay32.dll', openSSLPath + 'libeay32.dll', 'BINARY'), + (os.path.join('bitmsghash', 'bitmsghash%i.dll' % (arch)), os.path.join(srcPath, 'bitmsghash', 'bitmsghash%i.dll' % (arch)), 'BINARY'), + (os.path.join('bitmsghash', 'bitmsghash.cl'), os.path.join(srcPath, 'bitmsghash', 'bitmsghash.cl'), 'BINARY'), + (os.path.join('sslkeys', 'cert.pem'), os.path.join(srcPath, 'sslkeys', 'cert.pem'), 'BINARY'), + (os.path.join('sslkeys', 'key.pem'), os.path.join(srcPath, 'sslkeys', 'key.pem'), 'BINARY') + ] +with open(os.path.join(srcPath, 'version.py'), 'rt') as f: + softwareVersion = f.readline().split('\'')[1] fname = 'Bitmessage_%s_%s.exe' % ("x86" if arch == 32 else "x64", softwareVersion) if snapshot: @@ -96,18 +72,8 @@ exe = EXE(pyz, a.zipfiles, a.datas, a.binaries, - [], name=fname, debug=False, strip=None, upx=False, console=False, icon= os.path.join(srcPath, 'images', 'can-icon.ico')) - -coll = COLLECT(exe, - a.binaries, - a.zipfiles, - a.datas, - strip=False, - upx=False, - name='main') - diff --git a/pybitmessage b/pybitmessage deleted file mode 120000 index e8310385..00000000 --- a/pybitmessage +++ /dev/null @@ -1 +0,0 @@ -src \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index a4e0547c..3236eed1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,17 +1,14 @@ # Since there is overlap in the violations that the different tools check for, it makes sense to quiesce some warnings # in some tools if those warnings in other tools are preferred. This avoids the need to add duplicate lint warnings. -# max-line-length should be removed ASAP! - [pycodestyle] max-line-length = 119 [flake8] max-line-length = 119 -ignore = E722,F841,W503 +ignore = E722,F841 # E722: pylint is preferred for bare-except # F841: pylint is preferred for unused-variable -# W503: deprecated: https://bugs.python.org/issue26763 - https://www.python.org/dev/peps/pep-0008/#should-a-line-break-before-or-after-a-binary-operator # pylint honours the [MESSAGES CONTROL] section # as well as [MASTER] section diff --git a/setup.py b/setup.py index 3e585b6b..e3f97bac 100644 --- a/setup.py +++ b/setup.py @@ -16,8 +16,13 @@ EXTRAS_REQUIRE = { 'prctl': ['python_prctl'], # Named threads 'qrcode': ['qrcode'], 'sound;platform_system=="Windows"': ['winsound'], - 'tor': ['stem'], - 'docs': ['sphinx', 'sphinxcontrib-apidoc', 'm2r'] + 'docs': [ + 'sphinx', # fab build_docs + 'graphviz', # fab build_docs + 'curses', # src/depends.py + 'python2-pythondialog', # src/depends.py + 'm2r', # fab build_docs + ] } @@ -64,6 +69,7 @@ if __name__ == "__main__": 'pybitmessage.network', 'pybitmessage.plugins', 'pybitmessage.pyelliptic', + 'pybitmessage.socks', 'pybitmessage.storage' ] @@ -141,17 +147,10 @@ if __name__ == "__main__": 'libmessaging =' 'pybitmessage.plugins.indicator_libmessaging [gir]' ], - 'bitmessage.proxyconfig': [ - 'stem = pybitmessage.plugins.proxyconfig_stem [tor]' - ], # 'console_scripts': [ # 'pybitmessage = pybitmessage.bitmessagemain:main' # ] }, scripts=['src/pybitmessage'], - cmdclass={'install': InstallCmd}, - command_options={ - 'build_sphinx': { - 'source_dir': ('setup.py', 'docs')} - } + cmdclass={'install': InstallCmd} ) diff --git a/src/.buildozer/android/platform/python-for-android-new-toolchain b/src/.buildozer/android/platform/python-for-android-new-toolchain deleted file mode 160000 index 5aa322da..00000000 --- a/src/.buildozer/android/platform/python-for-android-new-toolchain +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5aa322da9179dae305fde5af1db516c1ad9baea4 diff --git a/src/addresses.py b/src/addresses.py index 0d3d4400..533ec169 100644 --- a/src/addresses.py +++ b/src/addresses.py @@ -1,22 +1,25 @@ """ -Operations with addresses +src/addresses.py +================ + """ # pylint: disable=redefined-outer-name,inconsistent-return-statements + import hashlib from binascii import hexlify, unhexlify from struct import pack, unpack from debug import logger + ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" def encodeBase58(num, alphabet=ALPHABET): """Encode a number in Base X - Args: - num: The number to encode - alphabet: The alphabet to use for encoding + `num`: The number to encode + `alphabet`: The alphabet to use for encoding """ if num == 0: return alphabet[0] @@ -24,6 +27,7 @@ def encodeBase58(num, alphabet=ALPHABET): base = len(alphabet) while num: rem = num % base + # print 'num is:', num num = num // base arr.append(alphabet[rem]) arr.reverse() @@ -33,9 +37,9 @@ def encodeBase58(num, alphabet=ALPHABET): def decodeBase58(string, alphabet=ALPHABET): """Decode a Base X encoded string into the number - Args: - string: The encoded string - alphabet: The alphabet to use for encoding + Arguments: + - `string`: The encoded string + - `alphabet`: The alphabet to use for encoding """ base = len(alphabet) num = 0 @@ -50,20 +54,11 @@ def decodeBase58(string, alphabet=ALPHABET): return num -class varintEncodeError(Exception): - """Exception class for encoding varint""" - pass - - -class varintDecodeError(Exception): - """Exception class for decoding varint data""" - pass - - def encodeVarint(integer): """Convert integer into varint bytes""" if integer < 0: - raise varintEncodeError('varint cannot be < 0') + logger.error('varint cannot be < 0') + raise SystemExit if integer < 253: return pack('>B', integer) if integer >= 253 and integer < 65536: @@ -73,7 +68,13 @@ def encodeVarint(integer): if integer >= 4294967296 and integer < 18446744073709551616: return pack('>B', 255) + pack('>Q', integer) if integer >= 18446744073709551616: - raise varintEncodeError('varint cannot be >= 18446744073709551616') + logger.error('varint cannot be >= 18446744073709551616') + raise SystemExit + + +class varintDecodeError(Exception): + """Exception class for decoding varint data""" + pass def decodeVarint(data): @@ -178,8 +179,7 @@ def decodeAddress(address): returns (status, address version number, stream number, data (almost certainly a ripe hash)) """ - # pylint: disable=too-many-return-statements,too-many-statements - # pylint: disable=too-many-branches + # pylint: disable=too-many-return-statements,too-many-statements,too-many-return-statements,too-many-branches address = str(address).strip() diff --git a/src/alice.png b/src/alice.png deleted file mode 100644 index 3f6c6a928b708897009c3b211e6825d252fc3389..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 669 zcmeAS@N?(olHy`uVBq!ia0vp^A3&Ic4M^IBzMRCsz?9+Q8b-XjVE4hJ7M zv9>6(m~tGv^iO$F`XbNoFM1l<^lEQT>)2s;ApVyWBZq{5fkFZZI~-_ea0FsT#%3U9 zW@2OE0b!7WISZv6^=i*wc^;j+Lq!@W0MX@e0HO=71EPyV0-_6MESe&iu`opzzO}cx zzuN}S&)=F@$A11i8{A@;3cRi(s3>Svx&4OsnX7Enet+M7YeORr*K*w80EGZt7TuXR z9q~z1uu#%jj&{Mb_je=EaQ!{E3SP5U-~OJ?+#H{Qh%8`4p+**J+(2R!t_T)4$chf= pdbz|LV=x1!0kp`%jL{DZ 0: - logger.warning( - 'Failed to start API listener on port %s', port) port = random.randint(32767, 65535) se = StoppableXMLRPCServer( (BMConfigParser().get( @@ -109,9 +112,8 @@ class singleAPI(StoppableThread): continue else: if attempt > 0: - logger.warning('Setting apiport to %s', port) BMConfigParser().set( - 'bitmessagesettings', 'apiport', str(port)) + "bitmessagesettings", "apiport", str(port)) BMConfigParser().save() break se.register_introspection_functions() @@ -137,11 +139,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): """ This is one of several classes that constitute the API - This class was written by Vaibhav Bhatia. - Modified by Jonathan Warren (Atheros). + This class was written by Vaibhav Bhatia. Modified by Jonathan Warren (Atheros). http://code.activestate.com/recipes/501148-xmlrpc-serverclient-which-does-cookie-handling-and/ """ - # pylint: disable=too-many-public-methods def do_POST(self): """ @@ -178,8 +178,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): # SimpleXMLRPCDispatcher. To maintain backwards compatibility, # check to see if a subclass implements _dispatch and dispatch # using that method if present. - # pylint: disable=protected-access - response = self.server._marshaled_dispatch( + response = self.server._marshaled_dispatch( # pylint: disable=protected-access data, getattr(self, '_dispatch', None) ) except BaseException: # This should only happen if the module is buggy @@ -217,10 +216,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): _, encstr = self.headers.get('Authorization').split() emailid, password = encstr.decode('base64').split(':') return ( - emailid == BMConfigParser().get( - 'bitmessagesettings', 'apiusername') and - password == BMConfigParser().get( - 'bitmessagesettings', 'apipassword') + emailid == BMConfigParser().get('bitmessagesettings', 'apiusername') and + password == BMConfigParser().get('bitmessagesettings', 'apipassword') ) else: logger.warning( @@ -257,14 +254,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): if status == 'invalidcharacters': raise APIError(9, 'Invalid characters in address: ' + address) if status == 'versiontoohigh': - raise APIError( - 10, - 'Address version number too high (or zero) in address: ' + - address) + raise APIError(10, 'Address version number too high (or zero) in address: ' + address) if status == 'varintmalformed': raise APIError(26, 'Malformed varint in address: ' + address) - raise APIError( - 7, 'Could not decode address: %s : %s' % (address, status)) + raise APIError(7, 'Could not decode address: %s : %s' % (address, status)) if addressVersionNumber < 2 or addressVersionNumber > 4: raise APIError( 11, 'The address version number currently must be 2, 3 or 4.' @@ -282,9 +275,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): def HandleListAddresses(self, method): """Handle a request to list addresses""" + data = '{"addresses":[' for addressInKeysFile in BMConfigParser().addresses(): - status, addressVersionNumber, streamNumber, hash01 = decodeAddress( + status, addressVersionNumber, streamNumber, hash01 = decodeAddress( # pylint: disable=unused-variable addressInKeysFile) if len(data) > 20: data += ',' @@ -388,19 +382,16 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): elif len(params) == 3: label, eighteenByteRipe, totalDifficulty = params nonceTrialsPerByte = int( - defaults.networkDefaultProofOfWorkNonceTrialsPerByte * - totalDifficulty) + defaults.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty) payloadLengthExtraBytes = BMConfigParser().get( 'bitmessagesettings', 'defaultpayloadlengthextrabytes') elif len(params) == 4: label, eighteenByteRipe, totalDifficulty, \ smallMessageDifficulty = params nonceTrialsPerByte = int( - defaults.networkDefaultProofOfWorkNonceTrialsPerByte * - totalDifficulty) + defaults.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty) payloadLengthExtraBytes = int( - defaults.networkDefaultPayloadLengthExtraBytes * - smallMessageDifficulty) + defaults.networkDefaultPayloadLengthExtraBytes * smallMessageDifficulty) else: raise APIError(0, 'Too many parameters!') label = self._decode(label, "base64") @@ -418,7 +409,6 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): def HandleCreateDeterministicAddresses(self, params): """Handle a request to create a deterministic address""" - # pylint: disable=too-many-branches, too-many-statements if not params: raise APIError(0, 'I need parameters!') @@ -474,8 +464,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): passphrase, numberOfAddresses, addressVersionNumber, \ streamNumber, eighteenByteRipe, totalDifficulty = params nonceTrialsPerByte = int( - defaults.networkDefaultProofOfWorkNonceTrialsPerByte * - totalDifficulty) + defaults.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty) payloadLengthExtraBytes = BMConfigParser().get( 'bitmessagesettings', 'defaultpayloadlengthextrabytes') @@ -484,11 +473,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): streamNumber, eighteenByteRipe, totalDifficulty, \ smallMessageDifficulty = params nonceTrialsPerByte = int( - defaults.networkDefaultProofOfWorkNonceTrialsPerByte * - totalDifficulty) + defaults.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty) payloadLengthExtraBytes = int( - defaults.networkDefaultPayloadLengthExtraBytes * - smallMessageDifficulty) + defaults.networkDefaultPayloadLengthExtraBytes * smallMessageDifficulty) else: raise APIError(0, 'Too many parameters!') if not passphrase: @@ -622,8 +609,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): label = str_chan + ' ' + passphrase except BaseException: label = str_chan + ' ' + repr(passphrase) - status, addressVersionNumber, streamNumber, toRipe = ( - self._verifyAddress(suppliedAddress)) + + status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress( # pylint: disable=unused-variable + suppliedAddress) suppliedAddress = addBMIfNotPresent(suppliedAddress) queues.apiAddressGeneratorReturnQueue.queue.clear() queues.addressGeneratorQueue.put(( @@ -646,8 +634,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): raise APIError(0, 'I need parameters.') elif len(params) == 1: address, = params - status, addressVersionNumber, streamNumber, toRipe = ( - self._verifyAddress(address)) + # pylint: disable=unused-variable + status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(address) address = addBMIfNotPresent(address) if not BMConfigParser().has_section(address): raise APIError( @@ -668,8 +656,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): raise APIError(0, 'I need parameters.') elif len(params) == 1: address, = params - status, addressVersionNumber, streamNumber, toRipe = ( - self._verifyAddress(address)) + # pylint: disable=unused-variable + status, addressVersionNumber, streamNumber, toRipe = self._verifyAddress(address) address = addBMIfNotPresent(address) if not BMConfigParser().has_section(address): raise APIError( @@ -681,7 +669,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): shared.reloadMyAddressHashes() return 'success' - def HandleGetAllInboxMessages(self, params): + def HandleGetAllInboxMessages(self, params): # pylint: disable=unused-argument """Handle a request to get all inbox messages""" queryreturn = sqlQuery( @@ -709,7 +697,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): data += ']}' return data - def HandleGetAllInboxMessageIds(self, params): + def HandleGetAllInboxMessageIds(self, params): # pylint: disable=unused-argument """Handle a request to get all inbox message IDs""" queryreturn = sqlQuery( @@ -768,7 +756,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): data += ']}' return data - def HandleGetAllSentMessages(self, params): + def HandleGetAllSentMessages(self, params): # pylint: disable=unused-argument """Handle a request to get all sent messages""" queryreturn = sqlQuery( @@ -797,7 +785,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): data += ']}' return data - def HandleGetAllSentMessageIds(self, params): + def HandleGetAllSentMessageIds(self, params): # pylint: disable=unused-argument """Handle a request to get all sent message IDs""" queryreturn = sqlQuery( @@ -888,7 +876,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): data = '{"sentMessages":[' for row in queryreturn: msgid, toAddress, fromAddress, subject, lastactiontime, message, \ - encodingtype, status, ackdata = row + encodingtype, status, ackdata = row # pylint: disable=unused-variable subject = shared.fixPotentiallyInvalidUTF8Data(subject) message = shared.fixPotentiallyInvalidUTF8Data(message) if len(data) > 25: @@ -967,7 +955,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', msgid) return 'Trashed sent message (assuming message existed).' - def HandleSendMessage(self, params): # pylint: disable=too-many-locals + def HandleSendMessage(self, params): """Handle a request to send a message""" if not params: @@ -998,6 +986,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): TTL = 28 * 24 * 60 * 60 toAddress = addBMIfNotPresent(toAddress) fromAddress = addBMIfNotPresent(fromAddress) + # pylint: disable=unused-variable status, addressVersionNumber, streamNumber, toRipe = \ self._verifyAddress(toAddress) self._verifyAddress(fromAddress) @@ -1171,9 +1160,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): queues.UISignalQueue.put(('rerenderSubscriptions', '')) return 'Deleted subscription if it existed.' - def ListSubscriptions(self, params): + def ListSubscriptions(self, params): # pylint: disable=unused-argument """Handle a request to list susbcriptions""" + # pylint: disable=unused-variable queryreturn = sqlQuery( "SELECT label, address, enabled FROM subscriptions") data = {'subscriptions': []} @@ -1208,15 +1198,12 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): ) with shared.printLock: print( - '(For msg message via API) Doing proof of work.' - 'Total required difficulty:', + '(For msg message via API) Doing proof of work. Total required difficulty:', float( requiredAverageProofOfWorkNonceTrialsPerByte ) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte, 'Required small message difficulty:', - float( - requiredPayloadLengthExtraBytes - ) / defaults.networkDefaultPayloadLengthExtraBytes, + float(requiredPayloadLengthExtraBytes) / defaults.networkDefaultPayloadLengthExtraBytes, ) powStartTime = time.time() initialHash = hashlib.sha512(encryptedPayload).digest() @@ -1225,9 +1212,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): print '(For msg message via API) Found proof of work', trialValue, 'Nonce:', nonce try: print( - 'POW took', int(time.time() - powStartTime), - 'seconds.', nonce / (time.time() - powStartTime), - 'nonce trials per second.', + 'POW took', int(time.time() - powStartTime), 'seconds.', + nonce / (time.time() - powStartTime), 'nonce trials per second.', ) except BaseException: pass @@ -1254,7 +1240,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=?", ackdata) return 'Trashed sent message (assuming message existed).' - def HandleDissimatePubKey(self, params): + def HandleDissimatePubKey(self, params): # pylint: disable=unused-argument """Handle a request to disseminate a public key""" # The device issuing this command to PyBitmessage supplies a pubkey @@ -1283,6 +1269,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): pubkeyReadPosition += 8 else: pubkeyReadPosition += 4 + # pylint: disable=unused-variable addressVersion, addressVersionLength = decodeVarint( payload[pubkeyReadPosition:pubkeyReadPosition + 10]) pubkeyReadPosition += addressVersionLength @@ -1341,7 +1328,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): data += ']}' return data - def HandleClientStatus(self, params): + def HandleClientStatus(self, params): # pylint: disable=unused-argument """Handle a request to get the status of the client""" connections_num = len(network.stats.connectedHostsList()) diff --git a/src/bitmessagecli.py b/src/bitmessagecli.py index 01dbc9bb..02fed7e9 100644 --- a/src/bitmessagecli.py +++ b/src/bitmessagecli.py @@ -13,15 +13,15 @@ TODO: fix the following (currently ignored) violations: """ +import xmlrpclib import datetime import imghdr -import json import ntpath -import os +import json import socket -import sys import time -import xmlrpclib +import sys +import os from bmconfigparser import BMConfigParser diff --git a/src/bitmessagecurses/__init__.py b/src/bitmessagecurses/__init__.py index d8daeef7..dc6e8a0c 100644 --- a/src/bitmessagecurses/__init__.py +++ b/src/bitmessagecurses/__init__.py @@ -1,39 +1,40 @@ -""" -Bitmessage commandline interface -""" # Copyright (c) 2014 Luke Montalvo # This file adds a alternative commandline interface, feel free to critique and fork -# +# # This has only been tested on Arch Linux and Linux Mint # Dependencies: # * from python2-pip # * python2-pythondialog # * dialog -import ConfigParser -import curses import os import sys +import StringIO +from textwrap import * + import time -from textwrap import fill +from time import strftime, localtime from threading import Timer +import curses +import dialog from dialog import Dialog +from helper_sql import * +from helper_ackPayload import genAckPayload + +from addresses import * +import ConfigParser +from bmconfigparser import BMConfigParser +from inventory import Inventory import l10n -import network.stats +from pyelliptic.openssl import OpenSSL import queues import shared import shutdown - -from addresses import addBMIfNotPresent, decodeAddress -from bmconfigparser import BMConfigParser -from helper_ackPayload import genAckPayload -from helper_sql import sqlExecute, sqlQuery -from inventory import Inventory -# pylint: disable=global-statement +import network.stats -quit_ = False +quit = False menutab = 1 menu = ["Inbox", "Send", "Sent", "Your Identities", "Subscriptions", "Address Book", "Blacklist", "Network Status"] naptime = 100 @@ -59,195 +60,156 @@ bwtype = "black" BROADCAST_STR = "[Broadcast subscribers]" - -class printLog(object): - """Printing logs""" - # pylint: disable=no-self-use - +class printLog: def write(self, output): - """Write logs""" global log log += output - def flush(self): - """Flush logs""" pass - - -class errLog(object): - """Error logs""" - # pylint: disable=no-self-use - +class errLog: def write(self, output): - """Write error logs""" global log - log += "!" + output - + log += "!"+output def flush(self): - """Flush error logs""" pass - - printlog = printLog() errlog = errLog() def cpair(a): - """Color pairs""" r = curses.color_pair(a) - if r not in range(1, curses.COLOR_PAIRS - 1): + if r not in range(1, curses.COLOR_PAIRS-1): r = curses.color_pair(0) return r - - def ascii(s): - """ASCII values""" r = "" for c in s: if ord(c) in range(128): r += c return r - def drawmenu(stdscr): - """Creating menu's""" menustr = " " - for i, _ in enumerate(menu): - if menutab == i + 1: + for i in range(0, len(menu)): + if menutab == i+1: menustr = menustr[:-1] menustr += "[" - menustr += str(i + 1) + menu[i] - if menutab == i + 1: + menustr += str(i+1)+menu[i] + if menutab == i+1: menustr += "] " - elif i != len(menu) - 1: + elif i != len(menu)-1: menustr += " " stdscr.addstr(2, 5, menustr, curses.A_UNDERLINE) - def set_background_title(d, title): - """Setting background title""" try: d.set_background_title(title) except: d.add_persistent_args(("--backtitle", title)) - def scrollbox(d, text, height=None, width=None): - """Setting scroll box""" try: - d.scrollbox(text, height, width, exit_label="Continue") + d.scrollbox(text, height, width, exit_label = "Continue") except: - d.msgbox(text, height or 0, width or 0, ok_label="Continue") - + d.msgbox(text, height or 0, width or 0, ok_label = "Continue") def resetlookups(): - """Reset the Inventory Lookups""" global inventorydata inventorydata = Inventory().numberOfInventoryLookupsPerformed Inventory().numberOfInventoryLookupsPerformed = 0 Timer(1, resetlookups, ()).start() - - def drawtab(stdscr): - """Method for drawing different tabs""" - # pylint: disable=too-many-branches, too-many-statements - if menutab in range(1, len(menu) + 1): - if menutab == 1: # Inbox + if menutab in range(1, len(menu)+1): + if menutab == 1: # Inbox stdscr.addstr(3, 5, "To", curses.A_BOLD) stdscr.addstr(3, 40, "From", curses.A_BOLD) stdscr.addstr(3, 80, "Subject", curses.A_BOLD) stdscr.addstr(3, 120, "Time Received", curses.A_BOLD) stdscr.hline(4, 5, '-', 121) - for i, item in enumerate(inbox[max(min(len(inbox) - curses.LINES + 6, inboxcur - 5), 0):]): - if 6 + i < curses.LINES: + for i, item in enumerate(inbox[max(min(len(inbox)-curses.LINES+6, inboxcur-5), 0):]): + if 6+i < curses.LINES: a = 0 - if i == inboxcur - max(min(len(inbox) - curses.LINES + 6, inboxcur - 5), 0): - # Highlight current address + if i == inboxcur - max(min(len(inbox)-curses.LINES+6, inboxcur-5), 0): # Highlight current address a = a | curses.A_REVERSE - if item[7] is False: # If not read, highlight + if item[7] == False: # If not read, highlight a = a | curses.A_BOLD - stdscr.addstr(5 + i, 5, item[1][:34], a) - stdscr.addstr(5 + i, 40, item[3][:39], a) - stdscr.addstr(5 + i, 80, item[5][:39], a) - stdscr.addstr(5 + i, 120, item[6][:39], a) - elif menutab == 3: # Sent + stdscr.addstr(5+i, 5, item[1][:34], a) + stdscr.addstr(5+i, 40, item[3][:39], a) + stdscr.addstr(5+i, 80, item[5][:39], a) + stdscr.addstr(5+i, 120, item[6][:39], a) + elif menutab == 3: # Sent stdscr.addstr(3, 5, "To", curses.A_BOLD) stdscr.addstr(3, 40, "From", curses.A_BOLD) stdscr.addstr(3, 80, "Subject", curses.A_BOLD) stdscr.addstr(3, 120, "Status", curses.A_BOLD) stdscr.hline(4, 5, '-', 121) - for i, item in enumerate(sentbox[max(min(len(sentbox) - curses.LINES + 6, sentcur - 5), 0):]): - if 6 + i < curses.LINES: + for i, item in enumerate(sentbox[max(min(len(sentbox)-curses.LINES+6, sentcur-5), 0):]): + if 6+i < curses.LINES: a = 0 - if i == sentcur - max(min(len(sentbox) - curses.LINES + 6, sentcur - 5), 0): - # Highlight current address + if i == sentcur - max(min(len(sentbox)-curses.LINES+6, sentcur-5), 0): # Highlight current address a = a | curses.A_REVERSE - stdscr.addstr(5 + i, 5, item[0][:34], a) - stdscr.addstr(5 + i, 40, item[2][:39], a) - stdscr.addstr(5 + i, 80, item[4][:39], a) - stdscr.addstr(5 + i, 120, item[5][:39], a) - elif menutab == 2 or menutab == 4: # Send or Identities + stdscr.addstr(5+i, 5, item[0][:34], a) + stdscr.addstr(5+i, 40, item[2][:39], a) + stdscr.addstr(5+i, 80, item[4][:39], a) + stdscr.addstr(5+i, 120, item[5][:39], a) + elif menutab == 2 or menutab == 4: # Send or Identities stdscr.addstr(3, 5, "Label", curses.A_BOLD) stdscr.addstr(3, 40, "Address", curses.A_BOLD) stdscr.addstr(3, 80, "Stream", curses.A_BOLD) stdscr.hline(4, 5, '-', 81) - for i, item in enumerate(addresses[max(min(len(addresses) - curses.LINES + 6, addrcur - 5), 0):]): - if 6 + i < curses.LINES: + for i, item in enumerate(addresses[max(min(len(addresses)-curses.LINES+6, addrcur-5), 0):]): + if 6+i < curses.LINES: a = 0 - if i == addrcur - max(min(len(addresses) - curses.LINES + 6, addrcur - 5), 0): - # Highlight current address + if i == addrcur - max(min(len(addresses)-curses.LINES+6, addrcur-5), 0): # Highlight current address a = a | curses.A_REVERSE - if item[1] and item[3] not in [8, 9]: # Embolden enabled, non-special addresses + if item[1] == True and item[3] not in [8,9]: # Embolden enabled, non-special addresses a = a | curses.A_BOLD - stdscr.addstr(5 + i, 5, item[0][:34], a) - stdscr.addstr(5 + i, 40, item[2][:39], cpair(item[3]) | a) - stdscr.addstr(5 + i, 80, str(1)[:39], a) - elif menutab == 5: # Subscriptions + stdscr.addstr(5+i, 5, item[0][:34], a) + stdscr.addstr(5+i, 40, item[2][:39], cpair(item[3]) | a) + stdscr.addstr(5+i, 80, str(1)[:39], a) + elif menutab == 5: # Subscriptions stdscr.addstr(3, 5, "Label", curses.A_BOLD) stdscr.addstr(3, 80, "Address", curses.A_BOLD) stdscr.addstr(3, 120, "Enabled", curses.A_BOLD) stdscr.hline(4, 5, '-', 121) - for i, item in enumerate(subscriptions[max(min(len(subscriptions) - curses.LINES + 6, subcur - 5), 0):]): - if 6 + i < curses.LINES: + for i, item in enumerate(subscriptions[max(min(len(subscriptions)-curses.LINES+6, subcur-5), 0):]): + if 6+i < curses.LINES: a = 0 - if i == subcur - max(min(len(subscriptions) - curses.LINES + 6, subcur - 5), 0): - # Highlight current address + if i == subcur - max(min(len(subscriptions)-curses.LINES+6, subcur-5), 0): # Highlight current address a = a | curses.A_REVERSE - if item[2]: # Embolden enabled subscriptions + if item[2] == True: # Embolden enabled subscriptions a = a | curses.A_BOLD - stdscr.addstr(5 + i, 5, item[0][:74], a) - stdscr.addstr(5 + i, 80, item[1][:39], a) - stdscr.addstr(5 + i, 120, str(item[2]), a) - elif menutab == 6: # Address book + stdscr.addstr(5+i, 5, item[0][:74], a) + stdscr.addstr(5+i, 80, item[1][:39], a) + stdscr.addstr(5+i, 120, str(item[2]), a) + elif menutab == 6: # Address book stdscr.addstr(3, 5, "Label", curses.A_BOLD) stdscr.addstr(3, 40, "Address", curses.A_BOLD) stdscr.hline(4, 5, '-', 41) - for i, item in enumerate(addrbook[max(min(len(addrbook) - curses.LINES + 6, abookcur - 5), 0):]): - if 6 + i < curses.LINES: + for i, item in enumerate(addrbook[max(min(len(addrbook)-curses.LINES+6, abookcur-5), 0):]): + if 6+i < curses.LINES: a = 0 - if i == abookcur - max(min(len(addrbook) - curses.LINES + 6, abookcur - 5), 0): - # Highlight current address + if i == abookcur - max(min(len(addrbook)-curses.LINES+6, abookcur-5), 0): # Highlight current address a = a | curses.A_REVERSE - stdscr.addstr(5 + i, 5, item[0][:34], a) - stdscr.addstr(5 + i, 40, item[1][:39], a) - elif menutab == 7: # Blacklist - stdscr.addstr(3, 5, "Type: " + bwtype) + stdscr.addstr(5+i, 5, item[0][:34], a) + stdscr.addstr(5+i, 40, item[1][:39], a) + elif menutab == 7: # Blacklist + stdscr.addstr(3, 5, "Type: "+bwtype) stdscr.addstr(4, 5, "Label", curses.A_BOLD) stdscr.addstr(4, 80, "Address", curses.A_BOLD) stdscr.addstr(4, 120, "Enabled", curses.A_BOLD) stdscr.hline(5, 5, '-', 121) - for i, item in enumerate(blacklist[max(min(len(blacklist) - curses.LINES + 6, blackcur - 5), 0):]): - if 7 + i < curses.LINES: + for i, item in enumerate(blacklist[max(min(len(blacklist)-curses.LINES+6, blackcur-5), 0):]): + if 7+i < curses.LINES: a = 0 - if i == blackcur - max(min(len(blacklist) - curses.LINES + 6, blackcur - 5), 0): - # Highlight current address + if i == blackcur - max(min(len(blacklist)-curses.LINES+6, blackcur-5), 0): # Highlight current address a = a | curses.A_REVERSE - if item[2]: # Embolden enabled subscriptions + if item[2] == True: # Embolden enabled subscriptions a = a | curses.A_BOLD - stdscr.addstr(6 + i, 5, item[0][:74], a) - stdscr.addstr(6 + i, 80, item[1][:39], a) - stdscr.addstr(6 + i, 120, str(item[2]), a) - elif menutab == 8: # Network status + stdscr.addstr(6+i, 5, item[0][:74], a) + stdscr.addstr(6+i, 80, item[1][:39], a) + stdscr.addstr(6+i, 120, str(item[2]), a) + elif menutab == 8: # Network status # Connection data connected_hosts = network.stats.connectedHostsList() stdscr.addstr( @@ -266,96 +228,73 @@ def drawtab(stdscr): for i, item in enumerate(streamcount): if i < 4: if i == 0: - stdscr.addstr(8 + i, 6, "?") + stdscr.addstr(8+i, 6, "?") else: - stdscr.addstr(8 + i, 6, str(i)) - stdscr.addstr(8 + i, 18, str(item).ljust(2)) - + stdscr.addstr(8+i, 6, str(i)) + stdscr.addstr(8+i, 18, str(item).ljust(2)) + # Uptime and processing data - stdscr.addstr(6, 35, "Since startup on " + l10n.formatTimestamp(startuptime, False)) - stdscr.addstr(7, 40, "Processed " + str( - shared.numberOfMessagesProcessed).ljust(4) + " person-to-person messages.") - stdscr.addstr(8, 40, "Processed " + str( - shared.numberOfBroadcastsProcessed).ljust(4) + " broadcast messages.") - stdscr.addstr(9, 40, "Processed " + str( - shared.numberOfPubkeysProcessed).ljust(4) + " public keys.") - + stdscr.addstr(6, 35, "Since startup on "+l10n.formatTimestamp(startuptime, False)) + stdscr.addstr(7, 40, "Processed "+str(shared.numberOfMessagesProcessed).ljust(4)+" person-to-person messages.") + stdscr.addstr(8, 40, "Processed "+str(shared.numberOfBroadcastsProcessed).ljust(4)+" broadcast messages.") + stdscr.addstr(9, 40, "Processed "+str(shared.numberOfPubkeysProcessed).ljust(4)+" public keys.") + # Inventory data - stdscr.addstr(11, 35, "Inventory lookups per second: " + str(inventorydata).ljust(3)) - + stdscr.addstr(11, 35, "Inventory lookups per second: "+str(inventorydata).ljust(3)) + # Log stdscr.addstr(13, 6, "Log", curses.A_BOLD) n = log.count('\n') if n > 0: - lg = log.split('\n') + l = log.split('\n') if n > 512: - del lg[:(n - 256)] + del l[:(n-256)] logpad.erase() - n = len(lg) - for i, item in enumerate(lg): + n = len(l) + for i, item in enumerate(l): a = 0 - if item and item[0] == '!': + if len(item) > 0 and item[0] == '!': a = curses.color_pair(1) item = item[1:] logpad.addstr(i, 0, item, a) - logpad.refresh(n - curses.LINES + 2, 0, 14, 6, curses.LINES - 2, curses.COLS - 7) + logpad.refresh(n-curses.LINES+2, 0, 14, 6, curses.LINES-2, curses.COLS-7) stdscr.refresh() - def redraw(stdscr): - """Redraw menu""" stdscr.erase() stdscr.border() drawmenu(stdscr) stdscr.refresh() - - def dialogreset(stdscr): - """Resetting dialogue""" stdscr.clear() stdscr.keypad(1) curses.curs_set(0) - - -# pylint: disable=too-many-branches, too-many-statements def handlech(c, stdscr): - """Handle character given on the command-line interface""" - # pylint: disable=redefined-outer-name, too-many-nested-blocks, too-many-locals if c != curses.ERR: global inboxcur, addrcur, sentcur, subcur, abookcur, blackcur - if c in range(256): + if c in range(256): if chr(c) in '12345678': global menutab menutab = int(chr(c)) elif chr(c) == 'q': - global quit_ - quit_ = True + global quit + quit = True elif chr(c) == '\n': curses.curs_set(1) d = Dialog(dialog="dialog") if menutab == 1: set_background_title(d, "Inbox Message Dialog Box") - r, t = d.menu( - "Do what with \"" + inbox[inboxcur][5] + "\" from \"" + inbox[inboxcur][3] + "\"?", - choices=[ - ("1", "View message"), + r, t = d.menu("Do what with \""+inbox[inboxcur][5]+"\" from \""+inbox[inboxcur][3]+"\"?", + choices=[("1", "View message"), ("2", "Mark message as unread"), ("3", "Reply"), ("4", "Add sender to Address Book"), ("5", "Save message as text file"), ("6", "Move to trash")]) if r == d.DIALOG_OK: - if t == "1": # View - set_background_title( - d, - "\"" + - inbox[inboxcur][5] + - "\" from \"" + - inbox[inboxcur][3] + - "\" to \"" + - inbox[inboxcur][1] + - "\"") - data = "" # pyint: disable=redefined-outer-name + if t == "1": # View + set_background_title(d, "\""+inbox[inboxcur][5]+"\" from \""+inbox[inboxcur][3]+"\" to \""+inbox[inboxcur][1]+"\"") + data = "" ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0]) if ret != []: for row in ret: @@ -363,16 +302,16 @@ def handlech(c, stdscr): data = shared.fixPotentiallyInvalidUTF8Data(data) msg = "" for i, item in enumerate(data.split("\n")): - msg += fill(item, replace_whitespace=False) + "\n" + msg += fill(item, replace_whitespace=False)+"\n" scrollbox(d, unicode(ascii(msg)), 30, 80) sqlExecute("UPDATE inbox SET read=1 WHERE msgid=?", inbox[inboxcur][0]) inbox[inboxcur][7] = 1 else: scrollbox(d, unicode("Could not fetch message.")) - elif t == "2": # Mark unread + elif t == "2": # Mark unread sqlExecute("UPDATE inbox SET read=0 WHERE msgid=?", inbox[inboxcur][0]) inbox[inboxcur][7] = 0 - elif t == "3": # Reply + elif t == "3": # Reply curses.curs_set(1) m = inbox[inboxcur] fromaddr = m[4] @@ -381,31 +320,29 @@ def handlech(c, stdscr): if fromaddr == item[2] and item[3] != 0: ischan = True break - if not addresses[i][1]: # pylint: disable=undefined-loop-variable - scrollbox(d, unicode( - "Sending address disabled, please either enable it" - "or choose a different address.")) + if not addresses[i][1]: + scrollbox(d, unicode("Sending address disabled, please either enable it or choose a different address.")) return toaddr = m[2] if ischan: toaddr = fromaddr - + subject = m[5] if not m[5][:4] == "Re: ": - subject = "Re: " + m[5] + subject = "Re: "+m[5] body = "" ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", m[0]) if ret != []: body = "\n\n------------------------------------------------------\n" for row in ret: body, = row - + sendMessage(fromaddr, toaddr, ischan, subject, body, True) dialogreset(stdscr) - elif t == "4": # Add to Address Book + elif t == "4": # Add to Address Book addr = inbox[inboxcur][4] - if addr not in [item[1] for i, item in enumerate(addrbook)]: - r, t = d.inputbox("Label for address \"" + addr + "\"") + if addr not in [item[1] for i,item in enumerate(addrbook)]: + r, t = d.inputbox("Label for address \""+addr+"\"") if r == d.DIALOG_OK: label = t sqlExecute("INSERT INTO addressbook VALUES (?,?)", label, addr) @@ -415,85 +352,61 @@ def handlech(c, stdscr): addrbook.reverse() else: scrollbox(d, unicode("The selected address is already in the Address Book.")) - elif t == "5": # Save message - set_background_title(d, "Save \"" + inbox[inboxcur][5] + "\" as text file") - r, t = d.inputbox("Filename", init=inbox[inboxcur][5] + ".txt") + elif t == "5": # Save message + set_background_title(d, "Save \""+inbox[inboxcur][5]+"\" as text file") + r, t = d.inputbox("Filename", init=inbox[inboxcur][5]+".txt") if r == d.DIALOG_OK: msg = "" ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0]) if ret != []: for row in ret: msg, = row - fh = open(t, "a") # Open in append mode just in case + fh = open(t, "a") # Open in append mode just in case fh.write(msg) fh.close() else: scrollbox(d, unicode("Could not fetch message.")) - elif t == "6": # Move to trash + elif t == "6": # Move to trash sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=?", inbox[inboxcur][0]) del inbox[inboxcur] - scrollbox(d, unicode( - "Message moved to trash. There is no interface to view your trash," - " \nbut the message is still on disk if you are desperate to recover it.")) + scrollbox(d, unicode("Message moved to trash. There is no interface to view your trash, \nbut the message is still on disk if you are desperate to recover it.")) elif menutab == 2: a = "" - if addresses[addrcur][3] != 0: # if current address is a chan + if addresses[addrcur][3] != 0: # if current address is a chan a = addresses[addrcur][2] sendMessage(addresses[addrcur][2], a) elif menutab == 3: set_background_title(d, "Sent Messages Dialog Box") - r, t = d.menu( - "Do what with \"" + sentbox[sentcur][4] + "\" to \"" + sentbox[sentcur][0] + "\"?", - choices=[ - ("1", "View message"), + r, t = d.menu("Do what with \""+sentbox[sentcur][4]+"\" to \""+sentbox[sentcur][0]+"\"?", + choices=[("1", "View message"), ("2", "Move to trash")]) if r == d.DIALOG_OK: - if t == "1": # View - set_background_title( - d, - "\"" + - sentbox[sentcur][4] + - "\" from \"" + - sentbox[sentcur][3] + - "\" to \"" + - sentbox[sentcur][1] + - "\"") + if t == "1": # View + set_background_title(d, "\""+sentbox[sentcur][4]+"\" from \""+sentbox[sentcur][3]+"\" to \""+sentbox[sentcur][1]+"\"") data = "" - ret = sqlQuery( - "SELECT message FROM sent WHERE subject=? AND ackdata=?", - sentbox[sentcur][4], - sentbox[sentcur][6]) + ret = sqlQuery("SELECT message FROM sent WHERE subject=? AND ackdata=?", sentbox[sentcur][4], sentbox[sentcur][6]) if ret != []: for row in ret: data, = row data = shared.fixPotentiallyInvalidUTF8Data(data) msg = "" for i, item in enumerate(data.split("\n")): - msg += fill(item, replace_whitespace=False) + "\n" + msg += fill(item, replace_whitespace=False)+"\n" scrollbox(d, unicode(ascii(msg)), 30, 80) else: scrollbox(d, unicode("Could not fetch message.")) - elif t == "2": # Move to trash - sqlExecute( - "UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=?", - sentbox[sentcur][4], - sentbox[sentcur][6]) + elif t == "2": # Move to trash + sqlExecute("UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=?", sentbox[sentcur][4], sentbox[sentcur][6]) del sentbox[sentcur] - scrollbox(d, unicode( - "Message moved to trash. There is no interface to view your trash" - " \nbut the message is still on disk if you are desperate to recover it.")) + scrollbox(d, unicode("Message moved to trash. There is no interface to view your trash, \nbut the message is still on disk if you are desperate to recover it.")) elif menutab == 4: set_background_title(d, "Your Identities Dialog Box") if len(addresses) <= addrcur: - r, t = d.menu( - "Do what with addresses?", - choices=[ - ("1", "Create new address")]) + r, t = d.menu("Do what with addresses?", + choices=[("1", "Create new address")]) else: - r, t = d.menu( - "Do what with \"" + addresses[addrcur][0] + "\" : \"" + addresses[addrcur][2] + "\"?", - choices=[ - ("1", "Create new address"), + r, t = d.menu("Do what with \""+addresses[addrcur][0]+"\" : \""+addresses[addrcur][2]+"\"?", + choices=[("1", "Create new address"), ("2", "Send a message from this address"), ("3", "Rename"), ("4", "Enable"), @@ -501,41 +414,31 @@ def handlech(c, stdscr): ("6", "Delete"), ("7", "Special address behavior")]) if r == d.DIALOG_OK: - if t == "1": # Create new address + if t == "1": # Create new address set_background_title(d, "Create new address") - scrollbox( - d, unicode( - "Here you may generate as many addresses as you like.\n" - "Indeed, creating and abandoning addresses is encouraged.\n" - "Deterministic addresses have several pros and cons:\n" - "\nPros:\n" - " * You can recreate your addresses on any computer from memory\n" - " * You need not worry about backing up your keys.dat file as long as you" - " \n can remember your passphrase\n" - "Cons:\n" - " * You must remember (or write down) your passphrase in order to recreate" - " \n your keys if they are lost\n" - " * You must also remember the address version and stream numbers\n" - " * If you choose a weak passphrase someone may be able to brute-force it" - " \n and then send and receive messages as you")) - r, t = d.menu( - "Choose an address generation technique", - choices=[ - ("1", "Use a random number generator"), + scrollbox(d, unicode("Here you may generate as many addresses as you like.\n" + "Indeed, creating and abandoning addresses is encouraged.\n" + "Deterministic addresses have several pros and cons:\n" + "\nPros:\n" + " * You can recreate your addresses on any computer from memory\n" + " * You need not worry about backing up your keys.dat file as long as you \n can remember your passphrase\n" + "Cons:\n" + " * You must remember (or write down) your passphrase in order to recreate \n your keys if they are lost\n" + " * You must also remember the address version and stream numbers\n" + " * If you choose a weak passphrase someone may be able to brute-force it \n and then send and receive messages as you")) + r, t = d.menu("Choose an address generation technique", + choices=[("1", "Use a random number generator"), ("2", "Use a passphrase")]) if r == d.DIALOG_OK: if t == "1": set_background_title(d, "Randomly generate address") r, t = d.inputbox("Label (not shown to anyone except you)") label = "" - if r == d.DIALOG_OK and t: + if r == d.DIALOG_OK and len(t) > 0: label = t - r, t = d.menu( - "Choose a stream", - choices=[("1", "Use the most available stream"), - ("", "(Best if this is the first of many addresses you will create)"), - ("2", "Use the same stream as an existing address"), - ("", "(Saves you some bandwidth and processing power)")]) + r, t = d.menu("Choose a stream", + choices=[("1", "Use the most available stream"),("", "(Best if this is the first of many addresses you will create)"), + ("2", "Use the same stream as an existing address"),("", "(Saves you some bandwidth and processing power)")]) if r == d.DIALOG_OK: if t == "1": stream = 1 @@ -547,69 +450,42 @@ def handlech(c, stdscr): if r == d.DIALOG_OK: stream = decodeAddress(addrs[int(t)][1])[2] shorten = False - r, t = d.checklist( - "Miscellaneous options", - choices=[( - "1", - "Spend time shortening the address", - 1 if shorten else 0)]) + r, t = d.checklist("Miscellaneous options", + choices=[("1", "Spend time shortening the address", 1 if shorten else 0)]) if r == d.DIALOG_OK and "1" in t: shorten = True - queues.addressGeneratorQueue.put(( - "createRandomAddress", - 4, - stream, - label, - 1, - "", - shorten)) + queues.addressGeneratorQueue.put(("createRandomAddress", 4, stream, label, 1, "", shorten)) elif t == "2": set_background_title(d, "Make deterministic addresses") - r, t = d.passwordform( - "Enter passphrase", - [ - ("Passphrase", 1, 1, "", 2, 1, 64, 128), - ("Confirm passphrase", 3, 1, "", 4, 1, 64, 128)], + r, t = d.passwordform("Enter passphrase", + [("Passphrase", 1, 1, "", 2, 1, 64, 128), + ("Confirm passphrase", 3, 1, "", 4, 1, 64, 128)], form_height=4, insecure=True) if r == d.DIALOG_OK: if t[0] == t[1]: passphrase = t[0] - r, t = d.rangebox( - "Number of addresses to generate", - width=48, - min=1, - max=99, - init=8) + r, t = d.rangebox("Number of addresses to generate", + width=48, min=1, max=99, init=8) if r == d.DIALOG_OK: number = t stream = 1 shorten = False - r, t = d.checklist( - "Miscellaneous options", - choices=[( - "1", - "Spend time shortening the address", - 1 if shorten else 0)]) + r, t = d.checklist("Miscellaneous options", + choices=[("1", "Spend time shortening the address", 1 if shorten else 0)]) if r == d.DIALOG_OK and "1" in t: shorten = True - scrollbox( - d, unicode( - "In addition to your passphrase, be sure to remember the" - " following numbers:\n" - "\n * Address version number: " + str(4) + "\n" - " * Stream number: " + str(stream))) - queues.addressGeneratorQueue.put( - ('createDeterministicAddresses', 4, stream, - "unused deterministic address", number, - str(passphrase), shorten)) + scrollbox(d, unicode("In addition to your passphrase, be sure to remember the following numbers:\n" + "\n * Address version number: "+str(4)+"\n" + " * Stream number: "+str(stream))) + queues.addressGeneratorQueue.put(('createDeterministicAddresses', 4, stream, "unused deterministic address", number, str(passphrase), shorten)) else: scrollbox(d, unicode("Passphrases do not match")) - elif t == "2": # Send a message + elif t == "2": # Send a message a = "" - if addresses[addrcur][3] != 0: # if current address is a chan + if addresses[addrcur][3] != 0: # if current address is a chan a = addresses[addrcur][2] sendMessage(addresses[addrcur][2], a) - elif t == "3": # Rename address label + elif t == "3": # Rename address label a = addresses[addrcur][2] label = addresses[addrcur][0] r, t = d.inputbox("New address label", init=label) @@ -619,79 +495,72 @@ def handlech(c, stdscr): # Write config BMConfigParser().save() addresses[addrcur][0] = label - elif t == "4": # Enable address + elif t == "4": # Enable address a = addresses[addrcur][2] - BMConfigParser().set(a, "enabled", "true") # Set config + BMConfigParser().set(a, "enabled", "true") # Set config # Write config BMConfigParser().save() # Change color if BMConfigParser().safeGetBoolean(a, 'chan'): - addresses[addrcur][3] = 9 # orange + addresses[addrcur][3] = 9 # orange elif BMConfigParser().safeGetBoolean(a, 'mailinglist'): - addresses[addrcur][3] = 5 # magenta + addresses[addrcur][3] = 5 # magenta else: - addresses[addrcur][3] = 0 # black + addresses[addrcur][3] = 0 # black addresses[addrcur][1] = True - shared.reloadMyAddressHashes() # Reload address hashes - elif t == "5": # Disable address + shared.reloadMyAddressHashes() # Reload address hashes + elif t == "5": # Disable address a = addresses[addrcur][2] - BMConfigParser().set(a, "enabled", "false") # Set config - addresses[addrcur][3] = 8 # Set color to gray + BMConfigParser().set(a, "enabled", "false") # Set config + addresses[addrcur][3] = 8 # Set color to gray # Write config BMConfigParser().save() addresses[addrcur][1] = False - shared.reloadMyAddressHashes() # Reload address hashes - elif t == "6": # Delete address + shared.reloadMyAddressHashes() # Reload address hashes + elif t == "6": # Delete address r, t = d.inputbox("Type in \"I want to delete this address\"", width=50) if r == d.DIALOG_OK and t == "I want to delete this address": - BMConfigParser().remove_section(addresses[addrcur][2]) - BMConfigParser().save() - del addresses[addrcur] - elif t == "7": # Special address behavior + BMConfigParser().remove_section(addresses[addrcur][2]) + BMConfigParser().save() + del addresses[addrcur] + elif t == "7": # Special address behavior a = addresses[addrcur][2] set_background_title(d, "Special address behavior") if BMConfigParser().safeGetBoolean(a, "chan"): - scrollbox(d, unicode( - "This is a chan address. You cannot use it as a pseudo-mailing list.")) + scrollbox(d, unicode("This is a chan address. You cannot use it as a pseudo-mailing list.")) else: m = BMConfigParser().safeGetBoolean(a, "mailinglist") - r, t = d.radiolist( - "Select address behavior", - choices=[ - ("1", "Behave as a normal address", not m), + r, t = d.radiolist("Select address behavior", + choices=[("1", "Behave as a normal address", not m), ("2", "Behave as a pseudo-mailing-list address", m)]) if r == d.DIALOG_OK: - if t == "1" and m: + if t == "1" and m == True: BMConfigParser().set(a, "mailinglist", "false") if addresses[addrcur][1]: - addresses[addrcur][3] = 0 # Set color to black + addresses[addrcur][3] = 0 # Set color to black else: - addresses[addrcur][3] = 8 # Set color to gray - elif t == "2" and m is False: + addresses[addrcur][3] = 8 # Set color to gray + elif t == "2" and m == False: try: mn = BMConfigParser().get(a, "mailinglistname") except ConfigParser.NoOptionError: - mn = "" + mn = "" r, t = d.inputbox("Mailing list name", init=mn) if r == d.DIALOG_OK: mn = t BMConfigParser().set(a, "mailinglist", "true") BMConfigParser().set(a, "mailinglistname", mn) - addresses[addrcur][3] = 6 # Set color to magenta + addresses[addrcur][3] = 6 # Set color to magenta # Write config BMConfigParser().save() elif menutab == 5: set_background_title(d, "Subscriptions Dialog Box") if len(subscriptions) <= subcur: - r, t = d.menu( - "Do what with subscription to \"" + subscriptions[subcur][0] + "\"?", - choices=[ - ("1", "Add new subscription")]) + r, t = d.menu("Do what with subscription to \""+subscriptions[subcur][0]+"\"?", + choices=[("1", "Add new subscription")]) else: - r, t = d.menu( - "Do what with subscription to \"" + subscriptions[subcur][0] + "\"?", - choices=[ - ("1", "Add new subscription"), + r, t = d.menu("Do what with subscription to \""+subscriptions[subcur][0]+"\"?", + choices=[("1", "Add new subscription"), ("2", "Delete this subscription"), ("3", "Enable"), ("4", "Disable")]) @@ -712,39 +581,27 @@ def handlech(c, stdscr): sqlExecute("INSERT INTO subscriptions VALUES (?,?,?)", label, addr, True) shared.reloadBroadcastSendersForWhichImWatching() elif t == "2": - r, t = d.inputbox("Type in \"I want to delete this subscription\"") + r, t = d.inpuxbox("Type in \"I want to delete this subscription\"") if r == d.DIALOG_OK and t == "I want to delete this subscription": - sqlExecute( - "DELETE FROM subscriptions WHERE label=? AND address=?", - subscriptions[subcur][0], - subscriptions[subcur][1]) - shared.reloadBroadcastSendersForWhichImWatching() - del subscriptions[subcur] + sqlExecute("DELETE FROM subscriptions WHERE label=? AND address=?", subscriptions[subcur][0], subscriptions[subcur][1]) + shared.reloadBroadcastSendersForWhichImWatching() + del subscriptions[subcur] elif t == "3": - sqlExecute( - "UPDATE subscriptions SET enabled=1 WHERE label=? AND address=?", - subscriptions[subcur][0], - subscriptions[subcur][1]) + sqlExecute("UPDATE subscriptions SET enabled=1 WHERE label=? AND address=?", subscriptions[subcur][0], subscriptions[subcur][1]) shared.reloadBroadcastSendersForWhichImWatching() subscriptions[subcur][2] = True elif t == "4": - sqlExecute( - "UPDATE subscriptions SET enabled=0 WHERE label=? AND address=?", - subscriptions[subcur][0], - subscriptions[subcur][1]) + sqlExecute("UPDATE subscriptions SET enabled=0 WHERE label=? AND address=?", subscriptions[subcur][0], subscriptions[subcur][1]) shared.reloadBroadcastSendersForWhichImWatching() subscriptions[subcur][2] = False elif menutab == 6: set_background_title(d, "Address Book Dialog Box") if len(addrbook) <= abookcur: - r, t = d.menu( - "Do what with addressbook?", + r, t = d.menu("Do what with addressbook?", choices=[("3", "Add new address to Address Book")]) else: - r, t = d.menu( - "Do what with \"" + addrbook[abookcur][0] + "\" : \"" + addrbook[abookcur][1] + "\"", - choices=[ - ("1", "Send a message to this address"), + r, t = d.menu("Do what with \""+addrbook[abookcur][0]+"\" : \""+addrbook[abookcur][1]+"\"", + choices=[("1", "Send a message to this address"), ("2", "Subscribe to this address"), ("3", "Add new address to Address Book"), ("4", "Delete this address")]) @@ -766,8 +623,8 @@ def handlech(c, stdscr): r, t = d.inputbox("Input new address") if r == d.DIALOG_OK: addr = t - if addr not in [item[1] for i, item in enumerate(addrbook)]: - r, t = d.inputbox("Label for address \"" + addr + "\"") + if addr not in [item[1] for i,item in enumerate(addrbook)]: + r, t = d.inputbox("Label for address \""+addr+"\"") if r == d.DIALOG_OK: sqlExecute("INSERT INTO addressbook VALUES (?,?)", t, addr) # Prepend entry @@ -779,39 +636,25 @@ def handlech(c, stdscr): elif t == "4": r, t = d.inputbox("Type in \"I want to delete this Address Book entry\"") if r == d.DIALOG_OK and t == "I want to delete this Address Book entry": - sqlExecute( - "DELETE FROM addressbook WHERE label=? AND address=?", - addrbook[abookcur][0], - addrbook[abookcur][1]) + sqlExecute("DELETE FROM addressbook WHERE label=? AND address=?", addrbook[abookcur][0], addrbook[abookcur][1]) del addrbook[abookcur] elif menutab == 7: set_background_title(d, "Blacklist Dialog Box") - r, t = d.menu( - "Do what with \"" + blacklist[blackcur][0] + "\" : \"" + blacklist[blackcur][1] + "\"?", - choices=[ - ("1", "Delete"), + r, t = d.menu("Do what with \""+blacklist[blackcur][0]+"\" : \""+blacklist[blackcur][1]+"\"?", + choices=[("1", "Delete"), ("2", "Enable"), ("3", "Disable")]) if r == d.DIALOG_OK: if t == "1": r, t = d.inputbox("Type in \"I want to delete this Blacklist entry\"") if r == d.DIALOG_OK and t == "I want to delete this Blacklist entry": - sqlExecute( - "DELETE FROM blacklist WHERE label=? AND address=?", - blacklist[blackcur][0], - blacklist[blackcur][1]) + sqlExecute("DELETE FROM blacklist WHERE label=? AND address=?", blacklist[blackcur][0], blacklist[blackcur][1]) del blacklist[blackcur] elif t == "2": - sqlExecute( - "UPDATE blacklist SET enabled=1 WHERE label=? AND address=?", - blacklist[blackcur][0], - blacklist[blackcur][1]) + sqlExecute("UPDATE blacklist SET enabled=1 WHERE label=? AND address=?", blacklist[blackcur][0], blacklist[blackcur][1]) blacklist[blackcur][2] = True - elif t == "3": - sqlExecute( - "UPDATE blacklist SET enabled=0 WHERE label=? AND address=?", - blacklist[blackcur][0], - blacklist[blackcur][1]) + elif t== "3": + sqlExecute("UPDATE blacklist SET enabled=0 WHERE label=? AND address=?", blacklist[blackcur][0], blacklist[blackcur][1]) blacklist[blackcur][2] = False dialogreset(stdscr) else: @@ -829,17 +672,17 @@ def handlech(c, stdscr): if menutab == 7 and blackcur > 0: blackcur -= 1 elif c == curses.KEY_DOWN: - if menutab == 1 and inboxcur < len(inbox) - 1: + if menutab == 1 and inboxcur < len(inbox)-1: inboxcur += 1 - if (menutab == 2 or menutab == 4) and addrcur < len(addresses) - 1: + if (menutab == 2 or menutab == 4) and addrcur < len(addresses)-1: addrcur += 1 - if menutab == 3 and sentcur < len(sentbox) - 1: + if menutab == 3 and sentcur < len(sentbox)-1: sentcur += 1 - if menutab == 5 and subcur < len(subscriptions) - 1: + if menutab == 5 and subcur < len(subscriptions)-1: subcur += 1 - if menutab == 6 and abookcur < len(addrbook) - 1: + if menutab == 6 and abookcur < len(addrbook)-1: abookcur += 1 - if menutab == 7 and blackcur < len(blacklist) - 1: + if menutab == 7 and blackcur < len(blacklist)-1: blackcur += 1 elif c == curses.KEY_HOME: if menutab == 1: @@ -856,47 +699,38 @@ def handlech(c, stdscr): blackcur = 0 elif c == curses.KEY_END: if menutab == 1: - inboxcur = len(inbox) - 1 + inboxcur = len(inbox)-1 if menutab == 2 or menutab == 4: - addrcur = len(addresses) - 1 + addrcur = len(addresses)-1 if menutab == 3: - sentcur = len(sentbox) - 1 + sentcur = len(sentbox)-1 if menutab == 5: - subcur = len(subscriptions) - 1 + subcur = len(subscriptions)-1 if menutab == 6: - abookcur = len(addrbook) - 1 + abookcur = len(addrbook)-1 if menutab == 7: - blackcur = len(blackcur) - 1 + blackcur = len(blackcur)-1 redraw(stdscr) - - -# pylint: disable=too-many-locals, too-many-arguments def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=False): - """Method for message sending""" if sender == "": return d = Dialog(dialog="dialog") set_background_title(d, "Send a message") if recv == "": - r, t = d.inputbox( - "Recipient address (Cancel to load from the Address Book or leave blank to broadcast)", - 10, - 60) + r, t = d.inputbox("Recipient address (Cancel to load from the Address Book or leave blank to broadcast)", 10, 60) if r != d.DIALOG_OK: global menutab menutab = 6 return recv = t - if broadcast is None and sender != recv: - r, t = d.radiolist( - "How to send the message?", - choices=[ - ("1", "Send to one or more specific people", 1), + if broadcast == None and sender != recv: + r, t = d.radiolist("How to send the message?", + choices=[("1", "Send to one or more specific people", 1), ("2", "Broadcast to everyone who is subscribed to your address", 0)]) if r != d.DIALOG_OK: return broadcast = False - if t == "2": # Broadcast + if t == "2": # Broadcast broadcast = True if subject == "" or reply: r, t = d.inputbox("Message subject", width=60, init=subject) @@ -912,12 +746,11 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F if not broadcast: recvlist = [] - for _, item in enumerate(recv.replace(",", ";").split(";")): + for i, item in enumerate(recv.replace(",", ";").split(";")): recvlist.append(item.strip()) - list(set(recvlist)) # Remove exact duplicates + list(set(recvlist)) # Remove exact duplicates for addr in recvlist: if addr != "": - # pylint: disable=redefined-outer-name status, version, stream, ripe = decodeAddress(addr) if status != "success": set_background_title(d, "Recipient address error") @@ -929,17 +762,13 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F elif status == "invalidcharacters": err += "The address contains invalid characters." elif status == "versiontoohigh": - err += ("The address version is too high. Either you need to upgrade your Bitmessage software" - " or your acquaintance is doing something clever.") + err += "The address version is too high. Either you need to upgrade your Bitmessage software or your acquaintance is doing something clever." elif status == "ripetooshort": - err += ("Some data encoded in the address is too short. There might be something wrong with" - " the software of your acquaintance.") + err += "Some data encoded in the address is too short. There might be something wrong with the software of your acquaintance." elif status == "ripetoolong": - err += ("Some data encoded in the address is too long. There might be something wrong with" - " the software of your acquaintance.") + err += "Some data encoded in the address is too long. There might be something wrong with the software of your acquaintance." elif status == "varintmalformed": - err += ("Some data encoded in the address is malformed. There might be something wrong with" - " the software of your acquaintance.") + err += "Some data encoded in the address is malformed. There might be something wrong with the software of your acquaintance." else: err += "It is unknown what is wrong with the address." scrollbox(d, unicode(err)) @@ -947,24 +776,17 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F addr = addBMIfNotPresent(addr) if version > 4 or version <= 1: set_background_title(d, "Recipient address error") - scrollbox(d, unicode( - "Could not understand version number " + - version + - "of address" + - addr + - ".")) + scrollbox(d, unicode("Could not understand version number " + version + "of address" + addr + ".")) continue if stream > 1 or stream == 0: set_background_title(d, "Recipient address error") - scrollbox(d, unicode( - "Bitmessage currently only supports stream numbers of 1," - "unlike as requested for address " + addr + ".")) + scrollbox(d, unicode("Bitmessage currently only supports stream numbers of 1, unlike as requested for address " + addr + ".")) continue if not network.stats.connectedHostsList(): set_background_title(d, "Not connected warning") scrollbox(d, unicode("Because you are not currently connected to the network, ")) stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel') - ackdata = genAckPayload(decodeAddress(addr)[2], stealthLevel) + ackdata = genAckPayload(streamNumber, stealthLevel) sqlExecute( "INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", "", @@ -974,22 +796,22 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F subject, body, ackdata, - int(time.time()), # sentTime (this will never change) - int(time.time()), # lastActionTime - 0, # sleepTill time. This will get set when the POW gets done. + int(time.time()), # sentTime (this will never change) + int(time.time()), # lastActionTime + 0, # sleepTill time. This will get set when the POW gets done. "msgqueued", - 0, # retryNumber + 0, # retryNumber "sent", - 2, # encodingType + 2, # encodingType BMConfigParser().getint('bitmessagesettings', 'ttl')) queues.workerQueue.put(("sendmessage", addr)) - else: # Broadcast + else: # Broadcast if recv == "": set_background_title(d, "Empty sender error") scrollbox(d, unicode("You must specify an address to send the message from.")) else: # dummy ackdata, no need for stealth - ackdata = genAckPayload(decodeAddress(addr)[2], 0) + ackdata = genAckPayload(streamNumber, 0) recv = BROADCAST_STR ripe = "" sqlExecute( @@ -1001,24 +823,21 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F subject, body, ackdata, - int(time.time()), # sentTime (this will never change) - int(time.time()), # lastActionTime - 0, # sleepTill time. This will get set when the POW gets done. + int(time.time()), # sentTime (this will never change) + int(time.time()), # lastActionTime + 0, # sleepTill time. This will get set when the POW gets done. "broadcastqueued", - 0, # retryNumber - "sent", # folder - 2, # encodingType + 0, # retryNumber + "sent", # folder + 2, # encodingType BMConfigParser().getint('bitmessagesettings', 'ttl')) queues.workerQueue.put(('sendbroadcast', '')) - -# pylint: disable=redefined-outer-name, too-many-locals def loadInbox(): - """Load the list of messages""" sys.stdout = sys.__stdout__ - print "Loading inbox messages..." + print("Loading inbox messages...") sys.stdout = printlog - + where = "toaddress || fromaddress || subject || message" what = "%%" ret = sqlQuery("""SELECT msgid, toaddress, fromaddress, subject, received, read @@ -1028,7 +847,7 @@ def loadInbox(): for row in ret: msgid, toaddr, fromaddr, subject, received, read = row subject = ascii(shared.fixPotentiallyInvalidUTF8Data(subject)) - + # Set label for to address try: if toaddr == BROADCAST_STR: @@ -1040,17 +859,17 @@ def loadInbox(): if tolabel == "": tolabel = toaddr tolabel = shared.fixPotentiallyInvalidUTF8Data(tolabel) - + # Set label for from address fromlabel = "" if BMConfigParser().has_section(fromaddr): fromlabel = BMConfigParser().get(fromaddr, "label") - if fromlabel == "": # Check Address Book + if fromlabel == "": # Check Address Book qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", fromaddr) if qr != []: for r in qr: fromlabel, = r - if fromlabel == "": # Check Subscriptions + if fromlabel == "": # Check Subscriptions qr = sqlQuery("SELECT label FROM subscriptions WHERE address=?", fromaddr) if qr != []: for r in qr: @@ -1058,19 +877,16 @@ def loadInbox(): if fromlabel == "": fromlabel = fromaddr fromlabel = shared.fixPotentiallyInvalidUTF8Data(fromlabel) - + # Load into array - inbox.append([msgid, tolabel, toaddr, fromlabel, fromaddr, subject, l10n.formatTimestamp( - received, False), read]) + inbox.append([msgid, tolabel, toaddr, fromlabel, fromaddr, subject, + l10n.formatTimestamp(received, False), read]) inbox.reverse() - - def loadSent(): - """Load the messages that sent""" sys.stdout = sys.__stdout__ - print "Loading sent messages..." + print("Loading sent messages...") sys.stdout = printlog - + where = "toaddress || fromaddress || subject || message" what = "%%" ret = sqlQuery("""SELECT toaddress, fromaddress, subject, status, ackdata, lastactiontime @@ -1080,7 +896,7 @@ def loadSent(): for row in ret: toaddr, fromaddr, subject, status, ackdata, lastactiontime = row subject = ascii(shared.fixPotentiallyInvalidUTF8Data(subject)) - + # Set label for to address tolabel = "" qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", toaddr) @@ -1097,14 +913,14 @@ def loadSent(): tolabel = BMConfigParser().get(toaddr, "label") if tolabel == "": tolabel = toaddr - + # Set label for from address fromlabel = "" if BMConfigParser().has_section(fromaddr): fromlabel = BMConfigParser().get(fromaddr, "label") if fromlabel == "": fromlabel = fromaddr - + # Set status string if status == "awaitingpubkey": statstr = "Waiting for their public key. Will request it again soon" @@ -1114,20 +930,20 @@ def loadSent(): statstr = "Message queued" elif status == "msgsent": t = l10n.formatTimestamp(lastactiontime, False) - statstr = "Message sent at " + t + ".Waiting for acknowledgement." + statstr = "Message sent at "+t+".Waiting for acknowledgement." elif status == "msgsentnoackexpected": t = l10n.formatTimestamp(lastactiontime, False) - statstr = "Message sent at " + t + "." + statstr = "Message sent at "+t+"." elif status == "doingmsgpow": statstr = "The proof of work required to send the message has been queued." elif status == "ackreceived": t = l10n.formatTimestamp(lastactiontime, False) - statstr = "Acknowledgment of the message received at " + t + "." + statstr = "Acknowledgment of the message received at "+t+"." elif status == "broadcastqueued": statstr = "Broadcast queued." elif status == "broadcastsent": t = l10n.formatTimestamp(lastactiontime, False) - statstr = "Broadcast sent at " + t + "." + statstr = "Broadcast sent at "+t+"." elif status == "forcepow": statstr = "Forced difficulty override. Message will start sending soon." elif status == "badkey": @@ -1136,46 +952,30 @@ def loadSent(): statstr = "Error: The work demanded by the recipient is more difficult than you are willing to do." else: t = l10n.formatTimestamp(lastactiontime, False) - statstr = "Unknown status " + status + " at " + t + "." - + statstr = "Unknown status "+status+" at "+t+"." + # Load into array - sentbox.append([ - tolabel, - toaddr, - fromlabel, - fromaddr, - subject, - statstr, - ackdata, + sentbox.append([tolabel, toaddr, fromlabel, fromaddr, subject, statstr, ackdata, l10n.formatTimestamp(lastactiontime, False)]) sentbox.reverse() - - def loadAddrBook(): - """Load address book""" sys.stdout = sys.__stdout__ - print "Loading address book..." + print("Loading address book...") sys.stdout = printlog - + ret = sqlQuery("SELECT label, address FROM addressbook") for row in ret: label, addr = row label = shared.fixPotentiallyInvalidUTF8Data(label) addrbook.append([label, addr]) addrbook.reverse() - - def loadSubscriptions(): - """Load subscription functionality""" ret = sqlQuery("SELECT label, address, enabled FROM subscriptions") for row in ret: label, address, enabled = row subscriptions.append([label, address, enabled]) subscriptions.reverse() - - def loadBlackWhiteList(): - """load black/white list""" global bwtype bwtype = BMConfigParser().get("bitmessagesettings", "blackwhitelist") if bwtype == "black": @@ -1187,54 +987,51 @@ def loadBlackWhiteList(): blacklist.append([label, address, enabled]) blacklist.reverse() - def runwrapper(): - """Main method""" sys.stdout = printlog - # sys.stderr = errlog - + #sys.stderr = errlog + + # Load messages from database loadInbox() loadSent() loadAddrBook() loadSubscriptions() loadBlackWhiteList() - + stdscr = curses.initscr() - + global logpad logpad = curses.newpad(1024, curses.COLS) - + stdscr.nodelay(0) curses.curs_set(0) stdscr.timeout(1000) - + curses.wrapper(run) doShutdown() - def run(stdscr): - """Main loop""" # Schedule inventory lookup data resetlookups() - + # Init color pairs if curses.has_colors(): - curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) # red - curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) # green - curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK) # yellow - curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK) # blue - curses.init_pair(5, curses.COLOR_MAGENTA, curses.COLOR_BLACK) # magenta - curses.init_pair(6, curses.COLOR_CYAN, curses.COLOR_BLACK) # cyan - curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_BLACK) # white + curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) # red + curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) # green + curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK) # yellow + curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK) # blue + curses.init_pair(5, curses.COLOR_MAGENTA, curses.COLOR_BLACK) # magenta + curses.init_pair(6, curses.COLOR_CYAN, curses.COLOR_BLACK) # cyan + curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_BLACK) # white if curses.can_change_color(): - curses.init_color(8, 500, 500, 500) # gray + curses.init_color(8, 500, 500, 500) # gray curses.init_pair(8, 8, 0) - curses.init_color(9, 844, 465, 0) # orange + curses.init_color(9, 844, 465, 0) # orange curses.init_pair(9, 9, 0) else: - curses.init_pair(8, curses.COLOR_WHITE, curses.COLOR_BLACK) # grayish - curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK) # orangish - + curses.init_pair(8, curses.COLOR_WHITE, curses.COLOR_BLACK) # grayish + curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK) # orangish + # Init list of address in 'Your Identities' tab configSections = BMConfigParser().addresses() for addressInKeysFile in configSections: @@ -1242,28 +1039,27 @@ def run(stdscr): addresses.append([BMConfigParser().get(addressInKeysFile, "label"), isEnabled, addressInKeysFile]) # Set address color if not isEnabled: - addresses[len(addresses) - 1].append(8) # gray + addresses[len(addresses)-1].append(8) # gray elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan'): - addresses[len(addresses) - 1].append(9) # orange + addresses[len(addresses)-1].append(9) # orange elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist'): - addresses[len(addresses) - 1].append(5) # magenta + addresses[len(addresses)-1].append(5) # magenta else: - addresses[len(addresses) - 1].append(0) # black + addresses[len(addresses)-1].append(0) # black addresses.reverse() - + stdscr.clear() redraw(stdscr) - while quit_ is False: + while quit == False: drawtab(stdscr) handlech(stdscr.getch(), stdscr) - def doShutdown(): - """Shutting the app down""" sys.stdout = sys.__stdout__ - print "Shutting down..." + print("Shutting down...") sys.stdout = printlog shutdown.doCleanShutdown() sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ - os._exit(0) # pylint: disable=protected-access + + os._exit(0) diff --git a/src/bitmessagekivy/android/python-for-android/recipes/bitmsghash/__init__.py b/src/bitmessagekivy/android/python-for-android/recipes/bitmsghash/__init__.py deleted file mode 100644 index 4566ebfb..00000000 --- a/src/bitmessagekivy/android/python-for-android/recipes/bitmsghash/__init__.py +++ /dev/null @@ -1,50 +0,0 @@ -from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory -from os.path import exists, join -import os -import sys -from multiprocessing import cpu_count -import sh - - -class BitmsghashRecipe(Recipe): - # This could also inherit from PythonRecipe etc. if you want to - # use their pre-written build processes - - url = 'https://github.com/surbhicis/bitmsghash/archive/master.zip' - # {version} will be replaced with self.version when downloading - - depends = ['openssl'] - - conflicts = [] - - def get_recipe_env(self, arch=None): - env = super(BitmsghashRecipe, self).get_recipe_env(arch) - r = Recipe.get_recipe('openssl', self.ctx) - b = r.get_build_dir(arch.arch) - env['CCFLAGS'] = env['CFLAGS'] = \ - env['CFLAGS'] + ' -I{openssl_build_path}/include ' \ - '-I{openssl_build_path}/include/openssl'.format( - openssl_build_path=b) - env['LDFLAGS'] = \ - env['LDFLAGS'] + ' -L{openssl_build_path} ' \ - '-lcrypto{openssl_version} ' \ - '-lssl{openssl_version}'.format( - openssl_build_path=b, - openssl_version=r.version) - return env - - def should_build(self, arch=None): - super(BitmsghashRecipe, self).should_build(arch) - return not exists( - join(self.ctx.get_libs_dir(arch.arch), 'libbitmsghash.so')) - - def build_arch(self, arch=None): - super(BitmsghashRecipe, self).build_arch(arch) - env = self.get_recipe_env(arch) - with current_directory(join(self.get_build_dir(arch.arch))): - dst_dir = join(self.get_build_dir(arch.arch)) - shprint(sh.make, '-j', str(cpu_count()), _env=env) - self.install_libs(arch, '{}/libbitmsghash.so'.format(dst_dir), - 'libbitmsghash.so') - -recipe = BitmsghashRecipe() diff --git a/src/bitmessagekivy/android/python-for-android/recipes/kivymd/__init__.py b/src/bitmessagekivy/android/python-for-android/recipes/kivymd/__init__.py deleted file mode 100644 index 5a29bba7..00000000 --- a/src/bitmessagekivy/android/python-for-android/recipes/kivymd/__init__.py +++ /dev/null @@ -1,41 +0,0 @@ -""" -src/bitmessagekivy/android/python-for-android/recipes/kivymd/__init__.py -================================= -""" -# pylint: disable=import-error -from os.path import join - -from pythonforandroid.recipe import PythonRecipe -# from pythonforandroid.util import ensure_dir - - -class KivyMDRecipe(PythonRecipe): - """This recipe installs KivyMD into the android dist from source""" - version = 'master' - url = 'https://github.com/surbhicis/kivymd/archive/master.zip' - depends = ['kivy'] - site_packages_name = 'kivymd' - call_hostpython_via_targetpython = False - - def should_build(self, arch): # pylint: disable=no-self-use, unused-argument - """Method helps to build the application""" - return True - - def get_recipe_env(self, arch): - """Method is used for getting all the env paths""" - env = super(KivyMDRecipe, self).get_recipe_env(arch) - env['PYTHON_ROOT'] = self.ctx.get_python_install_dir() - env['CFLAGS'] += ' -I' + env['PYTHON_ROOT'] + '/include/python2.7' - env['LDFLAGS'] += ' -L' + env['PYTHON_ROOT'] + '/lib' + \ - ' -lpython2.7' - if 'sdl2' in self.ctx.recipe_build_order: - env['USE_SDL2'] = '1' - env['KIVY_SDL2_PATH'] = ':'.join([ - join(self.ctx.bootstrap.build_dir, 'jni', 'SDL', 'include'), - join(self.ctx.bootstrap.build_dir, 'jni', 'SDL2_image'), - join(self.ctx.bootstrap.build_dir, 'jni', 'SDL2_mixer'), - join(self.ctx.bootstrap.build_dir, 'jni', 'SDL2_ttf'), ]) - return env - - -recipe = KivyMDRecipe() diff --git a/src/bitmessagekivy/android/python-for-android/recipes/kivymd/kivymd-fix-dev-compatibility.patch b/src/bitmessagekivy/android/python-for-android/recipes/kivymd/kivymd-fix-dev-compatibility.patch deleted file mode 100644 index bc8d5dee..00000000 --- a/src/bitmessagekivy/android/python-for-android/recipes/kivymd/kivymd-fix-dev-compatibility.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff -Naurp KivyMD.orig/kivymd/button.py KivyMD/kivymd/button.py ---- KivyMD.orig/kivymd/button.py 2017-08-25 13:12:34.000000000 +0200 -+++ KivyMD/kivymd/button.py 2018-07-10 10:37:55.719440354 +0200 -@@ -175,7 +175,8 @@ class BaseButton(ThemableBehavior, Butto - self._current_button_color = self.md_bg_color_disabled - else: - self._current_button_color = self.md_bg_color -- super(BaseButton, self).on_disabled(instance, value) -+ # To add compatibility to last kivy (disabled is now an Alias property) -+ # super(BaseButton, self).on_disabled(instance, value) - - - class BasePressedButton(BaseButton): -diff -Naurp KivyMD.orig/kivymd/selectioncontrols.py KivyMD/kivymd/selectioncontrols.py ---- KivyMD.orig/kivymd/selectioncontrols.py 2017-08-25 13:12:34.000000000 +0200 -+++ KivyMD/kivymd/selectioncontrols.py 2018-07-10 10:40:06.971439102 +0200 -@@ -45,6 +45,7 @@ Builder.load_string(''' - pos: self.pos - - : -+ _thumb_pos: (self.right - dp(12), self.center_y - dp(12)) if self.active else (self.x - dp(12), self.center_y - dp(12)) - canvas.before: - Color: - rgba: self._track_color_disabled if self.disabled else \ -diff -Naurp KivyMD.orig/kivymd/tabs.py KivyMD/kivymd/tabs.py ---- KivyMD.orig/kivymd/tabs.py 2017-08-25 13:12:34.000000000 +0200 -+++ KivyMD/kivymd/tabs.py 2018-07-10 10:39:20.603439544 +0200 -@@ -185,7 +185,7 @@ class MDBottomNavigationBar(ThemableBeha - - class MDTabHeader(MDFlatButton): - """ Internal widget for headers based on MDFlatButton""" -- -+ - width = BoundedNumericProperty(dp(0), min=dp(72), max=dp(264), errorhandler=lambda x: dp(72)) - tab = ObjectProperty(None) - panel = ObjectProperty(None) diff --git a/src/bitmessagekivy/identiconGeneration.py b/src/bitmessagekivy/identiconGeneration.py deleted file mode 100644 index ca8bd3bd..00000000 --- a/src/bitmessagekivy/identiconGeneration.py +++ /dev/null @@ -1,93 +0,0 @@ -""" -Core classes for loading images and converting them to a Texture. -The raw image data can be keep in memory for further access -""" - -import hashlib -from io import BytesIO - -from PIL import Image -from kivy.core.image import Image as CoreImage -from kivy.uix.image import Image as kiImage -# pylint: disable=import-error - - -# constants -RESOLUTION = 128, 128 -V_RESOLUTION = 7, 7 -BACKGROUND_COLOR = 255, 255, 255, 255 -MODE = "RGB" - - -def generate(Generate_string=None): - """Generating string""" - hash_string = generate_hash(Generate_string) - color = random_color(hash_string) - image = Image.new(MODE, V_RESOLUTION, BACKGROUND_COLOR) - image = generate_image(image, color, hash_string) - image = image.resize(RESOLUTION, 0) - - data = BytesIO() - image.save(data, format='png') - data.seek(0) - # yes you actually need this - im = CoreImage(BytesIO(data.read()), ext='png') - beeld = kiImage() - # only use this line in first code instance - beeld.texture = im.texture - return beeld - # image.show() - - -def generate_hash(string): - """Generating hash""" - try: - # make input case insensitive - string = str.lower(string) - hash_object = hashlib.md5(str.encode(string)) - print hash_object.hexdigest() - - # returned object is a hex string - return hash_object.hexdigest() - - except IndexError: - print "Error: Please enter a string as an argument." - - -def random_color(hash_string): - """Getting random color""" - # remove first three digits from hex string - split = 6 - rgb = hash_string[:split] - - split = 2 - r = rgb[:split] - g = rgb[split:2 * split] - b = rgb[2 * split:3 * split] - - color = (int(r, 16), int(g, 16), - int(b, 16), 0xFF) - - return color - - -def generate_image(image, color, hash_string): - """Generating images""" - hash_string = hash_string[6:] - - lower_x = 1 - lower_y = 1 - upper_x = int(V_RESOLUTION[0] / 2) + 1 - upper_y = V_RESOLUTION[1] - 1 - limit_x = V_RESOLUTION[0] - 1 - index = 0 - - for x in range(lower_x, upper_x): - for y in range(lower_y, upper_y): - if int(hash_string[index], 16) % 2 == 0: - image.putpixel((x, y), color) - image.putpixel((limit_x - x, y), color) - - index = index + 1 - - return image diff --git a/src/bitmessagekivy/kivy_helper_search.py b/src/bitmessagekivy/kivy_helper_search.py index 085e2aa2..684a1722 100644 --- a/src/bitmessagekivy/kivy_helper_search.py +++ b/src/bitmessagekivy/kivy_helper_search.py @@ -1,30 +1,19 @@ -""" -Sql queries for bitmessagekivy -""" -from helper_sql import sqlQuery +from helper_sql import * -def search_sql( - xAddress="toaddress", account=None, folder="inbox", where=None, - what=None, unreadOnly=False, start_indx=0, end_indx=20): - """Method helping for searching mails""" - # pylint: disable=too-many-arguments, too-many-branches +def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, what=None, unreadOnly=False): if what is not None and what != "": what = "%" + what + "%" else: what = None - if folder == "sent" or folder == "draft": - sqlStatementBase = ( - '''SELECT toaddress, fromaddress, subject, message, status,''' - ''' ackdata, lastactiontime FROM sent ''') - elif folder == "addressbook": - sqlStatementBase = '''SELECT label, address From addressbook ''' + if folder == "sent": + sqlStatementBase = ''' + SELECT toaddress, fromaddress, subject, status, ackdata, lastactiontime + FROM sent ''' else: - sqlStatementBase = ( - '''SELECT folder, msgid, toaddress, message, fromaddress,''' - ''' subject, received, read FROM inbox ''') - + sqlStatementBase = '''SELECT folder, msgid, toaddress, fromaddress, subject, received, read + FROM inbox ''' sqlStatementParts = [] sqlArguments = [] if account is not None: @@ -35,39 +24,22 @@ def search_sql( else: sqlStatementParts.append(xAddress + " = ? ") sqlArguments.append(account) - if folder != "addressbook": - if folder is not None: - if folder == "new": - folder = "inbox" - unreadOnly = True - sqlStatementParts.append("folder = ? ") - sqlArguments.append(folder) - else: - sqlStatementParts.append("folder != ?") - sqlArguments.append("trash") + if folder is not None: + if folder == "new": + folder = "inbox" + unreadOnly = True + sqlStatementParts.append("folder = ? ") + sqlArguments.append(folder) + else: + sqlStatementParts.append("folder != ?") + sqlArguments.append("trash") if what is not None: - for colmns in where: - if len(where) > 1: - if where[0] == colmns: - filter_col = "(%s LIKE ?" % (colmns) - else: - filter_col += " or %s LIKE ? )" % (colmns) - else: - filter_col = "%s LIKE ?" % (colmns) - sqlArguments.append(what) - sqlStatementParts.append(filter_col) + sqlStatementParts.append("%s LIKE ?" % (where)) + sqlArguments.append(what) if unreadOnly: sqlStatementParts.append("read = 0") - if sqlStatementParts: + if len(sqlStatementParts) > 0: sqlStatementBase += "WHERE " + " AND ".join(sqlStatementParts) - if folder == "sent" or folder == "draft": - sqlStatementBase += \ - " ORDER BY lastactiontime DESC limit {0}, {1}".format( - start_indx, end_indx) - elif folder == "inbox": - sqlStatementBase += \ - " ORDER BY received DESC limit {0}, {1}".format( - start_indx, end_indx) - # elif folder == "addressbook": - # sqlStatementBase += " limit {0}, {1}".format(start_indx, end_indx) + if folder == "sent": + sqlStatementBase += " ORDER BY lastactiontime" return sqlQuery(sqlStatementBase, sqlArguments) diff --git a/src/bitmessagekivy/main.kv b/src/bitmessagekivy/main.kv index 37c20f52..ea8936c5 100644 --- a/src/bitmessagekivy/main.kv +++ b/src/bitmessagekivy/main.kv @@ -1,1332 +1,354 @@ +#:import la kivy.adapters.listadapter +#:import factory kivy.factory +#:import mpybit bitmessagekivy.mpybit +#:import C kivy.utils.get_color_from_hex -#:import Toolbar kivymd.toolbar.Toolbar -#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout -#:import NavigationDrawerDivider kivymd.navigationdrawer.NavigationDrawerDivider -#:import NavigationDrawerSubheader kivymd.navigationdrawer.NavigationDrawerSubheader -#:import MDCheckbox kivymd.selectioncontrols.MDCheckbox -#:import MDList kivymd.list.MDList -#:import OneLineListItem kivymd.list.OneLineListItem -#:import MDTextField kivymd.textfields.MDTextField -#:import get_color_from_hex kivy.utils.get_color_from_hex -#:import colors kivymd.color_definitions.colors -#:import MDTabbedPanel kivymd.tabs.MDTabbedPanel -#:import MDTab kivymd.tabs.MDTab -#:import MDFloatingActionButton kivymd.button.MDFloatingActionButton -#:import Factory kivy.factory.Factory -#:import MDScrollViewRefreshLayout kivymd.refreshlayout.MDScrollViewRefreshLayout -#:import MDSpinner kivymd.spinner.MDSpinner -#:import NoTransition kivy.uix.screenmanager.NoTransition -#:import MDSeparator kivymd.card.MDSeparator - -#:set color_button (0.784, 0.443, 0.216, 1) # brown -#:set color_button_pressed (0.659, 0.522, 0.431, 1) # darker brown -#:set color_font (0.957, 0.890, 0.843, 1) # off white - -: - icon: 'checkbox-blank-circle' - -: - font_size: '12.5sp' - background_color: color_button if self.state == 'down' else color_button_pressed - background_down: 'atlas://data/images/defaulttheme/button' - color: color_font - -: - drawer_logo: './images/drawer_logo1.png' - NavigationDrawerDivider: - NavigationDrawerSubheader: - text: "Accounts" +: + id: nav_drawer NavigationDrawerIconButton: - CustomSpinner: + Spinner: + pos_hint:{"x":0,"y":.3} id: btn - pos_hint:{"x":0,"y":.0} - option_cls: Factory.get("MySpinnerOption") - font_size: '11.9sp' - text: app.getDefaultAccData() - background_color: color_button if self.state == 'normal' else color_button_pressed - background_down: 'atlas://data/images/defaulttheme/spinner' - color: color_font - values: app.variable_1 + background_color: app.theme_cls.primary_dark + text: app.showmeaddresses(name='text') + values: app.showmeaddresses(name='values') on_text:app.getCurrentAccountData(self.text) - Image: - source: app.get_default_image() - x: self.width/6 - y: self.parent.y + self.parent.height/4 - size: self.parent.height/2, self.parent.height/2 - ArrowImg: + NavigationDrawerIconButton: - id: inbox_cnt icon: 'email-open' - text: "Inbox" + text: "inbox" on_release: app.root.ids.scr_mngr.current = 'inbox' - badge_text: "0" - on_press: app.load_screen(self) NavigationDrawerIconButton: - id: send_cnt - icon: 'send' - text: "Sent" + icon: 'mail-send' + text: "sent" on_release: app.root.ids.scr_mngr.current = 'sent' - badge_text: "0" NavigationDrawerIconButton: - id: draft_cnt - icon: 'message-draw' - text: "Draft" - on_release: app.root.ids.scr_mngr.current = 'draft' - badge_text: "0" - #NavigationDrawerIconButton: - #text: "Starred" - #icon:'star' - #on_release: app.root.ids.scr_mngr.current = 'starred' - #badge_text: "0" - #NavigationDrawerIconButton: - #icon: 'archive' - #text: "Archieve" - #on_release: app.root.ids.scr_mngr.current = 'archieve' - #badge_text: "0" - #NavigationDrawerIconButton: - #icon: 'email-open-outline' - #text: "Spam" - #on_release: app.root.ids.scr_mngr.current = 'spam' - #badge_text: "0" - NavigationDrawerIconButton: - id: trash_cnt - icon: 'delete' - text: "Trash" + icon: 'dropbox' + text: "trash" on_release: app.root.ids.scr_mngr.current = 'trash' - badge_text: "0" NavigationDrawerIconButton: - id: allmail_cnt - text: "All Mails" - icon:'contact-mail' - on_release: app.root.ids.scr_mngr.current = 'allmails' - badge_text: "0" - on_press: app.load_screen(self) - NavigationDrawerDivider: - NavigationDrawerSubheader: - text: "All labels" + icon: 'email' + text: "drafts" + on_release: app.root.ids.scr_mngr.current = 'dialog' + NavigationDrawerIconButton: + icon: 'markunread-mailbox' + text: "test" + on_release: app.root.ids.scr_mngr.current = 'test' NavigationDrawerIconButton: - text: "Address Book" - icon:'book-multiple' - on_release: app.root.ids.scr_mngr.current = 'addressbook' - NavigationDrawerIconButton: - text: "Settings" - icon:'settings' - on_release: app.root.ids.scr_mngr.current = 'set' - NavigationDrawerIconButton: - text: "Subscriptions/Payment" - icon:'bell' - on_release: app.root.ids.scr_mngr.current = 'payment' - NavigationDrawerIconButton: - text: "Credits" - icon:'wallet' - on_release: app.root.ids.scr_mngr.current = 'credits' - NavigationDrawerIconButton: - text: "new address" - icon:'account-plus' - on_release: app.root.ids.scr_mngr.current = 'login' - NavigationDrawerIconButton: - text: "Network Status" - icon:'server-network' - on_release: app.root.ids.scr_mngr.current = 'networkstat' - NavigationDrawerIconButton: - text: "My Addresses" - icon:'account-multiple' - on_release: app.root.ids.scr_mngr.current = 'myaddress' + text: "new identity" + icon:'accounts-add' + on_release: app.root.ids.scr_mngr.current = 'newidentity' + +BoxLayout: + orientation: 'vertical' + Toolbar: + id: toolbar + title: app.getCurrentAccount() + background_color: app.theme_cls.primary_dark + left_action_items: [['menu', lambda x: app.nav_drawer.toggle()]] + Button: + text:"EXIT" + color: 0,0,0,1 + background_color: (0,0,0,0) + size_hint_y: 0.4 + size_hint_x: 0.1 + pos_hint: {'x': 0.8, 'y':0.4} + on_press: app.say_exit() -NavigationLayout: - id: nav_layout - ContentNavigationDrawer: - id: nav_drawer + ScreenManager: + id: scr_mngr + Inbox: + id:sc1 + Sent: + id:sc2 + Trash: + id:sc3 + Dialog: + id:sc4 + Test: + id:sc5 + Create: + id:sc6 + NewIdentity: + id:sc7 + Page: + id:sc8 + AddressSuccessful: + id:sc9 - FloatLayout: - id: float_box - BoxLayout: - id: box_layout - orientation: 'vertical' - Toolbar: - id: toolbar - title: app.current_address_label() - opacity: 1 if app.addressexist() else 0 - disabled: False if app.addressexist() else True - md_bg_color: app.theme_cls.primary_color - background_palette: 'Primary' - background_hue: '500' - left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer()]] - right_action_items: [['account-plus', lambda x: app.addingtoaddressbook()]] + Button: + id:create + height:100 + size_hint_y: 0.13 + size_hint_x: 0.1 + pos_hint: {'x': 0.85, 'y': 0.5} + background_color: (0,0,0,0) + on_press: scr_mngr.current = 'create' + Image: + source: 'images/plus.png' + y: self.parent.y - 7.5 + x: self.parent.x + self.parent.width - 50 + size: 70, 70 - ScreenManager: - id: scr_mngr - Inbox: - id:sc1 - Page: - id:sc2 - Create: - id:sc3 - Sent: - id:sc4 - Trash: - id:sc5 - Login: - id:sc6 - Random: - id:sc7 - Spam: - id:sc8 - Setting: - id:sc9 - MyAddress: - id:sc10 - AddressBook: - id:sc11 - Payment: - id:sc12 - NetworkStat: - id:sc13 - MailDetail: - id:sc14 - ShowQRCode: - id:sc15 - Draft: - id:sc16 - Allmails: - id:sc17 - Credits: - id:sc18 - Starred: - id:sc19 - Archieve: - id:sc20 +: + text: '' + size_hint_y: None + height: 48 + ignore_perpendicular_swipes: True + data_index: 0 + min_move: 20 / self.width + + on__offset: app.update_index(root.data_index, self.index) + + canvas.before: + Color: + rgba: C('FFFFFF33') + + Rectangle: + pos: self.pos + size: self.size + + Line: + rectangle: self.pos + self.size + + Button: + text: 'delete ({}:{})'.format(root.text, root.data_index) + on_press: app.delete(root.data_index) + + Button: + text: root.text + on_press: app.getInboxMessageDetail(self.text) + + Button: + text: 'archive' + on_press: app.archive(root.data_index) : name: 'inbox' - transition: NoTransition() - BoxLayout: - orientation: 'vertical' - spacing: dp(5) - SearchBar: - GridLayout: - id: identi_tag - padding: [20, 0, 0, 5] - cols: 1 + RecycleView: + data: root.data + viewclass: 'SwipeButton' + do_scroll_x: False + scroll_timeout: 100 + + RecycleBoxLayout: + id:rc + orientation: 'vertical' size_hint_y: None height: self.minimum_height - MDLabel: - text: '' - font_style: 'Body1' - bold: True - #FloatLayout: - # MDScrollViewRefreshLayout: - # id: refresh_layout - # refresh_callback: root.refresh_callback - # root_layout: root.set_root_layout() - # MDList: - # id: ml - BoxLayout: - orientation:'vertical' - ScrollView: - id: scroll_y - do_scroll_x: False - MDList: - id: ml - Loader: - ComposerButton: + default_size_hint: 1, None + canvas.before: + Color: + rgba: 0,0,0, 1 + Rectangle: + pos: self.pos + size: self.size : name: 'sent' - BoxLayout: - orientation: 'vertical' - spacing: dp(5) - SearchBar: - GridLayout: - id: identi_tag - padding: [20, 0, 0, 5] - cols: 1 + RecycleView: + data: root.data + viewclass: 'SwipeButton' + do_scroll_x: False + scroll_timeout: 100 + + RecycleBoxLayout: + id:rc + orientation: 'vertical' size_hint_y: None height: self.minimum_height - MDLabel: - text: '' - font_style: 'Body1' - bold: True - BoxLayout: - orientation:'vertical' - ScrollView: - id: scroll_y - do_scroll_x: False - MDList: - id: ml - Loader: - ComposerButton: + default_size_hint: 1, None + canvas.before: + Color: + rgba: 0,0,0, 1 + Rectangle: + pos: self.pos + size: self.size : name: 'trash' - BoxLayout: - orientation: 'vertical' - spacing: dp(5) - GridLayout: - id: identi_tag - padding: [20, 20, 0, 5] - spacing: dp(5) - cols: 1 + RecycleView: + data: root.data + viewclass: 'SwipeButton' + do_scroll_x: False + scroll_timeout: 100 + + RecycleBoxLayout: + id:rc + orientation: 'vertical' size_hint_y: None height: self.minimum_height - MDLabel: - text: '' - font_style: 'Body1' - bold: True - BoxLayout: - orientation:'vertical' - ScrollView: - id: scroll_y - do_scroll_x: False - MDList: - id: ml - Loader: - ComposerButton: - -: - name: 'draft' - BoxLayout: - orientation: 'vertical' - spacing: dp(5) - GridLayout: - id: identi_tag - padding: [20, 20, 0, 5] - cols: 1 - size_hint_y: None - height: self.minimum_height - MDLabel: - text: '' - font_style: 'Body1' - bold: True - BoxLayout: - orientation:'vertical' - ScrollView: - id: scroll_y - do_scroll_x: False - MDList: - id: ml - ComposerButton: + default_size_hint: 1, None + canvas.before: + Color: + rgba: 0,0,0, 1 + Rectangle: + pos: self.pos + size: self.size -: - name: 'starred' - ScrollView: - do_scroll_x: False - MDList: - id: ml - ComposerButton: - -: - name: 'archieve' - ScrollView: - do_scroll_x: False - MDList: - id: ml - ComposerButton: - -: - name: 'spam' - ScrollView: - do_scroll_x: False - MDList: - id: ml - ComposerButton: - -: - name: 'allmails' - #FloatLayout: - # MDScrollViewRefreshLayout: - # id: refresh_layout - # refresh_callback: root.refresh_callback - # root_layout: root.set_root_layout() - # MDList: - # id: ml - BoxLayout: - orientation: 'vertical' - spacing: dp(5) - GridLayout: - id: identi_tag - padding: [20, 20, 0, 5] - spacing: dp(5) - cols: 1 - size_hint_y: None - height: self.minimum_height - MDLabel: - text: '' - font_style: 'Body1' - bold: True - BoxLayout: - orientation:'vertical' - ScrollView: - id: scroll_y - do_scroll_x: False - MDList: - id: ml - Loader: - ComposerButton: - +: + name: 'dialog' + Label: + text:"I have a good dialox box" + color: 0,0,0,1 : name: 'test' Label: text:"I am in test" color: 0,0,0,1 +: + name: 'create' + GridLayout: + rows: 5 + cols: 1 + padding: 60,60,60,60 + spacing: 50 + BoxLayout: + size_hint_y: None + height: '32dp' + Label: + text: 'FROM' + color: 0,0,0,1 + Spinner: + size_hint: 1,1 + pos_hint: {"x":0,"top":1.} + pos: 10,10 + id: spinner_id + text: app.showmeaddresses(name='text') + values: app.showmeaddresses(name='values') + + BoxLayout: + size_hint_y: None + height: '32dp' + Label: + text: 'TO' + color: 0,0,0,1 + TextInput: + id: recipent + hint_text: 'To' + + BoxLayout: + size_hint_y: None + height: '32dp' + Label: + text: 'SUBJECT' + color: 0,0,0,1 + TextInput: + id: subject + hint_text: 'SUBJECT' + + BoxLayout: + size_hint_y: None + height: '32dp' + Label: + text: 'BODY' + color: 0,0,0,1 + TextInput: + id: message + multiline:True + size_hint: 1,2 + + Button: + text: 'send' + size_hint_y: 0.1 + size_hint_x: 0.2 + height: '32dp' + pos_hint: {'x': .5, 'y': 0.1} + on_press: root.send() + Button: + text: 'cancel' + size_hint_y: 0.1 + size_hint_x: 0.2 + height: '32dp' + pos_hint: {'x': .72, 'y': 0.1} + on_press: root.cancel() + +: + name: 'newidentity' + GridLayout: + padding: '120dp' + cols: 1 + Label: + text:"""Here you may generate as many addresses as you like. Indeed, creating and abandoning addresses is encouraged.""" + line_height:1.5 + text_size:(700,None) + color: 0,0,0,1 + BoxLayout: + CheckBox: + canvas.before: + Color: + rgb: 1,0,0 + Ellipse: + pos:self.center_x-8, self.center_y-8 + size:[16,16] + group: "money" + id:chk + text:"use a random number generator to make an address" + on_active: + root.checked = self.text + active:root.is_active + + Label: + text: "use a random number generator to make an address" + color: 0,0,0,1 + BoxLayout: + CheckBox: + canvas.before: + Color: + rgb: 1,0,0 + Ellipse: + pos:self.center_x-8, self.center_y-8 + size:[16,16] + group: "money" + id:chk + text:"use a pseudo number generator to make an address" + on_active: + root.checked = self.text + active:not root.is_active + Label: + text: "use a pseudo number generator to make an address" + color: 0,0,0,1 + Label: + color: 0,0,0,1 + size_hint_x: .35 + markup: True + text: "[b]{}[/b]".format("Randomly generated addresses") + BoxLayout: + size_hint_y: None + height: '32dp' + Label: + text: "Label (not shown to anyone except you)" + color: 0,0,0,1 + BoxLayout: + size_hint_y: None + height: '32dp' + TextInput: + id: label + + Button: + text: 'Cancel' + size_hint_y: 0.1 + size_hint_x: 0.3 + height: '32dp' + pos_hint: {'x': .1, 'y': 0.1} + Button: + text: 'Ok' + size_hint_y: 0.1 + size_hint_x: 0.3 + height: '32dp' + pos_hint: {'x': .5, 'y': 0.1} + on_press: root.generateaddress() + : name: 'page' Label: - text:"I am on page" + text: 'I am on description of my email yooooo' color: 0,0,0,1 -: - name: 'create' - Loader: - -: - name: 'credits' - ScrollView: - do_scroll_x: False - MDList: - id: ml - size_hint_y: None - height: dp(200) - OneLineListItem: - text: "Available Credits" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .6, .35 - height: dp(40) - MDLabel: - font_style: 'Title' - text: root.available_credits - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - -: - ScrollView: - BoxLayout: - orientation: 'vertical' - size_hint_y: None - height: self.minimum_height + 2 * self.parent.height/4 - padding: dp(32) - spacing: 15 - BoxLayout: - orientation: 'vertical' - MDTextField: - id: ti - hint_text: 'type or select sender address' - size_hint_y: None - height: 100 - font_size: '13sp' - multiline: False - required: True - helper_text_mode: "on_error" - - BoxLayout: - size_hint_y: None - height: dp(40) - CustomSpinner: - background_color: app.theme_cls.primary_dark - id: btn - values: app.variable_1 - on_text: root.auto_fill_fromaddr() if self.text != 'Select' else '' - option_cls: Factory.get("MySpinnerOption") - background_color: color_button if self.state == 'normal' else color_button_pressed - background_down: 'atlas://data/images/defaulttheme/spinner' - color: color_font - font_size: '12.5sp' - ArrowImg: - - BoxLayout: - orientation: 'vertical' - txt_input: txt_input - rv: rv - size : (890, 60) - size_hint: 1,1 - MyTextInput: - id: txt_input - size_hint_y: None - font_size: '13sp' - height: self.parent.height/2 - #hint_text: 'type or search recipients address starting with BM-' - hint_text: 'type, select or scan QR code for recipients address' - RV: - id: rv - MDTextField: - id: subject - hint_text: 'subject' - required: True - height: 100 - font_size: '13sp' - size_hint_y: None - multiline: False - helper_text_mode: "on_error" - - MDTextField: - id: body - multiline: True - hint_text: 'body' - size_hint_y: None - font_size: '13sp' - required: True - helper_text_mode: "on_error" - BoxLayout: - spacing:50 - -: - readonly: False - multiline: False - -: - # Draw a background to indicate selection - color: 0,0,0,1 - canvas.before: - Color: - rgba: app.theme_cls.primary_dark if self.selected else (1, 1, 1, 0) - Rectangle: - pos: self.pos - size: self.size - -: - canvas: - Color: - rgba: 0,0,0,.2 - - Line: - rectangle: self.x +1 , self.y, self.width - 2, self.height -2 - bar_width: 10 - scroll_type:['bars'] - viewclass: 'SelectableLabel' - SelectableRecycleBoxLayout: - default_size: None, dp(20) - default_size_hint: 1, None - size_hint_y: None - height: self.minimum_height - orientation: 'vertical' - multiselect: False - - -: - name: 'login' - ScrollView: - do_scroll_x: False - BoxLayout: - orientation: 'vertical' - size_hint_y: None - height: dp(750) - padding: dp(10) - BoxLayout: - MDLabel: - font_style: 'Body1' - theme_text_color: 'Primary' - text: "You may generate addresses by using either random numbers or by using a passphrase If you use a passphrase, the address is called a deterministic; address The Random Number option is selected by default but deterministic addresses have several \n pros and cons:\n" - halign: 'center' - bold: True - color:app.theme_cls.primary_dark - BoxLayout: - MDLabel: - font_style: 'Caption' - theme_text_color: 'Primary' - text: "If talk about pros You can recreate your addresses on any computer from memory, You need-not worry about backing up your keys.dat file as long as you can remember your passphrase and aside talk about cons You must remember (or write down) your You must remember the address version number and the stream number along with your passphrase If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you" - halign: 'center' - bold: True - color:app.theme_cls.primary_dark - MDCheckbox: - id: grp_chkbox_1 - group: 'test' - active: True - allow_no_selection: False - MDLabel: - font_style: 'Caption' - theme_text_color: 'Primary' - text: "use a random number generator to make an address" - halign: 'center' - size_hint_y: None - bold: True - height: self.texture_size[1] + dp(4) - color: [0.941, 0, 0,1] - MDCheckbox: - id: grp_chkbox_1 - group: 'test' - allow_no_selection: False - MDLabel: - font_style: 'Caption' - theme_text_color: 'Primary' - text: "use a pseudo number generator to make an address" - halign: 'center' - size_hint_y: None - bold: True - color: [0.941, 0, 0,1] - height: self.texture_size[1] + dp(4) - BoxLayout: - AnchorLayout: - MDRaisedButton: - height: dp(40) - on_press: app.root.ids.scr_mngr.current = 'random' - on_press: app.root.ids.sc7.reset_address_label() - MDLabel: - font_style: 'Title' - text: 'proceed' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - -: - name: 'random' - ScrollView: - BoxLayout: - orientation: 'vertical' - size_hint_y: None - height: self.minimum_height - padding: dp(20) - spacing: 100 - MDLabel: - font_style: 'Body1' - theme_text_color: 'Primary' - text: "Random Addresses" - halign: 'center' - bold: True - color:app.theme_cls.primary_dark - - MDLabel: - font_style: 'Body1' - theme_text_color: 'Primary' - text: "Here you may generate as many addresses as you like, Indeed creating and abandoning addresses is encouraged" - halign: 'center' - bold: True - color:app.theme_cls.primary_dark - - MDTextField: - id: label - multiline: True - hint_text: "Label" - required: True - helper_text_mode: "on_error" - on_text: root.add_validation(self) - BoxLayout: - AnchorLayout: - MDRaisedButton: - height: dp(40) - on_release: root.generateaddress(app) - opposite_colors: True - MDLabel: - font_style: 'Title' - text: 'next' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - -: - name: 'set' - ScrollView: - do_scroll_x: False - MDList: - id: ml - size_hint_y: None - height: dp(500) - OneLineListItem: - text: "SERVER SETTINGS" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .6, .55 - height: dp(40) - MDLabel: - font_style: 'Title' - text: 'Server' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - OneLineListItem: - text: "DATA SETTINGS" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .6, .55 - height: dp(40) - MDLabel: - font_style: 'Title' - text: 'Import or export data' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - OneLineListItem: - text: "OTHER SETTINGS" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .6, .55 - height: dp(40) - MDLabel: - font_style: 'Title' - text: 'Restart background service' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - BoxLayout: - AnchorLayout: - MDLabel: - font_style: 'Body1' - theme_text_color: 'Primary' - text: "bitmessage is 11 seconds behind the network" - halign: 'center' - bold: True - color: [0.941, 0, 0,1] - - BoxLayout: - MDCheckbox: - id: chkbox - size_hint: None, None - size: dp(48), dp(64) - active: True - MDLabel: - font_style: 'Body1' - theme_text_color: 'Primary' - text: "show settings (for advanced users only)" - halign: 'left' - bold: True - color: app.theme_cls.primary_dark - -: - name: 'myaddress' - BoxLayout: - orientation: 'vertical' - spacing: dp(5) - SearchBar: - GridLayout: - id: identi_tag - padding: [20, 0, 0, 5] - cols: 1 - size_hint_y: None - height: self.minimum_height - MDLabel: - text: 'My Addresses' - font_style: 'Body1' - bold: True - FloatLayout: - MDScrollViewRefreshLayout: - id: refresh_layout - refresh_callback: root.refresh_callback - root_layout: root.set_root_layout() - MDList: - id: ml - Loader: - ComposerButton: - -: - name: 'addressbook' - BoxLayout: - orientation: 'vertical' - spacing: dp(5) - SearchBar: - GridLayout: - id: identi_tag - padding: [20, 0, 0, 5] - cols: 1 - size_hint_y: None - height: self.minimum_height - MDLabel: - text: '' - font_style: 'Body1' - bold: True - BoxLayout: - orientation:'vertical' - ScrollView: - id: scroll_y - do_scroll_x: False - MDList: - id: ml - Loader: - ComposerButton: - -: - name: 'payment' - ScrollView: - do_scroll_x: False - BoxLayout: - orientation: 'vertical' - padding: [dp(app.window_size[0]/16 if app.window_size[0] <= 720 else app.window_size[0]/6 if app.window_size[0] <= 800 else app.window_size[0]/18), dp(10)] - spacing: 12 - size_hint_y: None - height: self.minimum_height + dp(app.window_size[1]) if app.window_size[1] > app.window_size[0] else dp(app.window_size[0]) - BoxLayout: - orientation: 'vertical' - padding: dp(5) - canvas.before: - Color: - rgba: app.theme_cls.primary_dark - Rectangle: - # self here refers to the widget i.e FloatLayout - pos: self.pos - size: self.size - MDLabel: - size_hint_y: None - font_style: 'Headline' - theme_text_color: 'Primary' - text: 'Platinum' - halign: 'center' - color: 1,1,1,1 - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: 'We provide subscriptions for proof of work calculation for first month. ' - halign: 'center' - color: 1,1,1,1 - MDLabel: - id: free_pak - font_style: 'Headline' - theme_text_color: 'Primary' - text: '€ 50.0' - halign: 'center' - color: 1,1,1,1 - MDRaisedButton: - canvas: - Color: - rgb: (0.93, 0.93, 0.93) - Rectangle: - pos: self.pos - size: self.size - size_hint: 1, None - height: dp(40) - on_press: root.get_available_credits(self) - MDLabel: - font_style: 'Title' - text: 'Get Free Credits' - font_size: '13sp' - color: (0,0,0,1) - halign: 'center' - BoxLayout: - orientation: 'vertical' - padding: dp(5) - canvas.before: - Color: - rgba: app.theme_cls.primary_dark - Rectangle: - # self here refers to the widget i.e FloatLayout - pos: self.pos - size: self.size - MDLabel: - size_hint_y: None - font_style: 'Headline' - theme_text_color: 'Primary' - text: 'Silver' - halign: 'center' - color: 1,1,1,1 - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: 'We provide for proof of work calculation for six month. ' - halign: 'center' - color: 1,1,1,1 - MDLabel: - font_style: 'Headline' - theme_text_color: 'Primary' - text: '€ 100.0' - halign: 'center' - color: 1,1,1,1 - MDRaisedButton: - canvas: - Color: - rgb: (0.93, 0.93, 0.93) - Rectangle: - pos: self.pos - size: self.size - size_hint: 1, None - height: dp(40) - MDLabel: - font_style: 'Title' - text: 'Get Monthly Credits' - font_size: '13sp' - color: (0,0,0,1) - halign: 'center' - BoxLayout: - orientation: 'vertical' - padding: dp(5) - canvas.before: - Color: - rgba: app.theme_cls.primary_dark - Rectangle: - # self here refers to the widget i.e FloatLayout - pos: self.pos - size: self.size - MDLabel: - size_hint_y: None - font_style: 'Headline' - theme_text_color: 'Primary' - text: 'Gold' - halign: 'center' - color: 1,1,1,1 - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: 'We provide for proof of work calculation for 1years. ' - halign: 'center' - color: 1,1,1,1 - MDLabel: - font_style: 'Headline' - theme_text_color: 'Primary' - text: '€ 500.0' - halign: 'center' - color: 1,1,1,1 - MDRaisedButton: - canvas: - Color: - rgb: (0.93, 0.93, 0.93) - Rectangle: - pos: self.pos - size: self.size - size_hint: 1, None - height: dp(40) - MDLabel: - font_style: 'Title' - text: 'Get Yearly Credits' - font_size: '13sp' - color: (0,0,0,1) - halign: 'center' - - -: - id: popup - size_hint : (None,None) - height: 2*(label.height + address.height) + 10 - width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4) - title: 'add contact\'s' - background: './images/popup.jpeg' - title_size: sp(20) - title_color: 0.4, 0.3765, 0.3451, 1 - auto_dismiss: False - separator_color: 0.3529, 0.3922, 0.102, 0.7 - BoxLayout: - size_hint_y: 0.5 - orientation: 'vertical' - spacing:dp(20) - id: popup_box - BoxLayout: - orientation: 'vertical' - MDTextField: - id: label - multiline: False - hint_text: "Label" - required: True - helper_text_mode: "on_error" - on_text: root.checkLabel_valid(self) - MDTextField: - id: address - hint_text: "Address" - required: True - helper_text_mode: "on_error" - on_text: root.checkAddress_valid(self) - BoxLayout: - spacing:5 - orientation: 'horizontal' - MDRaisedButton: - id: save_addr - size_hint: 1.5, None - height: dp(40) - on_release: - root.savecontact() - MDLabel: - font_style: 'Title' - text: 'Save' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - MDRaisedButton: - size_hint: 1.5, None - height: dp(40) - on_press: root.dismiss() - on_press: root.close_pop() - MDLabel: - font_style: 'Title' - text: 'Cancel' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - MDRaisedButton: - size_hint: 2, None - height: dp(40) - MDLabel: - font_style: 'Title' - text: 'Scan QR code' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - - -: - name: 'networkstat' - MDTabbedPanel: - id: tab_panel - tab_display_mode:'text' - - MDTab: - name: 'connections' - text: "Total connections" - ScrollView: - do_scroll_x: False - MDList: - id: ml - size_hint_y: None - height: dp(200) - OneLineListItem: - text: "Total Connections" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .6, .35 - height: dp(40) - MDLabel: - font_style: 'Title' - text: root.text_variable_1 - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - MDTab: - name: 'processes' - text: 'Processes' - ScrollView: - do_scroll_x: False - MDList: - id: ml - size_hint_y: None - height: dp(500) - OneLineListItem: - text: "person-to-person" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .7, .6 - height: dp(40) - MDLabel: - font_style: 'Title' - text: root.text_variable_2 - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - OneLineListItem: - text: "Brodcast" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .7, .6 - height: dp(40) - MDLabel: - font_style: 'Title' - text: root.text_variable_3 - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - OneLineListItem: - text: "publickeys" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .7, .6 - height: dp(40) - MDLabel: - font_style: 'Title' - text: root.text_variable_4 - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - OneLineListItem: - text: "objects" - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: .7, .6 - height: dp(40) - MDLabel: - font_style: 'Title' - text: root.text_variable_5 - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - -: - name: 'mailDetail' - ScrollView: - do_scroll_x: False - BoxLayout: - orientation: 'vertical' - size_hint_y: None - height: dp(500) + self.minimum_height - padding: dp(32) - MDLabel: - font_style: 'Headline' - theme_text_color: 'Primary' - text: root.subject - halign: 'left' - font_size: '20sp' - CopyTextBtn: - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: "From: " + root.from_addr - halign: 'left' - CopyTextBtn: - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: "To: " + root.to_addr - halign: 'left' - CopyTextBtn: - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: root.status - halign: 'left' - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: root.message - halign: 'left' - bold: True - CopyTextBtn: - BoxLayout: - orientation: 'vertical' - size_hint_y: None - height: dp(100) + self.minimum_height - Loader: - -: - id: cpyButton - color: 0,0,0,1 - background_color: (0,0,0,0) - center_x: self.parent.center_x * 2 - self.parent.parent.padding[0]/2 - center_y: self.parent.center_y - on_press:app.root.ids.sc14.copy_composer_text(self) - Image: - source: './images/copy_text.png' - center_x: self.parent.center_x - center_y: self.parent.center_y - size: 20, 20 - -: - size_hint_y: None - height: dp(56) - spacing: '10dp' - pos_hint: {'center_x':0.45, 'center_y': .1} - - Widget: - - MDFloatingActionButton: - icon: 'plus' - opposite_colors: True - elevation_normal: 8 - md_bg_color: [0.941, 0, 0,1] - on_press: app.root.ids.scr_mngr.current = 'create' - on_press: app.clear_composer() - -: - id: myadd_popup - size_hint : (None,None) - height: 4.5*(myaddr_label.height+ my_add_btn.children[0].height) - width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4) - background: './images/popup.jpeg' - auto_dismiss: False - separator_height: 0 - BoxLayout: - id: myadd_popup_box - size_hint_y: None - spacing:dp(70) - orientation: 'vertical' - BoxLayout: - size_hint_y: None - orientation: 'vertical' - spacing:dp(25) - MDLabel: - id: myaddr_label - font_style: 'Title' - theme_text_color: 'Primary' - text: "Label" - font_size: '17sp' - halign: 'left' - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: root.address_label - font_size: '15sp' - halign: 'left' - MDLabel: - font_style: 'Title' - theme_text_color: 'Primary' - text: "Address" - font_size: '17sp' - halign: 'left' - MDLabel: - font_style: 'Subhead' - theme_text_color: 'Primary' - text: root.address - font_size: '15sp' - halign: 'left' - BoxLayout: - id: my_add_btn - spacing:5 - orientation: 'horizontal' - MDRaisedButton: - size_hint: 2, None - height: dp(40) - on_press: root.send_message_from() - MDLabel: - font_style: 'Title' - text: 'Send message from' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - MDRaisedButton: - size_hint: 1.5, None - height: dp(40) - on_press: root.dismiss() - on_press: app.root.ids.scr_mngr.current = 'showqrcode' - on_press: app.root.ids.sc15.qrdisplay() - MDLabel: - font_style: 'Title' - text: 'Show QR code' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - MDRaisedButton: - size_hint: 1.5, None - height: dp(40) - on_press: root.dismiss() - on_press: root.close_pop() - MDLabel: - font_style: 'Title' - text: 'Cancel' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - -: - id: addbook_popup - size_hint : (None,None) - height: 4*(add_label.height) - width :app.window_size[0] - (app.window_size[0]/10 if app.app_platform == 'android' else app.window_size[0]/4) - background: './images/popup.jpeg' - separator_height: 0 - auto_dismiss: False - BoxLayout: - size_hint_y: None - spacing:dp(70) - id: addbook_popup_box - orientation: 'vertical' - BoxLayout: - size_hint_y: None - orientation: 'vertical' - spacing:dp(20) - MDLabel: - font_style: 'Title' - theme_text_color: 'Primary' - text: "Label" - font_size: '17sp' - halign: 'left' - MDTextField: - id: add_label - font_style: 'Subhead' - font_size: '15sp' - halign: 'left' - text: root.address_label - theme_text_color: 'Primary' - required: True - helper_text_mode: "on_error" - on_text: root.checkLabel_valid(self) - MDLabel: - font_style: 'Title' - theme_text_color: 'Primary' - text: "Address" - font_size: '17sp' - halign: 'left' - MDLabel: - id: address - font_style: 'Subhead' - theme_text_color: 'Primary' - text: root.address - font_size: '15sp' - halign: 'left' - BoxLayout: - id: addbook_btn - spacing:5 - orientation: 'horizontal' - MDRaisedButton: - size_hint: 2, None - height: dp(40) - on_press: root.send_message_to() - MDLabel: - font_style: 'Title' - text: 'Send message to' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - MDRaisedButton: - size_hint: 1.5, None - height: dp(40) - font_size: '10sp' - on_press: root.update_addbook_label(root.address) - MDLabel: - font_style: 'Title' - text: 'Save' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - MDRaisedButton: - size_hint: 1.5, None - height: dp(40) - on_press: root.dismiss() - on_press: root.close_pop() - MDLabel: - font_style: 'Title' - text: 'Cancel' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' - -: - name: 'showqrcode' - BoxLayout: - orientation: 'vertical' - id: qr - - -: - source: './images/down-arrow.png' if self.parent.is_open == True else './images/right-arrow.png' - size: 15, 15 - x: self.parent.x + self.parent.width - self.width - 5 - y: self.parent.y + self.parent.height/2 - self.height + 5 - - -: - id: search_bar - size_hint_y: None - height: self.minimum_height - - MDIconButton: - icon: 'magnify' - - MDTextField: - id: search_field - hint_text: 'Search' - on_text: app.searchQuery(self) - - -: - separator_color: 1, 1, 1, 1 - background: "White.png" - Button: - id: btn - disabled: True - background_disabled_normal: "White.png" - Image: - source: './images/loader.zip' - anim_delay: 0 - #mipmap: True - size: root.size - - -: - id: spinner - size_hint: None, None - size: dp(46), dp(46) - pos_hint: {'center_x': 0.5, 'center_y': 0.5} - active: False \ No newline at end of file +: + name: 'add_sucess' + Label: + text: 'Successfully created a new bit address' + color: 0,0,0,1 diff --git a/src/bitmessagekivy/mpybit.py b/src/bitmessagekivy/mpybit.py index 78921918..3f9b198b 100644 --- a/src/bitmessagekivy/mpybit.py +++ b/src/bitmessagekivy/mpybit.py @@ -1,2523 +1,393 @@ -""" -Bitmessage android(mobile) interface -""" -# pylint: disable=relative-import, import-error, no-name-in-module -# pylint: disable=too-few-public-methods, too-many-lines, unused-argument -import os -import time -from bmconfigparser import BMConfigParser -from functools import partial -from helper_sql import sqlExecute, sqlQuery -from kivy.app import App -from kivy.clock import Clock -from kivy.core.clipboard import Clipboard -from kivy.core.window import Window -from kivy.lang import Builder -from kivy.properties import ( - BooleanProperty, - ListProperty, - NumericProperty, - ObjectProperty, - StringProperty -) -from kivy.uix.behaviors import FocusBehavior -from kivy.uix.boxlayout import BoxLayout -from kivy.uix.button import Button -from kivy.uix.carousel import Carousel -from kivy.uix.image import Image -from kivy.uix.label import Label -from kivy.uix.popup import Popup -from kivy.uix.recycleboxlayout import RecycleBoxLayout -from kivy.uix.recycleview import RecycleView -from kivy.uix.recycleview.layout import LayoutSelectionBehavior -from kivy.uix.recycleview.views import RecycleDataViewBehavior -from kivy.uix.screenmanager import Screen -from kivy.uix.spinner import Spinner -from kivy.uix.textinput import TextInput -from kivy.utils import platform - import kivy_helper_search -from kivymd.button import MDIconButton -from kivymd.dialog import MDDialog -from kivymd.label import MDLabel -from kivymd.list import ( - ILeftBody, - ILeftBodyTouch, - IRightBodyTouch, - TwoLineAvatarIconListItem, - TwoLineListItem -) -from kivymd.navigationdrawer import ( - MDNavigationDrawer, - NavigationDrawerHeaderBase -) -from kivymd.selectioncontrols import MDCheckbox -from kivymd.theming import ThemeManager - +import os import queues -from semaphores import kivyuisignaler - +import shutdown import state -from uikivysignaler import UIkivySignaler +import time -import identiconGeneration -from addresses import addBMIfNotPresent, decodeAddress -import helper_sent +from kivy.app import App +from kivy.lang import Builder +from kivy.properties import BooleanProperty +from kivy.clock import Clock +from navigationdrawer import NavigationDrawer +from kivy.properties import ObjectProperty, StringProperty, ListProperty +from kivy.uix.screenmanager import Screen +from kivy.uix.textinput import TextInput +from kivymd.theming import ThemeManager +from kivymd.toolbar import Toolbar +from bmconfigparser import BMConfigParser +from helper_ackPayload import genAckPayload +from addresses import decodeAddress, addBMIfNotPresent +from helper_sql import sqlExecute + +statusIconColor = 'red' -def toast(text): - """Function displays toast message""" - # pylint: disable=redefined-outer-name - from kivymd.toast.kivytoast import toast - toast(text) - return +class NavigateApp(App, TextInput): + """Application uses kivy in which base Class of Navigate App inherits from the App class.""" + + theme_cls = ThemeManager() + nav_drawer = ObjectProperty() + + def build(self): + """Return a main_widget as a root widget. + + An application can be built if you return a widget on build(), or if you set + self.root. + """ + main_widget = Builder.load_file( + os.path.join(os.path.dirname(__file__), 'main.kv')) + self.nav_drawer = Navigator() + return main_widget + + def getCurrentAccountData(self, text): + """Get Current Address Account Data.""" + state.association = text + self.root.ids.sc1.clear_widgets() + self.root.ids.sc2.clear_widgets() + self.root.ids.sc3.clear_widgets() + self.root.ids.sc1.add_widget(Inbox()) + self.root.ids.sc2.add_widget(Sent()) + self.root.ids.sc3.add_widget(Trash()) + self.root.ids.toolbar.title = BMConfigParser().get( + state.association, 'label') + '({})'.format(state.association) + Inbox() + Sent() + Trash() + + def say_exit(self): + """Exit the application as uses shutdown PyBitmessage.""" + print("**************************EXITING FROM APPLICATION*****************************") + App.get_running_app().stop() + shutdown.doCleanShutdown() + + @staticmethod + def showmeaddresses(name="text"): + """Show the addresses in spinner to make as dropdown.""" + if name == "text": + return BMConfigParser().addresses()[0] + elif name == "values": + return BMConfigParser().addresses() + + def update_index(self, data_index, index): + """Update index after archieve message to trash.""" + if self.root.ids.scr_mngr.current == 'inbox': + self.root.ids.sc1.data[data_index]['index'] = index + elif self.root.ids.scr_mngr.current == 'sent': + self.root.ids.sc2.data[data_index]['index'] = index + elif self.root.ids.scr_mngr.current == 'trash': + self.root.ids.sc3.data[data_index]['index'] = index + + def delete(self, data_index): + """It will make delete using remove function.""" + print("delete {}".format(data_index)) + self._remove(data_index) + + def archive(self, data_index): + """It will make archieve using remove function.""" + print("archive {}".format(data_index)) + self._remove(data_index) + + def _remove(self, data_index): + """It will remove message by resetting the values in recycleview data.""" + if self.root.ids.scr_mngr.current == 'inbox': + self.root.ids.sc1.data.pop(data_index) + self.root.ids.sc1.data = [{ + 'data_index': i, + 'index': d['index'], + 'height': d['height'], + 'text': d['text']} + for i, d in enumerate(self.root.ids.sc1.data) + ] + elif self.root.ids.scr_mngr.current == 'sent': + self.root.ids.sc2.data.pop(data_index) + self.root.ids.sc2.data = [{ + 'data_index': i, + 'index': d['index'], + 'height': d['height'], + 'text': d['text']} + for i, d in enumerate(self.root.ids.sc2.data) + ] + elif self.root.ids.scr_mngr.current == 'trash': + self.root.ids.sc3.data.pop(data_index) + self.root.ids.sc3.data = [{ + 'data_index': i, + 'index': d['index'], + 'height': d['height'], + 'text': d['text']} + for i, d in enumerate(self.root.ids.sc3.data) + ] + + def getInboxMessageDetail(self, instance): + """It will get message detail after make selected message description.""" + try: + self.root.ids.scr_mngr.current = 'page' + except AttributeError: + self.parent.manager.current = 'page' + print('Message Clicked {}'.format(instance)) + + @staticmethod + def getCurrentAccount(): + """It uses to get current account label.""" + return BMConfigParser().get(state.association, 'label') + '({})'.format(state.association) -class CustomAvatarIconListItem(TwoLineAvatarIconListItem): +class Navigator(NavigationDrawer): + """Navigator class uses NavigationDrawer. - def __init__(self, **kwargs): - super(CustomAvatarIconListItem, self).__init__(**kwargs) - self.text_color=[0.12, 0.58, 0.95, 1] + It is an UI panel that shows our app's main navigation menu + It is hidden when not in use, but appears when the user swipes + a finger from the left edge of the screen or, when at the top + level of the app, the user touches the drawer icon in the app bar + """ - -class Navigatorss(MDNavigationDrawer): - """Navigator class (image, title and logo)""" image_source = StringProperty('images/qidenticon_two.png') title = StringProperty('Navigation') - drawer_logo = StringProperty() class Inbox(Screen): """Inbox Screen uses screen to show widgets of screens.""" - queryreturn = ListProperty() - has_refreshed = True - account = StringProperty() + + data = ListProperty() def __init__(self, *args, **kwargs): - """Method Parsing the address.""" super(Inbox, self).__init__(*args, **kwargs) - Clock.schedule_once(self.init_ui, 0) - - @staticmethod - def set_defaultAddress(): - """This method set's default address""" if state.association == '': - if BMConfigParser().addresses(): - state.association = BMConfigParser().addresses()[0] - - def init_ui(self, dt=0): - """Clock schdule for method inbox accounts.""" - self.loadMessagelist() - - def loadMessagelist(self, where="", what=""): - """Load Inbox list for Inbox messages.""" - # pylint: disable=too-many-locals - self.set_defaultAddress() - self.account = state.association - if state.searcing_text: - self.children[2].children[0].children[0].scroll_y = 1.0 - where = ['subject', 'message'] - what = state.searcing_text - xAddress = 'toaddress' - data = [] - self.inboxDataQuery(xAddress, where, what) - self.ids.identi_tag.children[0].text = '' - if self.queryreturn: - self.ids.identi_tag.children[0].text = 'Inbox' - state.kivyapp.get_inbox_count() - src_mng_obj = state.kivyapp.root.children[2].children[0].ids - src_mng_obj.inbox_cnt.badge_text = state.inbox_count - for mail in self.queryreturn: - # third_text = mail[3].replace('\n', ' ') - data.append({ - 'text': mail[4].strip(), - 'secondary_text': mail[5][:50] + '........' if len( - mail[5]) >= 50 else (mail[5] + ',' + mail[3].replace( - '\n', ''))[0:50] + '........', - 'msgid': mail[1]}) - self.has_refreshed = True - self.set_mdList(data) - self.children[2].children[0].children[0].bind( - scroll_y=self.check_scroll_y) - else: - content = MDLabel( - font_style='Body1', theme_text_color='Primary', - text="No message found!" if state.searcing_text - else "yet no message for this account!!!!!!!!!!!!!", - halign='center', bold=True, size_hint_y=None, valign='top') - self.ids.ml.add_widget(content) - - # pylint: disable=too-many-arguments - def inboxDataQuery(self, xAddress, where, what, start_indx=0, end_indx=20): - """This method used for retrieving inbox data""" - self.queryreturn = kivy_helper_search.search_sql( - xAddress, self.account, "inbox", where, what, - False, start_indx, end_indx) - - def set_mdList(self, data): - """This method is used to create the mdList""" - total_message = len(self.ids.ml.children) - for item in data: - meny = CustomAvatarIconListItem( - text=item['text'], secondary_text=item['secondary_text'], - theme_text_color='Custom', - ) - meny.add_widget(AvatarSampleWidget( - source='./images/text_images/{}.png'.format( - avatarImageFirstLetter(item['secondary_text'].strip())))) - meny.bind(on_press=partial(self.inbox_detail, item['msgid'])) - carousel = Carousel(direction='right') - carousel.height = meny.height - carousel.size_hint_y = None - carousel.ignore_perpendicular_swipes = True - carousel.data_index = 0 - carousel.min_move = 0.2 - del_btn = Button(text='Delete') - del_btn.background_normal = '' - del_btn.background_color = (1, 0, 0, 1) - del_btn.bind(on_press=partial(self.delete, item['msgid'])) - carousel.add_widget(del_btn) - carousel.add_widget(meny) - ach_btn = Button(text='Achieve') - ach_btn.background_color = (0, 1, 0, 1) - ach_btn.bind(on_press=partial(self.archive, item['msgid'])) - carousel.add_widget(ach_btn) - carousel.index = 1 - self.ids.ml.add_widget(carousel) - update_message = len(self.ids.ml.children) - self.has_refreshed = True if total_message != update_message else False - - def check_scroll_y(self, instance, somethingelse): - """Loads data on scroll""" - if self.children[2].children[0].children[ - 0].scroll_y <= -0.0 and self.has_refreshed: - self.children[2].children[0].children[0].scroll_y = 0.06 - total_message = len(self.ids.ml.children) - self.update_inbox_screen_on_scroll(total_message) - else: - pass - - def update_inbox_screen_on_scroll(self, total_message, where="", what=""): - """This method is used to load more data on scroll down""" - data = [] - if state.searcing_text: - where = ['subject', 'message'] - what = state.searcing_text - self.inboxDataQuery('toaddress', where, what, total_message, 5) - for mail in self.queryreturn: - # third_text = mail[3].replace('\n', ' ') - data.append({ - 'text': mail[4].strip(), - 'secondary_text': mail[5][:50] + '........' if len( - mail[5]) >= 50 else (mail[5] + ',' + mail[3].replace( - '\n', ''))[0:50] + '........', - 'msgid': mail[1]}) - self.set_mdList(data) - - def inbox_detail(self, msg_id, *args): - """Load inbox page details""" - state.detailPageType = 'inbox' - state.mail_id = msg_id - if self.manager: - src_mng_obj = self.manager - else: - src_mng_obj = self.parent.parent - src_mng_obj.screens[13].clear_widgets() - src_mng_obj.screens[13].add_widget(MailDetail()) - src_mng_obj.current = 'mailDetail' - - def delete(self, data_index, instance, *args): - """Delete inbox mail from inbox listing""" - sqlExecute( - "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", str( - data_index)) - try: - msg_count_objs = ( - self.parent.parent.parent.parent.children[2].children[0].ids) - except Exception: - msg_count_objs = ( - self.parent.parent.parent.parent.parent.children[ - 2].children[0].ids) - if int(state.inbox_count) > 0: - msg_count_objs.inbox_cnt.badge_text = str( - int(state.inbox_count) - 1) - msg_count_objs.trash_cnt.badge_text = str( - int(state.trash_count) + 1) - msg_count_objs.allmail_cnt.badge_text = str( - int(state.all_count) - 1) - state.inbox_count = str( - int(state.inbox_count) - 1) - state.trash_count = str( - int(state.trash_count) + 1) - state.all_count = str( - int(state.all_count) - 1) - if int(state.inbox_count) <= 0: - self.ids.identi_tag.children[0].text = '' - self.ids.ml.remove_widget( - instance.parent.parent) - toast('Deleted') - self.update_trash() - - def archive(self, data_index, instance, *args): - """Archive inbox mail from inbox listing""" - sqlExecute( - "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", - str(data_index)) - self.ids.ml.remove_widget(instance.parent.parent) - self.update_trash() - - def update_trash(self): - """Update trash screen mails which is deleted from inbox""" - try: - self.parent.screens[4].clear_widgets() - self.parent.screens[4].add_widget(Trash()) - except Exception: - self.parent.parent.screens[4].clear_widgets() - self.parent.parent.screens[4].add_widget(Trash()) - - # pylint: disable=attribute-defined-outside-init - def refresh_callback(self, *args): - """Method updates the state of application, - While the spinner remains on the screen""" - def refresh_callback(interval): - """Method used for loading the inbox screen data""" - state.searcing_text = '' - self.children[2].children[1].ids.search_field.text = '' - self.ids.ml.clear_widgets() - self.loadMessagelist(state.association) - self.has_refreshed = True - self.ids.refresh_layout.refresh_done() - self.tick = 0 - Clock.schedule_once(refresh_callback, 1) - - # def set_root_layout(self): - # """Setting root layout""" - # return self.parent.parent.parent - - -class MyAddress(Screen): - """MyAddress screen uses screen to show widgets of screens.""" - addresses_list = ListProperty() - has_refreshed = True - is_add_created = False - - def __init__(self, *args, **kwargs): - """Clock schdule for method Myaddress accounts.""" - super(MyAddress, self).__init__(*args, **kwargs) + state.association = Navigator().ids.btn.text Clock.schedule_once(self.init_ui, 0) def init_ui(self, dt=0): - """Clock schdule for method Myaddress accounts""" - self.addresses_list = state.kivyapp.variable_1 - if state.searcing_text: - self.ids.refresh_layout.scroll_y = 1.0 - # filtered_list = filter( - # lambda addr: self.filter_address( - # addr), BMConfigParser().addresses()) - filtered_list = [ - x - for x in BMConfigParser().addresses() - if self.filter_address(x)] - self.addresses_list = filtered_list - self.addresses_list = [obj for obj in reversed(self.addresses_list)] - self.ids.identi_tag.children[0].text = '' - if self.addresses_list: - self.ids.identi_tag.children[0].text = 'My Addresses' - self.has_refreshed = True - self.set_mdList(0, 15) - self.ids.refresh_layout.bind(scroll_y=self.check_scroll_y) + """Clock Schdule for method inbox accounts.""" + self.inboxaccounts() + print(dt) + + def inboxaccounts(self): + """Load inbox accounts.""" + account = state.association + self.loadMessagelist(account, 'All', '') + + def loadMessagelist(self, account, where="", what=""): + """Load Inbox list for inbox messages.""" + xAddress = "toaddress" + queryreturn = kivy_helper_search.search_sql( + xAddress, account, 'inbox', where, what, False) + if queryreturn: + self.data = [{ + 'data_index': i, + 'index': 1, + 'height': 48, + 'text': row[4]} + for i, row in enumerate(queryreturn) + ] else: - content = MDLabel( - font_style='Body1', theme_text_color='Primary', - text="No address found!" if state.searcing_text - else "yet no address is created by user!!!!!!!!!!!!!", - halign='center', bold=True, size_hint_y=None, valign='top') - self.ids.ml.add_widget(content) - if not state.searcing_text and not self.is_add_created: - try: - self.manager.current = 'login' - except Exception: - pass - - def set_mdList(self, first_index, last_index): - """Creating the mdlist""" - data = [] - for address in self.addresses_list[first_index:last_index]: - data.append({ - 'text': BMConfigParser().get(address, 'label'), - 'secondary_text': address}) - for item in data: - meny = CustomAvatarIconListItem( - text=item['text'], secondary_text=item['secondary_text'], - theme_text_color='Custom') - meny.add_widget(AvatarSampleWidget( - source='./images/text_images/{}.png'.format( - avatarImageFirstLetter(item['text'].strip())))) - meny.bind(on_press=partial( - self.myadd_detail, item['secondary_text'], item['text'])) - self.ids.ml.add_widget(meny) - - def check_scroll_y(self, instance, somethingelse): - """Load data on scroll down""" - if self.ids.refresh_layout.scroll_y <= -0.0 and self.has_refreshed: - self.ids.refresh_layout.scroll_y = 0.06 - my_addresses = len(self.ids.ml.children) - if my_addresses != len(self.addresses_list): - self.update_addressBook_on_scroll(my_addresses) - self.has_refreshed = True if my_addresses != len( - self.addresses_list) else False - else: - pass - - def update_addressBook_on_scroll(self, my_addresses): - """Loads more data on scroll down""" - self.set_mdList(my_addresses, my_addresses + 20) - - @staticmethod - def myadd_detail(fromaddress, label, *args): - """Load myaddresses details""" - p = MyaddDetailPopup() - p.open() - p.set_address(fromaddress, label) - - # pylint: disable=attribute-defined-outside-init - def refresh_callback(self, *args): - """Method updates the state of application, - While the spinner remains on the screen""" - def refresh_callback(interval): - """Method used for loading the myaddress screen data""" - state.searcing_text = '' - state.kivyapp.root.ids.sc10.children[2].active = False - self.children[2].children[2].ids.search_field.text = '' - self.has_refreshed = True - self.ids.ml.clear_widgets() - self.init_ui() - self.ids.refresh_layout.refresh_done() - self.tick = 0 - Clock.schedule_once(refresh_callback, 1) - - @staticmethod - def filter_address(address): - """Method will filter the my address list data""" - # if filter(lambda x: (state.searcing_text).lower() in x, [ - # BMConfigParser().get( - # address, 'label').lower(), address.lower()]): - if [x for x in [BMConfigParser().get( - address, 'label').lower(), address.lower()] if ( - state.searcing_text).lower() in x]: - return True - return False - - def set_root_layout(self): - """Setting root layout""" - return self.manager.parent.parent - - -class AddressBook(Screen): - """AddressBook Screen uses screen to show widgets of screens""" - queryreturn = ListProperty() - has_refreshed = True - - def __init__(self, *args, **kwargs): - """Getting AddressBook Details""" - super(AddressBook, self).__init__(*args, **kwargs) - Clock.schedule_once(self.init_ui, 0) - - def init_ui(self, dt=0): - """Clock Schdule for method AddressBook""" - self.loadAddresslist(None, 'All', '') - print dt - - def loadAddresslist(self, account, where="", what=""): - """Clock Schdule for method AddressBook""" - if state.searcing_text: - self.ids.scroll_y.scroll_y = 1.0 - where = ['label', 'address'] - what = state.searcing_text - xAddress = '' - self.ids.identi_tag.children[0].text = '' - self.queryreturn = kivy_helper_search.search_sql( - xAddress, account, "addressbook", where, what, False) - self.queryreturn = [obj for obj in reversed(self.queryreturn)] - if self.queryreturn: - self.ids.identi_tag.children[0].text = 'Address Book' - self.has_refreshed = True - self.set_mdList(0, 20) - self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) - else: - content = MDLabel( - font_style='Body1', theme_text_color='Primary', - text="No contact found!" if state.searcing_text - else "No contact found yet...... ", - halign='center', bold=True, size_hint_y=None, valign='top') - self.ids.ml.add_widget(content) - - def set_mdList(self, start_index, end_index): - """Creating the mdList""" - for item in self.queryreturn[start_index:end_index]: - meny = CustomAvatarIconListItem( - text=item[0], secondary_text=item[1], theme_text_color='Custom') - meny.add_widget(AvatarSampleWidget( - source='./images/text_images/{}.png'.format( - avatarImageFirstLetter(item[0].strip())))) - meny.bind(on_press=partial( - self.addBook_detail, item[1], item[0])) - carousel = Carousel(direction='right') - carousel.height = meny.height - carousel.size_hint_y = None - carousel.ignore_perpendicular_swipes = True - carousel.data_index = 0 - carousel.min_move = 0.2 - del_btn = Button(text='Delete') - del_btn.background_normal = '' - del_btn.background_color = (1, 0, 0, 1) - del_btn.bind(on_press=partial(self.delete_address, item[1])) - carousel.add_widget(del_btn) - carousel.add_widget(meny) - carousel.index = 1 - self.ids.ml.add_widget(carousel) - - def check_scroll_y(self, instance, somethingelse): - """Load data on scroll""" - if self.ids.scroll_y.scroll_y <= -0.0 and self.has_refreshed: - self.ids.scroll_y.scroll_y = 0.06 - exist_addresses = len(self.ids.ml.children) - if exist_addresses != len(self.queryreturn): - self.update_addressBook_on_scroll(exist_addresses) - self.has_refreshed = True if exist_addresses != len( - self.queryreturn) else False - else: - pass - - def update_addressBook_on_scroll(self, exist_addresses): - """Load more data on scroll down""" - self.set_mdList(exist_addresses, exist_addresses + 5) - - @staticmethod - def refreshs(*args): - """Refresh the Widget""" - # state.navinstance.ids.sc11.ids.ml.clear_widgets() - # state.navinstance.ids.sc11.loadAddresslist(None, 'All', '') - pass - - @staticmethod - def addBook_detail(address, label, *args): - """Addressbook details""" - p = AddbookDetailPopup() - p.open() - p.set_addbook_data(address, label) - - def delete_address(self, address, instance, *args): - """Delete inbox mail from inbox listing""" - self.ids.ml.remove_widget(instance.parent.parent) - if len(self.ids.ml.children) == 0: - self.ids.identi_tag.children[0].text = '' - sqlExecute( - "DELETE FROM addressbook WHERE address = '{}';".format(address)) - - -class SelectableRecycleBoxLayout( - FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout): - """Adds selection and focus behaviour to the view""" - # pylint: disable = too-many-ancestors, duplicate-bases - pass - - -class SelectableLabel(RecycleDataViewBehavior, Label): - """Add selection support to the Label""" - index = None - selected = BooleanProperty(False) - selectable = BooleanProperty(True) - - def refresh_view_attrs(self, rv, index, data): - """Catch and handle the view changes""" - self.index = index - return super(SelectableLabel, self).refresh_view_attrs( - rv, index, data) - - # pylint: disable=inconsistent-return-statements - def on_touch_down(self, touch): - """Add selection on touch down""" - if super(SelectableLabel, self).on_touch_down(touch): - return True - if self.collide_point(*touch.pos) and self.selectable: - return self.parent.select_with_touch(self.index, touch) - - def apply_selection(self, rv, index, is_selected): - """Respond to the selection of items in the view""" - self.selected = is_selected - if is_selected: - print "selection changed to {0}".format(rv.data[index]) - rv.parent.txt_input.text = rv.parent.txt_input.text.replace( - rv.parent.txt_input.text, rv.data[index]['text']) - - -class RV(RecycleView): - """Recycling View""" - - def __init__(self, **kwargs): # pylint: disable=useless-super-delegation - """Recycling Method""" - super(RV, self).__init__(**kwargs) - - -class DropDownWidget(BoxLayout): - """Adding Dropdown Widget""" - # pylint: disable=too-many-statements, too-many-locals - # pylint: disable=inconsistent-return-statements - txt_input = ObjectProperty() - rv = ObjectProperty() - - def send(self, navApp): - """Send message from one address to another""" - fromAddress = str(self.ids.ti.text) - toAddress = str(self.ids.txt_input.text) - subject = self.ids.subject.text.encode('utf-8').strip() - message = self.ids.body.text.encode('utf-8').strip() - encoding = 3 - print "message: ", self.ids.body.text - sendMessageToPeople = True - if sendMessageToPeople: - if toAddress != '' and subject and message: - status, addressVersionNumber, streamNumber, ripe = ( - decodeAddress(toAddress)) - valid_from_add = True if fromAddress in state.kivyapp.variable_1 else False - if status == 'success' and valid_from_add: - navApp.root.ids.sc3.children[0].active = True - if state.detailPageType == 'draft' \ - and state.send_draft_mail: - sqlExecute( - "UPDATE sent SET toaddress = ?, fromaddress = ? ," - " subject = ?, message = ?, folder = 'sent' WHERE" - " ackdata = ?;", toAddress, fromAddress, subject, - message, str(state.send_draft_mail)) - self.parent.parent.screens[15].clear_widgets() - self.parent.parent.screens[15].add_widget(Draft()) - else: - toAddress = addBMIfNotPresent(toAddress) - statusIconColor = 'red' - if (addressVersionNumber > 4) or ( - addressVersionNumber <= 1): - print "addressVersionNumber > 4"\ - " or addressVersionNumber <= 1" - if streamNumber > 1 or streamNumber == 0: - print "streamNumber > 1 or streamNumber == 0" - if statusIconColor == 'red': - print "shared.statusIconColor == 'red'" - stealthLevel = BMConfigParser().safeGetInt( - 'bitmessagesettings', 'ackstealthlevel') - from helper_ackPayload import genAckPayload - ackdata = genAckPayload(streamNumber, stealthLevel) - t = ( - '', - toAddress, - ripe, - fromAddress, - subject, - message, - ackdata, - int(time.time()), - int(time.time()), - 0, - 'msgqueued', - 0, - 'sent', - encoding, - BMConfigParser().getint('bitmessagesettings', 'ttl') - ) - helper_sent.insert(t) - state.check_sent_acc = fromAddress - state.msg_counter_objs = self.parent.parent.parent.parent\ - .parent.parent.children[2].children[0].ids - if state.detailPageType == 'draft' and state.send_draft_mail: - state.draft_count = str(int(state.draft_count) - 1) - state.msg_counter_objs.draft_cnt.badge_text = state.draft_count - state.detailPageType = '' - state.send_draft_mail = None - # self.parent.parent.screens[0].ids.ml.clear_widgets() - # self.parent.parent.screens[0].loadMessagelist(state.association) - self.parent.parent.screens[3].update_sent_messagelist() - # self.parent.parent.screens[16].clear_widgets() - # self.parent.parent.screens[16].add_widget(Allmails()) - Clock.schedule_once(self.callback_for_msgsend, 3) - queues.workerQueue.put(('sendmessage', toAddress)) - print "sqlExecute successfully #######################" - state.in_composer = True - return - elif valid_from_add is False: - msg = 'Please enter valid sender address' - else: - msg = 'Enter a valid recipients address' - elif not toAddress: - msg = 'Please fill the form' - else: - msg = 'Please fill the form' - self.address_error_message(msg) - - @staticmethod - def callback_for_msgsend(dt=0): - """Callback method for messagesend""" - state.kivyapp.root.ids.sc3.children[0].active = False - state.in_sent_method = True - state.kivyapp.back_press() - toast('sent') - - # pylint: disable=attribute-defined-outside-init - def address_error_message(self, msg): - """Generates error message""" - width = .8 if platform == 'android' else .55 - msg_dialog = MDDialog( - text=msg, - title='', size_hint=(width, .25), text_button_ok='Ok', - events_callback=self.callback_for_menu_items) - msg_dialog.open() - - @staticmethod - def callback_for_menu_items(text_item): - """Callback of alert box""" - toast(text_item) - - def reset_composer(self): - """Method will reset composer""" - self.ids.ti.text = '' - self.ids.btn.text = 'Select' - self.ids.txt_input.text = '' - self.ids.subject.text = '' - self.ids.body.text = '' - toast("Reset message") - - def auto_fill_fromaddr(self): - """Fill the text automatically From Address""" - self.ids.ti.text = self.ids.btn.text - self.ids.ti.focus = True - - -class MyTextInput(TextInput): - """Takes the text input in the field""" - txt_input = ObjectProperty() - flt_list = ObjectProperty() - word_list = ListProperty() - starting_no = NumericProperty(3) - suggestion_text = '' - - def __init__(self, **kwargs): # pylint: disable=useless-super-delegation - """Getting Text Input""" - super(MyTextInput, self).__init__(**kwargs) - - def on_text(self, instance, value): - """Find all the occurrence of the word""" - self.parent.parent.parent.parent.ids.rv.data = [] - matches = [self.word_list[i] for i in range( - len(self.word_list)) if self.word_list[ - i][:self.starting_no] == value[:self.starting_no]] - display_data = [] - for i in matches: - display_data.append({'text': i}) - self.parent.parent.parent.parent.ids.rv.data = display_data - if len(matches) <= 10: - self.parent.height = (250 + (len(matches) * 20)) - else: - self.parent.height = 400 - - def keyboard_on_key_down(self, window, keycode, text, modifiers): - """Keyboard on key Down""" - if self.suggestion_text and keycode[1] == 'tab': - self.insert_text(self.suggestion_text + ' ') - return True - return super(MyTextInput, self).keyboard_on_key_down( - window, keycode, text, modifiers) - - -class Payment(Screen): - """Payment module""" - - def get_available_credits(self, instance): # pylint: disable=no-self-use - """Get the available credits""" - state.availabe_credit = instance.parent.children[1].text - existing_credits = ( - state.kivyapp.root.ids.sc18.ids.ml.children[0].children[ - 0].children[0].children[0].text) - if len(existing_credits.split(' ')) > 1: - toast( - 'We already have added free coins' - ' for the subscription to your account!') - else: - toast('Coins added to your account!') - state.kivyapp.root.ids.sc18.ids.ml.children[0].children[ - 0].children[0].children[0].text = '{0}'.format( - state.availabe_credit) - - -class Credits(Screen): - """Module for screen screen""" - available_credits = StringProperty('{0}'.format('0')) - - -class Login(Screen): - """Login Screeen""" - pass - - -class NetworkStat(Screen): - """Method used to show network stat""" - text_variable_1 = StringProperty( - '{0}::{1}'.format('Total Connections', '0')) - text_variable_2 = StringProperty( - 'Processed {0} per-to-per messages'.format('0')) - text_variable_3 = StringProperty( - 'Processed {0} brodcast messages'.format('0')) - text_variable_4 = StringProperty( - 'Processed {0} public keys'.format('0')) - text_variable_5 = StringProperty( - 'Processed {0} object to be synced'.format('0')) - - def __init__(self, *args, **kwargs): - """Init method for network stat""" - super(NetworkStat, self).__init__(*args, **kwargs) - Clock.schedule_interval(self.init_ui, 1) - - def init_ui(self, dt=0): - """Clock Schdule for method networkstat screen""" - import network.stats - import shared - from network import objectracker - self.text_variable_1 = '{0} :: {1}'.format( - 'Total Connections', str(len(network.stats.connectedHostsList()))) - self.text_variable_2 = 'Processed {0} per-to-per messages'.format( - str(shared.numberOfMessagesProcessed)) - self.text_variable_3 = 'Processed {0} brodcast messages'.format( - str(shared.numberOfBroadcastsProcessed)) - self.text_variable_4 = 'Processed {0} public keys'.format( - str(shared.numberOfPubkeysProcessed)) - self.text_variable_5 = '{0} object to be synced'.format( - len(objectracker.missingObjects)) - - -class ContentNavigationDrawer(Navigatorss): - """Navigate Content Drawer""" - pass - - -class Random(Screen): - """Generates Random Address""" - is_active = BooleanProperty(False) - checked = StringProperty("") - - def generateaddress(self, navApp): - """Method for Address Generator""" - entered_label = str(self.ids.label.text).strip() - streamNumberForAddress = 1 - label = self.ids.label.text - eighteenByteRipe = False - nonceTrialsPerByte = 1000 - payloadLengthExtraBytes = 1000 - lables = [BMConfigParser().get(obj, 'label') - for obj in BMConfigParser().addresses()] - if entered_label and entered_label not in lables: - toast('Address Creating...') - queues.addressGeneratorQueue.put(( - 'createRandomAddress', 4, streamNumberForAddress, label, 1, - "", eighteenByteRipe, nonceTrialsPerByte, - payloadLengthExtraBytes)) - self.ids.label.text = '' - self.parent.parent.children[1].opacity = 1 - self.parent.parent.children[1].disabled = False - state.kivyapp.root.ids.sc10.children[1].active = True - self.manager.current = 'myaddress' - Clock.schedule_once(self.address_created_callback, 6) - - def address_created_callback(self, dt=0): - """New address created""" - state.kivyapp.root.ids.sc10.children[1].active = False - state.kivyapp.root.ids.sc10.ids.ml.clear_widgets() - state.kivyapp.root.ids.sc10.is_add_created = True - state.kivyapp.root.ids.sc10.init_ui() - self.reset_address_spinner() - toast('New address created') - - def reset_address_spinner(self): - """reseting spinner address and UI""" - addresses = BMConfigParser().addresses() - self.manager.parent.parent.parent.parent.ids.nav_drawer.ids.btn.values = [] - self.manager.parent.parent.parent.parent.ids.sc3.children[1].ids.btn.values = [] - self.manager.parent.parent.parent.parent.ids.nav_drawer.ids.btn.values = addresses - self.manager.parent.parent.parent.parent.ids.sc3.children[1].ids.btn.values = addresses - - def add_validation(self, instance): - """Checking validation at address creation time""" - entered_label = str(instance.text.strip()) - lables = [BMConfigParser().get(obj, 'label') - for obj in BMConfigParser().addresses()] - if entered_label in lables: - self.ids.label.error = True - self.ids.label.helper_text = 'Label name is already exist you'\ - ' can try this Ex. ( {0}_1, {0}_2 )'.format( - entered_label) - elif entered_label: - self.ids.label.error = False - else: - self.ids.label.error = False - self.ids.label.helper_text = 'This field is required' - - def reset_address_label(self): - """Resetting address labels""" - self.ids.label.text = '' - - -class Sent(Screen): - """Sent Screen uses screen to show widgets of screens""" - queryreturn = ListProperty() - has_refreshed = True - account = StringProperty() - - def __init__(self, *args, **kwargs): - """Association with the screen.""" - super(Sent, self).__init__(*args, **kwargs) - if state.association == '': - if BMConfigParser().addresses(): - state.association = BMConfigParser().addresses()[0] - Clock.schedule_once(self.init_ui, 0) - - def init_ui(self, dt=0): - """Clock Schdule for method sent accounts""" - self.loadSent() - print dt - - def loadSent(self, where="", what=""): - """Load Sent list for Sent messages.""" - self.account = state.association - if state.searcing_text: - self.ids.scroll_y.scroll_y = 1.0 - where = ['subject', 'message'] - what = state.searcing_text - xAddress = 'fromaddress' - data = [] - self.ids.identi_tag.children[0].text = '' - self.sentDataQuery(xAddress, where, what) - if self.queryreturn: - self.ids.identi_tag.children[0].text = 'Sent' - self.set_sentCount(state.sent_count) - for mail in self.queryreturn: - data.append({ - 'text': mail[1].strip(), - 'secondary_text': mail[2][:50] + '........' if len( - mail[2]) >= 50 else (mail[2] + ',' + mail[3].replace( - '\n', ''))[0:50] + '........', - 'ackdata': mail[5]}) - self.set_mdlist(data, 0) - self.has_refreshed = True - self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) - else: - content = MDLabel( - font_style='Body1', theme_text_color='Primary', - text="No message found!" if state.searcing_text - else "yet no message for this account!!!!!!!!!!!!!", - halign='center', bold=True, size_hint_y=None, valign='top') - self.ids.ml.add_widget(content) - - # pylint: disable=too-many-arguments - def sentDataQuery(self, xAddress, where, what, start_indx=0, end_indx=20): - """This method is used to retrieving data from sent table""" - self.queryreturn = kivy_helper_search.search_sql( - xAddress, self.account, "sent", where, what, - False, start_indx, end_indx) - - def set_mdlist(self, data, set_index=0): - """This method is used to create the mdList""" - total_sent_msg = len(self.ids.ml.children) - for item in data: - meny = CustomAvatarIconListItem( - text=item['text'], secondary_text=item['secondary_text'], - theme_text_color='Custom') - meny.add_widget(AvatarSampleWidget( - source='./images/text_images/{}.png'.format( - avatarImageFirstLetter(item['secondary_text'].strip())))) - meny.bind(on_press=partial(self.sent_detail, item['ackdata'])) - carousel = Carousel(direction='right') - carousel.height = meny.height - carousel.size_hint_y = None - carousel.ignore_perpendicular_swipes = True - carousel.data_index = 0 - carousel.min_move = 0.2 - del_btn = Button(text='Delete') - del_btn.background_normal = '' - del_btn.background_color = (1, 0, 0, 1) - del_btn.bind(on_press=partial(self.delete, item['ackdata'])) - carousel.add_widget(del_btn) - carousel.add_widget(meny) - ach_btn = Button(text='Achieve') - ach_btn.background_color = (0, 1, 0, 1) - ach_btn.bind(on_press=partial(self.archive, item['ackdata'])) - carousel.add_widget(ach_btn) - carousel.index = 1 - self.ids.ml.add_widget(carousel, index=set_index) - updated_msgs = len(self.ids.ml.children) - self.has_refreshed = True if total_sent_msg != updated_msgs else False - - def update_sent_messagelist(self): - """This method is used to update screen when new mail is sent""" - self.account = state.association - if len(self.ids.ml.children) < 3: - self.ids.ml.clear_widgets() - self.loadSent() - total_sent = int(state.sent_count) + 1 - self.set_sentCount(total_sent) - else: - data = [] - self.sentDataQuery('fromaddress', '', '', 0, 1) - total_sent = int(state.sent_count) + 1 - self.set_sentCount(total_sent) - for mail in self.queryreturn: - data.append({ - 'text': mail[1].strip(), - 'secondary_text': mail[2][:50] + '........' if len( - mail[2]) >= 50 else (mail[2] + ',' + mail[3].replace( - '\n', ''))[0:50] + '........', - 'ackdata': mail[5]}) - self.set_mdlist(data, total_sent - 1) - if state.msg_counter_objs and state.association == ( - state.check_sent_acc): - state.all_count = str(int(state.all_count) + 1) - state.msg_counter_objs.allmail_cnt.badge_text = state.all_count - state.check_sent_acc = None - - def check_scroll_y(self, instance, somethingelse): - """Load data on scroll down""" - if self.ids.scroll_y.scroll_y <= -0.0 and self.has_refreshed: - self.ids.scroll_y.scroll_y = 0.06 - total_sent_msg = len(self.ids.ml.children) - self.update_sent_screen_on_scroll(total_sent_msg) - else: - pass - - def update_sent_screen_on_scroll(self, total_sent_msg, where="", what=""): - """This method is used to load more data on scroll down""" - if state.searcing_text: - where = ['subject', 'message'] - what = state.searcing_text - self.sentDataQuery('fromaddress', where, what, total_sent_msg, 5) - data = [] - for mail in self.queryreturn: - data.append({ - 'text': mail[1].strip(), - 'secondary_text': mail[2][:50] + '........' if len( - mail[2]) >= 50 else (mail[2] + ',' + mail[3].replace( - '\n', ''))[0:50] + '........', - 'ackdata': mail[5]}) - self.set_mdlist(data, 0) - - @staticmethod - def set_sentCount(total_sent): - """Set the total no. of sent message count""" - src_mng_obj = state.kivyapp.root.children[2].children[0].ids - src_mng_obj.send_cnt.badge_text = str(total_sent) - state.sent_count = str(total_sent) - - def sent_detail(self, ackdata, *args): - """Load sent mail details""" - state.detailPageType = 'sent' - state.mail_id = ackdata - if self.manager: - src_mng_obj = self.manager - else: - src_mng_obj = self.parent.parent - src_mng_obj.screens[13].clear_widgets() - src_mng_obj.screens[13].add_widget(MailDetail()) - src_mng_obj.current = 'mailDetail' - - def delete(self, data_index, instance, *args): - """Delete sent mail from sent mail listing""" - try: - msg_count_objs = self.parent.parent.parent.parent.children[ - 2].children[0].ids - except Exception: - msg_count_objs = self.parent.parent.parent.parent.parent.children[ - 2].children[0].ids - if int(state.sent_count) > 0: - msg_count_objs.send_cnt.badge_text = str( - int(state.sent_count) - 1) - msg_count_objs.trash_cnt.badge_text = str( - int(state.trash_count) + 1) - msg_count_objs.allmail_cnt.badge_text = str( - int(state.all_count) - 1) - state.sent_count = str(int(state.sent_count) - 1) - state.trash_count = str(int(state.trash_count) + 1) - state.all_count = str(int(state.all_count) - 1) - if int(state.sent_count) <= 0: - self.ids.identi_tag.children[0].text = '' - sqlExecute( - "UPDATE sent SET folder = 'trash'" - " WHERE ackdata = ?;", str(data_index)) - self.ids.ml.remove_widget(instance.parent.parent) - toast('Deleted') - self.update_trash() - - def archive(self, data_index, instance, *args): - """Archive sent mail from sent mail listing""" - sqlExecute( - "UPDATE sent SET folder = 'trash' WHERE ackdata = ?;", - str(data_index)) - self.ids.ml.remove_widget(instance.parent.parent) - self.update_trash() - - def update_trash(self): - """Update trash screen mails which is deleted from inbox""" - try: - self.parent.screens[4].clear_widgets() - self.parent.screens[4].add_widget(Trash()) - self.parent.screens[16].clear_widgets() - self.parent.screens[16].add_widget(Allmails()) - except Exception: - self.parent.parent.screens[4].clear_widgets() - self.parent.parent.screens[4].add_widget(Trash()) - self.parent.parent.screens[16].clear_widgets() - self.parent.parent.screens[16].add_widget(Allmails()) - - -class Trash(Screen): - """Trash Screen uses screen to show widgets of screens""" - trash_messages = ListProperty() - has_refreshed = True - delete_index = StringProperty() - table_name = StringProperty() - - def __init__(self, *args, **kwargs): - """Trash method, delete sent message and add in Trash""" - super(Trash, self).__init__(*args, **kwargs) - Clock.schedule_once(self.init_ui, 0) - - def init_ui(self, dt=0): - """Clock Schdule for method trash screen.""" - if state.association == '': - if BMConfigParser().addresses(): - state.association = BMConfigParser().addresses()[0] - self.ids.identi_tag.children[0].text = '' - self.trashDataQuery(0, 20) - if self.trash_messages: - self.ids.identi_tag.children[0].text = 'Trash' - src_mng_obj = state.kivyapp.root.children[2].children[0].ids - src_mng_obj.trash_cnt.badge_text = state.trash_count - self.set_mdList() - self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) - else: - content = MDLabel( - font_style='Body1', theme_text_color='Primary', - text="yet no trashed message for this account!!!!!!!!!!!!!", - halign='center', bold=True, size_hint_y=None, valign='top') - self.ids.ml.add_widget(content) - - def trashDataQuery(self, start_indx, end_indx): - """Trash message query""" - self.trash_messages = sqlQuery( - "SELECT toaddress, fromaddress, subject, message," - " folder ||',' || 'sent' as folder, ackdata As" - " id, DATE(lastactiontime) As actionTime FROM sent" - " WHERE folder = 'trash' and fromaddress = '{0}' UNION" - " SELECT toaddress, fromaddress, subject, message," - " folder ||',' || 'inbox' as folder, msgid As id," - " DATE(received) As actionTime FROM inbox" - " WHERE folder = 'trash' and toaddress = '{0}'" - " ORDER BY actionTime DESC limit {1}, {2}".format( - state.association, start_indx, end_indx)) - - def set_mdList(self): - """This method is used to create the mdlist""" - total_trash_msg = len(self.ids.ml.children) - for item in self.trash_messages: - meny = CustomAvatarIconListItem( - text=item[1], - secondary_text=item[2][:50] + '........' if len( - item[2]) >= 50 else (item[2] + ',' + item[3].replace( - '\n', ''))[0:50] + '........', - theme_text_color='Custom') - img_latter = './images/text_images/{}.png'.format( - item[2][0].upper() if (item[2][0].upper() >= 'A' and item[ - 2][0].upper() <= 'Z') else '!') - meny.add_widget(AvatarSampleWidget(source=img_latter)) - carousel = Carousel(direction='right') - carousel.height = meny.height - carousel.size_hint_y = None - carousel.ignore_perpendicular_swipes = True - carousel.data_index = 0 - carousel.min_move = 0.2 - del_btn = Button(text='Delete') - del_btn.background_normal = '' - del_btn.background_color = (1, 0, 0, 1) - del_btn.bind(on_press=partial( - self.delete_permanently, item[5], item[4])) - carousel.add_widget(del_btn) - carousel.add_widget(meny) - carousel.index = 1 - self.ids.ml.add_widget(carousel) - self.has_refreshed = True if total_trash_msg != len( - self.ids.ml.children) else False - - def check_scroll_y(self, instance, somethingelse): - """Load data on scroll""" - if self.ids.scroll_y.scroll_y <= -0.0 and self.has_refreshed: - self.ids.scroll_y.scroll_y = 0.06 - total_trash_msg = len(self.ids.ml.children) - self.update_trash_screen_on_scroll(total_trash_msg) - else: - pass - - def update_trash_screen_on_scroll(self, total_trash_msg): - """Load more data on scroll down""" - self.trashDataQuery(total_trash_msg, 5) - self.set_mdList() - - def delete_permanently(self, data_index, folder, instance, *args): - """Deleting trash mail permanently""" - self.table_name = folder.split(',')[1] - self.delete_index = data_index - self.delete_confirmation() - - def callback_for_screen_load(self, dt=0): - """This methos is for loading screen""" - self.ids.ml.clear_widgets() - self.init_ui(0) - self.children[1].active = False - toast('Message is permanently deleted') - - def delete_confirmation(self): - """Show confirmation delete popup""" - width = .8 if platform == 'android' else .55 - delete_msg_dialog = MDDialog( - text='Are you sure you want to delete this' - ' message permanently from trash?', title='', - size_hint=(width, .25), text_button_ok='Yes', - text_button_cancel='No', - events_callback=self.callback_for_delete_msg) - delete_msg_dialog.open() - - def callback_for_delete_msg(self, text_item): - """Getting the callback of alert box""" - if text_item == 'Yes': - self.delete_message_from_trash() - else: - toast(text_item) - - def delete_message_from_trash(self): - """Deleting message from trash""" - self.children[1].active = True - if self.table_name == 'inbox': - sqlExecute( - "DELETE FROM inbox WHERE msgid = ?;", - str(self.delete_index)) - elif self.table_name == 'sent': - sqlExecute( - "DELETE FROM sent WHERE ackdata = ?;", - str(self.delete_index)) - msg_count_objs = state.kivyapp.root.children[2].children[0].ids - if int(state.trash_count) > 0: - msg_count_objs.trash_cnt.badge_text = str( - int(state.trash_count) - 1) - state.trash_count = str(int(state.trash_count) - 1) - Clock.schedule_once(self.callback_for_screen_load, 1) + self.data = [{ + 'data_index': 1, + 'index': 1, + 'height': 48, + 'text': "yet no message for this account!!!!!!!!!!!!!"} + ] class Page(Screen): - """Page Screen show widgets of page""" + pass + + +class AddressSuccessful(Screen): + pass + + +class Sent(Screen): + """Sent Screen uses screen to show widgets of screens.""" + + data = ListProperty() + + def __init__(self, *args, **kwargs): + super(Sent, self).__init__(*args, **kwargs) + if state.association == '': + state.association = Navigator().ids.btn.text + Clock.schedule_once(self.init_ui, 0) + + def init_ui(self, dt=0): + """Clock Schdule for method sent accounts.""" + self.sentaccounts() + print(dt) + + def sentaccounts(self): + """Load sent accounts.""" + account = state.association + self.loadSent(account, 'All', '') + + def loadSent(self, account, where="", what=""): + """Load Sent list for Sent messages.""" + xAddress = 'fromaddress' + queryreturn = kivy_helper_search.search_sql( + xAddress, account, "sent", where, what, False) + if queryreturn: + self.data = [{ + 'data_index': i, + 'index': 1, + 'height': 48, + 'text': row[2]} + for i, row in enumerate(queryreturn) + ] + else: + self.data = [{ + 'data_index': 1, + 'index': 1, + 'height': 48, + 'text': "yet no message for this account!!!!!!!!!!!!!"} + ] + + +class Trash(Screen): + """Trash Screen uses screen to show widgets of screens.""" + + data = ListProperty() + + def __init__(self, *args, **kwargs): + super(Trash, self).__init__(*args, **kwargs) + if state.association == '': + state.association = Navigator().ids.btn.text + Clock.schedule_once(self.init_ui, 0) + + def init_ui(self, dt=0): + """Clock Schdule for method inbox accounts.""" + self.inboxaccounts() + print(dt) + + def inboxaccounts(self): + """Load inbox accounts.""" + account = state.association + self.loadTrashlist(account, 'All', '') + + def loadTrashlist(self, account, where="", what=""): + """Load Trash list for trashed messages.""" + xAddress = "toaddress" + queryreturn = kivy_helper_search.search_sql( + xAddress, account, 'trash', where, what, False) + if queryreturn: + self.data = [{ + 'data_index': i, + 'index': 1, + 'height': 48, + 'text': row[4]} + for i, row in enumerate(queryreturn) + ] + else: + self.data = [{ + 'data_index': 1, + 'index': 1, + 'height': 48, + 'text': "yet no message for this account!!!!!!!!!!!!!"} + ] + + +class Dialog(Screen): + """Dialog Screen uses screen to show widgets of screens.""" + + pass + + +class Test(Screen): + """Test Screen uses screen to show widgets of screens.""" + pass class Create(Screen): - """Creates the screen widgets""" - - def __init__(self, **kwargs): - """Getting Labels and address from addressbook""" - super(Create, self).__init__(**kwargs) - widget_1 = DropDownWidget() - widget_1.ids.txt_input.word_list = [ - addr[1] for addr in sqlQuery( - "SELECT label, address from addressbook")] - widget_1.ids.txt_input.starting_no = 2 - self.add_widget(widget_1) - - -class Setting(Screen): - """Setting the Screen components""" - pass - - -class NavigateApp(App): # pylint: disable=too-many-public-methods - """Navigation Layout of class""" - theme_cls = ThemeManager() - previous_date = ObjectProperty() - obj_1 = ObjectProperty() - variable_1 = ListProperty(BMConfigParser().addresses()) - nav_drawer = ObjectProperty() - state.screen_density = Window.size - window_size = state.screen_density - app_platform = platform - title = "PyBitmessage" - imgstatus = False - count = 0 - - def build(self): - """Method builds the widget""" - main_widget = Builder.load_file( - os.path.join(os.path.dirname(__file__), 'main.kv')) - self.nav_drawer = Navigatorss() - self.obj_1 = AddressBook() - kivysignalthread = UIkivySignaler() - kivysignalthread.daemon = True - kivysignalthread.start() - Window.bind(on_keyboard=self.on_key) - return main_widget - - def run(self): - """Running the widgets""" - kivyuisignaler.release() - super(NavigateApp, self).run() - - # pylint: disable=inconsistent-return-statements - @staticmethod - def showmeaddresses(name="text"): - """Show the addresses in spinner to make as dropdown""" - if name == "text": - if BMConfigParser().addresses(): - return BMConfigParser().addresses()[0][:16] + '..' - return "textdemo" - elif name == "values": - if BMConfigParser().addresses(): - return [address[:16] + '..' - for address in BMConfigParser().addresses()] - return "valuesdemo" - - def getCurrentAccountData(self, text): - """Get Current Address Account Data""" - self.set_identicon(text) - address_label = self.current_address_label( - BMConfigParser().get(text, 'label'), text) - self.root_window.children[1].ids.toolbar.title = address_label - state.association = text - state.searcing_text = '' - LoadingPopup().open() - self.set_message_count() - Clock.schedule_once(self.setCurrentAccountData, 0.5) - - def setCurrentAccountData(self, dt=0): - """This method set the current accout data on all the screens.""" - self.root.ids.sc1.ids.ml.clear_widgets() - self.root.ids.sc1.loadMessagelist(state.association) - - self.root.ids.sc4.ids.ml.clear_widgets() - self.root.ids.sc4.children[2].children[2].ids.search_field.text = '' - self.root.ids.sc4.loadSent(state.association) - - self.root.ids.sc16.clear_widgets() - self.root.ids.sc16.add_widget(Draft()) - - self.root.ids.sc5.clear_widgets() - self.root.ids.sc5.add_widget(Trash()) - - self.root.ids.sc17.clear_widgets() - self.root.ids.sc17.add_widget(Allmails()) - - self.root.ids.scr_mngr.current = 'inbox' - - @staticmethod - def getCurrentAccount(): - """It uses to get current account label""" - if state.association: - return state.association - return "Bitmessage Login" - - @staticmethod - def addingtoaddressbook(): - """Adding to address Book""" - p = GrashofPopup() - p.open() - - def getDefaultAccData(self): - """Getting Default Account Data""" - if BMConfigParser().addresses(): - img = identiconGeneration.generate(BMConfigParser().addresses()[0]) - self.createFolder('./images/default_identicon/') - if platform == 'android': - # android_path = os.path.expanduser - # ("~/user/0/org.test.bitapp/files/app/") - android_path = os.path.join( - os.environ['ANDROID_PRIVATE'] + '/app/') - img.texture.save('{1}/images/default_identicon/{0}.png'.format( - BMConfigParser().addresses()[0], android_path)) - else: - img.texture.save('./images/default_identicon/{}.png'.format( - BMConfigParser().addresses()[0])) - return BMConfigParser().addresses()[0] - return 'Select Address' - - @staticmethod - def createFolder(directory): - """Create directory when app starts""" - try: - if not os.path.exists(directory): - os.makedirs(directory) - except OSError: - print 'Error: Creating directory. ' + directory - - @staticmethod - def get_default_image(): - """Getting default image on address""" - if BMConfigParser().addresses(): - return './images/default_identicon/{}.png'.format( - BMConfigParser().addresses()[0]) - return './images/no_identicons.png' - - @staticmethod - def addressexist(): - """Checking address existence""" - if BMConfigParser().addresses(): - return True - return False - - def on_key(self, window, key, *args): - """Method is used for going on previous screen""" - if key == 27: - if state.in_search_mode and self.root.ids.scr_mngr.current not in [ - "mailDetail", "create"]: - self.closeSearchScreen() - elif self.root.ids.scr_mngr.current == "mailDetail": - self.root.ids.scr_mngr.current = 'sent'\ - if state.detailPageType == 'sent' else 'inbox' \ - if state.detailPageType == 'inbox' else 'draft' - self.back_press() - if state.in_search_mode and state.searcing_text: - toolbar_obj = self.root.ids.toolbar - toolbar_obj.left_action_items = [ - ['arrow-left', lambda x: self.closeSearchScreen()]] - toolbar_obj.right_action_items = [] - self.root.ids.toolbar.title = '' - elif self.root.ids.scr_mngr.current == "create": - self.save_draft() - self.set_common_header() - state.in_composer = False - self.root.ids.scr_mngr.current = 'inbox' - elif self.root.ids.scr_mngr.current == "showqrcode": - self.root.ids.scr_mngr.current = 'myaddress' - elif self.root.ids.scr_mngr.current == "random": - self.root.ids.scr_mngr.current = 'login' - else: - if state.kivyapp.variable_1: - self.root.ids.scr_mngr.current = 'inbox' - self.root.ids.scr_mngr.transition.direction = 'right' - self.root.ids.scr_mngr.transition.bind(on_complete=self.reset) - return True - elif key == 13 and state.searcing_text and not state.in_composer: - if state.search_screen == 'inbox': - self.root.ids.sc1.children[1].active = True - Clock.schedule_once(self.search_callback, 0.5) - elif state.search_screen == 'addressbook': - self.root.ids.sc11.children[1].active = True - Clock.schedule_once(self.search_callback, 0.5) - elif state.search_screen == 'myaddress': - self.root.ids.sc10.children[1].active = True - Clock.schedule_once(self.search_callback, 0.5) - elif state.search_screen == 'sent': - self.root.ids.sc4.children[1].active = True - Clock.schedule_once(self.search_callback, 0.5) - - def search_callback(self, dt=0): - """Show data after loader is loaded""" - if state.search_screen == 'inbox': - self.root.ids.sc1.ids.ml.clear_widgets() - self.root.ids.sc1.loadMessagelist(state.association) - self.root.ids.sc1.children[1].active = False - elif state.search_screen == 'addressbook': - self.root.ids.sc11.ids.ml.clear_widgets() - self.root.ids.sc11.loadAddresslist(None, 'All', '') - self.root.ids.sc11.children[1].active = False - elif state.search_screen == 'myaddress': - self.root.ids.sc10.ids.ml.clear_widgets() - self.root.ids.sc10.init_ui() - self.root.ids.sc10.children[1].active = False - else: - self.root.ids.sc4.ids.ml.clear_widgets() - self.root.ids.sc4.loadSent(state.association) - self.root.ids.sc4.children[1].active = False - self.root.ids.scr_mngr.current = state.search_screen - - def save_draft(self): - """Saving drafts messages""" - composer_objs = self.root - from_addr = str(self.root.ids.sc3.children[1].ids.ti.text) - to_addr = str(self.root.ids.sc3.children[1].ids.txt_input.text) - if from_addr and to_addr and state.detailPageType != 'draft' \ - and not state.in_sent_method: - Draft().draft_msg(composer_objs) - return - - def reset(self, *args): - """Set transition direction""" - self.root.ids.scr_mngr.transition.direction = 'left' - self.root.ids.scr_mngr.transition.unbind(on_complete=self.reset) - - @staticmethod - def status_dispatching(data): - """Dispatching Status acknowledgment""" - ackData, message = data - if state.ackdata == ackData: - state.status.status = message - - def clear_composer(self): - """If slow down, the new composer edit screen""" - self.set_navbar_for_composer() - composer_obj = self.root.ids.sc3.children[1].ids - composer_obj.ti.text = '' - composer_obj.btn.text = 'Select' - composer_obj.txt_input.text = '' - composer_obj.subject.text = '' - composer_obj.body.text = '' - state.in_composer = True - state.in_sent_method = False - - def set_navbar_for_composer(self): - """Clearing toolbar data when composer open""" - self.root.ids.toolbar.left_action_items = [ - ['arrow-left', lambda x: self.back_press()]] - self.root.ids.toolbar.right_action_items = [ - ['refresh', - lambda x: self.root.ids.sc3.children[1].reset_composer()], - ['send', - lambda x: self.root.ids.sc3.children[1].send(self)]] - - def set_common_header(self): - """Common header for all window""" - self.root.ids.toolbar.right_action_items = [ - ['account-plus', lambda x: self.addingtoaddressbook()]] - self.root.ids.toolbar.left_action_items = [ - ['menu', lambda x: self.root.toggle_nav_drawer()]] - return - - def back_press(self): - """Method for, reverting composer to previous page""" - self.save_draft() - if self.root.ids.scr_mngr.current == \ - 'mailDetail' and state.in_search_mode: - toolbar_obj = self.root.ids.toolbar - toolbar_obj.left_action_items = [ - ['arrow-left', lambda x: self.closeSearchScreen()]] - toolbar_obj.right_action_items = [] - self.root.ids.toolbar.title = '' - else: - self.set_common_header() - self.root.ids.scr_mngr.current = 'inbox' \ - if state.in_composer else 'allmails'\ - if state.is_allmail else state.detailPageType\ - if state.detailPageType else 'inbox' - self.root.ids.scr_mngr.transition.direction = 'right' - self.root.ids.scr_mngr.transition.bind(on_complete=self.reset) - if state.is_allmail or state.detailPageType == 'draft': - state.is_allmail = False - state.detailPageType = '' - state.in_composer = False - - @staticmethod - def get_inbox_count(): - """Getting inbox count""" - state.inbox_count = str(sqlQuery( - "SELECT COUNT(*) FROM inbox WHERE toaddress = '{}' and" - " folder = 'inbox' ;".format(state.association))[0][0]) - - @staticmethod - def get_sent_count(): - """Getting sent count""" - state.sent_count = str(sqlQuery( - "SELECT COUNT(*) FROM sent WHERE fromaddress = '{}' and" - " folder = 'sent' ;".format(state.association))[0][0]) - - def set_message_count(self): - """Setting message count""" - try: - msg_counter_objs = ( - self.root_window.children[0].children[2].children[0].ids) - except Exception: - msg_counter_objs = ( - self.root_window.children[2].children[2].children[0].ids) - self.get_inbox_count() - self.get_sent_count() - state.trash_count = str(sqlQuery( - "SELECT (SELECT count(*) FROM sent" - " where fromaddress = '{0}' and folder = 'trash' )" - "+(SELECT count(*) FROM inbox where toaddress = '{0}' and" - " folder = 'trash') AS SumCount".format(state.association))[0][0]) - state.draft_count = str(sqlQuery( - "SELECT COUNT(*) FROM sent WHERE fromaddress = '{}' and" - " folder = 'draft' ;".format(state.association))[0][0]) - state.all_count = str(int(state.sent_count) + int(state.inbox_count)) - if msg_counter_objs: - msg_counter_objs.send_cnt.badge_text = state.sent_count - msg_counter_objs.inbox_cnt.badge_text = state.inbox_count - msg_counter_objs.trash_cnt.badge_text = state.trash_count - msg_counter_objs.draft_cnt.badge_text = state.draft_count - msg_counter_objs.allmail_cnt.badge_text = state.all_count - - def on_start(self): - """Method activates on start""" - self.set_message_count() - - @staticmethod - def on_stop(): - """On stop methos is used for stoping the runing script""" - print "*******************EXITING FROM APPLICATION*******************" - import shutdown - shutdown.doCleanShutdown() - - @staticmethod - def current_address_label(current_add_label=None, current_addr=None): - """Getting current address labels""" - if BMConfigParser().addresses(): - if current_add_label: - first_name = current_add_label - addr = current_addr - else: - addr = BMConfigParser().addresses()[0] - first_name = BMConfigParser().get(addr, 'label') - f_name = first_name.split() - label = f_name[0][:14].capitalize() + '...' if len( - f_name[0]) > 15 else f_name[0].capitalize() - address = ' (' + addr + '...)' - return label + address - return '' - - def searchQuery(self, instance): - """Showing searched mails""" - state.search_screen = self.root.ids.scr_mngr.current - state.searcing_text = str(instance.text).strip() - if instance.focus and state.searcing_text: - toolbar_obj = self.root.ids.toolbar - toolbar_obj.left_action_items = [ - ['arrow-left', lambda x: self.closeSearchScreen()]] - toolbar_obj.right_action_items = [] - self.root.ids.toolbar.title = '' - state.in_search_mode = True - - def closeSearchScreen(self): - """Function for close search screen""" - self.set_common_header() - if state.association: - address_label = self.current_address_label( - BMConfigParser().get( - state.association, 'label'), state.association) - self.root.ids.toolbar.title = address_label - state.searcing_text = '' - self.refreshScreen() - state.in_search_mode = False - - def refreshScreen(self): # pylint: disable=unused-variable - """Method show search button only on inbox or sent screen""" - state.searcing_text = '' - if state.search_screen == 'inbox': - try: - self.root.ids.sc1.children[ - 3].children[2].ids.search_field.text = '' - except Exception: - self.root.ids.sc1.children[ - 2].children[2].ids.search_field.text = '' - self.root.ids.sc1.children[1].active = True - Clock.schedule_once(self.search_callback, 0.5) - elif state.search_screen == 'addressbook': - self.root.ids.sc11.children[ - 2].children[2].ids.search_field.text = '' - self.root.ids.sc11.children[ - 1].active = True - Clock.schedule_once(self.search_callback, 0.5) - elif state.search_screen == 'myaddress': - try: - self.root.ids.sc10.children[ - 3].children[2].ids.search_field.text = '' - except Exception: - self.root.ids.sc10.children[ - 2].children[2].ids.search_field.text = '' - self.root.ids.sc10.children[1].active = True - Clock.schedule_once(self.search_callback, 0.5) - else: - self.root.ids.sc4.children[ - 2].children[2].ids.search_field.text = '' - self.root.ids.sc4.children[1].active = True - Clock.schedule_once(self.search_callback, 0.5) - return - - def set_identicon(self, text): - """Show identicon in address spinner""" - img = identiconGeneration.generate(text) - self.root.children[2].children[0].ids.btn.children[1].texture = ( - img.texture) - - def set_mail_detail_header(self): - """Setting the details of the page""" - if state.association and state.in_search_mode: - address_label = self.current_address_label( - BMConfigParser().get( - state.association, 'label'), state.association) - self.root.ids.toolbar.title = address_label - toolbar_obj = self.root.ids.toolbar - toolbar_obj.left_action_items = [ - ['arrow-left', lambda x: self.back_press()]] - delete_btn = ['delete-forever', - lambda x: self.root.ids.sc14.delete_mail()] - dynamic_list = [] - if state.detailPageType == 'inbox': - dynamic_list = [ - ['reply', lambda x: self.root.ids.sc14.inbox_reply()], - delete_btn] - elif state.detailPageType == 'sent': - dynamic_list = [delete_btn] - elif state.detailPageType == 'draft': - dynamic_list = [ - ['pencil', lambda x: self.root.ids.sc14.write_msg(self)], - delete_btn] - toolbar_obj.right_action_items = dynamic_list - - def load_screen(self, instance): - """This method is used for loading screen on every click""" - if instance.text == 'Inbox': - self.root.ids.scr_mngr.current = 'inbox' - self.root.ids.sc1.children[1].active = True - elif instance.text == 'All Mails': - self.root.ids.scr_mngr.current = 'allmails' - try: - self.root.ids.sc17.children[1].active = True - except Exception: - self.root.ids.sc17.children[0].children[1].active = True - Clock.schedule_once(partial(self.load_screen_callback, instance), 1) - - def load_screen_callback(self, instance, dt=0): - """This method is rotating loader for few seconds""" - if instance.text == 'Inbox': - self.root.ids.sc1.ids.ml.clear_widgets() - self.root.ids.sc1.loadMessagelist(state.association) - self.root.ids.sc1.children[1].active = False - elif instance.text == 'All Mails': - if len(self.root.ids.sc17.ids.ml.children) <= 2: - self.root.ids.sc17.clear_widgets() - self.root.ids.sc17.add_widget(Allmails()) - else: - self.root.ids.sc17.ids.ml.clear_widgets() - self.root.ids.sc17.loadMessagelist() - try: - self.root.ids.sc17.children[1].active = False - except Exception: - self.root.ids.sc17.children[0].children[1].active = False - - -class GrashofPopup(Popup): - """Moule for save contacts and error messages""" - valid = False - - def __init__(self, **kwargs): # pylint: disable=useless-super-delegation - """Grash of pop screen settings""" - super(GrashofPopup, self).__init__(**kwargs) - - def savecontact(self): - """Method is used for saving contacts""" - label = self.ids.label.text.strip() - address = self.ids.address.text.strip() - if label == '' and address == '': - self.ids.label.focus = True - self.ids.address.focus = True - elif address == '': - self.ids.address.focus = True - elif label == '': - self.ids.label.focus = True - - stored_address = [addr[1] for addr in kivy_helper_search.search_sql( - folder="addressbook")] - stored_labels = [labels[0] for labels in kivy_helper_search.search_sql( - folder="addressbook")] - if label and address and address not in stored_address \ - and label not in stored_labels and self.valid: - # state.navinstance = self.parent.children[1] - queues.UISignalQueue.put(('rerenderAddressBook', '')) - self.dismiss() - sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address) - self.parent.children[1].ids.sc11.ids.ml.clear_widgets() - self.parent.children[1].ids.sc11.loadAddresslist(None, 'All', '') - self.parent.children[1].ids.scr_mngr.current = 'addressbook' - toast('Saved') - - @staticmethod - def close_pop(): - """Pop is Canceled""" - toast('Canceled') - - def checkAddress_valid(self, instance): - """Checking address is valid or not""" - my_addresses = ( - self.parent.children[1].children[2].children[0].ids.btn.values) - add_book = [addr[1] for addr in kivy_helper_search.search_sql( - folder="addressbook")] - entered_text = str(instance.text).strip() - if entered_text in add_book: - text = 'Address is already in the addressbook.' - elif entered_text in my_addresses: - text = 'You can not save your own address.' - elif entered_text: - text = self.addressChanged(entered_text) - - if entered_text in my_addresses or entered_text in add_book: - self.ids.address.error = True - self.ids.address.helper_text = text - elif entered_text and self.valid: - self.ids.address.error = False - elif entered_text: - self.ids.address.error = True - self.ids.address.helper_text = text - else: - self.ids.address.error = False - self.ids.address.helper_text = 'This field is required' - - def checkLabel_valid(self, instance): - """Checking address label is unique or not""" - entered_label = instance.text.strip() - addr_labels = [labels[0] for labels in kivy_helper_search.search_sql( - folder="addressbook")] - if entered_label in addr_labels: - self.ids.label.error = True - self.ids.label.helper_text = 'label name already exists.' - elif entered_label: - self.ids.label.error = False - else: - self.ids.label.error = False - self.ids.label.helper_text = 'This field is required' - - def _onSuccess(self, addressVersion, streamNumber, ripe): - pass - - def addressChanged(self, addr): - """Address validation callback, performs validation and gives feedback""" - status, addressVersion, streamNumber, ripe = decodeAddress( - str(addr)) - self.valid = status == 'success' - if self.valid: - text = "Address is valid." - self._onSuccess(addressVersion, streamNumber, ripe) - elif status == 'missingbm': - text = "The address should start with ''BM-''" - elif status == 'checksumfailed': - text = "The address is not typed or copied correctly(the checksum failed)." - elif status == 'versiontoohigh': - text = "The version number of this address is higher"\ - " than this software can support. Please upgrade Bitmessage." - elif status == 'invalidcharacters': - text = "The address contains invalid characters." - elif status == 'ripetooshort': - text = "Some data encoded in the address is too short." - elif status == 'ripetoolong': - text = "Some data encoded in the address is too long." - elif status == 'varintmalformed': - text = "Some data encoded in the address is malformed." - return text - - -class AvatarSampleWidget(ILeftBody, Image): - """Avatar Sample Widget""" - pass - - -class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton): - """Left icon sample widget""" - pass - - -class IconRightSampleWidget(IRightBodyTouch, MDCheckbox): - """Right icon sample widget""" - pass - - -class NavigationDrawerTwoLineListItem( - TwoLineListItem, NavigationDrawerHeaderBase): - """Navigation Drawer in Listitems""" - address_property = StringProperty() - - def __init__(self, **kwargs): - """Method for Navigation Drawer""" - super(NavigationDrawerTwoLineListItem, self).__init__(**kwargs) - Clock.schedule_once(lambda dt: self.setup()) - - def setup(self): - """Bind Controller.current_account property""" - pass - - def on_current_account(self, account): - """Account detail""" - pass - - def _update_specific_text_color(self, instance, value): - pass - - def _set_active(self, active, list_): - pass - - -class MailDetail(Screen): - """MailDetail Screen uses to show the detail of mails""" - to_addr = StringProperty() - from_addr = StringProperty() - subject = StringProperty() - message = StringProperty() - status = StringProperty() - page_type = StringProperty() + """Create Screen uses screen to show widgets of screens.""" def __init__(self, *args, **kwargs): - """Mail Details method""" - super(MailDetail, self).__init__(*args, **kwargs) - Clock.schedule_once(self.init_ui, 0) + super(Create, self).__init__(*args, **kwargs) - def init_ui(self, dt=0): - """Clock Schdule for method MailDetail mails""" - self.page_type = state.detailPageType if state.detailPageType else '' - if state.detailPageType == 'sent' or state.detailPageType == 'draft': - data = sqlQuery( - "select toaddress, fromaddress, subject, message, status," - " ackdata from sent where ackdata = ?;", state.mail_id) - state.status = self - state.ackdata = data[0][5] - self.assign_mail_details(data) - state.kivyapp.set_mail_detail_header() - elif state.detailPageType == 'inbox': - data = sqlQuery( - "select toaddress, fromaddress, subject, message from inbox" - " where msgid = ?;", str(state.mail_id)) - self.assign_mail_details(data) - state.kivyapp.set_mail_detail_header() - - def assign_mail_details(self, data): - """Assigning mail details""" - self.to_addr = data[0][0] - self.from_addr = data[0][1] - self.subject = data[0][2].upper( - ) if data[0][2].upper() else '(no subject)' - self.message = data[0][3] - if len(data[0]) == 6: - self.status = data[0][4] - - def delete_mail(self): - """Method for mail delete""" - msg_count_objs = state.kivyapp.root.children[2].children[0].ids - state.searcing_text = '' - self.children[0].children[0].active = True - if state.detailPageType == 'sent': - state.kivyapp.root.ids.sc4.children[ - 2].children[2].ids.search_field.text = '' - sqlExecute( - "UPDATE sent SET folder = 'trash' WHERE" - " ackdata = ?;", str(state.mail_id)) - msg_count_objs.send_cnt.badge_text = str(int(state.sent_count) - 1) if int(state.sent_count) else '0' - state.sent_count = str(int(state.sent_count) - 1) if int(state.sent_count) else '0' - self.parent.screens[3].ids.ml.clear_widgets() - self.parent.screens[3].loadSent(state.association) - elif state.detailPageType == 'inbox': - state.kivyapp.root.ids.sc1.children[ - 2].children[2].ids.search_field.text = '' - self.parent.screens[0].children[2].children[ - 2].ids.search_field.text = '' - sqlExecute( - "UPDATE inbox SET folder = 'trash' WHERE" - " msgid = ?;", str(state.mail_id)) - msg_count_objs.inbox_cnt.badge_text = str( - int(state.inbox_count) - 1) if int(state.inbox_count) else '0' - state.inbox_count = str(int(state.inbox_count) - 1) if int(state.inbox_count) else '0' - self.parent.screens[0].ids.ml.clear_widgets() - self.parent.screens[0].loadMessagelist(state.association) - - elif state.detailPageType == 'draft': - sqlExecute( - "DELETE FROM sent WHERE ackdata = ?;", str(state.mail_id)) - msg_count_objs.draft_cnt.badge_text = str( - int(state.draft_count) - 1) - state.draft_count = str(int(state.draft_count) - 1) - self.parent.screens[15].clear_widgets() - self.parent.screens[15].add_widget(Draft()) - - # self.parent.current = 'allmails' \ - # if state.is_allmail else state.detailPageType - if state.detailPageType != 'draft': - msg_count_objs.trash_cnt.badge_text = str( - int(state.trash_count) + 1) - msg_count_objs.allmail_cnt.badge_text = str( - int(state.all_count) - 1) if int(state.all_count) else '0' - state.trash_count = str(int(state.trash_count) + 1) - state.all_count = str(int(state.all_count) - 1) if int(state.all_count) else '0' - self.parent.screens[4].clear_widgets() - self.parent.screens[4].add_widget(Trash()) - self.parent.screens[16].clear_widgets() - self.parent.screens[16].add_widget(Allmails()) - Clock.schedule_once(self.callback_for_delete, 4) - - def callback_for_delete(self, dt=0): - """Delete method from allmails""" - self.children[0].children[0].active = False - state.kivyapp.set_common_header() - self.parent.current = 'allmails' \ - if state.is_allmail else state.detailPageType - state.detailPageType = '' - toast('Deleted') - - def inbox_reply(self): - """Reply inbox messages""" - state.in_composer = True - data = sqlQuery( - "select toaddress, fromaddress, subject, message from inbox where" - " msgid = ?;", str(state.mail_id)) - composer_obj = self.parent.screens[2].children[1].ids - composer_obj.ti.text = data[0][0] - composer_obj.btn.text = data[0][0] - composer_obj.txt_input.text = data[0][1] - composer_obj.subject.text = data[0][2] - composer_obj.body.text = '' - state.kivyapp.root.ids.sc3.children[1].ids.rv.data = '' - self.parent.current = 'create' - state.kivyapp.set_navbar_for_composer() - - def write_msg(self, navApp): - """Write on draft mail""" - state.send_draft_mail = state.mail_id - data = sqlQuery( - "select toaddress, fromaddress, subject, message from sent where" - " ackdata = ?;", str(state.mail_id)) - composer_ids = ( - self.parent.parent.parent.parent.parent.ids.sc3.children[1].ids) - composer_ids.ti.text = data[0][1] - composer_ids.btn.text = data[0][1] - composer_ids.txt_input.text = data[0][0] - composer_ids.subject.text = data[0][2] if data[0][2] != '(no subject)' else '' - composer_ids.body.text = data[0][3] - self.parent.current = 'create' - navApp.set_navbar_for_composer() - - @staticmethod - def copy_composer_text(instance, *args): - """Copy the data from mail detail page""" - if len(instance.parent.text.split(':')) > 1: - cpy_text = instance.parent.text.split(':')[1].strip() - else: - cpy_text = instance.parent.text - Clipboard.copy(cpy_text) - toast('Copied') - - -class MyaddDetailPopup(Popup): - """MyaddDetailPopup pop is used for showing my address detail""" - address_label = StringProperty() - address = StringProperty() - - def __init__(self, **kwargs): # pylint: disable=useless-super-delegation - """My Address Details screen setting""" - super(MyaddDetailPopup, self).__init__(**kwargs) - - def set_address(self, address, label): - """Getting address for displaying details on popup""" - self.address_label = label - self.address = address - - def send_message_from(self): - """Method used to fill from address of composer autofield""" - state.kivyapp.set_navbar_for_composer() - window_obj = self.parent.children[1].ids - window_obj.sc3.children[1].ids.ti.text = self.address - window_obj.sc3.children[1].ids.btn.text = self.address - window_obj.sc3.children[1].ids.txt_input.text = '' - window_obj.sc3.children[1].ids.subject.text = '' - window_obj.sc3.children[1].ids.body.text = '' - window_obj.scr_mngr.current = 'create' - self.dismiss() - - @staticmethod - def close_pop(): - """Pop is Canceled""" - toast('Canceled') - - -class AddbookDetailPopup(Popup): - """AddbookDetailPopup pop is used for showing my address detail""" - address_label = StringProperty() - address = StringProperty() - - def __init__(self, **kwargs): - """Set screen of address detail page""" - # pylint: disable=useless-super-delegation - super(AddbookDetailPopup, self).__init__(**kwargs) - - def set_addbook_data(self, address, label): - """Getting address book data for detial dipaly""" - self.address_label = label - self.address = address - - def update_addbook_label(self, address): - """Updating the label of address book address""" - address_list = kivy_helper_search.search_sql(folder="addressbook") - stored_labels = [labels[0] for labels in address_list] - add_dict = dict(address_list) - label = str(self.ids.add_label.text) - if label in stored_labels and self.address == add_dict[label]: - stored_labels.remove(label) - if label and label not in stored_labels: - sqlExecute( - "UPDATE addressbook SET label = '{}' WHERE" - " address = '{}';".format( - str(self.ids.add_label.text), address)) - self.parent.children[1].ids.sc11.ids.ml.clear_widgets() - self.parent.children[1].ids.sc11.loadAddresslist(None, 'All', '') - self.dismiss() - toast('Saved') - - def send_message_to(self): - """Method used to fill to_address of composer autofield""" - state.kivyapp.set_navbar_for_composer() - window_obj = self.parent.children[1].ids - window_obj.sc3.children[1].ids.txt_input.text = self.address - window_obj.sc3.children[1].ids.ti.text = '' - window_obj.sc3.children[1].ids.btn.text = 'Select' - window_obj.sc3.children[1].ids.subject.text = '' - window_obj.sc3.children[1].ids.body.text = '' - window_obj.scr_mngr.current = 'create' - self.dismiss() - - @staticmethod - def close_pop(): - """Pop is Canceled""" - toast('Canceled') - - def checkLabel_valid(self, instance): - """Checking address label is unique of not""" - entered_label = str(instance.text.strip()) - address_list = kivy_helper_search.search_sql(folder="addressbook") - addr_labels = [labels[0] for labels in address_list] - add_dict = dict(address_list) - if self.address and entered_label in addr_labels \ - and self.address != add_dict[entered_label]: - self.ids.add_label.error = True - self.ids.add_label.helper_text = 'label name already exists.' - elif entered_label: - self.ids.add_label.error = False - else: - self.ids.add_label.error = False - self.ids.add_label.helper_text = 'This field is required' - - -class ShowQRCode(Screen): - """ShowQRCode Screen uses to show the detail of mails""" - - def qrdisplay(self): - """Showing QR Code""" - # self.manager.parent.parent.parent.ids.search_bar.clear_widgets() - self.ids.qr.clear_widgets() - from kivy.garden.qrcode import QRCodeWidget - self.ids.qr.add_widget(QRCodeWidget( - data=self.manager.get_parent_window().children[0].address)) - toast('Show QR code') - - -class Draft(Screen): - """Draft screen is used to show the list of draft messages""" - data = ListProperty() - account = StringProperty() - queryreturn = ListProperty() - has_refreshed = True - - def __init__(self, *args, **kwargs): - """Method used for storing draft messages""" - super(Draft, self).__init__(*args, **kwargs) - if state.association == '': - if BMConfigParser().addresses(): - state.association = BMConfigParser().addresses()[0] - Clock.schedule_once(self.init_ui, 0) - - def init_ui(self, dt=0): - """Clock Schdule for method draft accounts""" - self.sentaccounts() - print dt - - def sentaccounts(self): - """Load draft accounts.""" - self.account = state.association - self.loadDraft() - - def loadDraft(self, where="", what=""): - """Load draft list for Draft messages.""" - xAddress = 'fromaddress' - self.ids.identi_tag.children[0].text = '' - self.draftDataQuery(xAddress, where, what) - if state.msg_counter_objs: - state.msg_counter_objs.draft_cnt.badge_text = str( - len(self.queryreturn)) - if self.queryreturn: - self.ids.identi_tag.children[0].text = 'Draft' - src_mng_obj = state.kivyapp.root.children[2].children[0].ids - src_mng_obj.draft_cnt.badge_text = state.draft_count - self.set_mdList() - self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) - else: - content = MDLabel( - font_style='Body1', theme_text_color='Primary', - text="yet no message for this account!!!!!!!!!!!!!", - halign='center', bold=True, size_hint_y=None, valign='top') - self.ids.ml.add_widget(content) - - # pylint: disable=too-many-arguments - def draftDataQuery(self, xAddress, where, what, start_indx=0, end_indx=20): - """This methosd is for retrieving draft messages""" - self.queryreturn = kivy_helper_search.search_sql( - xAddress, self.account, "draft", where, what, - False, start_indx, end_indx) - - def set_mdList(self): - """This method is used to create mdlist""" - data = [] - total_draft_msg = len(self.ids.ml.children) - for mail in self.queryreturn: - third_text = mail[3].replace('\n', ' ') - data.append({ - 'text': mail[1].strip(), - 'secondary_text': mail[2][:10] + '...........' if len( - mail[2]) > 10 else mail[2] + '\n' + " " + ( - third_text[:25] + '...!') if len( - third_text) > 25 else third_text, - 'ackdata': mail[5]}) - for item in data: - meny = CustomAvatarIconListItem( - text='Draft', secondary_text=item['text'], - theme_text_color='Custom') - meny.add_widget(AvatarSampleWidget( - source='./images/avatar.png')) - meny.bind(on_press=partial( - self.draft_detail, item['ackdata'])) - carousel = Carousel(direction='right') - carousel.height = meny.height - carousel.size_hint_y = None - carousel.ignore_perpendicular_swipes = True - carousel.data_index = 0 - carousel.min_move = 0.2 - del_btn = Button(text='Delete') - del_btn.background_normal = '' - del_btn.background_color = (1, 0, 0, 1) - del_btn.bind(on_press=partial(self.delete_draft, item['ackdata'])) - carousel.add_widget(del_btn) - carousel.add_widget(meny) - carousel.index = 1 - self.ids.ml.add_widget(carousel) - updated_msg = len(self.ids.ml.children) - self.has_refreshed = True if total_draft_msg != updated_msg else False - - def check_scroll_y(self, instance, somethingelse): - """Load data on scroll""" - if self.ids.scroll_y.scroll_y <= -0.0 and self.has_refreshed: - self.ids.scroll_y.scroll_y = 0.06 - total_draft_msg = len(self.ids.ml.children) - self.update_draft_screen_on_scroll(total_draft_msg) - else: - pass - - def update_draft_screen_on_scroll(self, total_draft_msg, where='', what=''): - """Load more data on scroll down""" - self.draftDataQuery('fromaddress', where, what, total_draft_msg, 5) - self.set_mdList() - - def draft_detail(self, ackdata, *args): - """Show draft Details""" - state.detailPageType = 'draft' - state.mail_id = ackdata - if self.manager: - src_mng_obj = self.manager - else: - src_mng_obj = self.parent.parent - src_mng_obj.screens[13].clear_widgets() - src_mng_obj.screens[13].add_widget(MailDetail()) - src_mng_obj.current = 'mailDetail' - - def delete_draft(self, data_index, instance, *args): - """Delete draft message permanently""" - sqlExecute("DELETE FROM sent WHERE ackdata = ?;", str( - data_index)) - try: - msg_count_objs = ( - self.parent.parent.parent.parent.parent.parent.children[ - 2].children[0].ids) - except Exception: - msg_count_objs = self.parent.parent.parent.parent.parent.children[ - 2].children[0].ids - if int(state.draft_count) > 0: - msg_count_objs.draft_cnt.badge_text = str( - int(state.draft_count) - 1) - state.draft_count = str(int(state.draft_count) - 1) - if int(state.draft_count) <= 0: - self.ids.identi_tag.children[0].text = '' - self.ids.ml.remove_widget(instance.parent.parent) - toast('Deleted') - - @staticmethod - def draft_msg(src_object): # pylint: disable=too-many-locals - """Save draft mails""" - composer_object = state.kivyapp.root.ids.sc3.children[1].ids - fromAddress = str(composer_object.ti.text) - toAddress = str(composer_object.txt_input.text) - subject = str(composer_object.subject.text) - message = str(composer_object.body.text) + def send(self): + """Send message from one address to another.""" + fromAddress = self.ids.spinner_id.text + # For now we are using static address i.e we are not using recipent field value. + toAddress = "BM-2cWyUfBdY2FbgyuCb7abFZ49JYxSzUhNFe" + message = self.ids.message.text + subject = self.ids.subject.text encoding = 3 + print("message: ", self.ids.message.text) sendMessageToPeople = True if sendMessageToPeople: - streamNumber, ripe = decodeAddress(toAddress)[2:] - toAddress = addBMIfNotPresent(toAddress) - stealthLevel = BMConfigParser().safeGetInt( - 'bitmessagesettings', 'ackstealthlevel') - from helper_ackPayload import genAckPayload - ackdata = genAckPayload(streamNumber, stealthLevel) - t = ( - '', - toAddress, - ripe, - fromAddress, - subject, - message, - ackdata, - int(time.time()), - int(time.time()), - 0, - 'msgqueued', - 0, - 'draft', - encoding, - BMConfigParser().getint('bitmessagesettings', 'ttl') + if toAddress != '': + status, addressVersionNumber, streamNumber, ripe = decodeAddress( + toAddress) + if status == 'success': + toAddress = addBMIfNotPresent(toAddress) + + if addressVersionNumber > 4 or addressVersionNumber <= 1: + print("addressVersionNumber > 4 or addressVersionNumber <= 1") + if streamNumber > 1 or streamNumber == 0: + print("streamNumber > 1 or streamNumber == 0") + if statusIconColor == 'red': + print("shared.statusIconColor == 'red'") + stealthLevel = BMConfigParser().safeGetInt( + 'bitmessagesettings', 'ackstealthlevel') + ackdata = genAckPayload(streamNumber, stealthLevel) + t = () + sqlExecute( + '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', + '', + toAddress, + ripe, + fromAddress, + subject, + message, + ackdata, + int(time.time()), + int(time.time()), + 0, + 'msgqueued', + 0, + 'sent', + encoding, + BMConfigParser().getint('bitmessagesettings', 'ttl')) + toLabel = '' + queues.workerQueue.put(('sendmessage', toAddress)) + print("sqlExecute successfully ##### ##################") + self.ids.message.text = '' + self.ids.spinner_id.text = '' + self.ids.subject.text = '' + self.ids.recipent.text = '' + return None + + +class NewIdentity(Screen): + """Create new address for PyBitmessage.""" + + is_active = BooleanProperty(False) + checked = StringProperty("") + # self.manager.parent.ids.create.children[0].source = 'images/plus-4-xxl.png' + + def generateaddress(self): + """Generate new address.""" + if self.checked == 'use a random number generator to make an address': + queues.apiAddressGeneratorReturnQueue.queue.clear() + streamNumberForAddress = 1 + label = self.ids.label.text + eighteenByteRipe = False + nonceTrialsPerByte = 1000 + payloadLengthExtraBytes = 1000 + + queues.addressGeneratorQueue.put(( + 'createRandomAddress', + 4, streamNumberForAddress, + label, 1, "", eighteenByteRipe, + nonceTrialsPerByte, + payloadLengthExtraBytes) ) - helper_sent.insert(t) - state.msg_counter_objs = src_object.children[2].children[0].ids - state.draft_count = str(int(state.draft_count) + 1) - src_object.ids.sc16.clear_widgets() - src_object.ids.sc16.add_widget(Draft()) - toast('Save draft') - return + self.manager.current = 'add_sucess' -class CustomSpinner(Spinner): - """This class is used for setting spinner size""" - - def __init__(self, *args, **kwargs): - """Setting size of spinner""" - super(CustomSpinner, self).__init__(*args, **kwargs) - self.dropdown_cls.max_height = Window.size[1] / 3 - - -class Allmails(Screen): - """All mails Screen uses screen to show widgets of screens""" - data = ListProperty() - has_refreshed = True - all_mails = ListProperty() - account = StringProperty() - - def __init__(self, *args, **kwargs): - """Method Parsing the address.""" - super(Allmails, self).__init__(*args, **kwargs) - if state.association == '': - if BMConfigParser().addresses(): - state.association = BMConfigParser().addresses()[0] - Clock.schedule_once(self.init_ui, 0) - - def init_ui(self, dt=0): - """Clock Schdule for method all mails""" - self.loadMessagelist() - print dt - - def loadMessagelist(self): - """Load Inbox, Sent anf Draft list of messages.""" - self.account = state.association - self.ids.identi_tag.children[0].text = '' - self.allMessageQuery(0, 20) - if self.all_mails: - self.ids.identi_tag.children[0].text = 'All Mails' - state.kivyapp.get_inbox_count() - state.kivyapp.get_sent_count() - state.all_count = str( - int(state.sent_count) + int(state.inbox_count)) - state.kivyapp.root.children[2].children[ - 0].ids.allmail_cnt.badge_text = state.all_count - self.set_mdlist() - # self.ids.refresh_layout.bind(scroll_y=self.check_scroll_y) - self.ids.scroll_y.bind(scroll_y=self.check_scroll_y) - else: - content = MDLabel( - font_style='Body1', theme_text_color='Primary', - text="yet no message for this account!!!!!!!!!!!!!", - halign='center', bold=True, size_hint_y=None, valign='top') - self.ids.ml.add_widget(content) - - def allMessageQuery(self, start_indx, end_indx): - """Retrieving data from inbox or sent both tables""" - self.all_mails = sqlQuery( - "SELECT toaddress, fromaddress, subject, message, folder, ackdata" - " As id, DATE(lastactiontime) As actionTime FROM sent WHERE" - " folder = 'sent' and fromaddress = '{0}'" - " UNION SELECT toaddress, fromaddress, subject, message, folder," - " msgid As id, DATE(received) As actionTime FROM inbox" - " WHERE folder = 'inbox' and toaddress = '{0}'" - " ORDER BY actionTime DESC limit {1}, {2}".format( - self.account, start_indx, end_indx)) - - def set_mdlist(self): - """This method is used to create mdList for allmaills""" - data_exist = len(self.ids.ml.children) - for item in self.all_mails: - meny = CustomAvatarIconListItem( - text=item[1], - secondary_text=item[2][:50] + '........' if len( - item[2]) >= 50 else ( - item[2] + ',' + item[3].replace( - '\n', ''))[0:50] + '........', - theme_text_color='Custom', - text_color=NavigateApp().theme_cls.primary_color) - meny.add_widget(AvatarSampleWidget( - source='./images/text_images/{}.png'.format( - avatarImageFirstLetter(item[2].strip())))) - meny.bind(on_press=partial( - self.mail_detail, item[5], item[4])) - carousel = Carousel(direction='right') - carousel.height = meny.height - carousel.size_hint_y = None - carousel.ignore_perpendicular_swipes = True - carousel.data_index = 0 - carousel.min_move = 0.2 - del_btn = Button(text='Delete') - del_btn.background_normal = '' - del_btn.background_color = (1, 0, 0, 1) - del_btn.bind(on_press=partial( - self.swipe_delete, item[5], item[4])) - carousel.add_widget(del_btn) - carousel.add_widget(meny) - carousel.index = 1 - self.ids.ml.add_widget(carousel) - updated_data = len(self.ids.ml.children) - self.has_refreshed = True if data_exist != updated_data else False - - def check_scroll_y(self, instance, somethingelse): - """Scroll fixed length""" - if self.ids.scroll_y.scroll_y <= -0.00 and self.has_refreshed: - self.ids.scroll_y.scroll_y = .06 - load_more = len(self.ids.ml.children) - self.updating_allmail(load_more) - else: - pass - - def updating_allmail(self, load_more): - """This method is used to update the all mail - listing value on the scroll of screen""" - self.allMessageQuery(load_more, 5) - self.set_mdlist() - - def mail_detail(self, unique_id, folder, *args): - """Load sent and inbox mail details""" - state.detailPageType = folder - state.is_allmail = True - state.mail_id = unique_id - if self.manager: - src_mng_obj = self.manager - else: - src_mng_obj = self.parent.parent - src_mng_obj.screens[13].clear_widgets() - src_mng_obj.screens[13].add_widget(MailDetail()) - src_mng_obj.current = 'mailDetail' - - def swipe_delete(self, unique_id, folder, instance, *args): - """Delete inbox mail from all mail listing""" - if folder == 'inbox': - sqlExecute( - "UPDATE inbox SET folder = 'trash' WHERE msgid = ?;", - str(unique_id)) - else: - sqlExecute( - "UPDATE sent SET folder = 'trash' WHERE ackdata = ?;", - str(unique_id)) - self.ids.ml.remove_widget(instance.parent.parent) - try: - msg_count_objs = self.parent.parent.parent.parent.parent.children[ - 2].children[0].ids - nav_lay_obj = self.parent.parent.parent.parent.parent.ids - except Exception: - msg_count_objs = self.parent.parent.parent.parent.parent.parent.children[ - 2].children[0].ids - nav_lay_obj = self.parent.parent.parent.parent.parent.parent.ids - if folder == 'inbox': - msg_count_objs.inbox_cnt.badge_text = str( - int(state.inbox_count) - 1) - state.inbox_count = str(int(state.inbox_count) - 1) - nav_lay_obj.sc1.ids.ml.clear_widgets() - nav_lay_obj.sc1.loadMessagelist(state.association) - else: - msg_count_objs.send_cnt.badge_text = str(int(state.sent_count) - 1) - state.sent_count = str(int(state.sent_count) - 1) - nav_lay_obj.sc4.ids.ml.clear_widgets() - nav_lay_obj.sc4.loadSent(state.association) - msg_count_objs.trash_cnt.badge_text = str(int(state.trash_count) + 1) - msg_count_objs.allmail_cnt.badge_text = str(int(state.all_count) - 1) - state.trash_count = str(int(state.trash_count) + 1) - state.all_count = str(int(state.all_count) - 1) - if int(state.all_count) <= 0: - self.ids.identi_tag.children[0].text = '' - nav_lay_obj.sc5.clear_widgets() - nav_lay_obj.sc5.add_widget(Trash()) - nav_lay_obj.sc17.remove_widget(instance.parent.parent) - - # pylint: disable=attribute-defined-outside-init - def refresh_callback(self, *args): - """Method updates the state of application, - While the spinner remains on the screen""" - def refresh_callback(interval): - """Load the allmails screen data""" - self.ids.ml.clear_widgets() - self.remove_widget(self.children[1]) - try: - screens_obj = self.parent.screens[16] - except Exception: - screens_obj = self.parent.parent.screens[16] - screens_obj.add_widget(Allmails()) - self.ids.refresh_layout.refresh_done() - self.tick = 0 - Clock.schedule_once(refresh_callback, 1) - - def set_root_layout(self): - """Setting root layout""" - try: - return self.manager.parent.parent - except Exception: - return state.kivyapp.root.ids.float_box - - -def avatarImageFirstLetter(letter_string): - """This function is used to the first letter for the avatar image""" - try: - if letter_string[0].upper() >= 'A' and letter_string[0].upper() <= 'Z': - img_latter = letter_string[0].upper() - elif int(letter_string[0]) >= 0 and int(letter_string[0]) <= 9: - img_latter = letter_string[0] - else: - img_latter = '!' - except ValueError as e: - img_latter = '!' - return img_latter if img_latter else '!' - - -class Starred(Screen): - """Starred Screen show widgets of page""" - pass - - -class Archieve(Screen): - """Archieve Screen show widgets of page""" - pass - - -class Spam(Screen): - """Spam Screen show widgets of page""" - pass - - -class LoadingPopup(Popup): - """Class for loading Popup""" - - def __init__(self, **kwargs): - super(LoadingPopup, self).__init__(**kwargs) - # call dismiss_popup in 2 seconds - Clock.schedule_once(self.dismiss_popup, 0.5) - - def dismiss_popup(self, dt): - """Dismiss popups""" - self.dismiss() +if __name__ == '__main__': + NavigateApp().run() diff --git a/src/bitmessagekivy/uikivysignaler.py b/src/bitmessagekivy/uikivysignaler.py deleted file mode 100644 index fe9c9884..00000000 --- a/src/bitmessagekivy/uikivysignaler.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -Ui Singnaler for kivy interface -""" -from threading import Thread - -import queues -import state -from semaphores import kivyuisignaler - - -class UIkivySignaler(Thread): - """Kivy ui signaler""" - - def run(self): - kivyuisignaler.acquire() - while state.shutdown == 0: - try: - command, data = queues.UISignalQueue.get() - if command == 'writeNewAddressToTable': - address = data[1] - state.kivyapp.variable_1.append(address) - # elif command == 'rerenderAddressBook': - # state.kivyapp.obj_1.refreshs() - # Need to discuss this - elif command == 'updateSentItemStatusByAckdata': - state.kivyapp.status_dispatching(data) - except Exception as e: - print e diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index d1e023c6..4efd0154 100755 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -1,16 +1,25 @@ #!/usr/bin/python2.7 -""" -The PyBitmessage startup script -""" # Copyright (c) 2012-2016 Jonathan Warren -# Copyright (c) 2012-2020 The Bitmessage developers +# Copyright (c) 2012-2019 The Bitmessage developers # Distributed under the MIT/X11 software license. See the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # Right now, PyBitmessage only support connecting to stream 1. It doesn't # yet contain logic to expand into further streams. + +# The software version variable is now held in shared.py + import os import sys + +app_dir = os.path.dirname(os.path.abspath(__file__)) +os.chdir(app_dir) +sys.path.insert(0, app_dir) + + +import depends +depends.check_dependencies() + import ctypes import getopt import multiprocessing @@ -22,40 +31,43 @@ import time import traceback from struct import pack -import defaults -import depends -import shared -import shutdown -import state -from bmconfigparser import BMConfigParser -from debug import logger # this should go before any threads from helper_startup import ( - isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections, - start_proxyconfig -) -from inventory import Inventory -from knownnodes import readKnownNodes -# Network objects and threads -from network import ( - BMConnectionPool, Dandelion, AddrThread, AnnounceThread, BMNetworkThread, - InvThread, ReceiveQueueThread, DownloadThread, UploadThread + isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections ) from singleinstance import singleinstance -# Synchronous threads -from threads import ( - set_thread_name, addressGenerator, objectProcessor, singleCleaner, - singleWorker, sqlThread -) -app_dir = os.path.dirname(os.path.abspath(__file__)) -os.chdir(app_dir) -sys.path.insert(0, app_dir) +import defaults +import shared +import knownnodes +import state +import shutdown +from debug import logger -depends.check_dependencies() +# Classes +from class_sqlThread import sqlThread +from class_singleCleaner import singleCleaner +from class_objectProcessor import objectProcessor +from class_singleWorker import singleWorker +from class_addressGenerator import addressGenerator +from bmconfigparser import BMConfigParser + +from inventory import Inventory + +from network.connectionpool import BMConnectionPool +from network.dandelion import Dandelion +from network.networkthread import BMNetworkThread +from network.receivequeuethread import ReceiveQueueThread +from network.announcethread import AnnounceThread +from network.invthread import InvThread +from network.addrthread import AddrThread +from network.downloadthread import DownloadThread +from network.uploadthread import UploadThread + +# Helper Functions +import helper_threading def connectToStream(streamNumber): - """Connect to a stream""" state.streamsInWhichIAmParticipating.append(streamNumber) if isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections(): @@ -72,6 +84,14 @@ def connectToStream(streamNumber): except: pass + with knownnodes.knownNodesLock: + if streamNumber not in knownnodes.knownNodes: + knownnodes.knownNodes[streamNumber] = {} + if streamNumber*2 not in knownnodes.knownNodes: + knownnodes.knownNodes[streamNumber*2] = {} + if streamNumber*2+1 not in knownnodes.knownNodes: + knownnodes.knownNodes[streamNumber*2+1] = {} + BMConnectionPool().connectToStream(streamNumber) @@ -88,8 +108,6 @@ def _fixSocket(): addressToString = ctypes.windll.ws2_32.WSAAddressToStringA def inet_ntop(family, host): - """Converting an IP address in packed - binary format to string format""" if family == socket.AF_INET: if len(host) != 4: raise ValueError("invalid IPv4 host") @@ -111,8 +129,6 @@ def _fixSocket(): stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA def inet_pton(family, host): - """Converting an IP address in string format - to a packed binary format""" buf = "\0" * 28 lengthBuf = pack("I", len(buf)) if stringToAddress(str(host), @@ -153,32 +169,29 @@ def signal_handler(signum, frame): if thread.name not in ("PyBitmessage", "MainThread"): return logger.error("Got signal %i", signum) - # there are possible non-UI variants to run bitmessage - # which should shutdown especially test-mode + # there are possible non-UI variants to run bitmessage which should shutdown + # especially test-mode if shared.thisapp.daemon or not state.enableGUI: shutdown.doCleanShutdown() else: - print '# Thread: %s(%d)' % (thread.name, thread.ident) + print('# Thread: %s(%d)' % (thread.name, thread.ident)) for filename, lineno, name, line in traceback.extract_stack(frame): - print 'File: "%s", line %d, in %s' % (filename, lineno, name) + print('File: "%s", line %d, in %s' % (filename, lineno, name)) if line: - print ' %s' % line.strip() - print 'Unfortunately you cannot use Ctrl+C when running the UI \ - because the UI captures the signal.' + print(' %s' % line.strip()) + print('Unfortunately you cannot use Ctrl+C when running the UI' + ' because the UI captures the signal.') -class Main(object): - """Main PyBitmessage class""" +class Main: def start(self): - """Start main application""" - # pylint: disable=too-many-statements,too-many-branches,too-many-locals _fixSocket() - config = BMConfigParser() - daemon = config.safeGetBoolean('bitmessagesettings', 'daemon') + daemon = BMConfigParser().safeGetBoolean( + 'bitmessagesettings', 'daemon') try: - opts, _ = getopt.getopt( + opts, args = getopt.getopt( sys.argv[1:], "hcdt", ["help", "curses", "daemon", "test"]) @@ -186,7 +199,7 @@ class Main(object): self.usage() sys.exit(2) - for opt, _ in opts: + for opt, arg in opts: if opt in ("-h", "--help"): self.usage() sys.exit() @@ -203,6 +216,7 @@ class Main(object): # Fallback: in case when no api command was issued state.last_api_response = time.time() # Apply special settings + config = BMConfigParser() config.set( 'bitmessagesettings', 'apienabled', 'true') config.set( @@ -217,8 +231,7 @@ class Main(object): if daemon: state.enableGUI = False # run without a UI - # is the application already running? If yes then exit. - if state.enableGUI and not state.curses and not state.kivy and not depends.check_pyqt(): + if state.enableGUI and not state.curses and not depends.check_pyqt(): sys.exit( 'PyBitmessage requires PyQt unless you want' ' to run it as a daemon and interact with it' @@ -232,36 +245,32 @@ class Main(object): ' \'-c\' as a commandline argument.' ) # is the application already running? If yes then exit. - try: - shared.thisapp = singleinstance("", daemon) - except Exception: - pass + shared.thisapp = singleinstance("", daemon) if daemon: with shared.printLock: - print 'Running as a daemon. Send TERM signal to end.' + print('Running as a daemon. Send TERM signal to end.') self.daemonize() self.setSignalHandler() - set_thread_name("PyBitmessage") + helper_threading.set_thread_name("PyBitmessage") - state.dandelion = config.safeGetInt('network', 'dandelion') + state.dandelion = BMConfigParser().safeGetInt('network', 'dandelion') # dandelion requires outbound connections, without them, # stem objects will get stuck forever - if state.dandelion and not config.safeGetBoolean( + if state.dandelion and not BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'sendoutgoingconnections'): state.dandelion = 0 - if state.testmode or config.safeGetBoolean( + if state.testmode or BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'extralowdifficulty'): defaults.networkDefaultProofOfWorkNonceTrialsPerByte = int( defaults.networkDefaultProofOfWorkNonceTrialsPerByte / 100) defaults.networkDefaultPayloadLengthExtraBytes = int( defaults.networkDefaultPayloadLengthExtraBytes / 100) - readKnownNodes() - + knownnodes.readKnownNodes() # Not needed if objproc is disabled if state.enableObjProc: @@ -284,21 +293,24 @@ class Main(object): # The closeEvent should command this thread to exit gracefully. sqlLookup.daemon = False sqlLookup.start() + Inventory() # init # init, needs to be early because other thread may access it early Dandelion() + # Enable object processor and SMTP only if objproc enabled if state.enableObjProc: + # SMTP delivery thread - if daemon and config.safeGet( - 'bitmessagesettings', 'smtpdeliver', '') != '': + if daemon and BMConfigParser().safeGet( + "bitmessagesettings", "smtpdeliver", '') != '': from class_smtpDeliver import smtpDeliver smtpDeliveryThread = smtpDeliver() smtpDeliveryThread.start() # SMTP daemon thread - if daemon and config.safeGetBoolean( - 'bitmessagesettings', 'smtpd'): + if daemon and BMConfigParser().safeGetBoolean( + "bitmessagesettings", "smtpd"): from class_smtpServer import smtpServer smtpServerThread = smtpServer() smtpServerThread.start() @@ -310,30 +322,33 @@ class Main(object): # each object. objectProcessorThread.daemon = False objectProcessorThread.start() + # Start the cleanerThread singleCleanerThread = singleCleaner() # close the main program even if there are threads left singleCleanerThread.daemon = True singleCleanerThread.start() + # Not needed if objproc disabled if state.enableObjProc: shared.reloadMyAddressHashes() shared.reloadBroadcastSendersForWhichImWatching() + # API is also objproc dependent - if config.safeGetBoolean('bitmessagesettings', 'apienabled'): + if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'): import api # pylint: disable=relative-import singleAPIThread = api.singleAPI() # close the main program even if there are threads left singleAPIThread.daemon = True singleAPIThread.start() + # start network components if networking is enabled if state.enableNetwork: - start_proxyconfig() BMConnectionPool() asyncoreThread = BMNetworkThread() asyncoreThread.daemon = True asyncoreThread.start() - for i in range(config.getint('threads', 'receive')): + for i in range(BMConfigParser().getint("threads", "receive")): receiveQueueThread = ReceiveQueueThread(i) receiveQueueThread.daemon = True receiveQueueThread.start() @@ -354,43 +369,41 @@ class Main(object): state.uploadThread.start() connectToStream(1) - if config.safeGetBoolean('bitmessagesettings', 'upnp'): + + if BMConfigParser().safeGetBoolean( + 'bitmessagesettings', 'upnp'): import upnp upnpThread = upnp.uPnPThread() upnpThread.start() else: # Populate with hardcoded value (same as connectToStream above) state.streamsInWhichIAmParticipating.append(1) + if not daemon and state.enableGUI: if state.curses: if not depends.check_curses(): sys.exit() - print 'Running with curses' + print('Running with curses') import bitmessagecurses bitmessagecurses.runwrapper() - elif state.kivy: - config.remove_option('bitmessagesettings', 'dontconnect') + BMConfigParser().remove_option('bitmessagesettings', 'dontconnect') from bitmessagekivy.mpybit import NavigateApp - state.kivyapp = NavigateApp() - state.kivyapp.run() + NavigateApp().run() else: import bitmessageqt bitmessageqt.run() else: - config.remove_option('bitmessagesettings', 'dontconnect') + BMConfigParser().remove_option('bitmessagesettings', 'dontconnect') if daemon: while state.shutdown == 0: time.sleep(1) - if ( - state.testmode and time.time() - - state.last_api_response >= 30 - ): + if (state.testmode and + time.time() - state.last_api_response >= 30): self.stop() elif not state.enableGUI: - # pylint: disable=relative-import - from tests import core as test_core + from tests import core as test_core # pylint: disable=relative-import test_core_result = test_core.run() state.enableGUI = True self.stop() @@ -401,9 +414,7 @@ class Main(object): else 0 ) - @staticmethod - def daemonize(): - """Running as a daemon. Send signal in end.""" + def daemonize(self): grandfatherPid = os.getpid() parentPid = None try: @@ -413,8 +424,7 @@ class Main(object): # wait until grandchild ready while True: time.sleep(1) - - os._exit(0) # pylint: disable=protected-access + os._exit(0) except AttributeError: # fork not implemented pass @@ -435,7 +445,7 @@ class Main(object): # wait until child ready while True: time.sleep(1) - os._exit(0) # pylint: disable=protected-access + os._exit(0) except AttributeError: # fork not implemented pass @@ -456,18 +466,14 @@ class Main(object): os.kill(parentPid, signal.SIGTERM) os.kill(grandfatherPid, signal.SIGTERM) - @staticmethod - def setSignalHandler(): - """Setting the Signal Handler""" + def setSignalHandler(self): signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) # signal.signal(signal.SIGINT, signal.SIG_DFL) - @staticmethod - def usage(): - """Displaying the usages""" - print('Usage: ' + sys.argv[0] + ' [OPTIONS]') - print(''' + def usage(self): + print 'Usage: ' + sys.argv[0] + ' [OPTIONS]' + print ''' Options: -h, --help show this help message and exit -c, --curses use curses (text mode) interface @@ -475,19 +481,15 @@ Options: -t, --test dryrun, make testing All parameters are optional. -''') +''' - @staticmethod - def stop(): - """Stop main application""" + def stop(self): with shared.printLock: - print 'Stopping Bitmessage Deamon.' + print('Stopping Bitmessage Deamon.') shutdown.doCleanShutdown() - # .. todo:: nice function but no one is using this - @staticmethod - def getApiAddress(): - """This function returns API address and port""" + # TODO: nice function but no one is using this + def getApiAddress(self): if not BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'apienabled'): return None @@ -497,7 +499,6 @@ All parameters are optional. def main(): - """Triggers main module""" mainprogram = Main() mainprogram.start() diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 440d36b2..507e6ca0 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -23,6 +23,7 @@ from addresses import decodeAddress, addBMIfNotPresent import shared from bitmessageui import Ui_MainWindow from bmconfigparser import BMConfigParser +import defaults import namecoin from messageview import MessageView from migrationwizard import Ui_MigrationWizard @@ -30,12 +31,15 @@ from foldertree import ( AccountMixin, Ui_FolderWidget, Ui_AddressWidget, Ui_SubscriptionWidget, MessageList_AddressWidget, MessageList_SubjectWidget, Ui_AddressBookWidgetItemLabel, Ui_AddressBookWidgetItemAddress) +from settings import Ui_settingsDialog import settingsmixin import support +import debug from helper_ackPayload import genAckPayload from helper_sql import sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure import helper_search import l10n +import openclpow from utils import str_broadcast_subscribers, avatarize from account import ( getSortedAccounts, getSortedSubscriptions, accountClass, BMAccount, @@ -43,15 +47,16 @@ from account import ( import dialogs from network.stats import pendingDownload, pendingUpload from uisignaler import UISignaler +import knownnodes import paths from proofofwork import getPowType import queues import shutdown import state from statusbar import BMStatusBar +from network.asyncore_pollchoose import set_rates import sound -# This is needed for tray icon -import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import + try: from plugins.plugin import get_plugin, get_plugins @@ -59,6 +64,49 @@ except ImportError: get_plugins = False +def change_translation(newlocale): + global qmytranslator, qsystranslator + try: + if not qmytranslator.isEmpty(): + QtGui.QApplication.removeTranslator(qmytranslator) + except: + pass + try: + if not qsystranslator.isEmpty(): + QtGui.QApplication.removeTranslator(qsystranslator) + except: + pass + + qmytranslator = QtCore.QTranslator() + translationpath = os.path.join (paths.codePath(), 'translations', 'bitmessage_' + newlocale) + qmytranslator.load(translationpath) + QtGui.QApplication.installTranslator(qmytranslator) + + qsystranslator = QtCore.QTranslator() + if paths.frozen: + translationpath = os.path.join (paths.codePath(), 'translations', 'qt_' + newlocale) + else: + translationpath = os.path.join (str(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)), 'qt_' + newlocale) + qsystranslator.load(translationpath) + QtGui.QApplication.installTranslator(qsystranslator) + + lang = locale.normalize(l10n.getTranslationLanguage()) + langs = [lang.split(".")[0] + "." + l10n.encoding, lang.split(".")[0] + "." + 'UTF-8', lang] + if 'win32' in sys.platform or 'win64' in sys.platform: + langs = [l10n.getWindowsLocale(lang)] + for lang in langs: + try: + l10n.setlocale(locale.LC_ALL, lang) + if 'win32' not in sys.platform and 'win64' not in sys.platform: + l10n.encoding = locale.nl_langinfo(locale.CODESET) + else: + l10n.encoding = locale.getlocale()[1] + logger.info("Successfully set locale to %s", lang) + break + except: + logger.error("Failed to set locale to %s", lang, exc_info=True) + + # TODO: rewrite def powQueueSize(): """Returns the size of queues.workerQueue including current unfinished work""" @@ -74,6 +122,9 @@ def powQueueSize(): class MyForm(settingsmixin.SMainWindow): + # the last time that a message arrival sound was played + lastSoundTime = datetime.now() - timedelta(days=1) + # the maximum frequency of message sounds in seconds maxSoundFrequencySec = 60 @@ -81,58 +132,6 @@ class MyForm(settingsmixin.SMainWindow): REPLY_TYPE_CHAN = 1 REPLY_TYPE_UPD = 2 - def change_translation(self, newlocale=None): - """Change translation language for the application""" - if newlocale is None: - newlocale = l10n.getTranslationLanguage() - try: - if not self.qmytranslator.isEmpty(): - QtGui.QApplication.removeTranslator(self.qmytranslator) - except: - pass - try: - if not self.qsystranslator.isEmpty(): - QtGui.QApplication.removeTranslator(self.qsystranslator) - except: - pass - - self.qmytranslator = QtCore.QTranslator() - translationpath = os.path.join( - paths.codePath(), 'translations', 'bitmessage_' + newlocale) - self.qmytranslator.load(translationpath) - QtGui.QApplication.installTranslator(self.qmytranslator) - - self.qsystranslator = QtCore.QTranslator() - if paths.frozen: - translationpath = os.path.join( - paths.codePath(), 'translations', 'qt_' + newlocale) - else: - translationpath = os.path.join( - str(QtCore.QLibraryInfo.location( - QtCore.QLibraryInfo.TranslationsPath)), 'qt_' + newlocale) - self.qsystranslator.load(translationpath) - QtGui.QApplication.installTranslator(self.qsystranslator) - - lang = locale.normalize(l10n.getTranslationLanguage()) - langs = [ - lang.split(".")[0] + "." + l10n.encoding, - lang.split(".")[0] + "." + 'UTF-8', - lang - ] - if 'win32' in sys.platform or 'win64' in sys.platform: - langs = [l10n.getWindowsLocale(lang)] - for lang in langs: - try: - l10n.setlocale(locale.LC_ALL, lang) - if 'win32' not in sys.platform and 'win64' not in sys.platform: - l10n.encoding = locale.nl_langinfo(locale.CODESET) - else: - l10n.encoding = locale.getlocale()[1] - logger.info("Successfully set locale to %s", lang) - break - except: - logger.error("Failed to set locale to %s", lang, exc_info=True) - def init_file_menu(self): QtCore.QObject.connect(self.ui.actionExit, QtCore.SIGNAL( "triggered()"), self.quit) @@ -606,13 +605,6 @@ class MyForm(settingsmixin.SMainWindow): self.ui = Ui_MainWindow() self.ui.setupUi(self) - self.qmytranslator = self.qsystranslator = None - self.indicatorUpdate = None - self.actionStatus = None - - # the last time that a message arrival sound was played - self.lastSoundTime = datetime.now() - timedelta(days=1) - # Ask the user if we may delete their old version 1 addresses if they # have any. for addressInKeysFile in getSortedAccounts(): @@ -628,13 +620,26 @@ class MyForm(settingsmixin.SMainWindow): BMConfigParser().remove_section(addressInKeysFile) BMConfigParser().save() - self.updateStartOnLogon() - - self.change_translation() + # Configure Bitmessage to start on startup (or remove the + # configuration) based on the setting in the keys.dat file + if 'win32' in sys.platform or 'win64' in sys.platform: + # Auto-startup for Windows + RUN_PATH = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" + self.settings = QtCore.QSettings(RUN_PATH, QtCore.QSettings.NativeFormat) + self.settings.remove( + "PyBitmessage") # In case the user moves the program and the registry entry is no longer valid, this will delete the old registry entry. + if BMConfigParser().getboolean('bitmessagesettings', 'startonlogon'): + self.settings.setValue("PyBitmessage", sys.argv[0]) + elif 'darwin' in sys.platform: + # startup for mac + pass + elif 'linux' in sys.platform: + # startup for linux + pass # e.g. for editing labels self.recurDepth = 0 - + # switch back to this when replying self.replyFromTab = None @@ -781,9 +786,6 @@ class MyForm(settingsmixin.SMainWindow): self.ui.treeWidgetSubscriptions.keyPressEvent = self.treeWidgetKeyPressEvent self.ui.treeWidgetChans.keyPressEvent = self.treeWidgetKeyPressEvent - # Key press in addressbook - self.ui.tableWidgetAddressBook.keyPressEvent = self.addressbookKeyPressEvent - # Key press in messagelist self.ui.tableWidgetInbox.keyPressEvent = self.tableWidgetKeyPressEvent self.ui.tableWidgetInboxSubscriptions.keyPressEvent = self.tableWidgetKeyPressEvent @@ -826,28 +828,6 @@ class MyForm(settingsmixin.SMainWindow): finally: self._contact_selected = None - def updateStartOnLogon(self): - # Configure Bitmessage to start on startup (or remove the - # configuration) based on the setting in the keys.dat file - if 'win32' in sys.platform or 'win64' in sys.platform: - # Auto-startup for Windows - RUN_PATH = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" - self.settings = QtCore.QSettings( - RUN_PATH, QtCore.QSettings.NativeFormat) - # In case the user moves the program and the registry entry is - # no longer valid, this will delete the old registry entry. - self.settings.remove("PyBitmessage") - if BMConfigParser().getboolean( - 'bitmessagesettings', 'startonlogon' - ): - self.settings.setValue("PyBitmessage", sys.argv[0]) - elif 'darwin' in sys.platform: - # startup for mac - pass - elif 'linux' in sys.platform: - # startup for linux - pass - def updateTTL(self, sliderPosition): TTL = int(sliderPosition ** 3.199 + 3600) self.updateHumanFriendlyTTLDescription(TTL) @@ -1453,15 +1433,6 @@ class MyForm(settingsmixin.SMainWindow): def treeWidgetKeyPressEvent(self, event): return self.handleKeyPress(event, self.getCurrentTreeWidget()) - # addressbook - def addressbookKeyPressEvent(self, event): - """Handle keypress event in addressbook widget""" - if event.key() == QtCore.Qt.Key_Delete: - self.on_action_AddressBookDelete() - else: - return QtGui.QTableWidget.keyPressEvent( - self.ui.tableWidgetAddressBook, event) - # inbox / sent def tableWidgetKeyPressEvent(self, event): return self.handleKeyPress(event, self.getCurrentMessagelist()) @@ -1470,12 +1441,11 @@ class MyForm(settingsmixin.SMainWindow): def textEditKeyPressEvent(self, event): return self.handleKeyPress(event, self.getCurrentMessageTextedit()) - def handleKeyPress(self, event, focus=None): - """This method handles keypress events for all widgets on MyForm""" + def handleKeyPress(self, event, focus = None): messagelist = self.getCurrentMessagelist() folder = self.getCurrentFolder() if event.key() == QtCore.Qt.Key_Delete: - if isinstance(focus, MessageView) or isinstance(focus, QtGui.QTableWidget): + if isinstance (focus, MessageView) or isinstance(focus, QtGui.QTableWidget): if folder == "sent": self.on_action_SentTrash() else: @@ -1511,17 +1481,17 @@ class MyForm(settingsmixin.SMainWindow): self.ui.lineEditTo.setFocus() event.ignore() elif event.key() == QtCore.Qt.Key_F: - searchline = self.getCurrentSearchLine(retObj=True) + searchline = self.getCurrentSearchLine(retObj = True) if searchline: searchline.setFocus() event.ignore() if not event.isAccepted(): return - if isinstance(focus, MessageView): + if isinstance (focus, MessageView): return MessageView.keyPressEvent(focus, event) - elif isinstance(focus, QtGui.QTableWidget): + elif isinstance (focus, QtGui.QTableWidget): return QtGui.QTableWidget.keyPressEvent(focus, event) - elif isinstance(focus, QtGui.QTreeWidget): + elif isinstance (focus, QtGui.QTreeWidget): return QtGui.QTreeWidget.keyPressEvent(focus, event) # menu button 'manage keys' @@ -1652,6 +1622,7 @@ class MyForm(settingsmixin.SMainWindow): # The window state has just been changed to # Normal/Maximised/FullScreen pass + # QtGui.QWidget.changeEvent(self, event) def __icon_activated(self, reason): if reason == QtGui.QSystemTrayIcon.Trigger: @@ -2463,7 +2434,225 @@ class MyForm(settingsmixin.SMainWindow): dialogs.AboutDialog(self).exec_() def click_actionSettings(self): - dialogs.SettingsDialog(self, firstrun=self._firstrun).exec_() + self.settingsDialogInstance = settingsDialog(self) + if self._firstrun: + self.settingsDialogInstance.ui.tabWidgetSettings.setCurrentIndex(1) + if self.settingsDialogInstance.exec_(): + if self._firstrun: + BMConfigParser().remove_option( + 'bitmessagesettings', 'dontconnect') + BMConfigParser().set('bitmessagesettings', 'startonlogon', str( + self.settingsDialogInstance.ui.checkBoxStartOnLogon.isChecked())) + BMConfigParser().set('bitmessagesettings', 'minimizetotray', str( + self.settingsDialogInstance.ui.checkBoxMinimizeToTray.isChecked())) + BMConfigParser().set('bitmessagesettings', 'trayonclose', str( + self.settingsDialogInstance.ui.checkBoxTrayOnClose.isChecked())) + BMConfigParser().set('bitmessagesettings', 'hidetrayconnectionnotifications', str( + self.settingsDialogInstance.ui.checkBoxHideTrayConnectionNotifications.isChecked())) + BMConfigParser().set('bitmessagesettings', 'showtraynotifications', str( + self.settingsDialogInstance.ui.checkBoxShowTrayNotifications.isChecked())) + BMConfigParser().set('bitmessagesettings', 'startintray', str( + self.settingsDialogInstance.ui.checkBoxStartInTray.isChecked())) + BMConfigParser().set('bitmessagesettings', 'willinglysendtomobile', str( + self.settingsDialogInstance.ui.checkBoxWillinglySendToMobile.isChecked())) + BMConfigParser().set('bitmessagesettings', 'useidenticons', str( + self.settingsDialogInstance.ui.checkBoxUseIdenticons.isChecked())) + BMConfigParser().set('bitmessagesettings', 'replybelow', str( + self.settingsDialogInstance.ui.checkBoxReplyBelow.isChecked())) + + lang = str(self.settingsDialogInstance.ui.languageComboBox.itemData(self.settingsDialogInstance.ui.languageComboBox.currentIndex()).toString()) + BMConfigParser().set('bitmessagesettings', 'userlocale', lang) + change_translation(l10n.getTranslationLanguage()) + + if int(BMConfigParser().get('bitmessagesettings', 'port')) != int(self.settingsDialogInstance.ui.lineEditTCPPort.text()): + if not BMConfigParser().safeGetBoolean('bitmessagesettings', 'dontconnect'): + QtGui.QMessageBox.about(self, _translate("MainWindow", "Restart"), _translate( + "MainWindow", "You must restart Bitmessage for the port number change to take effect.")) + BMConfigParser().set('bitmessagesettings', 'port', str( + self.settingsDialogInstance.ui.lineEditTCPPort.text())) + if self.settingsDialogInstance.ui.checkBoxUPnP.isChecked() != BMConfigParser().safeGetBoolean('bitmessagesettings', 'upnp'): + BMConfigParser().set('bitmessagesettings', 'upnp', str(self.settingsDialogInstance.ui.checkBoxUPnP.isChecked())) + if self.settingsDialogInstance.ui.checkBoxUPnP.isChecked(): + import upnp + upnpThread = upnp.uPnPThread() + upnpThread.start() + #print 'self.settingsDialogInstance.ui.comboBoxProxyType.currentText()', self.settingsDialogInstance.ui.comboBoxProxyType.currentText() + #print 'self.settingsDialogInstance.ui.comboBoxProxyType.currentText())[0:5]', self.settingsDialogInstance.ui.comboBoxProxyType.currentText()[0:5] + if BMConfigParser().get('bitmessagesettings', 'socksproxytype') == 'none' and self.settingsDialogInstance.ui.comboBoxProxyType.currentText()[0:5] == 'SOCKS': + if shared.statusIconColor != 'red': + QtGui.QMessageBox.about(self, _translate("MainWindow", "Restart"), _translate( + "MainWindow", "Bitmessage will use your proxy from now on but you may want to manually restart Bitmessage now to close existing connections (if any).")) + if BMConfigParser().get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and self.settingsDialogInstance.ui.comboBoxProxyType.currentText()[0:5] != 'SOCKS': + self.statusbar.clearMessage() + state.resetNetworkProtocolAvailability() # just in case we changed something in the network connectivity + if self.settingsDialogInstance.ui.comboBoxProxyType.currentText()[0:5] == 'SOCKS': + BMConfigParser().set('bitmessagesettings', 'socksproxytype', str( + self.settingsDialogInstance.ui.comboBoxProxyType.currentText())) + else: + BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none') + BMConfigParser().set('bitmessagesettings', 'socksauthentication', str( + self.settingsDialogInstance.ui.checkBoxAuthentication.isChecked())) + BMConfigParser().set('bitmessagesettings', 'sockshostname', str( + self.settingsDialogInstance.ui.lineEditSocksHostname.text())) + BMConfigParser().set('bitmessagesettings', 'socksport', str( + self.settingsDialogInstance.ui.lineEditSocksPort.text())) + BMConfigParser().set('bitmessagesettings', 'socksusername', str( + self.settingsDialogInstance.ui.lineEditSocksUsername.text())) + BMConfigParser().set('bitmessagesettings', 'sockspassword', str( + self.settingsDialogInstance.ui.lineEditSocksPassword.text())) + BMConfigParser().set('bitmessagesettings', 'sockslisten', str( + self.settingsDialogInstance.ui.checkBoxSocksListen.isChecked())) + try: + # Rounding to integers just for aesthetics + BMConfigParser().set('bitmessagesettings', 'maxdownloadrate', str( + int(float(self.settingsDialogInstance.ui.lineEditMaxDownloadRate.text())))) + BMConfigParser().set('bitmessagesettings', 'maxuploadrate', str( + int(float(self.settingsDialogInstance.ui.lineEditMaxUploadRate.text())))) + except ValueError: + QtGui.QMessageBox.about(self, _translate("MainWindow", "Number needed"), _translate( + "MainWindow", "Your maximum download and upload rate must be numbers. Ignoring what you typed.")) + else: + set_rates(BMConfigParser().safeGetInt("bitmessagesettings", "maxdownloadrate"), + BMConfigParser().safeGetInt("bitmessagesettings", "maxuploadrate")) + + BMConfigParser().set('bitmessagesettings', 'maxoutboundconnections', str( + int(float(self.settingsDialogInstance.ui.lineEditMaxOutboundConnections.text())))) + + BMConfigParser().set('bitmessagesettings', 'namecoinrpctype', + self.settingsDialogInstance.getNamecoinType()) + BMConfigParser().set('bitmessagesettings', 'namecoinrpchost', str( + self.settingsDialogInstance.ui.lineEditNamecoinHost.text())) + BMConfigParser().set('bitmessagesettings', 'namecoinrpcport', str( + self.settingsDialogInstance.ui.lineEditNamecoinPort.text())) + BMConfigParser().set('bitmessagesettings', 'namecoinrpcuser', str( + self.settingsDialogInstance.ui.lineEditNamecoinUser.text())) + BMConfigParser().set('bitmessagesettings', 'namecoinrpcpassword', str( + self.settingsDialogInstance.ui.lineEditNamecoinPassword.text())) + self.resetNamecoinConnection() + + # Demanded difficulty tab + if float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) >= 1: + BMConfigParser().set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(int(float( + self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) * defaults.networkDefaultProofOfWorkNonceTrialsPerByte))) + if float(self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text()) >= 1: + BMConfigParser().set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(int(float( + self.settingsDialogInstance.ui.lineEditSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes))) + + if self.settingsDialogInstance.ui.comboBoxOpenCL.currentText().toUtf8() != BMConfigParser().safeGet("bitmessagesettings", "opencl"): + BMConfigParser().set('bitmessagesettings', 'opencl', str(self.settingsDialogInstance.ui.comboBoxOpenCL.currentText())) + queues.workerQueue.put(('resetPoW', '')) + + acceptableDifficultyChanged = False + + if float(self.settingsDialogInstance.ui.lineEditMaxAcceptableTotalDifficulty.text()) >= 1 or float(self.settingsDialogInstance.ui.lineEditMaxAcceptableTotalDifficulty.text()) == 0: + if BMConfigParser().get('bitmessagesettings','maxacceptablenoncetrialsperbyte') != str(int(float( + self.settingsDialogInstance.ui.lineEditMaxAcceptableTotalDifficulty.text()) * defaults.networkDefaultProofOfWorkNonceTrialsPerByte)): + # the user changed the max acceptable total difficulty + acceptableDifficultyChanged = True + BMConfigParser().set('bitmessagesettings', 'maxacceptablenoncetrialsperbyte', str(int(float( + self.settingsDialogInstance.ui.lineEditMaxAcceptableTotalDifficulty.text()) * defaults.networkDefaultProofOfWorkNonceTrialsPerByte))) + if float(self.settingsDialogInstance.ui.lineEditMaxAcceptableSmallMessageDifficulty.text()) >= 1 or float(self.settingsDialogInstance.ui.lineEditMaxAcceptableSmallMessageDifficulty.text()) == 0: + if BMConfigParser().get('bitmessagesettings','maxacceptablepayloadlengthextrabytes') != str(int(float( + self.settingsDialogInstance.ui.lineEditMaxAcceptableSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes)): + # the user changed the max acceptable small message difficulty + acceptableDifficultyChanged = True + BMConfigParser().set('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', str(int(float( + self.settingsDialogInstance.ui.lineEditMaxAcceptableSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes))) + if acceptableDifficultyChanged: + # It might now be possible to send msgs which were previously marked as toodifficult. + # Let us change them to 'msgqueued'. The singleWorker will try to send them and will again + # mark them as toodifficult if the receiver's required difficulty is still higher than + # we are willing to do. + sqlExecute('''UPDATE sent SET status='msgqueued' WHERE status='toodifficult' ''') + queues.workerQueue.put(('sendmessage', '')) + + #start:UI setting to stop trying to send messages after X days/months + # I'm open to changing this UI to something else if someone has a better idea. + if ((self.settingsDialogInstance.ui.lineEditDays.text()=='') and (self.settingsDialogInstance.ui.lineEditMonths.text()=='')):#We need to handle this special case. Bitmessage has its default behavior. The input is blank/blank + BMConfigParser().set('bitmessagesettings', 'stopresendingafterxdays', '') + BMConfigParser().set('bitmessagesettings', 'stopresendingafterxmonths', '') + shared.maximumLengthOfTimeToBotherResendingMessages = float('inf') + try: + float(self.settingsDialogInstance.ui.lineEditDays.text()) + lineEditDaysIsValidFloat = True + except: + lineEditDaysIsValidFloat = False + try: + float(self.settingsDialogInstance.ui.lineEditMonths.text()) + lineEditMonthsIsValidFloat = True + except: + lineEditMonthsIsValidFloat = False + if lineEditDaysIsValidFloat and not lineEditMonthsIsValidFloat: + self.settingsDialogInstance.ui.lineEditMonths.setText("0") + if lineEditMonthsIsValidFloat and not lineEditDaysIsValidFloat: + self.settingsDialogInstance.ui.lineEditDays.setText("0") + if lineEditDaysIsValidFloat or lineEditMonthsIsValidFloat: + if (float(self.settingsDialogInstance.ui.lineEditDays.text()) >=0 and float(self.settingsDialogInstance.ui.lineEditMonths.text()) >=0): + shared.maximumLengthOfTimeToBotherResendingMessages = (float(str(self.settingsDialogInstance.ui.lineEditDays.text())) * 24 * 60 * 60) + (float(str(self.settingsDialogInstance.ui.lineEditMonths.text())) * (60 * 60 * 24 *365)/12) + if shared.maximumLengthOfTimeToBotherResendingMessages < 432000: # If the time period is less than 5 hours, we give zero values to all fields. No message will be sent again. + QtGui.QMessageBox.about(self, _translate("MainWindow", "Will not resend ever"), _translate( + "MainWindow", "Note that the time limit you entered is less than the amount of time Bitmessage waits for the first resend attempt therefore your messages will never be resent.")) + BMConfigParser().set('bitmessagesettings', 'stopresendingafterxdays', '0') + BMConfigParser().set('bitmessagesettings', 'stopresendingafterxmonths', '0') + shared.maximumLengthOfTimeToBotherResendingMessages = 0 + else: + BMConfigParser().set('bitmessagesettings', 'stopresendingafterxdays', str(float( + self.settingsDialogInstance.ui.lineEditDays.text()))) + BMConfigParser().set('bitmessagesettings', 'stopresendingafterxmonths', str(float( + self.settingsDialogInstance.ui.lineEditMonths.text()))) + + BMConfigParser().save() + + if 'win32' in sys.platform or 'win64' in sys.platform: + # Auto-startup for Windows + RUN_PATH = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" + self.settings = QtCore.QSettings(RUN_PATH, QtCore.QSettings.NativeFormat) + if BMConfigParser().getboolean('bitmessagesettings', 'startonlogon'): + self.settings.setValue("PyBitmessage", sys.argv[0]) + else: + self.settings.remove("PyBitmessage") + elif 'darwin' in sys.platform: + # startup for mac + pass + elif 'linux' in sys.platform: + # startup for linux + pass + + if state.appdata != paths.lookupExeFolder() and self.settingsDialogInstance.ui.checkBoxPortableMode.isChecked(): # If we are NOT using portable mode now but the user selected that we should... + # Write the keys.dat file to disk in the new location + sqlStoredProcedure('movemessagstoprog') + with open(paths.lookupExeFolder() + 'keys.dat', 'wb') as configfile: + BMConfigParser().write(configfile) + # Write the knownnodes.dat file to disk in the new location + knownnodes.saveKnownNodes(paths.lookupExeFolder()) + os.remove(state.appdata + 'keys.dat') + os.remove(state.appdata + 'knownnodes.dat') + previousAppdataLocation = state.appdata + state.appdata = paths.lookupExeFolder() + debug.resetLogging() + try: + os.remove(previousAppdataLocation + 'debug.log') + os.remove(previousAppdataLocation + 'debug.log.1') + except: + pass + + if state.appdata == paths.lookupExeFolder() and not self.settingsDialogInstance.ui.checkBoxPortableMode.isChecked(): # If we ARE using portable mode now but the user selected that we shouldn't... + state.appdata = paths.lookupAppdataFolder() + if not os.path.exists(state.appdata): + os.makedirs(state.appdata) + sqlStoredProcedure('movemessagstoappdata') + # Write the keys.dat file to disk in the new location + BMConfigParser().save() + # Write the knownnodes.dat file to disk in the new location + knownnodes.saveKnownNodes(state.appdata) + os.remove(paths.lookupExeFolder() + 'keys.dat') + os.remove(paths.lookupExeFolder() + 'knownnodes.dat') + debug.resetLogging() + try: + os.remove(paths.lookupExeFolder() + 'debug.log') + os.remove(paths.lookupExeFolder() + 'debug.log.1') + except: + pass def on_action_Send(self): """Send message to current selected address""" @@ -3081,8 +3270,8 @@ class MyForm(settingsmixin.SMainWindow): tableWidget.model().removeRows(r.topRow(), r.bottomRow()-r.topRow()+1) idCount = len(inventoryHashesToTrash) sqlExecuteChunked( - ("DELETE FROM inbox" if folder == "trash" or shifted else - "UPDATE inbox SET folder='trash'") + + "DELETE FROM inbox" if folder == "trash" or shifted else + "UPDATE inbox SET folder='trash'" " WHERE msgid IN ({0})", idCount, *inventoryHashesToTrash) tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1) tableWidget.setUpdatesEnabled(True) @@ -3204,7 +3393,8 @@ class MyForm(settingsmixin.SMainWindow): 0].row() item = self.ui.tableWidgetAddressBook.item(currentRow, 0) sqlExecute( - 'DELETE FROM addressbook WHERE address=?', item.address) + 'DELETE FROM addressbook WHERE label=? AND address=?', + item.label, item.address) self.ui.tableWidgetAddressBook.removeRow(currentRow) self.rerenderMessagelistFromLabels() self.rerenderMessagelistToLabels() @@ -4063,6 +4253,237 @@ class MyForm(settingsmixin.SMainWindow): obj.loadSettings() +class settingsDialog(QtGui.QDialog): + + def __init__(self, parent): + QtGui.QWidget.__init__(self, parent) + self.ui = Ui_settingsDialog() + self.ui.setupUi(self) + self.parent = parent + self.ui.checkBoxStartOnLogon.setChecked( + BMConfigParser().getboolean('bitmessagesettings', 'startonlogon')) + self.ui.checkBoxMinimizeToTray.setChecked( + BMConfigParser().getboolean('bitmessagesettings', 'minimizetotray')) + self.ui.checkBoxTrayOnClose.setChecked( + BMConfigParser().safeGetBoolean('bitmessagesettings', 'trayonclose')) + self.ui.checkBoxHideTrayConnectionNotifications.setChecked( + BMConfigParser().getboolean("bitmessagesettings", "hidetrayconnectionnotifications")) + self.ui.checkBoxShowTrayNotifications.setChecked( + BMConfigParser().getboolean('bitmessagesettings', 'showtraynotifications')) + self.ui.checkBoxStartInTray.setChecked( + BMConfigParser().getboolean('bitmessagesettings', 'startintray')) + self.ui.checkBoxWillinglySendToMobile.setChecked( + BMConfigParser().safeGetBoolean('bitmessagesettings', 'willinglysendtomobile')) + self.ui.checkBoxUseIdenticons.setChecked( + BMConfigParser().safeGetBoolean('bitmessagesettings', 'useidenticons')) + self.ui.checkBoxReplyBelow.setChecked( + BMConfigParser().safeGetBoolean('bitmessagesettings', 'replybelow')) + + if state.appdata == paths.lookupExeFolder(): + self.ui.checkBoxPortableMode.setChecked(True) + else: + try: + import tempfile + tempfile.NamedTemporaryFile( + dir=paths.lookupExeFolder(), delete=True + ).close() # should autodelete + except: + self.ui.checkBoxPortableMode.setDisabled(True) + + if 'darwin' in sys.platform: + self.ui.checkBoxStartOnLogon.setDisabled(True) + self.ui.checkBoxStartOnLogon.setText(_translate( + "MainWindow", "Start-on-login not yet supported on your OS.")) + self.ui.checkBoxMinimizeToTray.setDisabled(True) + self.ui.checkBoxMinimizeToTray.setText(_translate( + "MainWindow", "Minimize-to-tray not yet supported on your OS.")) + self.ui.checkBoxShowTrayNotifications.setDisabled(True) + self.ui.checkBoxShowTrayNotifications.setText(_translate( + "MainWindow", "Tray notifications not yet supported on your OS.")) + elif 'linux' in sys.platform: + self.ui.checkBoxStartOnLogon.setDisabled(True) + self.ui.checkBoxStartOnLogon.setText(_translate( + "MainWindow", "Start-on-login not yet supported on your OS.")) + # On the Network settings tab: + self.ui.lineEditTCPPort.setText(str( + BMConfigParser().get('bitmessagesettings', 'port'))) + self.ui.checkBoxUPnP.setChecked( + BMConfigParser().safeGetBoolean('bitmessagesettings', 'upnp')) + self.ui.checkBoxAuthentication.setChecked(BMConfigParser().getboolean( + 'bitmessagesettings', 'socksauthentication')) + self.ui.checkBoxSocksListen.setChecked(BMConfigParser().getboolean( + 'bitmessagesettings', 'sockslisten')) + if str(BMConfigParser().get('bitmessagesettings', 'socksproxytype')) == 'none': + self.ui.comboBoxProxyType.setCurrentIndex(0) + self.ui.lineEditSocksHostname.setEnabled(False) + self.ui.lineEditSocksPort.setEnabled(False) + self.ui.lineEditSocksUsername.setEnabled(False) + self.ui.lineEditSocksPassword.setEnabled(False) + self.ui.checkBoxAuthentication.setEnabled(False) + self.ui.checkBoxSocksListen.setEnabled(False) + elif str(BMConfigParser().get('bitmessagesettings', 'socksproxytype')) == 'SOCKS4a': + self.ui.comboBoxProxyType.setCurrentIndex(1) + elif str(BMConfigParser().get('bitmessagesettings', 'socksproxytype')) == 'SOCKS5': + self.ui.comboBoxProxyType.setCurrentIndex(2) + + self.ui.lineEditSocksHostname.setText(str( + BMConfigParser().get('bitmessagesettings', 'sockshostname'))) + self.ui.lineEditSocksPort.setText(str( + BMConfigParser().get('bitmessagesettings', 'socksport'))) + self.ui.lineEditSocksUsername.setText(str( + BMConfigParser().get('bitmessagesettings', 'socksusername'))) + self.ui.lineEditSocksPassword.setText(str( + BMConfigParser().get('bitmessagesettings', 'sockspassword'))) + QtCore.QObject.connect(self.ui.comboBoxProxyType, QtCore.SIGNAL( + "currentIndexChanged(int)"), self.comboBoxProxyTypeChanged) + self.ui.lineEditMaxDownloadRate.setText(str( + BMConfigParser().get('bitmessagesettings', 'maxdownloadrate'))) + self.ui.lineEditMaxUploadRate.setText(str( + BMConfigParser().get('bitmessagesettings', 'maxuploadrate'))) + self.ui.lineEditMaxOutboundConnections.setText(str( + BMConfigParser().get('bitmessagesettings', 'maxoutboundconnections'))) + + # Demanded difficulty tab + self.ui.lineEditTotalDifficulty.setText(str((float(BMConfigParser().getint( + 'bitmessagesettings', 'defaultnoncetrialsperbyte')) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte))) + self.ui.lineEditSmallMessageDifficulty.setText(str((float(BMConfigParser().getint( + 'bitmessagesettings', 'defaultpayloadlengthextrabytes')) / defaults.networkDefaultPayloadLengthExtraBytes))) + + # Max acceptable difficulty tab + self.ui.lineEditMaxAcceptableTotalDifficulty.setText(str((float(BMConfigParser().getint( + 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte')) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte))) + self.ui.lineEditMaxAcceptableSmallMessageDifficulty.setText(str((float(BMConfigParser().getint( + 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / defaults.networkDefaultPayloadLengthExtraBytes))) + + # OpenCL + if openclpow.openclAvailable(): + self.ui.comboBoxOpenCL.setEnabled(True) + else: + self.ui.comboBoxOpenCL.setEnabled(False) + self.ui.comboBoxOpenCL.clear() + self.ui.comboBoxOpenCL.addItem("None") + self.ui.comboBoxOpenCL.addItems(openclpow.vendors) + self.ui.comboBoxOpenCL.setCurrentIndex(0) + for i in range(self.ui.comboBoxOpenCL.count()): + if self.ui.comboBoxOpenCL.itemText(i) == BMConfigParser().safeGet('bitmessagesettings', 'opencl'): + self.ui.comboBoxOpenCL.setCurrentIndex(i) + break + + # Namecoin integration tab + nmctype = BMConfigParser().get('bitmessagesettings', 'namecoinrpctype') + self.ui.lineEditNamecoinHost.setText(str( + BMConfigParser().get('bitmessagesettings', 'namecoinrpchost'))) + self.ui.lineEditNamecoinPort.setText(str( + BMConfigParser().get('bitmessagesettings', 'namecoinrpcport'))) + self.ui.lineEditNamecoinUser.setText(str( + BMConfigParser().get('bitmessagesettings', 'namecoinrpcuser'))) + self.ui.lineEditNamecoinPassword.setText(str( + BMConfigParser().get('bitmessagesettings', 'namecoinrpcpassword'))) + + if nmctype == "namecoind": + self.ui.radioButtonNamecoinNamecoind.setChecked(True) + elif nmctype == "nmcontrol": + self.ui.radioButtonNamecoinNmcontrol.setChecked(True) + self.ui.lineEditNamecoinUser.setEnabled(False) + self.ui.labelNamecoinUser.setEnabled(False) + self.ui.lineEditNamecoinPassword.setEnabled(False) + self.ui.labelNamecoinPassword.setEnabled(False) + else: + assert False + + QtCore.QObject.connect(self.ui.radioButtonNamecoinNamecoind, QtCore.SIGNAL( + "toggled(bool)"), self.namecoinTypeChanged) + QtCore.QObject.connect(self.ui.radioButtonNamecoinNmcontrol, QtCore.SIGNAL( + "toggled(bool)"), self.namecoinTypeChanged) + QtCore.QObject.connect(self.ui.pushButtonNamecoinTest, QtCore.SIGNAL( + "clicked()"), self.click_pushButtonNamecoinTest) + + #Message Resend tab + self.ui.lineEditDays.setText(str( + BMConfigParser().get('bitmessagesettings', 'stopresendingafterxdays'))) + self.ui.lineEditMonths.setText(str( + BMConfigParser().get('bitmessagesettings', 'stopresendingafterxmonths'))) + + + #'System' tab removed for now. + """try: + maxCores = BMConfigParser().getint('bitmessagesettings', 'maxcores') + except: + maxCores = 99999 + if maxCores <= 1: + self.ui.comboBoxMaxCores.setCurrentIndex(0) + elif maxCores == 2: + self.ui.comboBoxMaxCores.setCurrentIndex(1) + elif maxCores <= 4: + self.ui.comboBoxMaxCores.setCurrentIndex(2) + elif maxCores <= 8: + self.ui.comboBoxMaxCores.setCurrentIndex(3) + elif maxCores <= 16: + self.ui.comboBoxMaxCores.setCurrentIndex(4) + else: + self.ui.comboBoxMaxCores.setCurrentIndex(5)""" + + QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + + def comboBoxProxyTypeChanged(self, comboBoxIndex): + if comboBoxIndex == 0: + self.ui.lineEditSocksHostname.setEnabled(False) + self.ui.lineEditSocksPort.setEnabled(False) + self.ui.lineEditSocksUsername.setEnabled(False) + self.ui.lineEditSocksPassword.setEnabled(False) + self.ui.checkBoxAuthentication.setEnabled(False) + self.ui.checkBoxSocksListen.setEnabled(False) + elif comboBoxIndex == 1 or comboBoxIndex == 2: + self.ui.lineEditSocksHostname.setEnabled(True) + self.ui.lineEditSocksPort.setEnabled(True) + self.ui.checkBoxAuthentication.setEnabled(True) + self.ui.checkBoxSocksListen.setEnabled(True) + if self.ui.checkBoxAuthentication.isChecked(): + self.ui.lineEditSocksUsername.setEnabled(True) + self.ui.lineEditSocksPassword.setEnabled(True) + + # Check status of namecoin integration radio buttons and translate + # it to a string as in the options. + def getNamecoinType(self): + if self.ui.radioButtonNamecoinNamecoind.isChecked(): + return "namecoind" + if self.ui.radioButtonNamecoinNmcontrol.isChecked(): + return "nmcontrol" + assert False + + # Namecoin connection type was changed. + def namecoinTypeChanged(self, checked): + nmctype = self.getNamecoinType() + assert nmctype == "namecoind" or nmctype == "nmcontrol" + + isNamecoind = (nmctype == "namecoind") + self.ui.lineEditNamecoinUser.setEnabled(isNamecoind) + self.ui.labelNamecoinUser.setEnabled(isNamecoind) + self.ui.lineEditNamecoinPassword.setEnabled(isNamecoind) + self.ui.labelNamecoinPassword.setEnabled(isNamecoind) + + if isNamecoind: + self.ui.lineEditNamecoinPort.setText(defaults.namecoinDefaultRpcPort) + else: + self.ui.lineEditNamecoinPort.setText("9000") + + def click_pushButtonNamecoinTest(self): + """Test the namecoin settings specified in the settings dialog.""" + self.ui.labelNamecoinTestResult.setText(_translate( + "MainWindow", "Testing...")) + options = {} + options["type"] = self.getNamecoinType() + options["host"] = str(self.ui.lineEditNamecoinHost.text().toUtf8()) + options["port"] = str(self.ui.lineEditNamecoinPort.text().toUtf8()) + options["user"] = str(self.ui.lineEditNamecoinUser.text().toUtf8()) + options["password"] = str(self.ui.lineEditNamecoinPassword.text().toUtf8()) + nc = namecoin.namecoinConnection(options) + status, text = nc.test() + self.ui.labelNamecoinTestResult.setText(text) + if status == 'success': + self.parent.namecoin = nc + + # In order for the time columns on the Inbox and Sent tabs to be sorted # correctly (rather than alphabetically), we need to overload the < # operator and use this class instead of QTableWidgetItem. @@ -4137,6 +4558,7 @@ def init(): def run(): global myapp app = init() + change_translation(l10n.getTranslationLanguage()) app.setStyleSheet("QStatusBar::item { border: 0px solid black }") myapp = MyForm() diff --git a/src/bitmessageqt/about.ui b/src/bitmessageqt/about.ui index 7073bbd1..a912927a 100644 --- a/src/bitmessageqt/about.ui +++ b/src/bitmessageqt/about.ui @@ -46,7 +46,7 @@ - <html><head/><body><p>Copyright © 2012-2016 Jonathan Warren<br/>Copyright © 2012-2020 The Bitmessage Developers</p></body></html> + <html><head/><body><p>Copyright © 2012-2016 Jonathan Warren<br/>Copyright © 2012-2019 The Bitmessage Developers</p></body></html> Qt::AlignLeft diff --git a/src/bitmessageqt/dialogs.py b/src/bitmessageqt/dialogs.py index c667edb1..1acdbc3f 100644 --- a/src/bitmessageqt/dialogs.py +++ b/src/bitmessageqt/dialogs.py @@ -5,25 +5,22 @@ src/bitmessageqt/dialogs.py from PyQt4 import QtGui +from version import softwareVersion + import paths import widgets from address_dialogs import ( - AddAddressDialog, EmailGatewayDialog, NewAddressDialog, - NewSubscriptionDialog, RegenerateAddressesDialog, + AddAddressDialog, EmailGatewayDialog, NewAddressDialog, NewSubscriptionDialog, RegenerateAddressesDialog, SpecialAddressBehaviorDialog ) from newchandialog import NewChanDialog from retranslateui import RetranslateMixin -from settings import SettingsDialog from tr import _translate -from version import softwareVersion - __all__ = [ "NewChanDialog", "AddAddressDialog", "NewAddressDialog", "NewSubscriptionDialog", "RegenerateAddressesDialog", - "SpecialAddressBehaviorDialog", "EmailGatewayDialog", - "SettingsDialog" + "SpecialAddressBehaviorDialog", "EmailGatewayDialog" ] @@ -47,7 +44,7 @@ class AboutDialog(QtGui.QDialog, RetranslateMixin): try: self.label_2.setText( self.label_2.text().replace( - '2020', str(last_commit.get('time').year) + '2019', str(last_commit.get('time').year) )) except AttributeError: pass diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index 6fbf5df6..5f014563 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -14,7 +14,7 @@ import network.stats import shared import widgets from inventory import Inventory -from network import BMConnectionPool +from network.connectionpool import BMConnectionPool from retranslateui import RetranslateMixin from tr import _translate from uisignaler import UISignaler diff --git a/src/bitmessageqt/safehtmlparser.py b/src/bitmessageqt/safehtmlparser.py index edacd4bb..d1d7910c 100644 --- a/src/bitmessageqt/safehtmlparser.py +++ b/src/bitmessageqt/safehtmlparser.py @@ -1,73 +1,51 @@ -"""Subclass of HTMLParser.HTMLParser for MessageView widget""" - +from HTMLParser import HTMLParser import inspect import re -from HTMLParser import HTMLParser - -from urllib import quote_plus +from urllib import quote, quote_plus from urlparse import urlparse - class SafeHTMLParser(HTMLParser): - """HTML parser with sanitisation""" # from html5lib.sanitiser - acceptable_elements = ( - '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', 'header', 'h1', - 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', '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' - ) - replaces_pre = ( - ("&", "&"), ("\"", """), ("<", "<"), (">", ">")) - replaces_post = ( - ("\n", "
"), ("\t", "    "), - (" ", "  "), (" ", "  "), ("
", "
 ")) - src_schemes = ["data"] - # uriregex1 = re.compile( - # r'(?i)\b((?:(https?|ftp|bitcoin):(?:/{1,3}|[a-z0-9%])' - # r'|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)' - # r'(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))' - # r'+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?]))') - uriregex1 = re.compile( - r'((https?|ftp|bitcoin):(?:/{1,3}|[a-z0-9%])' - r'(?:[a-zA-Z]|[0-9]|[$-_@.&+#]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)' - ) + acceptable_elements = ['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', 'header', 'h1', + 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', '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'] + replaces_pre = [["&", "&"], ["\"", """], ["<", "<"], [">", ">"]] + replaces_post = [["\n", "
"], ["\t", "    "], [" ", "  "], [" ", "  "], ["
", "
 "]] + src_schemes = [ "data" ] + #uriregex1 = re.compile(r'(?i)\b((?:(https?|ftp|bitcoin):(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?]))') + uriregex1 = re.compile(r'((https?|ftp|bitcoin):(?:/{1,3}|[a-z0-9%])(?:[a-zA-Z]|[0-9]|[$-_@.&+#]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)') uriregex2 = re.compile(r' 1 and text[0] == " ": text = " " + text[1:] return text def __init__(self, *args, **kwargs): HTMLParser.__init__(self, *args, **kwargs) - self.reset() self.reset_safe() - + def reset_safe(self): - """Reset runtime variables specific to this class""" self.elements = set() self.raw = u"" self.sanitised = u"" @@ -75,9 +53,8 @@ class SafeHTMLParser(HTMLParser): self.allow_picture = False self.allow_external_src = False - def add_if_acceptable(self, tag, attrs=None): - """Add tag if it passes sanitisation""" - if tag not in self.acceptable_elements: + def add_if_acceptable(self, tag, attrs = None): + if tag not in SafeHTMLParser.acceptable_elements: return self.sanitised += "<" if inspect.stack()[1][3] == "handle_endtag": @@ -89,7 +66,7 @@ class SafeHTMLParser(HTMLParser): val = "" elif attr == "src" and not self.allow_external_src: url = urlparse(val) - if url.scheme not in self.src_schemes: + if url.scheme not in SafeHTMLParser.src_schemes: val = "" self.sanitised += " " + quote_plus(attr) if not (val is None): @@ -97,26 +74,26 @@ class SafeHTMLParser(HTMLParser): if inspect.stack()[1][3] == "handle_startendtag": self.sanitised += "/" self.sanitised += ">" - + def handle_starttag(self, tag, attrs): - if tag in self.acceptable_elements: + if tag in SafeHTMLParser.acceptable_elements: self.has_html = True self.add_if_acceptable(tag, attrs) def handle_endtag(self, tag): self.add_if_acceptable(tag) - + def handle_startendtag(self, tag, attrs): - if tag in self.acceptable_elements: + if tag in SafeHTMLParser.acceptable_elements: self.has_html = True self.add_if_acceptable(tag, attrs) - + def handle_data(self, data): self.sanitised += data - + def handle_charref(self, name): self.sanitised += "&#" + name + ";" - + def handle_entityref(self, name): self.sanitised += "&" + name + ";" @@ -127,14 +104,15 @@ class SafeHTMLParser(HTMLParser): data = unicode(data, 'utf-8', errors='replace') HTMLParser.feed(self, data) tmp = SafeHTMLParser.replace_pre(data) - tmp = self.uriregex1.sub(r'\1', tmp) - tmp = self.uriregex2.sub(r'\1', tmp) + tmp = SafeHTMLParser.uriregex1.sub( + r'\1', + tmp) + tmp = SafeHTMLParser.uriregex2.sub(r'\1', tmp) tmp = SafeHTMLParser.replace_post(tmp) self.raw += tmp - def is_html(self, text=None, allow_picture=False): - """Detect if string contains HTML tags""" + def is_html(self, text = None, allow_picture = False): if text: self.reset() self.reset_safe() diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 011d38ed..3a3db962 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -1,581 +1,630 @@ -import ConfigParser -import os -import sys +# -*- coding: utf-8 -*- +# pylint: disable=too-many-instance-attributes,too-many-locals,too-many-statements,attribute-defined-outside-init +""" +src/bitmessageqt/settings.py +============================ + +Form implementation generated from reading ui file 'settings.ui' + +Created: Thu Dec 25 23:21:20 2014 + by: PyQt4 UI code generator 4.10.3 + +WARNING! All changes made in this file will be lost! +""" + +from sys import platform from PyQt4 import QtCore, QtGui -import debug -import defaults -import knownnodes -import namecoin -import openclpow -import paths -import queues -import shared -import state -import tempfile -import widgets -from bmconfigparser import BMConfigParser -from helper_sql import sqlExecute, sqlStoredProcedure -from helper_startup import start_proxyconfig -from network.asyncore_pollchoose import set_rates -from tr import _translate +from . import bitmessage_icons_rc # pylint: disable=unused-import +from .languagebox import LanguageBox + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) -def getSOCKSProxyType(config): - """Get user socksproxytype setting from *config*""" - try: - result = ConfigParser.SafeConfigParser.get( - config, 'bitmessagesettings', 'socksproxytype') - except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): - return - else: - if result.lower() in ('', 'none', 'false'): - result = None - return result +class Ui_settingsDialog(object): + """Encapsulate a UI settings dialog object""" + def setupUi(self, settingsDialog): + """Set up the UI""" -class SettingsDialog(QtGui.QDialog): - """The "Settings" dialog""" - def __init__(self, parent=None, firstrun=False): - super(SettingsDialog, self).__init__(parent) - widgets.load('settings.ui', self) - - self.parent = parent - self.firstrun = firstrun - self.config = BMConfigParser() - self.net_restart_needed = False - self.timer = QtCore.QTimer() - - try: - import pkg_resources - except ImportError: - pass - else: - # Append proxy types defined in plugins - for ep in pkg_resources.iter_entry_points( - 'bitmessage.proxyconfig'): - self.comboBoxProxyType.addItem(ep.name) - + settingsDialog.setObjectName(_fromUtf8("settingsDialog")) + settingsDialog.resize(521, 413) + self.gridLayout = QtGui.QGridLayout(settingsDialog) + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.buttonBox = QtGui.QDialogButtonBox(settingsDialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName(_fromUtf8("buttonBox")) + self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1) + self.tabWidgetSettings = QtGui.QTabWidget(settingsDialog) + self.tabWidgetSettings.setObjectName(_fromUtf8("tabWidgetSettings")) + self.tabUserInterface = QtGui.QWidget() + self.tabUserInterface.setEnabled(True) + self.tabUserInterface.setObjectName(_fromUtf8("tabUserInterface")) + self.formLayout = QtGui.QFormLayout(self.tabUserInterface) + self.formLayout.setObjectName(_fromUtf8("formLayout")) + self.checkBoxStartOnLogon = QtGui.QCheckBox(self.tabUserInterface) + self.checkBoxStartOnLogon.setObjectName(_fromUtf8("checkBoxStartOnLogon")) + self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.checkBoxStartOnLogon) + self.groupBoxTray = QtGui.QGroupBox(self.tabUserInterface) + self.groupBoxTray.setObjectName(_fromUtf8("groupBoxTray")) + self.formLayoutTray = QtGui.QFormLayout(self.groupBoxTray) + self.formLayoutTray.setObjectName(_fromUtf8("formLayoutTray")) + self.checkBoxStartInTray = QtGui.QCheckBox(self.groupBoxTray) + self.checkBoxStartInTray.setObjectName(_fromUtf8("checkBoxStartInTray")) + self.formLayoutTray.setWidget(0, QtGui.QFormLayout.SpanningRole, self.checkBoxStartInTray) + self.checkBoxMinimizeToTray = QtGui.QCheckBox(self.groupBoxTray) + self.checkBoxMinimizeToTray.setChecked(True) + self.checkBoxMinimizeToTray.setObjectName(_fromUtf8("checkBoxMinimizeToTray")) + self.formLayoutTray.setWidget(1, QtGui.QFormLayout.LabelRole, self.checkBoxMinimizeToTray) + self.checkBoxTrayOnClose = QtGui.QCheckBox(self.groupBoxTray) + self.checkBoxTrayOnClose.setChecked(True) + self.checkBoxTrayOnClose.setObjectName(_fromUtf8("checkBoxTrayOnClose")) + self.formLayoutTray.setWidget(2, QtGui.QFormLayout.LabelRole, self.checkBoxTrayOnClose) + self.formLayout.setWidget(1, QtGui.QFormLayout.SpanningRole, self.groupBoxTray) + self.checkBoxHideTrayConnectionNotifications = QtGui.QCheckBox(self.tabUserInterface) + self.checkBoxHideTrayConnectionNotifications.setChecked(False) + self.checkBoxHideTrayConnectionNotifications.setObjectName( + _fromUtf8("checkBoxHideTrayConnectionNotifications")) + self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.checkBoxHideTrayConnectionNotifications) + self.checkBoxShowTrayNotifications = QtGui.QCheckBox(self.tabUserInterface) + self.checkBoxShowTrayNotifications.setObjectName(_fromUtf8("checkBoxShowTrayNotifications")) + self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.checkBoxShowTrayNotifications) + self.checkBoxPortableMode = QtGui.QCheckBox(self.tabUserInterface) + self.checkBoxPortableMode.setObjectName(_fromUtf8("checkBoxPortableMode")) + self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.checkBoxPortableMode) + self.PortableModeDescription = QtGui.QLabel(self.tabUserInterface) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.PortableModeDescription.sizePolicy().hasHeightForWidth()) + self.PortableModeDescription.setSizePolicy(sizePolicy) + self.PortableModeDescription.setWordWrap(True) + self.PortableModeDescription.setObjectName(_fromUtf8("PortableModeDescription")) + self.formLayout.setWidget(5, QtGui.QFormLayout.SpanningRole, self.PortableModeDescription) + self.checkBoxWillinglySendToMobile = QtGui.QCheckBox(self.tabUserInterface) + self.checkBoxWillinglySendToMobile.setObjectName(_fromUtf8("checkBoxWillinglySendToMobile")) + self.formLayout.setWidget(6, QtGui.QFormLayout.SpanningRole, self.checkBoxWillinglySendToMobile) + self.checkBoxUseIdenticons = QtGui.QCheckBox(self.tabUserInterface) + self.checkBoxUseIdenticons.setObjectName(_fromUtf8("checkBoxUseIdenticons")) + self.formLayout.setWidget(7, QtGui.QFormLayout.LabelRole, self.checkBoxUseIdenticons) + self.checkBoxReplyBelow = QtGui.QCheckBox(self.tabUserInterface) + self.checkBoxReplyBelow.setObjectName(_fromUtf8("checkBoxReplyBelow")) + self.formLayout.setWidget(8, QtGui.QFormLayout.LabelRole, self.checkBoxReplyBelow) + self.groupBox = QtGui.QGroupBox(self.tabUserInterface) + self.groupBox.setObjectName(_fromUtf8("groupBox")) + self.formLayout_2 = QtGui.QFormLayout(self.groupBox) + self.formLayout_2.setObjectName(_fromUtf8("formLayout_2")) + self.languageComboBox = LanguageBox(self.groupBox) + self.languageComboBox.setMinimumSize(QtCore.QSize(100, 0)) + self.languageComboBox.setObjectName(_fromUtf8("languageComboBox")) # pylint: disable=not-callable + self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.languageComboBox) + self.formLayout.setWidget(9, QtGui.QFormLayout.FieldRole, self.groupBox) + self.tabWidgetSettings.addTab(self.tabUserInterface, _fromUtf8("")) + self.tabNetworkSettings = QtGui.QWidget() + self.tabNetworkSettings.setObjectName(_fromUtf8("tabNetworkSettings")) + self.gridLayout_4 = QtGui.QGridLayout(self.tabNetworkSettings) + self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4")) + self.groupBox1 = QtGui.QGroupBox(self.tabNetworkSettings) + self.groupBox1.setObjectName(_fromUtf8("groupBox1")) + self.gridLayout_3 = QtGui.QGridLayout(self.groupBox1) + self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) + self.label = QtGui.QLabel(self.groupBox1) + self.label.setObjectName(_fromUtf8("label")) + self.gridLayout_3.addWidget(self.label, 0, 0, 1, 1, QtCore.Qt.AlignRight) + self.lineEditTCPPort = QtGui.QLineEdit(self.groupBox1) + self.lineEditTCPPort.setMaximumSize(QtCore.QSize(70, 16777215)) + self.lineEditTCPPort.setObjectName(_fromUtf8("lineEditTCPPort")) + self.gridLayout_3.addWidget(self.lineEditTCPPort, 0, 1, 1, 1, QtCore.Qt.AlignLeft) + self.labelUPnP = QtGui.QLabel(self.groupBox1) + self.labelUPnP.setObjectName(_fromUtf8("labelUPnP")) + self.gridLayout_3.addWidget(self.labelUPnP, 0, 2, 1, 1, QtCore.Qt.AlignRight) + self.checkBoxUPnP = QtGui.QCheckBox(self.groupBox1) + self.checkBoxUPnP.setObjectName(_fromUtf8("checkBoxUPnP")) + self.gridLayout_3.addWidget(self.checkBoxUPnP, 0, 3, 1, 1, QtCore.Qt.AlignLeft) + self.gridLayout_4.addWidget(self.groupBox1, 0, 0, 1, 1) + self.groupBox_3 = QtGui.QGroupBox(self.tabNetworkSettings) + self.groupBox_3.setObjectName(_fromUtf8("groupBox_3")) + self.gridLayout_9 = QtGui.QGridLayout(self.groupBox_3) + self.gridLayout_9.setObjectName(_fromUtf8("gridLayout_9")) + spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_9.addItem(spacerItem1, 0, 0, 2, 1) + self.label_24 = QtGui.QLabel(self.groupBox_3) + self.label_24.setObjectName(_fromUtf8("label_24")) + self.gridLayout_9.addWidget(self.label_24, 0, 1, 1, 1) + self.lineEditMaxDownloadRate = QtGui.QLineEdit(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.lineEditMaxDownloadRate.sizePolicy().hasHeightForWidth()) + self.lineEditMaxDownloadRate.setSizePolicy(sizePolicy) + self.lineEditMaxDownloadRate.setMaximumSize(QtCore.QSize(60, 16777215)) + self.lineEditMaxDownloadRate.setObjectName(_fromUtf8("lineEditMaxDownloadRate")) + self.gridLayout_9.addWidget(self.lineEditMaxDownloadRate, 0, 2, 1, 1) + self.label_25 = QtGui.QLabel(self.groupBox_3) + self.label_25.setObjectName(_fromUtf8("label_25")) + self.gridLayout_9.addWidget(self.label_25, 1, 1, 1, 1) + self.lineEditMaxUploadRate = QtGui.QLineEdit(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.lineEditMaxUploadRate.sizePolicy().hasHeightForWidth()) + self.lineEditMaxUploadRate.setSizePolicy(sizePolicy) + self.lineEditMaxUploadRate.setMaximumSize(QtCore.QSize(60, 16777215)) + self.lineEditMaxUploadRate.setObjectName(_fromUtf8("lineEditMaxUploadRate")) + self.gridLayout_9.addWidget(self.lineEditMaxUploadRate, 1, 2, 1, 1) + self.label_26 = QtGui.QLabel(self.groupBox_3) + self.label_26.setObjectName(_fromUtf8("label_26")) + self.gridLayout_9.addWidget(self.label_26, 2, 1, 1, 1) + self.lineEditMaxOutboundConnections = QtGui.QLineEdit(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.lineEditMaxOutboundConnections.sizePolicy().hasHeightForWidth()) + self.lineEditMaxOutboundConnections.setSizePolicy(sizePolicy) + self.lineEditMaxOutboundConnections.setMaximumSize(QtCore.QSize(60, 16777215)) + self.lineEditMaxOutboundConnections.setObjectName(_fromUtf8("lineEditMaxOutboundConnections")) self.lineEditMaxOutboundConnections.setValidator( QtGui.QIntValidator(0, 8, self.lineEditMaxOutboundConnections)) - - self.adjust_from_config(self.config) - if firstrun: - # switch to "Network Settings" tab if user selected - # "Let me configure special network settings first" on first run - self.tabWidgetSettings.setCurrentIndex( - self.tabWidgetSettings.indexOf(self.tabNetworkSettings) - ) - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) - - def adjust_from_config(self, config): - """Adjust all widgets state according to config settings""" - # pylint: disable=too-many-branches,too-many-statements - if not self.parent.tray.isSystemTrayAvailable(): - self.groupBoxTray.setEnabled(False) - self.groupBoxTray.setTitle(_translate( - "MainWindow", "Tray (not available in your system)")) - for setting in ( - 'minimizetotray', 'trayonclose', 'startintray'): - config.set('bitmessagesettings', setting, 'false') + self.gridLayout_9.addWidget(self.lineEditMaxOutboundConnections, 2, 2, 1, 1) + self.gridLayout_4.addWidget(self.groupBox_3, 2, 0, 1, 1) + self.groupBox_2 = QtGui.QGroupBox(self.tabNetworkSettings) + self.groupBox_2.setObjectName(_fromUtf8("groupBox_2")) + self.gridLayout_2 = QtGui.QGridLayout(self.groupBox_2) + self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) + self.label_2 = QtGui.QLabel(self.groupBox_2) + self.label_2.setObjectName(_fromUtf8("label_2")) + self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1) + self.label_3 = QtGui.QLabel(self.groupBox_2) + self.label_3.setObjectName(_fromUtf8("label_3")) + self.gridLayout_2.addWidget(self.label_3, 1, 1, 1, 1) + self.lineEditSocksHostname = QtGui.QLineEdit(self.groupBox_2) + self.lineEditSocksHostname.setObjectName(_fromUtf8("lineEditSocksHostname")) + self.lineEditSocksHostname.setPlaceholderText(_fromUtf8("127.0.0.1")) + self.gridLayout_2.addWidget(self.lineEditSocksHostname, 1, 2, 1, 2) + self.label_4 = QtGui.QLabel(self.groupBox_2) + self.label_4.setObjectName(_fromUtf8("label_4")) + self.gridLayout_2.addWidget(self.label_4, 1, 4, 1, 1) + self.lineEditSocksPort = QtGui.QLineEdit(self.groupBox_2) + self.lineEditSocksPort.setObjectName(_fromUtf8("lineEditSocksPort")) + if platform in ['darwin', 'win32', 'win64']: + self.lineEditSocksPort.setPlaceholderText(_fromUtf8("9150")) else: - self.checkBoxMinimizeToTray.setChecked( - config.getboolean('bitmessagesettings', 'minimizetotray')) - self.checkBoxTrayOnClose.setChecked( - config.safeGetBoolean('bitmessagesettings', 'trayonclose')) - self.checkBoxStartInTray.setChecked( - config.getboolean('bitmessagesettings', 'startintray')) + self.lineEditSocksPort.setPlaceholderText(_fromUtf8("9050")) + self.gridLayout_2.addWidget(self.lineEditSocksPort, 1, 5, 1, 1) + self.checkBoxAuthentication = QtGui.QCheckBox(self.groupBox_2) + self.checkBoxAuthentication.setObjectName(_fromUtf8("checkBoxAuthentication")) + self.gridLayout_2.addWidget(self.checkBoxAuthentication, 2, 1, 1, 1) + self.label_5 = QtGui.QLabel(self.groupBox_2) + self.label_5.setObjectName(_fromUtf8("label_5")) + self.gridLayout_2.addWidget(self.label_5, 2, 2, 1, 1) + self.lineEditSocksUsername = QtGui.QLineEdit(self.groupBox_2) + self.lineEditSocksUsername.setEnabled(False) + self.lineEditSocksUsername.setObjectName(_fromUtf8("lineEditSocksUsername")) + self.gridLayout_2.addWidget(self.lineEditSocksUsername, 2, 3, 1, 1) + self.label_6 = QtGui.QLabel(self.groupBox_2) + self.label_6.setObjectName(_fromUtf8("label_6")) + self.gridLayout_2.addWidget(self.label_6, 2, 4, 1, 1) + self.lineEditSocksPassword = QtGui.QLineEdit(self.groupBox_2) + self.lineEditSocksPassword.setEnabled(False) + self.lineEditSocksPassword.setInputMethodHints( + QtCore.Qt.ImhHiddenText | QtCore.Qt.ImhNoAutoUppercase | QtCore.Qt.ImhNoPredictiveText) + self.lineEditSocksPassword.setEchoMode(QtGui.QLineEdit.Password) + self.lineEditSocksPassword.setObjectName(_fromUtf8("lineEditSocksPassword")) + self.gridLayout_2.addWidget(self.lineEditSocksPassword, 2, 5, 1, 1) + self.checkBoxSocksListen = QtGui.QCheckBox(self.groupBox_2) + self.checkBoxSocksListen.setObjectName(_fromUtf8("checkBoxSocksListen")) + self.gridLayout_2.addWidget(self.checkBoxSocksListen, 3, 1, 1, 4) + self.comboBoxProxyType = QtGui.QComboBox(self.groupBox_2) + self.comboBoxProxyType.setObjectName(_fromUtf8("comboBoxProxyType")) # pylint: disable=not-callable + self.comboBoxProxyType.addItem(_fromUtf8("")) + self.comboBoxProxyType.addItem(_fromUtf8("")) + self.comboBoxProxyType.addItem(_fromUtf8("")) + self.gridLayout_2.addWidget(self.comboBoxProxyType, 0, 1, 1, 1) + self.gridLayout_4.addWidget(self.groupBox_2, 1, 0, 1, 1) + spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.gridLayout_4.addItem(spacerItem2, 3, 0, 1, 1) + self.tabWidgetSettings.addTab(self.tabNetworkSettings, _fromUtf8("")) + self.tabDemandedDifficulty = QtGui.QWidget() + self.tabDemandedDifficulty.setObjectName(_fromUtf8("tabDemandedDifficulty")) + self.gridLayout_6 = QtGui.QGridLayout(self.tabDemandedDifficulty) + self.gridLayout_6.setObjectName(_fromUtf8("gridLayout_6")) + self.label_9 = QtGui.QLabel(self.tabDemandedDifficulty) + self.label_9.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.label_9.setObjectName(_fromUtf8("label_9")) + self.gridLayout_6.addWidget(self.label_9, 1, 1, 1, 1) + self.label_10 = QtGui.QLabel(self.tabDemandedDifficulty) + self.label_10.setWordWrap(True) + self.label_10.setObjectName(_fromUtf8("label_10")) + self.gridLayout_6.addWidget(self.label_10, 2, 0, 1, 3) + self.label_11 = QtGui.QLabel(self.tabDemandedDifficulty) + self.label_11.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.label_11.setObjectName(_fromUtf8("label_11")) + self.gridLayout_6.addWidget(self.label_11, 3, 1, 1, 1) + self.label_8 = QtGui.QLabel(self.tabDemandedDifficulty) + self.label_8.setWordWrap(True) + self.label_8.setObjectName(_fromUtf8("label_8")) + self.gridLayout_6.addWidget(self.label_8, 0, 0, 1, 3) + spacerItem3 = QtGui.QSpacerItem(203, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_6.addItem(spacerItem3, 1, 0, 1, 1) + self.label_12 = QtGui.QLabel(self.tabDemandedDifficulty) + self.label_12.setWordWrap(True) + self.label_12.setObjectName(_fromUtf8("label_12")) + self.gridLayout_6.addWidget(self.label_12, 4, 0, 1, 3) + self.lineEditSmallMessageDifficulty = QtGui.QLineEdit(self.tabDemandedDifficulty) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.lineEditSmallMessageDifficulty.sizePolicy().hasHeightForWidth()) + self.lineEditSmallMessageDifficulty.setSizePolicy(sizePolicy) + self.lineEditSmallMessageDifficulty.setMaximumSize(QtCore.QSize(70, 16777215)) + self.lineEditSmallMessageDifficulty.setObjectName(_fromUtf8("lineEditSmallMessageDifficulty")) + self.gridLayout_6.addWidget(self.lineEditSmallMessageDifficulty, 3, 2, 1, 1) + self.lineEditTotalDifficulty = QtGui.QLineEdit(self.tabDemandedDifficulty) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.lineEditTotalDifficulty.sizePolicy().hasHeightForWidth()) + self.lineEditTotalDifficulty.setSizePolicy(sizePolicy) + self.lineEditTotalDifficulty.setMaximumSize(QtCore.QSize(70, 16777215)) + self.lineEditTotalDifficulty.setObjectName(_fromUtf8("lineEditTotalDifficulty")) + self.gridLayout_6.addWidget(self.lineEditTotalDifficulty, 1, 2, 1, 1) + spacerItem4 = QtGui.QSpacerItem(203, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_6.addItem(spacerItem4, 3, 0, 1, 1) + spacerItem5 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.gridLayout_6.addItem(spacerItem5, 5, 0, 1, 1) + self.tabWidgetSettings.addTab(self.tabDemandedDifficulty, _fromUtf8("")) + self.tabMaxAcceptableDifficulty = QtGui.QWidget() + self.tabMaxAcceptableDifficulty.setObjectName(_fromUtf8("tabMaxAcceptableDifficulty")) + self.gridLayout_7 = QtGui.QGridLayout(self.tabMaxAcceptableDifficulty) + self.gridLayout_7.setObjectName(_fromUtf8("gridLayout_7")) + self.label_15 = QtGui.QLabel(self.tabMaxAcceptableDifficulty) + self.label_15.setWordWrap(True) + self.label_15.setObjectName(_fromUtf8("label_15")) + self.gridLayout_7.addWidget(self.label_15, 0, 0, 1, 3) + spacerItem6 = QtGui.QSpacerItem(102, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_7.addItem(spacerItem6, 1, 0, 1, 1) + self.label_13 = QtGui.QLabel(self.tabMaxAcceptableDifficulty) + self.label_13.setLayoutDirection(QtCore.Qt.LeftToRight) + self.label_13.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.label_13.setObjectName(_fromUtf8("label_13")) + self.gridLayout_7.addWidget(self.label_13, 1, 1, 1, 1) + self.lineEditMaxAcceptableTotalDifficulty = QtGui.QLineEdit(self.tabMaxAcceptableDifficulty) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.lineEditMaxAcceptableTotalDifficulty.sizePolicy().hasHeightForWidth()) + self.lineEditMaxAcceptableTotalDifficulty.setSizePolicy(sizePolicy) + self.lineEditMaxAcceptableTotalDifficulty.setMaximumSize(QtCore.QSize(70, 16777215)) + self.lineEditMaxAcceptableTotalDifficulty.setObjectName(_fromUtf8("lineEditMaxAcceptableTotalDifficulty")) + self.gridLayout_7.addWidget(self.lineEditMaxAcceptableTotalDifficulty, 1, 2, 1, 1) + spacerItem7 = QtGui.QSpacerItem(102, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_7.addItem(spacerItem7, 2, 0, 1, 1) + self.label_14 = QtGui.QLabel(self.tabMaxAcceptableDifficulty) + self.label_14.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.label_14.setObjectName(_fromUtf8("label_14")) + self.gridLayout_7.addWidget(self.label_14, 2, 1, 1, 1) + self.lineEditMaxAcceptableSmallMessageDifficulty = QtGui.QLineEdit(self.tabMaxAcceptableDifficulty) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.lineEditMaxAcceptableSmallMessageDifficulty.sizePolicy().hasHeightForWidth()) + self.lineEditMaxAcceptableSmallMessageDifficulty.setSizePolicy(sizePolicy) + self.lineEditMaxAcceptableSmallMessageDifficulty.setMaximumSize(QtCore.QSize(70, 16777215)) + self.lineEditMaxAcceptableSmallMessageDifficulty.setObjectName( + _fromUtf8("lineEditMaxAcceptableSmallMessageDifficulty")) + self.gridLayout_7.addWidget(self.lineEditMaxAcceptableSmallMessageDifficulty, 2, 2, 1, 1) + spacerItem8 = QtGui.QSpacerItem(20, 147, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.gridLayout_7.addItem(spacerItem8, 3, 1, 1, 1) + self.labelOpenCL = QtGui.QLabel(self.tabMaxAcceptableDifficulty) + self.labelOpenCL.setObjectName(_fromUtf8("labelOpenCL")) + self.gridLayout_7.addWidget(self.labelOpenCL, 4, 0, 1, 1) + self.comboBoxOpenCL = QtGui.QComboBox(self.tabMaxAcceptableDifficulty) + self.comboBoxOpenCL.setObjectName = (_fromUtf8("comboBoxOpenCL")) + self.gridLayout_7.addWidget(self.comboBoxOpenCL, 4, 1, 1, 1) + self.tabWidgetSettings.addTab(self.tabMaxAcceptableDifficulty, _fromUtf8("")) + self.tabNamecoin = QtGui.QWidget() + self.tabNamecoin.setObjectName(_fromUtf8("tabNamecoin")) + self.gridLayout_8 = QtGui.QGridLayout(self.tabNamecoin) + self.gridLayout_8.setObjectName(_fromUtf8("gridLayout_8")) + spacerItem9 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_8.addItem(spacerItem9, 2, 0, 1, 1) + self.label_16 = QtGui.QLabel(self.tabNamecoin) + self.label_16.setWordWrap(True) + self.label_16.setObjectName(_fromUtf8("label_16")) + self.gridLayout_8.addWidget(self.label_16, 0, 0, 1, 3) + self.label_17 = QtGui.QLabel(self.tabNamecoin) + self.label_17.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.label_17.setObjectName(_fromUtf8("label_17")) + self.gridLayout_8.addWidget(self.label_17, 2, 1, 1, 1) + self.lineEditNamecoinHost = QtGui.QLineEdit(self.tabNamecoin) + self.lineEditNamecoinHost.setObjectName(_fromUtf8("lineEditNamecoinHost")) + self.gridLayout_8.addWidget(self.lineEditNamecoinHost, 2, 2, 1, 1) + spacerItem10 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_8.addItem(spacerItem10, 3, 0, 1, 1) + spacerItem11 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_8.addItem(spacerItem11, 4, 0, 1, 1) + self.label_18 = QtGui.QLabel(self.tabNamecoin) + self.label_18.setEnabled(True) + self.label_18.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.label_18.setObjectName(_fromUtf8("label_18")) + self.gridLayout_8.addWidget(self.label_18, 3, 1, 1, 1) + self.lineEditNamecoinPort = QtGui.QLineEdit(self.tabNamecoin) + self.lineEditNamecoinPort.setObjectName(_fromUtf8("lineEditNamecoinPort")) + self.gridLayout_8.addWidget(self.lineEditNamecoinPort, 3, 2, 1, 1) + spacerItem12 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.gridLayout_8.addItem(spacerItem12, 8, 1, 1, 1) + self.labelNamecoinUser = QtGui.QLabel(self.tabNamecoin) + self.labelNamecoinUser.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.labelNamecoinUser.setObjectName(_fromUtf8("labelNamecoinUser")) + self.gridLayout_8.addWidget(self.labelNamecoinUser, 4, 1, 1, 1) + self.lineEditNamecoinUser = QtGui.QLineEdit(self.tabNamecoin) + self.lineEditNamecoinUser.setObjectName(_fromUtf8("lineEditNamecoinUser")) + self.gridLayout_8.addWidget(self.lineEditNamecoinUser, 4, 2, 1, 1) + spacerItem13 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_8.addItem(spacerItem13, 5, 0, 1, 1) + self.labelNamecoinPassword = QtGui.QLabel(self.tabNamecoin) + self.labelNamecoinPassword.setAlignment( + QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.labelNamecoinPassword.setObjectName(_fromUtf8("labelNamecoinPassword")) + self.gridLayout_8.addWidget(self.labelNamecoinPassword, 5, 1, 1, 1) + self.lineEditNamecoinPassword = QtGui.QLineEdit(self.tabNamecoin) + self.lineEditNamecoinPassword.setInputMethodHints( + QtCore.Qt.ImhHiddenText | QtCore.Qt.ImhNoAutoUppercase | QtCore.Qt.ImhNoPredictiveText) + self.lineEditNamecoinPassword.setEchoMode(QtGui.QLineEdit.Password) + self.lineEditNamecoinPassword.setObjectName(_fromUtf8("lineEditNamecoinPassword")) + self.gridLayout_8.addWidget(self.lineEditNamecoinPassword, 5, 2, 1, 1) + self.labelNamecoinTestResult = QtGui.QLabel(self.tabNamecoin) + self.labelNamecoinTestResult.setText(_fromUtf8("")) + self.labelNamecoinTestResult.setObjectName(_fromUtf8("labelNamecoinTestResult")) + self.gridLayout_8.addWidget(self.labelNamecoinTestResult, 7, 0, 1, 2) + self.pushButtonNamecoinTest = QtGui.QPushButton(self.tabNamecoin) + self.pushButtonNamecoinTest.setObjectName(_fromUtf8("pushButtonNamecoinTest")) + self.gridLayout_8.addWidget(self.pushButtonNamecoinTest, 7, 2, 1, 1) + self.horizontalLayout = QtGui.QHBoxLayout() + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.label_21 = QtGui.QLabel(self.tabNamecoin) + self.label_21.setObjectName(_fromUtf8("label_21")) + self.horizontalLayout.addWidget(self.label_21) + self.radioButtonNamecoinNamecoind = QtGui.QRadioButton(self.tabNamecoin) + self.radioButtonNamecoinNamecoind.setObjectName(_fromUtf8("radioButtonNamecoinNamecoind")) + self.horizontalLayout.addWidget(self.radioButtonNamecoinNamecoind) + self.radioButtonNamecoinNmcontrol = QtGui.QRadioButton(self.tabNamecoin) + self.radioButtonNamecoinNmcontrol.setObjectName(_fromUtf8("radioButtonNamecoinNmcontrol")) + self.horizontalLayout.addWidget(self.radioButtonNamecoinNmcontrol) + self.gridLayout_8.addLayout(self.horizontalLayout, 1, 0, 1, 3) + self.tabWidgetSettings.addTab(self.tabNamecoin, _fromUtf8("")) + self.tabResendsExpire = QtGui.QWidget() + self.tabResendsExpire.setObjectName(_fromUtf8("tabResendsExpire")) + self.gridLayout_5 = QtGui.QGridLayout(self.tabResendsExpire) + self.gridLayout_5.setObjectName(_fromUtf8("gridLayout_5")) + self.label_7 = QtGui.QLabel(self.tabResendsExpire) + self.label_7.setWordWrap(True) + self.label_7.setObjectName(_fromUtf8("label_7")) + self.gridLayout_5.addWidget(self.label_7, 0, 0, 1, 3) + spacerItem14 = QtGui.QSpacerItem(212, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout_5.addItem(spacerItem14, 1, 0, 1, 1) + self.widget = QtGui.QWidget(self.tabResendsExpire) + self.widget.setMinimumSize(QtCore.QSize(231, 75)) + self.widget.setObjectName(_fromUtf8("widget")) + self.label_19 = QtGui.QLabel(self.widget) + self.label_19.setGeometry(QtCore.QRect(10, 20, 101, 20)) + self.label_19.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.label_19.setObjectName(_fromUtf8("label_19")) + self.label_20 = QtGui.QLabel(self.widget) + self.label_20.setGeometry(QtCore.QRect(30, 40, 80, 16)) + self.label_20.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.label_20.setObjectName(_fromUtf8("label_20")) + self.lineEditDays = QtGui.QLineEdit(self.widget) + self.lineEditDays.setGeometry(QtCore.QRect(113, 20, 51, 20)) + self.lineEditDays.setObjectName(_fromUtf8("lineEditDays")) + self.lineEditMonths = QtGui.QLineEdit(self.widget) + self.lineEditMonths.setGeometry(QtCore.QRect(113, 40, 51, 20)) + self.lineEditMonths.setObjectName(_fromUtf8("lineEditMonths")) + self.label_22 = QtGui.QLabel(self.widget) + self.label_22.setGeometry(QtCore.QRect(169, 23, 61, 16)) + self.label_22.setObjectName(_fromUtf8("label_22")) + self.label_23 = QtGui.QLabel(self.widget) + self.label_23.setGeometry(QtCore.QRect(170, 41, 71, 16)) + self.label_23.setObjectName(_fromUtf8("label_23")) + self.gridLayout_5.addWidget(self.widget, 1, 2, 1, 1) + spacerItem15 = QtGui.QSpacerItem(20, 129, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.gridLayout_5.addItem(spacerItem15, 2, 1, 1, 1) + self.tabWidgetSettings.addTab(self.tabResendsExpire, _fromUtf8("")) + self.gridLayout.addWidget(self.tabWidgetSettings, 0, 0, 1, 1) - self.checkBoxHideTrayConnectionNotifications.setChecked( - config.getboolean( - 'bitmessagesettings', 'hidetrayconnectionnotifications')) - self.checkBoxShowTrayNotifications.setChecked( - config.getboolean('bitmessagesettings', 'showtraynotifications')) + self.retranslateUi(settingsDialog) + self.tabWidgetSettings.setCurrentIndex(0) + QtCore.QObject.connect( # pylint: disable=no-member + self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), settingsDialog.accept) + QtCore.QObject.connect( # pylint: disable=no-member + self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), settingsDialog.reject) + QtCore.QObject.connect( # pylint: disable=no-member + self.checkBoxAuthentication, + QtCore.SIGNAL( + _fromUtf8("toggled(bool)")), + self.lineEditSocksUsername.setEnabled) + QtCore.QObject.connect( # pylint: disable=no-member + self.checkBoxAuthentication, + QtCore.SIGNAL( + _fromUtf8("toggled(bool)")), + self.lineEditSocksPassword.setEnabled) + QtCore.QMetaObject.connectSlotsByName(settingsDialog) + settingsDialog.setTabOrder(self.tabWidgetSettings, self.checkBoxStartOnLogon) + settingsDialog.setTabOrder(self.checkBoxStartOnLogon, self.checkBoxStartInTray) + settingsDialog.setTabOrder(self.checkBoxStartInTray, self.checkBoxMinimizeToTray) + settingsDialog.setTabOrder(self.checkBoxMinimizeToTray, self.lineEditTCPPort) + settingsDialog.setTabOrder(self.lineEditTCPPort, self.comboBoxProxyType) + settingsDialog.setTabOrder(self.comboBoxProxyType, self.lineEditSocksHostname) + settingsDialog.setTabOrder(self.lineEditSocksHostname, self.lineEditSocksPort) + settingsDialog.setTabOrder(self.lineEditSocksPort, self.checkBoxAuthentication) + settingsDialog.setTabOrder(self.checkBoxAuthentication, self.lineEditSocksUsername) + settingsDialog.setTabOrder(self.lineEditSocksUsername, self.lineEditSocksPassword) + settingsDialog.setTabOrder(self.lineEditSocksPassword, self.checkBoxSocksListen) + settingsDialog.setTabOrder(self.checkBoxSocksListen, self.buttonBox) - self.checkBoxStartOnLogon.setChecked( - config.getboolean('bitmessagesettings', 'startonlogon')) + def retranslateUi(self, settingsDialog): + """Re-translate the UI into the supported languages""" - self.checkBoxWillinglySendToMobile.setChecked( - config.safeGetBoolean( - 'bitmessagesettings', 'willinglysendtomobile')) - self.checkBoxUseIdenticons.setChecked( - config.safeGetBoolean('bitmessagesettings', 'useidenticons')) - self.checkBoxReplyBelow.setChecked( - config.safeGetBoolean('bitmessagesettings', 'replybelow')) - - if state.appdata == paths.lookupExeFolder(): - self.checkBoxPortableMode.setChecked(True) - else: - try: - tempfile.NamedTemporaryFile( - dir=paths.lookupExeFolder(), delete=True - ).close() # should autodelete - except: - self.checkBoxPortableMode.setDisabled(True) - - if 'darwin' in sys.platform: - self.checkBoxStartOnLogon.setDisabled(True) - self.checkBoxStartOnLogon.setText(_translate( - "MainWindow", "Start-on-login not yet supported on your OS.")) - self.checkBoxMinimizeToTray.setDisabled(True) - self.checkBoxMinimizeToTray.setText(_translate( - "MainWindow", - "Minimize-to-tray not yet supported on your OS.")) - self.checkBoxShowTrayNotifications.setDisabled(True) - self.checkBoxShowTrayNotifications.setText(_translate( - "MainWindow", - "Tray notifications not yet supported on your OS.")) - elif 'linux' in sys.platform: - self.checkBoxStartOnLogon.setDisabled(True) - self.checkBoxStartOnLogon.setText(_translate( - "MainWindow", "Start-on-login not yet supported on your OS.")) - # On the Network settings tab: - self.lineEditTCPPort.setText(str( - config.get('bitmessagesettings', 'port'))) - self.checkBoxUPnP.setChecked( - config.safeGetBoolean('bitmessagesettings', 'upnp')) - self.checkBoxAuthentication.setChecked( - config.getboolean('bitmessagesettings', 'socksauthentication')) - self.checkBoxSocksListen.setChecked( - config.getboolean('bitmessagesettings', 'sockslisten')) - self.checkBoxOnionOnly.setChecked( - config.safeGetBoolean('bitmessagesettings', 'onionservicesonly')) - - self._proxy_type = getSOCKSProxyType(config) - self.comboBoxProxyType.setCurrentIndex( - 0 if not self._proxy_type - else self.comboBoxProxyType.findText(self._proxy_type)) - self.comboBoxProxyTypeChanged(self.comboBoxProxyType.currentIndex()) - - self.lineEditSocksHostname.setText( - config.get('bitmessagesettings', 'sockshostname')) - self.lineEditSocksPort.setText(str( - config.get('bitmessagesettings', 'socksport'))) - self.lineEditSocksUsername.setText( - config.get('bitmessagesettings', 'socksusername')) - self.lineEditSocksPassword.setText( - config.get('bitmessagesettings', 'sockspassword')) - - self.lineEditMaxDownloadRate.setText(str( - config.get('bitmessagesettings', 'maxdownloadrate'))) - self.lineEditMaxUploadRate.setText(str( - config.get('bitmessagesettings', 'maxuploadrate'))) - self.lineEditMaxOutboundConnections.setText(str( - config.get('bitmessagesettings', 'maxoutboundconnections'))) - - # Demanded difficulty tab - self.lineEditTotalDifficulty.setText(str((float( - config.getint( - 'bitmessagesettings', 'defaultnoncetrialsperbyte') - ) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte))) - self.lineEditSmallMessageDifficulty.setText(str((float( - config.getint( - 'bitmessagesettings', 'defaultpayloadlengthextrabytes') - ) / defaults.networkDefaultPayloadLengthExtraBytes))) - - # Max acceptable difficulty tab - self.lineEditMaxAcceptableTotalDifficulty.setText(str((float( - config.getint( - 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte') - ) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte))) - self.lineEditMaxAcceptableSmallMessageDifficulty.setText(str((float( - config.getint( - 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') - ) / defaults.networkDefaultPayloadLengthExtraBytes))) - - # OpenCL - self.comboBoxOpenCL.setEnabled(openclpow.openclAvailable()) - self.comboBoxOpenCL.clear() - self.comboBoxOpenCL.addItem("None") - self.comboBoxOpenCL.addItems(openclpow.vendors) - self.comboBoxOpenCL.setCurrentIndex(0) - for i in range(self.comboBoxOpenCL.count()): - if self.comboBoxOpenCL.itemText(i) == config.safeGet( - 'bitmessagesettings', 'opencl'): - self.comboBoxOpenCL.setCurrentIndex(i) - break - - # Namecoin integration tab - nmctype = config.get('bitmessagesettings', 'namecoinrpctype') - self.lineEditNamecoinHost.setText( - config.get('bitmessagesettings', 'namecoinrpchost')) - self.lineEditNamecoinPort.setText(str( - config.get('bitmessagesettings', 'namecoinrpcport'))) - self.lineEditNamecoinUser.setText( - config.get('bitmessagesettings', 'namecoinrpcuser')) - self.lineEditNamecoinPassword.setText( - config.get('bitmessagesettings', 'namecoinrpcpassword')) - - if nmctype == "namecoind": - self.radioButtonNamecoinNamecoind.setChecked(True) - elif nmctype == "nmcontrol": - self.radioButtonNamecoinNmcontrol.setChecked(True) - self.lineEditNamecoinUser.setEnabled(False) - self.labelNamecoinUser.setEnabled(False) - self.lineEditNamecoinPassword.setEnabled(False) - self.labelNamecoinPassword.setEnabled(False) - else: - assert False - - # Message Resend tab - self.lineEditDays.setText(str( - config.get('bitmessagesettings', 'stopresendingafterxdays'))) - self.lineEditMonths.setText(str( - config.get('bitmessagesettings', 'stopresendingafterxmonths'))) - - def comboBoxProxyTypeChanged(self, comboBoxIndex): - """A callback for currentIndexChanged event of comboBoxProxyType""" - if comboBoxIndex == 0: - self.lineEditSocksHostname.setEnabled(False) - self.lineEditSocksPort.setEnabled(False) - self.lineEditSocksUsername.setEnabled(False) - self.lineEditSocksPassword.setEnabled(False) - self.checkBoxAuthentication.setEnabled(False) - self.checkBoxSocksListen.setEnabled(False) - self.checkBoxOnionOnly.setEnabled(False) - else: - self.lineEditSocksHostname.setEnabled(True) - self.lineEditSocksPort.setEnabled(True) - self.checkBoxAuthentication.setEnabled(True) - self.checkBoxSocksListen.setEnabled(True) - self.checkBoxOnionOnly.setEnabled(True) - if self.checkBoxAuthentication.isChecked(): - self.lineEditSocksUsername.setEnabled(True) - self.lineEditSocksPassword.setEnabled(True) - - def getNamecoinType(self): - """ - Check status of namecoin integration radio buttons - and translate it to a string as in the options. - """ - if self.radioButtonNamecoinNamecoind.isChecked(): - return "namecoind" - if self.radioButtonNamecoinNmcontrol.isChecked(): - return "nmcontrol" - assert False - - # Namecoin connection type was changed. - def namecoinTypeChanged(self, checked): # pylint: disable=unused-argument - """A callback for toggled event of radioButtonNamecoinNamecoind""" - nmctype = self.getNamecoinType() - assert nmctype == "namecoind" or nmctype == "nmcontrol" - - isNamecoind = (nmctype == "namecoind") - self.lineEditNamecoinUser.setEnabled(isNamecoind) - self.labelNamecoinUser.setEnabled(isNamecoind) - self.lineEditNamecoinPassword.setEnabled(isNamecoind) - self.labelNamecoinPassword.setEnabled(isNamecoind) - - if isNamecoind: - self.lineEditNamecoinPort.setText(defaults.namecoinDefaultRpcPort) - else: - self.lineEditNamecoinPort.setText("9000") - - def click_pushButtonNamecoinTest(self): - """Test the namecoin settings specified in the settings dialog.""" - self.labelNamecoinTestResult.setText( - _translate("MainWindow", "Testing...")) - nc = namecoin.namecoinConnection({ - 'type': self.getNamecoinType(), - 'host': str(self.lineEditNamecoinHost.text().toUtf8()), - 'port': str(self.lineEditNamecoinPort.text().toUtf8()), - 'user': str(self.lineEditNamecoinUser.text().toUtf8()), - 'password': str(self.lineEditNamecoinPassword.text().toUtf8()) - }) - status, text = nc.test() - self.labelNamecoinTestResult.setText(text) - if status == 'success': - self.parent.namecoin = nc - - def accept(self): - """A callback for accepted event of buttonBox (OK button pressed)""" - # pylint: disable=too-many-branches,too-many-statements - super(SettingsDialog, self).accept() - if self.firstrun: - self.config.remove_option('bitmessagesettings', 'dontconnect') - self.config.set('bitmessagesettings', 'startonlogon', str( - self.checkBoxStartOnLogon.isChecked())) - self.config.set('bitmessagesettings', 'minimizetotray', str( - self.checkBoxMinimizeToTray.isChecked())) - self.config.set('bitmessagesettings', 'trayonclose', str( - self.checkBoxTrayOnClose.isChecked())) - self.config.set( - 'bitmessagesettings', 'hidetrayconnectionnotifications', - str(self.checkBoxHideTrayConnectionNotifications.isChecked())) - self.config.set('bitmessagesettings', 'showtraynotifications', str( - self.checkBoxShowTrayNotifications.isChecked())) - self.config.set('bitmessagesettings', 'startintray', str( - self.checkBoxStartInTray.isChecked())) - self.config.set('bitmessagesettings', 'willinglysendtomobile', str( - self.checkBoxWillinglySendToMobile.isChecked())) - self.config.set('bitmessagesettings', 'useidenticons', str( - self.checkBoxUseIdenticons.isChecked())) - self.config.set('bitmessagesettings', 'replybelow', str( - self.checkBoxReplyBelow.isChecked())) - - lang = str(self.languageComboBox.itemData( - self.languageComboBox.currentIndex()).toString()) - self.config.set('bitmessagesettings', 'userlocale', lang) - self.parent.change_translation() - - if int(self.config.get('bitmessagesettings', 'port')) != int( - self.lineEditTCPPort.text()): - self.config.set( - 'bitmessagesettings', 'port', str(self.lineEditTCPPort.text())) - if not self.config.safeGetBoolean('bitmessagesettings', 'dontconnect'): - self.net_restart_needed = True - - if self.checkBoxUPnP.isChecked() != self.config.safeGetBoolean( - 'bitmessagesettings', 'upnp'): - self.config.set( - 'bitmessagesettings', 'upnp', - str(self.checkBoxUPnP.isChecked())) - if self.checkBoxUPnP.isChecked(): - import upnp - upnpThread = upnp.uPnPThread() - upnpThread.start() - - proxytype_index = self.comboBoxProxyType.currentIndex() - if proxytype_index == 0: - if self._proxy_type and shared.statusIconColor != 'red': - self.net_restart_needed = True - elif self.comboBoxProxyType.currentText() != self._proxy_type: - self.net_restart_needed = True - self.parent.statusbar.clearMessage() - - self.config.set( - 'bitmessagesettings', 'socksproxytype', - 'none' if self.comboBoxProxyType.currentIndex() == 0 - else str(self.comboBoxProxyType.currentText()) - ) - if proxytype_index > 2: # last literal proxytype in ui - start_proxyconfig() - - self.config.set('bitmessagesettings', 'socksauthentication', str( - self.checkBoxAuthentication.isChecked())) - self.config.set('bitmessagesettings', 'sockshostname', str( - self.lineEditSocksHostname.text())) - self.config.set('bitmessagesettings', 'socksport', str( - self.lineEditSocksPort.text())) - self.config.set('bitmessagesettings', 'socksusername', str( - self.lineEditSocksUsername.text())) - self.config.set('bitmessagesettings', 'sockspassword', str( - self.lineEditSocksPassword.text())) - self.config.set('bitmessagesettings', 'sockslisten', str( - self.checkBoxSocksListen.isChecked())) - if self.checkBoxOnionOnly.isChecked() \ - and not self.config.safeGetBoolean('bitmessagesettings', 'onionservicesonly'): - self.net_restart_needed = True - self.config.set('bitmessagesettings', 'onionservicesonly', str( - self.checkBoxOnionOnly.isChecked())) - try: - # Rounding to integers just for aesthetics - self.config.set('bitmessagesettings', 'maxdownloadrate', str( - int(float(self.lineEditMaxDownloadRate.text())))) - self.config.set('bitmessagesettings', 'maxuploadrate', str( - int(float(self.lineEditMaxUploadRate.text())))) - except ValueError: - QtGui.QMessageBox.about( - self, _translate("MainWindow", "Number needed"), - _translate( - "MainWindow", - "Your maximum download and upload rate must be numbers." - " Ignoring what you typed.") - ) - else: - set_rates( - self.config.safeGetInt('bitmessagesettings', 'maxdownloadrate'), - self.config.safeGetInt('bitmessagesettings', 'maxuploadrate')) - - self.config.set('bitmessagesettings', 'maxoutboundconnections', str( - int(float(self.lineEditMaxOutboundConnections.text())))) - - self.config.set( - 'bitmessagesettings', 'namecoinrpctype', self.getNamecoinType()) - self.config.set('bitmessagesettings', 'namecoinrpchost', str( - self.lineEditNamecoinHost.text())) - self.config.set('bitmessagesettings', 'namecoinrpcport', str( - self.lineEditNamecoinPort.text())) - self.config.set('bitmessagesettings', 'namecoinrpcuser', str( - self.lineEditNamecoinUser.text())) - self.config.set('bitmessagesettings', 'namecoinrpcpassword', str( - self.lineEditNamecoinPassword.text())) - self.parent.resetNamecoinConnection() - - # Demanded difficulty tab - if float(self.lineEditTotalDifficulty.text()) >= 1: - self.config.set( - 'bitmessagesettings', 'defaultnoncetrialsperbyte', - str(int( - float(self.lineEditTotalDifficulty.text()) * - defaults.networkDefaultProofOfWorkNonceTrialsPerByte))) - if float(self.lineEditSmallMessageDifficulty.text()) >= 1: - self.config.set( - 'bitmessagesettings', 'defaultpayloadlengthextrabytes', - str(int( - float(self.lineEditSmallMessageDifficulty.text()) * - defaults.networkDefaultPayloadLengthExtraBytes))) - - if self.comboBoxOpenCL.currentText().toUtf8() != self.config.safeGet( - 'bitmessagesettings', 'opencl'): - self.config.set( - 'bitmessagesettings', 'opencl', - str(self.comboBoxOpenCL.currentText())) - queues.workerQueue.put(('resetPoW', '')) - - acceptableDifficultyChanged = False - - if ( - float(self.lineEditMaxAcceptableTotalDifficulty.text()) >= 1 or - float(self.lineEditMaxAcceptableTotalDifficulty.text()) == 0 - ): - if self.config.get( - 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte' - ) != str(int( - float(self.lineEditMaxAcceptableTotalDifficulty.text()) * - defaults.networkDefaultProofOfWorkNonceTrialsPerByte) - ): - # the user changed the max acceptable total difficulty - acceptableDifficultyChanged = True - self.config.set( - 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', - str(int( - float(self.lineEditMaxAcceptableTotalDifficulty.text()) * - defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) - ) - if ( - float(self.lineEditMaxAcceptableSmallMessageDifficulty.text()) >= 1 or - float(self.lineEditMaxAcceptableSmallMessageDifficulty.text()) == 0 - ): - if self.config.get( - 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes' - ) != str(int( - float(self.lineEditMaxAcceptableSmallMessageDifficulty.text()) * - defaults.networkDefaultPayloadLengthExtraBytes) - ): - # the user changed the max acceptable small message difficulty - acceptableDifficultyChanged = True - self.config.set( - 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', - str(int( - float(self.lineEditMaxAcceptableSmallMessageDifficulty.text()) * - defaults.networkDefaultPayloadLengthExtraBytes)) - ) - if acceptableDifficultyChanged: - # It might now be possible to send msgs which were previously - # marked as toodifficult. Let us change them to 'msgqueued'. - # The singleWorker will try to send them and will again mark - # them as toodifficult if the receiver's required difficulty - # is still higher than we are willing to do. - sqlExecute( - "UPDATE sent SET status='msgqueued'" - " WHERE status='toodifficult'") - queues.workerQueue.put(('sendmessage', '')) - - # UI setting to stop trying to send messages after X days/months - # I'm open to changing this UI to something else if someone has a better idea. - if self.lineEditDays.text() == '' and self.lineEditMonths.text() == '': - # We need to handle this special case. Bitmessage has its - # default behavior. The input is blank/blank - self.config.set('bitmessagesettings', 'stopresendingafterxdays', '') - self.config.set('bitmessagesettings', 'stopresendingafterxmonths', '') - shared.maximumLengthOfTimeToBotherResendingMessages = float('inf') - - try: - days = float(self.lineEditDays.text()) - except ValueError: - self.lineEditDays.setText("0") - days = 0.0 - try: - months = float(self.lineEditMonths.text()) - except ValueError: - self.lineEditMonths.setText("0") - months = 0.0 - - if days >= 0 and months >= 0: - shared.maximumLengthOfTimeToBotherResendingMessages = \ - days * 24 * 60 * 60 + months * 60 * 60 * 24 * 365 / 12 - if shared.maximumLengthOfTimeToBotherResendingMessages < 432000: - # If the time period is less than 5 hours, we give - # zero values to all fields. No message will be sent again. - QtGui.QMessageBox.about( - self, - _translate("MainWindow", "Will not resend ever"), - _translate( - "MainWindow", - "Note that the time limit you entered is less" - " than the amount of time Bitmessage waits for" - " the first resend attempt therefore your" - " messages will never be resent.") - ) - self.config.set( - 'bitmessagesettings', 'stopresendingafterxdays', '0') - self.config.set( - 'bitmessagesettings', 'stopresendingafterxmonths', '0') - shared.maximumLengthOfTimeToBotherResendingMessages = 0.0 - else: - self.config.set( - 'bitmessagesettings', 'stopresendingafterxdays', str(days)) - self.config.set( - 'bitmessagesettings', 'stopresendingafterxmonths', - str(months)) - - self.config.save() - - if self.net_restart_needed: - self.net_restart_needed = False - self.config.setTemp('bitmessagesettings', 'dontconnect', 'true') - self.timer.singleShot( - 5000, lambda: - self.config.setTemp( - 'bitmessagesettings', 'dontconnect', 'false') - ) - - self.parent.updateStartOnLogon() - - if ( - state.appdata != paths.lookupExeFolder() and - self.checkBoxPortableMode.isChecked() - ): - # If we are NOT using portable mode now but the user selected - # that we should... - # Write the keys.dat file to disk in the new location - sqlStoredProcedure('movemessagstoprog') - with open(paths.lookupExeFolder() + 'keys.dat', 'wb') as configfile: - self.config.write(configfile) - # Write the knownnodes.dat file to disk in the new location - knownnodes.saveKnownNodes(paths.lookupExeFolder()) - os.remove(state.appdata + 'keys.dat') - os.remove(state.appdata + 'knownnodes.dat') - previousAppdataLocation = state.appdata - state.appdata = paths.lookupExeFolder() - debug.resetLogging() - try: - os.remove(previousAppdataLocation + 'debug.log') - os.remove(previousAppdataLocation + 'debug.log.1') - except: - pass - - if ( - state.appdata == paths.lookupExeFolder() and - not self.checkBoxPortableMode.isChecked() - ): - # If we ARE using portable mode now but the user selected - # that we shouldn't... - state.appdata = paths.lookupAppdataFolder() - if not os.path.exists(state.appdata): - os.makedirs(state.appdata) - sqlStoredProcedure('movemessagstoappdata') - # Write the keys.dat file to disk in the new location - self.config.save() - # Write the knownnodes.dat file to disk in the new location - knownnodes.saveKnownNodes(state.appdata) - os.remove(paths.lookupExeFolder() + 'keys.dat') - os.remove(paths.lookupExeFolder() + 'knownnodes.dat') - debug.resetLogging() - try: - os.remove(paths.lookupExeFolder() + 'debug.log') - os.remove(paths.lookupExeFolder() + 'debug.log.1') - except: - pass + settingsDialog.setWindowTitle(_translate("settingsDialog", "Settings", None)) + self.checkBoxStartOnLogon.setText(_translate("settingsDialog", "Start Bitmessage on user login", None)) + self.groupBoxTray.setTitle(_translate("settingsDialog", "Tray", None)) + self.checkBoxStartInTray.setText( + _translate( + "settingsDialog", + "Start Bitmessage in the tray (don\'t show main window)", + None)) + self.checkBoxMinimizeToTray.setText(_translate("settingsDialog", "Minimize to tray", None)) + self.checkBoxTrayOnClose.setText(_translate("settingsDialog", "Close to tray", None)) + self.checkBoxHideTrayConnectionNotifications.setText( + _translate("settingsDialog", "Hide connection notifications", None)) + self.checkBoxShowTrayNotifications.setText( + _translate( + "settingsDialog", + "Show notification when message received", + None)) + self.checkBoxPortableMode.setText(_translate("settingsDialog", "Run in Portable Mode", None)) + self.PortableModeDescription.setText( + _translate( + "settingsDialog", + "In Portable Mode, messages and config files are stored in the same directory as the" + " program rather than the normal application-data folder. This makes it convenient to" + " run Bitmessage from a USB thumb drive.", + None)) + self.checkBoxWillinglySendToMobile.setText( + _translate( + "settingsDialog", + "Willingly include unencrypted destination address when sending to a mobile device", + None)) + self.checkBoxUseIdenticons.setText(_translate("settingsDialog", "Use Identicons", None)) + self.checkBoxReplyBelow.setText(_translate("settingsDialog", "Reply below Quote", None)) + self.groupBox.setTitle(_translate("settingsDialog", "Interface Language", None)) + self.languageComboBox.setItemText(0, _translate("settingsDialog", "System Settings", "system")) + self.tabWidgetSettings.setTabText( + self.tabWidgetSettings.indexOf( + self.tabUserInterface), + _translate( + "settingsDialog", "User Interface", None)) + self.groupBox1.setTitle(_translate("settingsDialog", "Listening port", None)) + self.label.setText(_translate("settingsDialog", "Listen for connections on port:", None)) + self.labelUPnP.setText(_translate("settingsDialog", "UPnP:", None)) + self.groupBox_3.setTitle(_translate("settingsDialog", "Bandwidth limit", None)) + self.label_24.setText(_translate("settingsDialog", "Maximum download rate (kB/s): [0: unlimited]", None)) + self.label_25.setText(_translate("settingsDialog", "Maximum upload rate (kB/s): [0: unlimited]", None)) + self.label_26.setText(_translate("settingsDialog", "Maximum outbound connections: [0: none]", None)) + self.groupBox_2.setTitle(_translate("settingsDialog", "Proxy server / Tor", None)) + self.label_2.setText(_translate("settingsDialog", "Type:", None)) + self.label_3.setText(_translate("settingsDialog", "Server hostname:", None)) + self.label_4.setText(_translate("settingsDialog", "Port:", None)) + self.checkBoxAuthentication.setText(_translate("settingsDialog", "Authentication", None)) + self.label_5.setText(_translate("settingsDialog", "Username:", None)) + self.label_6.setText(_translate("settingsDialog", "Pass:", None)) + self.checkBoxSocksListen.setText( + _translate( + "settingsDialog", + "Listen for incoming connections when using proxy", + None)) + self.comboBoxProxyType.setItemText(0, _translate("settingsDialog", "none", None)) + self.comboBoxProxyType.setItemText(1, _translate("settingsDialog", "SOCKS4a", None)) + self.comboBoxProxyType.setItemText(2, _translate("settingsDialog", "SOCKS5", None)) + self.tabWidgetSettings.setTabText( + self.tabWidgetSettings.indexOf( + self.tabNetworkSettings), + _translate( + "settingsDialog", "Network Settings", None)) + self.label_9.setText(_translate("settingsDialog", "Total difficulty:", None)) + self.label_10.setText( + _translate( + "settingsDialog", + "The \'Total difficulty\' affects the absolute amount of work the sender must complete." + " Doubling this value doubles the amount of work.", + None)) + self.label_11.setText(_translate("settingsDialog", "Small message difficulty:", None)) + self.label_8.setText(_translate( + "settingsDialog", + "When someone sends you a message, their computer must first complete some work. The difficulty of this" + " work, by default, is 1. You may raise this default for new addresses you create by changing the values" + " here. Any new addresses you create will require senders to meet the higher difficulty. There is one" + " exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically" + " notify them when you next send a message that they need only complete the minimum amount of" + " work: difficulty 1. ", + None)) + self.label_12.setText( + _translate( + "settingsDialog", + "The \'Small message difficulty\' mostly only affects the difficulty of sending small messages." + " Doubling this value makes it almost twice as difficult to send a small message but doesn\'t really" + " affect large messages.", + None)) + self.tabWidgetSettings.setTabText( + self.tabWidgetSettings.indexOf( + self.tabDemandedDifficulty), + _translate( + "settingsDialog", "Demanded difficulty", None)) + self.label_15.setText( + _translate( + "settingsDialog", + "Here you may set the maximum amount of work you are willing to do to send a message to another" + " person. Setting these values to 0 means that any value is acceptable.", + None)) + self.label_13.setText(_translate("settingsDialog", "Maximum acceptable total difficulty:", None)) + self.label_14.setText(_translate("settingsDialog", "Maximum acceptable small message difficulty:", None)) + self.tabWidgetSettings.setTabText( + self.tabWidgetSettings.indexOf( + self.tabMaxAcceptableDifficulty), + _translate( + "settingsDialog", "Max acceptable difficulty", None)) + self.labelOpenCL.setText(_translate("settingsDialog", "Hardware GPU acceleration (OpenCL):", None)) + self.label_16.setText(_translate( + "settingsDialog", + "

Bitmessage can utilize a different Bitcoin-based program called Namecoin to make" + " addresses human-friendly. For example, instead of having to tell your friend your long Bitmessage" + " address, you can simply tell him to send a message to test." + "

(Getting your own Bitmessage address into Namecoin is still rather difficult).

" + "

Bitmessage can use either namecoind directly or a running nmcontrol instance.

", + None)) + self.label_17.setText(_translate("settingsDialog", "Host:", None)) + self.label_18.setText(_translate("settingsDialog", "Port:", None)) + self.labelNamecoinUser.setText(_translate("settingsDialog", "Username:", None)) + self.labelNamecoinPassword.setText(_translate("settingsDialog", "Password:", None)) + self.pushButtonNamecoinTest.setText(_translate("settingsDialog", "Test", None)) + self.label_21.setText(_translate("settingsDialog", "Connect to:", None)) + self.radioButtonNamecoinNamecoind.setText(_translate("settingsDialog", "Namecoind", None)) + self.radioButtonNamecoinNmcontrol.setText(_translate("settingsDialog", "NMControl", None)) + self.tabWidgetSettings.setTabText( + self.tabWidgetSettings.indexOf( + self.tabNamecoin), + _translate( + "settingsDialog", "Namecoin integration", None)) + self.label_7.setText(_translate( + "settingsDialog", + "

By default, if you send a message to someone and he is offline for more than two" + " days, Bitmessage will send the message again after an additional two days. This will be continued with" + " exponential backoff forever; messages will be resent after 5, 10, 20 days ect. until the receiver" + " acknowledges them. Here you may change that behavior by having Bitmessage give up after a certain" + " number of days or months.

Leave these input fields blank for the default behavior." + "

", + None)) + self.label_19.setText(_translate("settingsDialog", "Give up after", None)) + self.label_20.setText(_translate("settingsDialog", "and", None)) + self.label_22.setText(_translate("settingsDialog", "days", None)) + self.label_23.setText(_translate("settingsDialog", "months.", None)) + self.tabWidgetSettings.setTabText( + self.tabWidgetSettings.indexOf( + self.tabResendsExpire), + _translate( + "settingsDialog", "Resends Expire", None)) diff --git a/src/bitmessageqt/settings.ui b/src/bitmessageqt/settings.ui index 0ffbf442..4aeba3ce 100644 --- a/src/bitmessageqt/settings.ui +++ b/src/bitmessageqt/settings.ui @@ -37,18 +37,6 @@ User Interface - - 8 - - - 8 - - - 8 - - - 8 - @@ -56,43 +44,20 @@ - - - - Tray + + + + Start Bitmessage in the tray (don't show main window) - - - - - Start Bitmessage in the tray (don't show main window) - - - - - - - Minimize to tray - - - false - - - - - - - Close to tray - - - - - + - Hide connection notifications + Minimize to tray + + + true @@ -152,15 +117,90 @@ Interface Language - - - + + + 100 0 + + + System Settings + + + + + English + + + + + Esperanto + + + + + Français + + + + + Deutsch + + + + + Español + + + + + русский + + + + + Norsk + + + + + العربية + + + + + 简体中文 + + + + + 日本語 + + + + + Nederlands + + + + + Česky + + + + + Pirate English + + + + + Other (set in keys.dat) + + @@ -173,18 +213,6 @@ Network Settings - - 8 - - - 8 - - - 8 - - - 8 - @@ -192,13 +220,26 @@ + + + Qt::Horizontal + + + + 125 + 20 + + + + + Listen for connections on port: - + @@ -208,26 +249,6 @@ - - - - UPnP - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -403,13 +424,6 @@ - - - - Only connect to onion services (*.onion) - - - @@ -419,12 +433,12 @@ - SOCKS4a + SOCKS4a - SOCKS5 + SOCKS5 @@ -452,18 +466,6 @@ Demanded difficulty - - 8 - - - 8 - - - 8 - - - 8 - @@ -592,18 +594,6 @@ Max acceptable difficulty - - 8 - - - 8 - - - 8 - - - 8 - @@ -708,33 +698,6 @@ - - - - - - Hardware GPU acceleration (OpenCL): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - @@ -742,18 +705,6 @@ Namecoin integration - - 8 - - - 8 - - - 8 - - - 8 - @@ -937,18 +888,6 @@ Resends Expire - - 8 - - - 8 - - - 8 - - - 8 - @@ -973,69 +912,91 @@ - + 231 75 - - + + + 10 + 20 + 101 + 20 + + Give up after - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + - - + + + 30 + 40 + 80 + 16 + + and - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 55 - 100 - - + + + + 113 + 20 + 51 + 20 + + - - - - - - 55 - 100 - - + + + + 113 + 40 + 51 + 20 + + - - - + + + + 169 + 23 + 61 + 16 + + days - - - + + + + 170 + 41 + 71 + 16 + + months. - - @@ -1056,14 +1017,7 @@ -
- - - LanguageBox - QComboBox -
bitmessageqt.languagebox
-
-
+ tabWidgetSettings checkBoxStartOnLogon @@ -1147,53 +1101,5 @@ - - comboBoxProxyType - currentIndexChanged(int) - settingsDialog - comboBoxProxyTypeChanged - - - 20 - 20 - - - 20 - 20 - - - - - radioButtonNamecoinNamecoind - toggled(bool) - settingsDialog - namecoinTypeChanged - - - 20 - 20 - - - 20 - 20 - - - - - pushButtonNamecoinTest - clicked() - settingsDialog - click_pushButtonNamecoinTest - - - 20 - 20 - - - 20 - 20 - - - diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index d6d4543d..2a1ddb18 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -15,7 +15,6 @@ from openclpow import openclAvailable, openclEnabled import paths import proofofwork from pyelliptic.openssl import OpenSSL -from settings import getSOCKSProxyType import queues import network.stats import state @@ -119,7 +118,8 @@ def createSupportMessage(myapp): BMConfigParser().safeGet('bitmessagesettings', 'opencl') ) if openclEnabled() else "None" locale = getTranslationLanguage() - socks = getSOCKSProxyType(BMConfigParser()) or "N/A" + socks = BMConfigParser().safeGet( + 'bitmessagesettings', 'socksproxytype', "N/A") upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', "N/A") connectedhosts = len(network.stats.connectedHostsList()) diff --git a/src/bitmsghash/bitmsghash.cpp b/src/bitmsghash/bitmsghash.cpp index ce305ebf..24775475 100644 --- a/src/bitmsghash/bitmsghash.cpp +++ b/src/bitmsghash/bitmsghash.cpp @@ -162,4 +162,4 @@ extern "C" EXPORT unsigned long long BitmessagePOW(unsigned char * starthash, un free(threads); free(threaddata); return successval; -} \ No newline at end of file +} diff --git a/src/bmconfigparser.py b/src/bmconfigparser.py index 328cf0c7..1ee64e94 100644 --- a/src/bmconfigparser.py +++ b/src/bmconfigparser.py @@ -3,8 +3,8 @@ BMConfigParser class definition and default configuration settings """ import ConfigParser -import os import shutil +import os from datetime import datetime import state @@ -43,13 +43,8 @@ BMConfigDefaults = { @Singleton class BMConfigParser(ConfigParser.SafeConfigParser): - """ - Singleton class inherited from :class:`ConfigParser.SafeConfigParser` - with additional methods specific to bitmessage config. - """ - # pylint: disable=too-many-ancestors - - _temp = {} + """Singleton class inherited from ConfigParser.SafeConfigParser + with additional methods specific to bitmessage config.""" def set(self, section, option, value=None): if self._optcre is self.OPTCRE or value: @@ -60,15 +55,10 @@ class BMConfigParser(ConfigParser.SafeConfigParser): return ConfigParser.ConfigParser.set(self, section, option, value) def get(self, section, option, raw=False, variables=None): - # pylint: disable=arguments-differ try: if section == "bitmessagesettings" and option == "timeformat": return ConfigParser.ConfigParser.get( self, section, option, raw, variables) - try: - return self._temp[section][option] - except KeyError: - pass return ConfigParser.ConfigParser.get( self, section, option, True, variables) except ConfigParser.InterpolationError: @@ -80,15 +70,7 @@ class BMConfigParser(ConfigParser.SafeConfigParser): except (KeyError, ValueError, AttributeError): raise e - def setTemp(self, section, option, value=None): - """Temporary set option to value, not saving.""" - try: - self._temp[section][option] = value - except KeyError: - self._temp[section] = {option: value} - def safeGetBoolean(self, section, field): - """Return value as boolean, False on exceptions""" try: return self.getboolean(section, field) except (ConfigParser.NoSectionError, ConfigParser.NoOptionError, @@ -96,8 +78,6 @@ class BMConfigParser(ConfigParser.SafeConfigParser): return False def safeGetInt(self, section, field, default=0): - """Return value as integer, default on exceptions, - 0 if default missing""" try: return self.getint(section, field) except (ConfigParser.NoSectionError, ConfigParser.NoOptionError, @@ -105,7 +85,6 @@ class BMConfigParser(ConfigParser.SafeConfigParser): return default def safeGet(self, section, option, default=None): - """Return value as is, default on exceptions, None if default missing""" try: return self.get(section, option) except (ConfigParser.NoSectionError, ConfigParser.NoOptionError, @@ -113,16 +92,11 @@ class BMConfigParser(ConfigParser.SafeConfigParser): return default def items(self, section, raw=False, variables=None): - """Return section variables as parent, - but override the "raw" argument to always True""" - # pylint: disable=arguments-differ return ConfigParser.ConfigParser.items(self, section, True, variables) - @staticmethod - def addresses(): - """Return a list of local bitmessage addresses (from section labels)""" - return [ - x for x in BMConfigParser().sections() if x.startswith('BM-')] + def addresses(self): + return filter( + lambda x: x.startswith('BM-'), BMConfigParser().sections()) def read(self, filenames): ConfigParser.ConfigParser.read(self, filenames) @@ -143,7 +117,6 @@ class BMConfigParser(ConfigParser.SafeConfigParser): continue def save(self): - """Save the runtime config onto the filesystem""" fileName = os.path.join(state.appdata, 'keys.dat') fileNameBak = '.'.join([ fileName, datetime.now().strftime("%Y%j%H%M%S%f"), 'bak']) @@ -165,15 +138,12 @@ class BMConfigParser(ConfigParser.SafeConfigParser): os.remove(fileNameBak) def validate(self, section, option, value): - """Input validator interface (using factory pattern)""" try: return getattr(self, 'validate_%s_%s' % (section, option))(value) except AttributeError: return True - @staticmethod - def validate_bitmessagesettings_maxoutboundconnections(value): - """Reject maxoutboundconnections that are too high or too low""" + def validate_bitmessagesettings_maxoutboundconnections(self, value): try: value = int(value) except ValueError: diff --git a/src/bob.png b/src/bob.png deleted file mode 100644 index 74aeb99e70503bedb782b5f2211f137be20060bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 640 zcmeAS@N?(olHy`uVBq!ia0vp^A3&Ic4M^IBzMRCsz~t`f;uunK>+Q9Jf(;5h43330 z7d1>T#;$t6Y4)&3uw47X13_<>HOxPjT;^~%(9poh*bKzXOl&MXAj}~F!U6^g2_Oto z;D}9;fC1Txn3>vSW85aZaeHg}_48RXnMu5qSqgMIvh%UK42L3z1IT`aD}n_A#E%XK zHcS^1e0@=R;q@!}Hn$62S?4dAUt4cx@S_z=fI$o-Csb`788xMtXRTj3KY!c92|2*P zC*LfP%TZ$}(Ogw&nqdPduwha#3m`F!;`==>*bbIT>~CJUvm2PQ7(8A5T-G@yGywp< C&zlec diff --git a/src/build_osx.py b/src/build_osx.py index 83d2f280..1d8f470e 100644 --- a/src/build_osx.py +++ b/src/build_osx.py @@ -1,6 +1,5 @@ -"""Building osx.""" -import os from glob import glob +import os from PyQt4 import QtCore from setuptools import setup @@ -13,26 +12,20 @@ DATA_FILES = [ ('bitmsghash', ['bitmsghash/bitmsghash.cl', 'bitmsghash/bitmsghash.so']), ('translations', glob('translations/*.qm')), ('ui', glob('bitmessageqt/*.ui')), - ( - 'translations', - glob(os.path.join(str(QtCore.QLibraryInfo.location( - QtCore.QLibraryInfo.TranslationsPath)), 'qt_??.qm'))), - ( - 'translations', - glob(os.path.join(str(QtCore.QLibraryInfo.location( - QtCore.QLibraryInfo.TranslationsPath)), 'qt_??_??.qm'))), + ('translations', glob(str(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)) + '/qt_??.qm')), + ('translations', glob(str(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)) + '/qt_??_??.qm')), ] setup( - name=name, - version=version, - app=mainscript, - data_files=DATA_FILES, - setup_requires=["py2app"], - options=dict( - py2app=dict( - includes=['sip', 'PyQt4._qt'], - iconfile="images/bitmessage.icns" + name = name, + version = version, + app = mainscript, + data_files = DATA_FILES, + setup_requires = ["py2app"], + options = dict( + py2app = dict( + includes = ['sip', 'PyQt4._qt'], + iconfile = "images/bitmessage.icns" ) ) ) diff --git a/src/buildozer.spec b/src/buildozer.spec index fc0bf18b..07f9e6b2 100644 --- a/src/buildozer.spec +++ b/src/buildozer.spec @@ -1,10 +1,10 @@ [app] # (str) Title of your application -title = bitapp +title = PyBitmessage # (str) Package name -package.name = bitapp +package.name = PyBitmessage # (str) Package domain (needed for android/ios packaging) package.domain = org.test @@ -13,7 +13,7 @@ package.domain = org.test source.dir = . # (list) Source files to include (let empty to include all the files) -source.include_exts = py,png,jpg,kv,atlas,gif,zip +source.include_exts = py,png,jpg,kv,atlas # (list) List of inclusions using pattern matching #source.include_patterns = assets/*,images/*.png @@ -35,25 +35,16 @@ version = 0.1 # version.filename = %(source.dir)s/main.py # (list) Application requirements -# comma separated e.g. requirements = sqlite3,kivy -requirements = - openssl, - sqlite3, - python2, - kivy, - bitmsghash, - kivymd, - kivy-garden, - qrcode, - Pillow, - msgpack +# comma seperated e.g. requirements = sqlite3,kivy +requirements = python2, sqlite3, kivy, openssl # (str) Custom source folders for requirements # Sets custom source for any requirements with recipes # requirements.source.kivy = ../../kivy +#requirements.source.sqlite3 = # (list) Garden requirements -garden_requirements = qrcode +#garden_requirements = # (str) Presplash of the application #presplash.filename = %(source.dir)s/data/presplash.png @@ -75,7 +66,8 @@ orientation = portrait # author = © Copyright Info # change the major version of python used by the app -osx.python_version = 3 +#osx.python_version = 2 + # Kivy version to use osx.kivy_version = 1.9.1 @@ -95,22 +87,22 @@ fullscreen = 0 #android.presplash_color = #FFFFFF # (list) Permissions -android.permissions = INTERNET, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE +android.permissions = INTERNET # (int) Android API to use -android.api = 27 +#android.api = 19 # (int) Minimum API required -android.minapi = 21 +#android.minapi = 9 # (int) Android SDK version to use -android.sdk = 20 +#android.sdk = 20 # (str) Android NDK version to use -android.ndk = 17c +#android.ndk = 9c # (bool) Use --private data storage (True) or --dir public storage (False) -# android.private_storage = True +#android.private_storage = True # (str) Android NDK directory (if empty, it will be automatically downloaded.) #android.ndk_path = @@ -132,6 +124,9 @@ android.ndk = 17c # (list) Pattern to whitelist for the whole project #android.whitelist = +android.whitelist = /usr/lib/komodo-edit/python/lib/python2.7/lib-dynload/_sqlite3.so + + # (str) Path to a custom whitelist file #android.whitelist_src = @@ -155,12 +150,9 @@ android.ndk = 17c # (list) Gradle dependencies to add (currently works only with sdl2_gradle # bootstrap) #android.gradle_dependencies = - -# (list) Java classes to add as activities to the manifest. -#android.add_activites = com.example.ExampleActivity - +, /home/cis/Downloads/libssl1.0.2_1.0.2l-2+deb9u2_amd64 # (str) python-for-android branch to use, defaults to stable -p4a.branch = release-2019.07.08 +#p4a.branch = stable # (str) OUYA Console category. Should be one of GAME or APP # If you leave this blank, OUYA support will not be enabled @@ -172,10 +164,7 @@ p4a.branch = release-2019.07.08 # (str) XML file to include as an intent filters in tag #android.manifest.intent_filters = -# (str) launchMode to set for the main activity -#android.manifest.launch_mode = standard - -# (list) Android additional libraries to copy into libs/armeabi +# (list) Android additionnal libraries to copy into libs/armeabi #android.add_libs_armeabi = libs/android/*.so #android.add_libs_armeabi_v7a = libs/android-v7/*.so #android.add_libs_x86 = libs/android-x86/*.so @@ -209,7 +198,7 @@ android.arch = armeabi-v7a #p4a.source_dir = # (str) The directory in which python-for-android should look for your own build recipes (if any) -p4a.local_recipes = /home/cis/navjotrepo/PyBitmessage/src/bitmessagekivy/android/python-for-android/recipes/ +#p4a.local_recipes = # (str) Filename to the hook for p4a #p4a.hook = @@ -217,9 +206,6 @@ p4a.local_recipes = /home/cis/navjotrepo/PyBitmessage/src/bitmessagekivy/android # (str) Bootstrap to use for android builds # p4a.bootstrap = sdl2 -# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask) -#p4a.port = - # # iOS specific @@ -286,4 +272,4 @@ warn_on_root = 1 # # Then, invoke the command line with the "demo" profile: # -#buildozer --profile demo android debug \ No newline at end of file +#buildozer --profile demo android debug diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py index 520733fb..0893b73a 100644 --- a/src/class_addressGenerator.py +++ b/src/class_addressGenerator.py @@ -1,28 +1,30 @@ -""" -A thread for creating addresses -""" -import hashlib -import time -from binascii import hexlify -import defaults -import highlevelcrypto -import queues -import shared -import state -import tr -from addresses import decodeAddress, encodeAddress, encodeVarint -from bmconfigparser import BMConfigParser -from fallback import RIPEMD160Hash -from network import StoppableThread +import time +import threading +import hashlib +from binascii import hexlify from pyelliptic import arithmetic from pyelliptic.openssl import OpenSSL +import tr +import queues +import state +import shared +import defaults +import highlevelcrypto +from bmconfigparser import BMConfigParser +from debug import logger +from addresses import decodeAddress, encodeAddress, encodeVarint +from fallback import RIPEMD160Hash +from helper_threading import StoppableThread -class addressGenerator(StoppableThread): - """A thread for creating addresses""" - name = "addressGenerator" +class addressGenerator(threading.Thread, StoppableThread): + + def __init__(self): + # QThread.__init__(self, parent) + threading.Thread.__init__(self, name="addressGenerator") + self.initStop() def stopThread(self): try: @@ -32,12 +34,6 @@ class addressGenerator(StoppableThread): super(addressGenerator, self).stopThread() def run(self): - """ - Process the requests for addresses generation - from `.queues.addressGeneratorQueue` - """ - # pylint: disable=too-many-locals, too-many-branches - # pylint: disable=protected-access, too-many-statements while state.shutdown == 0: queueValue = queues.addressGeneratorQueue.get() nonceTrialsPerByte = 0 @@ -93,12 +89,12 @@ class addressGenerator(StoppableThread): elif queueValue[0] == 'stopThread': break else: - self.logger.error( + logger.error( 'Programming error: A structure with the wrong number' ' of values was passed into the addressGeneratorQueue.' ' Here is the queueValue: %r\n', queueValue) if addressVersionNumber < 3 or addressVersionNumber > 4: - self.logger.error( + logger.error( 'Program error: For some reason the address generator' ' queue has been given a request to create at least' ' one version %s address which it cannot do.\n', @@ -119,7 +115,9 @@ class addressGenerator(StoppableThread): defaults.networkDefaultPayloadLengthExtraBytes if command == 'createRandomAddress': queues.UISignalQueue.put(( - 'updateStatusBar', "" + 'updateStatusBar', + tr._translate( + "MainWindow", "Generating one new address") )) # This next section is a little bit strange. We're going # to generate keys over and over until we find one @@ -145,10 +143,10 @@ class addressGenerator(StoppableThread): '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash ): break - self.logger.info( + logger.info( 'Generated address with ripe digest: %s', hexlify(ripe)) try: - self.logger.info( + logger.info( 'Address generator calculated %s addresses at %s' ' addresses per second before finding one with' ' the correct ripe-prefix.', @@ -176,6 +174,7 @@ class addressGenerator(StoppableThread): privEncryptionKey).digest()).digest()[0:4] privEncryptionKeyWIF = arithmetic.changebase( privEncryptionKey + checksum, 256, 58) + BMConfigParser().add_section(address) BMConfigParser().set(address, 'label', label) BMConfigParser().set(address, 'enabled', 'true') @@ -195,7 +194,11 @@ class addressGenerator(StoppableThread): queues.apiAddressGeneratorReturnQueue.put(address) queues.UISignalQueue.put(( - 'updateStatusBar', "" + 'updateStatusBar', + tr._translate( + "MainWindow", + "Done generating address. Doing work necessary" + " to broadcast it...") )) queues.UISignalQueue.put(('writeNewAddressToTable', ( label, address, streamNumber))) @@ -210,8 +213,8 @@ class addressGenerator(StoppableThread): elif command == 'createDeterministicAddresses' \ or command == 'getDeterministicAddress' \ or command == 'createChan' or command == 'joinChan': - if not deterministicPassphrase: - self.logger.warning( + if len(deterministicPassphrase) == 0: + logger.warning( 'You are creating deterministic' ' address(es) using a blank passphrase.' ' Bitmessage will do it but it is rather stupid.') @@ -264,10 +267,10 @@ class addressGenerator(StoppableThread): ): break - self.logger.info( + logger.info( 'Generated address with ripe digest: %s', hexlify(ripe)) try: - self.logger.info( + logger.info( 'Address generator calculated %s addresses' ' at %s addresses per second before finding' ' one with the correct ripe-prefix.', @@ -317,7 +320,7 @@ class addressGenerator(StoppableThread): addressAlreadyExists = True if addressAlreadyExists: - self.logger.info( + logger.info( '%s already exists. Not adding it again.', address ) @@ -330,7 +333,7 @@ class addressGenerator(StoppableThread): ).arg(address) )) else: - self.logger.debug('label: %s', label) + logger.debug('label: %s', label) BMConfigParser().set(address, 'label', label) BMConfigParser().set(address, 'enabled', 'true') BMConfigParser().set(address, 'decoy', 'false') @@ -359,7 +362,7 @@ class addressGenerator(StoppableThread): address) shared.myECCryptorObjects[ripe] = \ highlevelcrypto.makeCryptor( - hexlify(potentialPrivEncryptionKey)) + hexlify(potentialPrivEncryptionKey)) shared.myAddressesByHash[ripe] = address tag = hashlib.sha512(hashlib.sha512( encodeVarint(addressVersionNumber) + diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 824580c2..720cdf02 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -1,42 +1,32 @@ -""" -The objectProcessor thread, of which there is only one, -processes the network objects -""" -# pylint: disable=too-many-locals,too-many-return-statements -# pylint: disable=too-many-branches,too-many-statements import hashlib -import logging import random +import shared import threading import time from binascii import hexlify from subprocess import call # nosec +import highlevelcrypto +import knownnodes +from addresses import ( + calculateInventoryHash, decodeAddress, decodeVarint, encodeAddress, + encodeVarint, varintDecodeError +) +from bmconfigparser import BMConfigParser import helper_bitcoin import helper_inbox import helper_msgcoding import helper_sent -import highlevelcrypto -import knownnodes -import l10n +from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery +from helper_ackPayload import genAckPayload +from network import bmproto import protocol import queues -import shared import state import tr -from addresses import ( - calculateInventoryHash, decodeAddress, decodeVarint, - encodeAddress, encodeVarint, varintDecodeError -) -from bmconfigparser import BMConfigParser +from debug import logger from fallback import RIPEMD160Hash -from helper_ackPayload import genAckPayload -from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery -from network import bmproto -from network.node import Peer -# pylint: disable=too-many-locals, too-many-return-statements, too-many-branches, too-many-statements - -logger = logging.getLogger('default') +import l10n class objectProcessor(threading.Thread): @@ -45,13 +35,12 @@ class objectProcessor(threading.Thread): objects (msg, broadcast, pubkey, getpubkey) from the receiveDataThreads. """ def __init__(self): - threading.Thread.__init__(self, name="objectProcessor") - random.seed() # It may be the case that the last time Bitmessage was running, # the user closed it before it finished processing everything in the # objectProcessorQueue. Assuming that Bitmessage wasn't closed # forcefully, it should have saved the data in the queue into the # objectprocessorqueue table. Let's pull it out. + threading.Thread.__init__(self, name="objectProcessor") queryreturn = sqlQuery( '''SELECT objecttype, data FROM objectprocessorqueue''') for row in queryreturn: @@ -65,7 +54,6 @@ class objectProcessor(threading.Thread): self.successfullyDecryptMessageTimings = [] def run(self): - """Process the objects from `.queues.objectProcessorQueue`""" while True: objectType, data = queues.objectProcessorQueue.get() @@ -129,10 +117,7 @@ class objectProcessor(threading.Thread): state.shutdown = 2 break - @staticmethod - def checkackdata(data): - """Checking Acknowledgement of message received or not?""" - # pylint: disable=protected-access + def checkackdata(self, data): # Let's check whether this is a message acknowledgement bound for us. if len(data) < 32: return @@ -149,13 +134,11 @@ class objectProcessor(threading.Thread): 'ackreceived', int(time.time()), data[readPosition:]) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', - ( - data[readPosition:], - tr._translate( - "MainWindow", - "Acknowledgement of the message received %1" - ).arg(l10n.formatTimestamp()) - ) + (data[readPosition:], + tr._translate( + "MainWindow", + "Acknowledgement of the message received %1" + ).arg(l10n.formatTimestamp())) )) else: logger.debug('This object is not an acknowledgement bound for me.') @@ -174,7 +157,7 @@ class objectProcessor(threading.Thread): if not host: return - peer = Peer(host, port) + peer = state.Peer(host, port) with knownnodes.knownNodesLock: knownnodes.addKnownNode( stream, peer, is_self=state.ownAddresses.get(peer)) @@ -284,7 +267,6 @@ class objectProcessor(threading.Thread): queues.workerQueue.put(('sendOutOrStoreMyV4Pubkey', myAddress)) def processpubkey(self, data): - """Process a pubkey object""" pubkeyProcessingStartTime = time.time() shared.numberOfPubkeysProcessed += 1 queues.UISignalQueue.put(( @@ -333,14 +315,13 @@ class objectProcessor(threading.Thread): '\x04' + publicSigningKey + '\x04' + publicEncryptionKey) ripe = RIPEMD160Hash(sha.digest()).digest() - if logger.isEnabledFor(logging.DEBUG): - logger.debug( - 'within recpubkey, addressVersion: %s, streamNumber: %s' - '\nripe %s\npublicSigningKey in hex: %s' - '\npublicEncryptionKey in hex: %s', - addressVersion, streamNumber, hexlify(ripe), - hexlify(publicSigningKey), hexlify(publicEncryptionKey) - ) + logger.debug( + 'within recpubkey, addressVersion: %s, streamNumber: %s' + '\nripe %s\npublicSigningKey in hex: %s' + '\npublicEncryptionKey in hex: %s', + addressVersion, streamNumber, hexlify(ripe), + hexlify(publicSigningKey), hexlify(publicEncryptionKey) + ) address = encodeAddress(addressVersion, streamNumber, ripe) @@ -398,14 +379,13 @@ class objectProcessor(threading.Thread): sha.update(publicSigningKey + publicEncryptionKey) ripe = RIPEMD160Hash(sha.digest()).digest() - if logger.isEnabledFor(logging.DEBUG): - logger.debug( - 'within recpubkey, addressVersion: %s, streamNumber: %s' - '\nripe %s\npublicSigningKey in hex: %s' - '\npublicEncryptionKey in hex: %s', - addressVersion, streamNumber, hexlify(ripe), - hexlify(publicSigningKey), hexlify(publicEncryptionKey) - ) + logger.debug( + 'within recpubkey, addressVersion: %s, streamNumber: %s' + '\nripe %s\npublicSigningKey in hex: %s' + '\npublicEncryptionKey in hex: %s', + addressVersion, streamNumber, hexlify(ripe), + hexlify(publicSigningKey), hexlify(publicEncryptionKey) + ) address = encodeAddress(addressVersion, streamNumber, ripe) queryreturn = sqlQuery( @@ -457,7 +437,6 @@ class objectProcessor(threading.Thread): timeRequiredToProcessPubkey) def processmsg(self, data): - """Process a message object""" messageProcessingStartTime = time.time() shared.numberOfMessagesProcessed += 1 queues.UISignalQueue.put(( @@ -599,18 +578,17 @@ class objectProcessor(threading.Thread): logger.debug('ECDSA verify failed') return logger.debug('ECDSA verify passed') - if logger.isEnabledFor(logging.DEBUG): - logger.debug( - 'As a matter of intellectual curiosity, here is the Bitcoin' - ' address associated with the keys owned by the other person:' - ' %s ..and here is the testnet address: %s. The other person' - ' must take their private signing key from Bitmessage and' - ' import it into Bitcoin (or a service like Blockchain.info)' - ' for it to be of any use. Do not use this unless you know' - ' what you are doing.', - helper_bitcoin.calculateBitcoinAddressFromPubkey(pubSigningKey), - helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey) - ) + logger.debug( + 'As a matter of intellectual curiosity, here is the Bitcoin' + ' address associated with the keys owned by the other person:' + ' %s ..and here is the testnet address: %s. The other person' + ' must take their private signing key from Bitmessage and' + ' import it into Bitcoin (or a service like Blockchain.info)' + ' for it to be of any use. Do not use this unless you know' + ' what you are doing.', + helper_bitcoin.calculateBitcoinAddressFromPubkey(pubSigningKey), + helper_bitcoin.calculateTestnetAddressFromPubkey(pubSigningKey) + ) # Used to detect and ignore duplicate messages in our inbox sigHash = hashlib.sha512( hashlib.sha512(signature).digest()).digest()[32:] @@ -647,8 +625,7 @@ class objectProcessor(threading.Thread): if decodeAddress(toAddress)[1] >= 3 \ and not BMConfigParser().safeGetBoolean(toAddress, 'chan'): # If I'm not friendly with this person: - if not shared.isAddressInMyAddressBookSubscriptionsListOrWhitelist( - fromAddress): + if not shared.isAddressInMyAddressBookSubscriptionsListOrWhitelist(fromAddress): requiredNonceTrialsPerByte = BMConfigParser().getint( toAddress, 'noncetrialsperbyte') requiredPayloadLengthExtraBytes = BMConfigParser().getint( @@ -754,7 +731,7 @@ class objectProcessor(threading.Thread): # We really should have a discussion about how to # set the TTL for mailing list broadcasts. This is obviously # hard-coded. - TTL = 2 * 7 * 24 * 60 * 60 # 2 weeks + TTL = 2*7*24*60*60 # 2 weeks t = ('', toAddress, ripe, @@ -806,7 +783,6 @@ class objectProcessor(threading.Thread): ) def processbroadcast(self, data): - """Process a broadcast object""" messageProcessingStartTime = time.time() shared.numberOfBroadcastsProcessed += 1 queues.UISignalQueue.put(( @@ -991,7 +967,7 @@ class objectProcessor(threading.Thread): fromAddress = encodeAddress( sendersAddressVersion, sendersStream, calculatedRipe) - logger.info('fromAddress: %s', fromAddress) + logger.info('fromAddress: %s' % fromAddress) # Let's store the public key in case we want to reply to this person. sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', @@ -1008,7 +984,7 @@ class objectProcessor(threading.Thread): fromAddress = encodeAddress( sendersAddressVersion, sendersStream, calculatedRipe) - logger.debug('fromAddress: %s', fromAddress) + logger.debug('fromAddress: ' + fromAddress) try: decodedMessage = helper_msgcoding.MsgDecode( @@ -1069,18 +1045,17 @@ class objectProcessor(threading.Thread): # for it. elif addressVersion >= 4: tag = hashlib.sha512(hashlib.sha512( - encodeVarint(addressVersion) + encodeVarint(streamNumber) - + ripe + encodeVarint(addressVersion) + encodeVarint(streamNumber) + ripe ).digest()).digest()[32:] if tag in state.neededPubkeys: del state.neededPubkeys[tag] self.sendMessages(address) - @staticmethod - def sendMessages(address): + def sendMessages(self, address): """ - This method is called by the `possibleNewPubkey` when it sees - that we now have the necessary pubkey to send one or more messages. + This function is called by the possibleNewPubkey function when + that function sees that we now have the necessary pubkey + to send one or more messages. """ logger.info('We have been awaiting the arrival of this pubkey.') sqlExecute( @@ -1090,9 +1065,7 @@ class objectProcessor(threading.Thread): " AND folder='sent'", address) queues.workerQueue.put(('sendmessage', '')) - @staticmethod - def ackDataHasAValidHeader(ackData): - """Checking ackData with valid Header, not sending ackData when false""" + def ackDataHasAValidHeader(self, ackData): if len(ackData) < protocol.Header.size: logger.info( 'The length of ackData is unreasonably short. Not sending' @@ -1127,12 +1100,11 @@ class objectProcessor(threading.Thread): return False return True - @staticmethod - def addMailingListNameToSubject(subject, mailingListName): - """Adding mailingListName to subject""" + def addMailingListNameToSubject(self, subject, mailingListName): subject = subject.strip() if subject[:3] == 'Re:' or subject[:3] == 'RE:': subject = subject[3:].strip() if '[' + mailingListName + ']' in subject: return subject - return '[' + mailingListName + '] ' + subject + else: + return '[' + mailingListName + '] ' + subject diff --git a/src/class_objectProcessorQueue.py b/src/class_objectProcessorQueue.py new file mode 100644 index 00000000..b6628816 --- /dev/null +++ b/src/class_objectProcessorQueue.py @@ -0,0 +1,24 @@ +import Queue +import threading +import time + +class ObjectProcessorQueue(Queue.Queue): + maxSize = 32000000 + + def __init__(self): + Queue.Queue.__init__(self) + self.sizeLock = threading.Lock() + self.curSize = 0 # in Bytes. We maintain this to prevent nodes from flooing us with objects which take up too much memory. If this gets too big we'll sleep before asking for further objects. + + def put(self, item, block = True, timeout = None): + while self.curSize >= self.maxSize: + time.sleep(1) + with self.sizeLock: + self.curSize += len(item[1]) + Queue.Queue.put(self, item, block, timeout) + + def get(self, block = True, timeout = None): + item = Queue.Queue.get(self, block, timeout) + with self.sizeLock: + self.curSize -= len(item[1]) + return item diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py index e3acff1d..e2cdbb89 100644 --- a/src/class_singleCleaner.py +++ b/src/class_singleCleaner.py @@ -1,58 +1,61 @@ """ -The `singleCleaner` class is a timer-driven thread that cleans data structures +The singleCleaner class is a timer-driven thread that cleans data structures to free memory, resends messages when a remote node doesn't respond, and sends pong messages to keep connections alive if the network isn't busy. - It cleans these data structures in memory: - - inventory (moves data to the on-disk sql database) - - inventorySets (clears then reloads data out of sql database) +inventory (moves data to the on-disk sql database) +inventorySets (clears then reloads data out of sql database) It cleans these tables on the disk: - - inventory (clears expired objects) - - pubkeys (clears pubkeys older than 4 weeks old which we have not used - personally) - - knownNodes (clears addresses which have not been online for over 3 days) +inventory (clears expired objects) +pubkeys (clears pubkeys older than 4 weeks old which we have not used + personally) +knownNodes (clears addresses which have not been online for over 3 days) It resends messages when there has been no response: - - resends getpubkey messages in 5 days (then 10 days, then 20 days, etc...) - - resends msg messages in 5 days (then 10 days, then 20 days, etc...) +resends getpubkey messages in 5 days (then 10 days, then 20 days, etc...) +resends msg messages in 5 days (then 10 days, then 20 days, etc...) """ -# pylint: disable=relative-import, protected-access + import gc import os -from datetime import datetime, timedelta -import time import shared +import threading +import time +import tr +from bmconfigparser import BMConfigParser +from helper_sql import sqlQuery, sqlExecute +from helper_threading import StoppableThread +from inventory import Inventory +from network.connectionpool import BMConnectionPool +from debug import logger import knownnodes import queues import state -import tr -from bmconfigparser import BMConfigParser -from helper_sql import sqlExecute, sqlQuery -from inventory import Inventory -from network import BMConnectionPool, StoppableThread -class singleCleaner(StoppableThread): - """The singleCleaner thread class""" - name = "singleCleaner" +class singleCleaner(threading.Thread, StoppableThread): cycleLength = 300 expireDiscoveredPeers = 300 - def run(self): # pylint: disable=too-many-branches + def __init__(self): + threading.Thread.__init__(self, name="singleCleaner") + self.initStop() + + def run(self): gc.disable() timeWeLastClearedInventoryAndPubkeysTables = 0 try: shared.maximumLengthOfTimeToBotherResendingMessages = ( float(BMConfigParser().get( - 'bitmessagesettings', 'stopresendingafterxdays')) - * 24 * 60 * 60 + 'bitmessagesettings', 'stopresendingafterxdays')) * + 24 * 60 * 60 ) + ( float(BMConfigParser().get( - 'bitmessagesettings', 'stopresendingafterxmonths')) - * (60 * 60 * 24 * 365) / 12) + 'bitmessagesettings', 'stopresendingafterxmonths')) * + (60 * 60 * 24 * 365) / 12) except: # Either the user hasn't set stopresendingafterxdays and # stopresendingafterxmonths yet or the options are missing @@ -74,7 +77,7 @@ class singleCleaner(StoppableThread): # If we are running as a daemon then we are going to fill up the UI # queue which will never be handled by a UI. We should clear it to # save memory. - # ..FIXME redundant? + # FIXME redundant? if shared.thisapp.daemon or not state.enableGUI: queues.UISignalQueue.queue.clear() if timeWeLastClearedInventoryAndPubkeysTables < \ @@ -94,12 +97,12 @@ class singleCleaner(StoppableThread): "SELECT toaddress, ackdata, status FROM sent" " WHERE ((status='awaitingpubkey' OR status='msgsent')" " AND folder='sent' AND sleeptill?)", - int(time.time()), int(time.time()) - - shared.maximumLengthOfTimeToBotherResendingMessages + int(time.time()), int(time.time()) - + shared.maximumLengthOfTimeToBotherResendingMessages ) for row in queryreturn: if len(row) < 2: - self.logger.error( + logger.error( 'Something went wrong in the singleCleaner thread:' ' a query did not return the requested fields. %r', row @@ -108,18 +111,17 @@ class singleCleaner(StoppableThread): break toAddress, ackData, status = row if status == 'awaitingpubkey': - self.resendPubkeyRequest(toAddress) + resendPubkeyRequest(toAddress) elif status == 'msgsent': - self.resendMsg(ackData) - deleteTrashMsgPermonantly() + resendMsg(ackData) + try: # Cleanup knownnodes and handle possible severe exception # while writing it to disk knownnodes.cleanupKnownNodes() except Exception as err: - # pylint: disable=protected-access if "Errno 28" in str(err): - self.logger.fatal( + logger.fatal( '(while writing knownnodes to disk)' ' Alert: Your disk or data storage volume is full.' ) @@ -130,13 +132,21 @@ class singleCleaner(StoppableThread): "MainWindow", 'Alert: Your disk or data storage volume' ' is full. Bitmessage will now exit.'), - True) + True) )) - if shared.thisapp.daemon or not state.enableGUI: + # FIXME redundant? + if shared.daemon or not state.enableGUI: os._exit(1) +# # clear download queues +# for thread in threading.enumerate(): +# if thread.isAlive() and hasattr(thread, 'downloadQueue'): +# thread.downloadQueue.clear() + # inv/object tracking - for connection in BMConnectionPool().connections(): + for connection in \ + BMConnectionPool().inboundConnections.values() + \ + BMConnectionPool().outboundConnections.values(): connection.clean() # discovery tracking @@ -147,58 +157,48 @@ class singleCleaner(StoppableThread): del state.discoveredPeers[k] except KeyError: pass - - # ..todo:: cleanup pending upload / download + # TODO: cleanup pending upload / download gc.collect() if state.shutdown == 0: self.stop.wait(singleCleaner.cycleLength) - def resendPubkeyRequest(self, address): - """Resend pubkey request for address""" - self.logger.debug( - 'It has been a long time and we haven\'t heard a response to our' - ' getpubkey request. Sending again.' - ) - try: - # We need to take this entry out of the neededPubkeys structure - # because the queues.workerQueue checks to see whether the entry - # is already present and will not do the POW and send the message - # because it assumes that it has already done it recently. - del state.neededPubkeys[address] - except: - pass - queues.UISignalQueue.put(( - 'updateStatusBar', - 'Doing work necessary to again attempt to request a public key...' - )) - sqlExecute( - '''UPDATE sent SET status='msgqueued' WHERE toaddress=?''', - address) - queues.workerQueue.put(('sendmessage', '')) +def resendPubkeyRequest(address): + logger.debug( + 'It has been a long time and we haven\'t heard a response to our' + ' getpubkey request. Sending again.' + ) + try: + # We need to take this entry out of the neededPubkeys structure + # because the queues.workerQueue checks to see whether the entry + # is already present and will not do the POW and send the message + # because it assumes that it has already done it recently. + del state.neededPubkeys[address] + except: + pass - def resendMsg(self, ackdata): - """Resend message by ackdata""" - self.logger.debug( - 'It has been a long time and we haven\'t heard an acknowledgement' - ' to our msg. Sending again.' - ) - sqlExecute( - '''UPDATE sent SET status='msgqueued' WHERE ackdata=?''', - ackdata) - queues.workerQueue.put(('sendmessage', '')) - queues.UISignalQueue.put(( - 'updateStatusBar', - 'Doing work necessary to again attempt to deliver a message...' - )) + queues.UISignalQueue.put(( + 'updateStatusBar', + 'Doing work necessary to again attempt to request a public key...' + )) + sqlExecute( + '''UPDATE sent SET status='msgqueued' WHERE toaddress=?''', + address) + queues.workerQueue.put(('sendmessage', '')) -def deleteTrashMsgPermonantly(): - """This method is used to delete old messages""" - ndays_before_time = datetime.now() - timedelta(days=30) - old_messages = time.mktime(ndays_before_time.timetuple()) - sqlExecute("delete from sent where folder = 'trash' and lastactiontime <= ?;", int(old_messages)) - sqlExecute("delete from inbox where folder = 'trash' and received <= ?;", int(old_messages)) - return +def resendMsg(ackdata): + logger.debug( + 'It has been a long time and we haven\'t heard an acknowledgement' + ' to our msg. Sending again.' + ) + sqlExecute( + '''UPDATE sent SET status='msgqueued' WHERE ackdata=?''', + ackdata) + queues.workerQueue.put(('sendmessage', '')) + queues.UISignalQueue.put(( + 'updateStatusBar', + 'Doing work necessary to again attempt to deliver a message...' + )) diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 0bb110a7..d979ae19 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -1,13 +1,13 @@ """ -Thread for performing PoW +src/class_singleWorker.py +========================= """ -# pylint: disable=protected-access,too-many-branches,too-many-statements -# pylint: disable=no-self-use,too-many-lines,too-many-locals,relative-import - +# pylint: disable=protected-access,too-many-branches,too-many-statements,no-self-use,too-many-lines,too-many-locals from __future__ import division import hashlib +import threading import time from binascii import hexlify, unhexlify from struct import pack @@ -25,16 +25,12 @@ import queues import shared import state import tr -from addresses import ( - calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint -) +from addresses import calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint from bmconfigparser import BMConfigParser +from debug import logger from helper_sql import sqlExecute, sqlQuery +from helper_threading import StoppableThread from inventory import Inventory -from network import StoppableThread - -# This thread, of which there is only one, does the heavy lifting: -# calculating POWs. def sizeof_fmt(num, suffix='h/s'): @@ -47,11 +43,12 @@ def sizeof_fmt(num, suffix='h/s'): return "%.1f%s%s" % (num, 'Yi', suffix) -class singleWorker(StoppableThread): +class singleWorker(threading.Thread, StoppableThread): """Thread for performing PoW""" def __init__(self): - super(singleWorker, self).__init__(name="singleWorker") + threading.Thread.__init__(self, name="singleWorker") + self.initStop() proofofwork.init() def stopThread(self): @@ -74,7 +71,7 @@ class singleWorker(StoppableThread): # Initialize the neededPubkeys dictionary. queryreturn = sqlQuery( '''SELECT DISTINCT toaddress FROM sent''' - ''' WHERE (status='awaitingpubkey' AND folder LIKE '%sent%')''') + ''' WHERE (status='awaitingpubkey' AND folder='sent')''') for row in queryreturn: toAddress, = row # toStatus @@ -103,7 +100,7 @@ class singleWorker(StoppableThread): '''SELECT ackdata FROM sent WHERE status = 'msgsent' ''') for row in queryreturn: ackdata, = row - self.logger.info('Watching for ackdata %s', hexlify(ackdata)) + logger.info('Watching for ackdata %s', hexlify(ackdata)) shared.ackdataForWhichImWatching[ackdata] = 0 # Fix legacy (headerless) watched ackdata to include header @@ -178,14 +175,14 @@ class singleWorker(StoppableThread): self.busy = 0 return else: - self.logger.error( + logger.error( 'Probable programming error: The command sent' ' to the workerThread is weird. It is: %s\n', command ) queues.workerQueue.task_done() - self.logger.info("Quitting...") + logger.info("Quitting...") def _getKeysForAddress(self, address): privSigningKeyBase58 = BMConfigParser().get( @@ -222,34 +219,33 @@ class singleWorker(StoppableThread): )) / (2 ** 16)) )) initialHash = hashlib.sha512(payload).digest() - self.logger.info( + logger.info( '%s Doing proof of work... TTL set to %s', log_prefix, TTL) if log_time: start_time = time.time() trialValue, nonce = proofofwork.run(target, initialHash) - self.logger.info( + logger.info( '%s Found proof of work %s Nonce: %s', log_prefix, trialValue, nonce ) try: delta = time.time() - start_time - self.logger.info( + logger.info( 'PoW took %.1f seconds, speed %s.', delta, sizeof_fmt(nonce / delta) ) except: # NameError pass payload = pack('>Q', nonce) + payload + # inventoryHash = calculateInventoryHash(payload) return payload def doPOWForMyV2Pubkey(self, adressHash): - """ This function also broadcasts out the pubkey - message once it is done with the POW""" + """ This function also broadcasts out the pubkey message once it is done with the POW""" # Look up my stream number based on my address hash myAddress = shared.myAddressesByHash[adressHash] # status - _, addressVersionNumber, streamNumber, adressHash = ( - decodeAddress(myAddress)) + _, addressVersionNumber, streamNumber, adressHash = decodeAddress(myAddress) # 28 days from now plus or minus five minutes TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300)) @@ -266,7 +262,7 @@ class singleWorker(StoppableThread): _, _, pubSigningKey, pubEncryptionKey = \ self._getKeysForAddress(myAddress) except Exception as err: - self.logger.error( + logger.error( 'Error within doPOWForMyV2Pubkey. Could not read' ' the keys from the keys.dat file for a requested' ' address. %s\n', err @@ -284,8 +280,7 @@ class singleWorker(StoppableThread): Inventory()[inventoryHash] = ( objectType, streamNumber, payload, embeddedTime, '') - self.logger.info( - 'broadcasting inv with hash: %s', hexlify(inventoryHash)) + logger.info('broadcasting inv with hash: %s', hexlify(inventoryHash)) queues.invQueue.put((streamNumber, inventoryHash)) queues.UISignalQueue.put(('updateStatusBar', '')) @@ -310,7 +305,7 @@ class singleWorker(StoppableThread): # The address has been deleted. return if BMConfigParser().safeGetBoolean(myAddress, 'chan'): - self.logger.info('This is a chan address. Not sending pubkey.') + logger.info('This is a chan address. Not sending pubkey.') return _, addressVersionNumber, streamNumber, adressHash = decodeAddress( myAddress) @@ -340,7 +335,7 @@ class singleWorker(StoppableThread): privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \ self._getKeysForAddress(myAddress) except Exception as err: - self.logger.error( + logger.error( 'Error within sendOutOrStoreMyV3Pubkey. Could not read' ' the keys from the keys.dat file for a requested' ' address. %s\n', err @@ -367,8 +362,7 @@ class singleWorker(StoppableThread): Inventory()[inventoryHash] = ( objectType, streamNumber, payload, embeddedTime, '') - self.logger.info( - 'broadcasting inv with hash: %s', hexlify(inventoryHash)) + logger.info('broadcasting inv with hash: %s', hexlify(inventoryHash)) queues.invQueue.put((streamNumber, inventoryHash)) queues.UISignalQueue.put(('updateStatusBar', '')) @@ -391,7 +385,7 @@ class singleWorker(StoppableThread): # The address has been deleted. return if shared.BMConfigParser().safeGetBoolean(myAddress, 'chan'): - self.logger.info('This is a chan address. Not sending pubkey.') + logger.info('This is a chan address. Not sending pubkey.') return _, addressVersionNumber, streamNumber, addressHash = decodeAddress( myAddress) @@ -410,7 +404,7 @@ class singleWorker(StoppableThread): privSigningKeyHex, _, pubSigningKey, pubEncryptionKey = \ self._getKeysForAddress(myAddress) except Exception as err: - self.logger.error( + logger.error( 'Error within sendOutOrStoreMyV4Pubkey. Could not read' ' the keys from the keys.dat file for a requested' ' address. %s\n', err @@ -458,8 +452,7 @@ class singleWorker(StoppableThread): doubleHashOfAddressData[32:] ) - self.logger.info( - 'broadcasting inv with hash: %s', hexlify(inventoryHash)) + logger.info('broadcasting inv with hash: %s', hexlify(inventoryHash)) queues.invQueue.put((streamNumber, inventoryHash)) queues.UISignalQueue.put(('updateStatusBar', '')) @@ -468,7 +461,7 @@ class singleWorker(StoppableThread): myAddress, 'lastpubkeysendtime', str(int(time.time()))) BMConfigParser().save() except Exception as err: - self.logger.error( + logger.error( 'Error: Couldn\'t add the lastpubkeysendtime' ' to the keys.dat file. Error message: %s', err ) @@ -485,7 +478,7 @@ class singleWorker(StoppableThread): embeddedTime = int(time.time() + TTL) streamNumber = 1 # Don't know yet what should be here objectType = protocol.OBJECT_ONIONPEER - # ..FIXME: ideally the objectPayload should be signed + # FIXME: ideally the objectPayload should be signed objectPayload = encodeVarint(peer.port) + protocol.encodeHost(peer.host) tag = calculateInventoryHash(objectPayload) @@ -506,7 +499,7 @@ class singleWorker(StoppableThread): objectType, streamNumber, buffer(payload), embeddedTime, buffer(tag) ) - self.logger.info( + logger.info( 'sending inv (within sendOnionPeerObj function) for object: %s', hexlify(inventoryHash)) queues.invQueue.put((streamNumber, inventoryHash)) @@ -521,7 +514,7 @@ class singleWorker(StoppableThread): queryreturn = sqlQuery( '''SELECT fromaddress, subject, message, ''' ''' ackdata, ttl, encodingtype FROM sent ''' - ''' WHERE status=? and folder LIKE '%sent%' ''', 'broadcastqueued') + ''' WHERE status=? and folder='sent' ''', 'broadcastqueued') for row in queryreturn: fromaddress, subject, body, ackdata, TTL, encoding = row @@ -529,7 +522,7 @@ class singleWorker(StoppableThread): _, addressVersionNumber, streamNumber, ripe = \ decodeAddress(fromaddress) if addressVersionNumber <= 1: - self.logger.error( + logger.error( 'Error: In the singleWorker thread, the ' ' sendBroadcast function doesn\'t understand' ' the address version.\n') @@ -645,7 +638,7 @@ class singleWorker(StoppableThread): # to not let the user try to send a message this large # until we implement message continuation. if len(payload) > 2 ** 18: # 256 KiB - self.logger.critical( + logger.critical( 'This broadcast object is too large to send.' ' This should never happen. Object size: %s', len(payload) @@ -656,7 +649,7 @@ class singleWorker(StoppableThread): objectType = 3 Inventory()[inventoryHash] = ( objectType, streamNumber, payload, embeddedTime, tag) - self.logger.info( + logger.info( 'sending inv (within sendBroadcast function)' ' for object: %s', hexlify(inventoryHash) @@ -691,7 +684,7 @@ class singleWorker(StoppableThread): '''SELECT toaddress, fromaddress, subject, message, ''' ''' ackdata, status, ttl, retrynumber, encodingtype FROM ''' ''' sent WHERE (status='msgqueued' or status='forcepow') ''' - ''' and folder LIKE '%sent%' ''') + ''' and folder='sent' ''') # while we have a msg that needs some work for row in queryreturn: toaddress, fromaddress, subject, message, \ @@ -876,8 +869,8 @@ class singleWorker(StoppableThread): "MainWindow", "Looking up the receiver\'s public key")) )) - self.logger.info('Sending a message.') - self.logger.debug( + logger.info('Sending a message.') + logger.debug( 'First 150 characters of message: %s', repr(message[:150]) ) @@ -921,7 +914,7 @@ class singleWorker(StoppableThread): if not shared.BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'willinglysendtomobile' ): - self.logger.info( + logger.info( 'The receiver is a mobile user but the' ' sender (you) has not selected that you' ' are willing to send to mobiles. Aborting' @@ -987,7 +980,7 @@ class singleWorker(StoppableThread): defaults.networkDefaultPayloadLengthExtraBytes: requiredPayloadLengthExtraBytes = \ defaults.networkDefaultPayloadLengthExtraBytes - self.logger.debug( + logger.debug( 'Using averageProofOfWorkNonceTrialsPerByte: %s' ' and payloadLengthExtraBytes: %s.', requiredAverageProofOfWorkNonceTrialsPerByte, @@ -1052,9 +1045,8 @@ class singleWorker(StoppableThread): l10n.formatTimestamp())))) continue else: # if we are sending a message to ourselves or a chan.. - self.logger.info('Sending a message.') - self.logger.debug( - 'First 150 characters of message: %r', message[:150]) + logger.info('Sending a message.') + logger.debug('First 150 characters of message: %r', message[:150]) behaviorBitfield = protocol.getBitfield(fromaddress) try: @@ -1073,7 +1065,7 @@ class singleWorker(StoppableThread): " message. %1" ).arg(l10n.formatTimestamp())) )) - self.logger.error( + logger.error( 'Error within sendMsg. Could not read the keys' ' from the keys.dat file for our own address. %s\n', err) @@ -1149,14 +1141,14 @@ class singleWorker(StoppableThread): payload += encodeVarint(encodedMessage.length) payload += encodedMessage.data if BMConfigParser().has_section(toaddress): - self.logger.info( + logger.info( 'Not bothering to include ackdata because we are' ' sending to ourselves or a chan.' ) fullAckPayload = '' elif not protocol.checkBitfield( behaviorBitfield, protocol.BITFIELD_DOESACK): - self.logger.info( + logger.info( 'Not bothering to include ackdata because' ' the receiver said that they won\'t relay it anyway.' ) @@ -1209,7 +1201,7 @@ class singleWorker(StoppableThread): requiredPayloadLengthExtraBytes )) / (2 ** 16)) )) - self.logger.info( + logger.info( '(For msg message) Doing proof of work. Total required' ' difficulty: %f. Required small message difficulty: %f.', float(requiredAverageProofOfWorkNonceTrialsPerByte) / @@ -1221,13 +1213,12 @@ class singleWorker(StoppableThread): powStartTime = time.time() initialHash = hashlib.sha512(encryptedPayload).digest() trialValue, nonce = proofofwork.run(target, initialHash) - print("nonce calculated value#############################", nonce) - self.logger.info( + logger.info( '(For msg message) Found proof of work %s Nonce: %s', trialValue, nonce ) try: - self.logger.info( + logger.info( 'PoW took %.1f seconds, speed %s.', time.time() - powStartTime, sizeof_fmt(nonce / (time.time() - powStartTime)) @@ -1242,7 +1233,7 @@ class singleWorker(StoppableThread): # in the code to not let the user try to send a message # this large until we implement message continuation. if len(encryptedPayload) > 2 ** 18: # 256 KiB - self.logger.critical( + logger.critical( 'This msg object is too large to send. This should' ' never happen. Object size: %i', len(encryptedPayload) @@ -1273,7 +1264,7 @@ class singleWorker(StoppableThread): " Sent on %1" ).arg(l10n.formatTimestamp())) )) - self.logger.info( + logger.info( 'Broadcasting inv for my msg(within sendmsg function): %s', hexlify(inventoryHash) ) @@ -1326,7 +1317,7 @@ class singleWorker(StoppableThread): toStatus, addressVersionNumber, streamNumber, ripe = decodeAddress( toAddress) if toStatus != 'success': - self.logger.error( + logger.error( 'Very abnormal error occurred in requestPubKey.' ' toAddress is: %r. Please report this error to Atheros.', toAddress @@ -1340,7 +1331,7 @@ class singleWorker(StoppableThread): toAddress ) if not queryReturn: - self.logger.critical( + logger.critical( 'BUG: Why are we requesting the pubkey for %s' ' if there are no messages in the sent folder' ' to that address?', toAddress @@ -1388,11 +1379,11 @@ class singleWorker(StoppableThread): payload += encodeVarint(streamNumber) if addressVersionNumber <= 3: payload += ripe - self.logger.info( + logger.info( 'making request for pubkey with ripe: %s', hexlify(ripe)) else: payload += tag - self.logger.info( + logger.info( 'making request for v4 pubkey with tag: %s', hexlify(tag)) # print 'trial value', trialValue @@ -1413,7 +1404,7 @@ class singleWorker(StoppableThread): objectType = 1 Inventory()[inventoryHash] = ( objectType, streamNumber, payload, embeddedTime, '') - self.logger.info('sending inv (for the getpubkey message)') + logger.info('sending inv (for the getpubkey message)') queues.invQueue.put((streamNumber, inventoryHash)) # wait 10% past expiration diff --git a/src/class_smtpDeliver.py b/src/class_smtpDeliver.py index 4f8422cc..ef7a4363 100644 --- a/src/class_smtpDeliver.py +++ b/src/class_smtpDeliver.py @@ -1,9 +1,12 @@ """ -SMTP client thread for delivering emails +src/class_smtpDeliver.py +======================== """ # pylint: disable=unused-variable import smtplib +import sys +import threading import urlparse from email.header import Header from email.mime.text import MIMEText @@ -11,20 +14,23 @@ from email.mime.text import MIMEText import queues import state from bmconfigparser import BMConfigParser -from network.threads import StoppableThread +from debug import logger +from helper_threading import StoppableThread SMTPDOMAIN = "bmaddr.lan" -class smtpDeliver(StoppableThread): +class smtpDeliver(threading.Thread, StoppableThread): """SMTP client thread for delivery""" - name = "smtpDeliver" _instance = None + def __init__(self): + threading.Thread.__init__(self, name="smtpDeliver") + self.initStop() + def stopThread(self): - # pylint: disable=no-member try: - queues.UISignallerQueue.put(("stopThread", "data")) + queues.UISignallerQueue.put(("stopThread", "data")) # pylint: disable=no-member except: pass super(smtpDeliver, self).stopThread() @@ -38,7 +44,6 @@ class smtpDeliver(StoppableThread): def run(self): # pylint: disable=too-many-branches,too-many-statements,too-many-locals - # pylint: disable=deprecated-lambda while state.shutdown == 0: command, data = queues.UISignalQueue.get() if command == 'writeNewAddressToTable': @@ -61,9 +66,9 @@ class smtpDeliver(StoppableThread): msg = MIMEText(body, 'plain', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = fromAddress + '@' + SMTPDOMAIN - toLabel = map( + toLabel = map( # pylint: disable=deprecated-lambda lambda y: BMConfigParser().safeGet(y, "label"), - filter( + filter( # pylint: disable=deprecated-lambda lambda x: x == toAddress, BMConfigParser().addresses()) ) if toLabel: @@ -74,12 +79,10 @@ class smtpDeliver(StoppableThread): client.starttls() client.ehlo() client.sendmail(msg['From'], [to], msg.as_string()) - self.logger.info( - 'Delivered via SMTP to %s through %s:%i ...', - to, u.hostname, u.port) + logger.info("Delivered via SMTP to %s through %s:%i ...", to, u.hostname, u.port) client.quit() except: - self.logger.error('smtp delivery error', exc_info=True) + logger.error("smtp delivery error", exc_info=True) elif command == 'displayNewSentMessage': toAddress, fromLabel, fromAddress, subject, message, ackdata = data elif command == 'updateNetworkStatusTab': @@ -113,5 +116,5 @@ class smtpDeliver(StoppableThread): elif command == 'stopThread': break else: - self.logger.warning( - 'Command sent to smtpDeliver not recognized: %s', command) + sys.stderr.write( + 'Command sent to smtpDeliver not recognized: %s\n' % command) diff --git a/src/class_smtpServer.py b/src/class_smtpServer.py index 453ca640..216d35be 100644 --- a/src/class_smtpServer.py +++ b/src/class_smtpServer.py @@ -1,37 +1,28 @@ -""" -SMTP server thread -""" import asyncore import base64 import email -import logging +from email.parser import Parser +from email.header import decode_header import re import signal import smtpd import threading import time -from email.header import decode_header -from email.parser import Parser -import queues from addresses import decodeAddress from bmconfigparser import BMConfigParser -from helper_ackPayload import genAckPayload +from debug import logger from helper_sql import sqlExecute -from network.threads import StoppableThread +from helper_ackPayload import genAckPayload +from helper_threading import StoppableThread +import queues from version import softwareVersion SMTPDOMAIN = "bmaddr.lan" LISTENPORT = 8425 -logger = logging.getLogger('default') -# pylint: disable=attribute-defined-outside-init - - class smtpServerChannel(smtpd.SMTPChannel): - """Asyncore channel for SMTP protocol (server)""" def smtp_EHLO(self, arg): - """Process an EHLO""" if not arg: self.push('501 Syntax: HELO hostname') return @@ -39,17 +30,15 @@ class smtpServerChannel(smtpd.SMTPChannel): self.push('250 AUTH PLAIN') def smtp_AUTH(self, arg): - """Process AUTH""" if not arg or arg[0:5] not in ["PLAIN"]: self.push('501 Syntax: AUTH PLAIN') return authstring = arg[6:] try: decoded = base64.b64decode(authstring) - correctauth = "\x00" + BMConfigParser().safeGet( - "bitmessagesettings", "smtpdusername", "") + "\x00" + BMConfigParser().safeGet( - "bitmessagesettings", "smtpdpassword", "") - logger.debug('authstring: %s / %s', correctauth, decoded) + correctauth = "\x00" + BMConfigParser().safeGet("bitmessagesettings", "smtpdusername", "") + \ + "\x00" + BMConfigParser().safeGet("bitmessagesettings", "smtpdpassword", "") + logger.debug("authstring: %s / %s", correctauth, decoded) if correctauth == decoded: self.auth = True self.push('235 2.7.0 Authentication successful') @@ -59,17 +48,14 @@ class smtpServerChannel(smtpd.SMTPChannel): self.push('501 Authentication fail') def smtp_DATA(self, arg): - """Process DATA""" if not hasattr(self, "auth") or not self.auth: - self.push('530 Authentication required') + self.push ("530 Authentication required") return smtpd.SMTPChannel.smtp_DATA(self, arg) class smtpServerPyBitmessage(smtpd.SMTPServer): - """Asyncore SMTP server class""" def handle_accept(self): - """Accept a connection""" pair = self.accept() if pair is not None: conn, addr = pair @@ -77,9 +63,7 @@ class smtpServerPyBitmessage(smtpd.SMTPServer): self.channel = smtpServerChannel(self, conn, addr) def send(self, fromAddress, toAddress, subject, message): - """Send a bitmessage""" - # pylint: disable=arguments-differ - streamNumber, ripe = decodeAddress(toAddress)[2:] + status, addressVersionNumber, streamNumber, ripe = decodeAddress(toAddress) stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel') ackdata = genAckPayload(streamNumber, stealthLevel) sqlExecute( @@ -91,21 +75,19 @@ class smtpServerPyBitmessage(smtpd.SMTPServer): subject, message, ackdata, - int(time.time()), # sentTime (this will never change) - int(time.time()), # lastActionTime - 0, # sleepTill time. This will get set when the POW gets done. + int(time.time()), # sentTime (this will never change) + int(time.time()), # lastActionTime + 0, # sleepTill time. This will get set when the POW gets done. 'msgqueued', - 0, # retryNumber - 'sent', # folder - 2, # encodingtype - # not necessary to have a TTL higher than 2 days - min(BMConfigParser().getint('bitmessagesettings', 'ttl'), 86400 * 2) + 0, # retryNumber + 'sent', # folder + 2, # encodingtype + min(BMConfigParser().getint('bitmessagesettings', 'ttl'), 86400 * 2) # not necessary to have a TTL higher than 2 days ) queues.workerQueue.put(('sendmessage', toAddress)) def decode_header(self, hdr): - """Email header decoding""" ret = [] for h in decode_header(self.msg_headers[hdr]): if h[1]: @@ -115,38 +97,37 @@ class smtpServerPyBitmessage(smtpd.SMTPServer): return ret + def process_message(self, peer, mailfrom, rcpttos, data): - """Process an email""" - # pylint: disable=too-many-locals, too-many-branches - # print 'Receiving message from:', peer +# print 'Receiving message from:', peer p = re.compile(".*<([^>]+)>") if not hasattr(self.channel, "auth") or not self.channel.auth: - logger.error('Missing or invalid auth') + logger.error("Missing or invalid auth") return try: self.msg_headers = Parser().parsestr(data) except: - logger.error('Invalid headers') + logger.error("Invalid headers") return try: sender, domain = p.sub(r'\1', mailfrom).split("@") if domain != SMTPDOMAIN: - raise Exception("Bad domain %s" % domain) + raise Exception("Bad domain %s", domain) if sender not in BMConfigParser().addresses(): - raise Exception("Nonexisting user %s" % sender) + raise Exception("Nonexisting user %s", sender) except Exception as err: - logger.debug('Bad envelope from %s: %r', mailfrom, err) + logger.debug("Bad envelope from %s: %s", mailfrom, repr(err)) msg_from = self.decode_header("from") try: msg_from = p.sub(r'\1', self.decode_header("from")[0]) sender, domain = msg_from.split("@") if domain != SMTPDOMAIN: - raise Exception("Bad domain %s" % domain) + raise Exception("Bad domain %s", domain) if sender not in BMConfigParser().addresses(): - raise Exception("Nonexisting user %s" % sender) + raise Exception("Nonexisting user %s", sender) except Exception as err: - logger.error('Bad headers from %s: %r', msg_from, err) + logger.error("Bad headers from %s: %s", msg_from, repr(err)) return try: @@ -164,21 +145,19 @@ class smtpServerPyBitmessage(smtpd.SMTPServer): try: rcpt, domain = p.sub(r'\1', to).split("@") if domain != SMTPDOMAIN: - raise Exception("Bad domain %s" % domain) - logger.debug( - 'Sending %s to %s about %s', sender, rcpt, msg_subject) + raise Exception("Bad domain %s", domain) + logger.debug("Sending %s to %s about %s", sender, rcpt, msg_subject) self.send(sender, rcpt, msg_subject, body) - logger.info('Relayed %s to %s', sender, rcpt) + logger.info("Relayed %s to %s", sender, rcpt) except Exception as err: - logger.error('Bad to %s: %r', to, err) + logger.error( "Bad to %s: %s", to, repr(err)) continue return - -class smtpServer(StoppableThread): - """SMTP server thread""" - def __init__(self, _=None): - super(smtpServer, self).__init__(name="smtpServerThread") +class smtpServer(threading.Thread, StoppableThread): + def __init__(self, parent=None): + threading.Thread.__init__(self, name="smtpServerThread") + self.initStop() self.server = smtpServerPyBitmessage(('127.0.0.1', LISTENPORT), None) def stopThread(self): @@ -189,26 +168,21 @@ class smtpServer(StoppableThread): def run(self): asyncore.loop(1) - -def signals(_, __): - """Signal handler""" - logger.warning('Got signal, terminating') +def signals(signal, frame): + print "Got signal, terminating" for thread in threading.enumerate(): if thread.isAlive() and isinstance(thread, StoppableThread): thread.stopThread() - def runServer(): - """Run SMTP server as a standalone python process""" - logger.warning('Running SMTPd thread') + print "Running SMTPd thread" smtpThread = smtpServer() smtpThread.start() signal.signal(signal.SIGINT, signals) signal.signal(signal.SIGTERM, signals) - logger.warning('Processing') + print "Processing" smtpThread.join() - logger.warning('The end') - + print "The end" if __name__ == "__main__": runServer() diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 7e9eb6c5..a45571e0 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -1,33 +1,29 @@ -""" -sqlThread is defined here -""" - -import os -import shutil # used for moving the messages.dat file -import sqlite3 -import sys import threading +from bmconfigparser import BMConfigParser +import sqlite3 import time - +import shutil # used for moving the messages.dat file +import sys +import os +from debug import logger import helper_sql import helper_startup import paths import queues import state import tr -from bmconfigparser import BMConfigParser -from debug import logger -# pylint: disable=attribute-defined-outside-init,protected-access + +# This thread exists because SQLITE3 is so un-threadsafe that we must +# submit queries to it and it puts results back in a different queue. They +# won't let us just use locks. class sqlThread(threading.Thread): - """A thread for all SQL operations""" def __init__(self): threading.Thread.__init__(self, name="SQL") - def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-statements - """Process SQL queries from `.helper_sql.sqlSubmitQueue`""" + def run(self): self.conn = sqlite3.connect(state.appdata + 'messages.dat') self.conn.text_factory = str self.cur = self.conn.cursor() @@ -36,38 +32,30 @@ class sqlThread(threading.Thread): try: self.cur.execute( - '''CREATE TABLE inbox (msgid blob, toaddress text, fromaddress text, subject text,''' - ''' received text, message text, folder text, encodingtype int, read bool, sighash blob,''' - ''' UNIQUE(msgid) ON CONFLICT REPLACE)''') + '''CREATE TABLE inbox (msgid blob, toaddress text, fromaddress text, subject text, received text, message text, folder text, encodingtype int, read bool, sighash blob, UNIQUE(msgid) ON CONFLICT REPLACE)''' ) self.cur.execute( - '''CREATE TABLE sent (msgid blob, toaddress text, toripe blob, fromaddress text, subject text,''' - ''' message text, ackdata blob, senttime integer, lastactiontime integer,''' - ''' sleeptill integer, status text, retrynumber integer, folder text, encodingtype int, ttl int)''') + '''CREATE TABLE sent (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text, ackdata blob, senttime integer, lastactiontime integer, sleeptill integer, status text, retrynumber integer, folder text, encodingtype int, ttl int)''' ) self.cur.execute( - '''CREATE TABLE subscriptions (label text, address text, enabled bool)''') + '''CREATE TABLE subscriptions (label text, address text, enabled bool)''' ) self.cur.execute( - '''CREATE TABLE addressbook (label text, address text)''') + '''CREATE TABLE addressbook (label text, address text)''' ) self.cur.execute( - '''CREATE TABLE blacklist (label text, address text, enabled bool)''') + '''CREATE TABLE blacklist (label text, address text, enabled bool)''' ) self.cur.execute( - '''CREATE TABLE whitelist (label text, address text, enabled bool)''') + '''CREATE TABLE whitelist (label text, address text, enabled bool)''' ) self.cur.execute( - '''CREATE TABLE pubkeys (address text, addressversion int, transmitdata blob, time int,''' - ''' usedpersonally text, UNIQUE(address) ON CONFLICT REPLACE)''') + '''CREATE TABLE pubkeys (address text, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(address) ON CONFLICT REPLACE)''' ) self.cur.execute( - '''CREATE TABLE inventory (hash blob, objecttype int, streamnumber int, payload blob,''' - ''' expirestime integer, tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''') + '''CREATE TABLE inventory (hash blob, objecttype int, streamnumber int, payload blob, expirestime integer, tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''' ) self.cur.execute( - '''INSERT INTO subscriptions VALUES''' - '''('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''') + '''INSERT INTO subscriptions VALUES('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''') self.cur.execute( - '''CREATE TABLE settings (key blob, value blob, UNIQUE(key) ON CONFLICT REPLACE)''') - self.cur.execute('''INSERT INTO settings VALUES('version','10')''') - self.cur.execute('''INSERT INTO settings VALUES('lastvacuumtime',?)''', ( + '''CREATE TABLE settings (key blob, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' ) + self.cur.execute( '''INSERT INTO settings VALUES('version','10')''') + self.cur.execute( '''INSERT INTO settings VALUES('lastvacuumtime',?)''', ( int(time.time()),)) self.cur.execute( - '''CREATE TABLE objectprocessorqueue''' - ''' (objecttype int, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''') + '''CREATE TABLE objectprocessorqueue (objecttype int, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''' ) self.conn.commit() logger.info('Created messages database file') except Exception as err: @@ -132,38 +120,33 @@ class sqlThread(threading.Thread): logger.debug( "In messages.dat database, creating new 'settings' table.") self.cur.execute( - '''CREATE TABLE settings (key text, value blob, UNIQUE(key) ON CONFLICT REPLACE)''') - self.cur.execute('''INSERT INTO settings VALUES('version','1')''') - self.cur.execute('''INSERT INTO settings VALUES('lastvacuumtime',?)''', ( + '''CREATE TABLE settings (key text, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' ) + self.cur.execute( '''INSERT INTO settings VALUES('version','1')''') + self.cur.execute( '''INSERT INTO settings VALUES('lastvacuumtime',?)''', ( int(time.time()),)) logger.debug('In messages.dat database, removing an obsolete field from the pubkeys table.') self.cur.execute( - '''CREATE TEMPORARY TABLE pubkeys_backup(hash blob, transmitdata blob, time int,''' - ''' usedpersonally text, UNIQUE(hash) ON CONFLICT REPLACE);''') + '''CREATE TEMPORARY TABLE pubkeys_backup(hash blob, transmitdata blob, time int, usedpersonally text, UNIQUE(hash) ON CONFLICT REPLACE);''') self.cur.execute( '''INSERT INTO pubkeys_backup SELECT hash, transmitdata, time, usedpersonally FROM pubkeys;''') - self.cur.execute('''DROP TABLE pubkeys''') + self.cur.execute( '''DROP TABLE pubkeys''') self.cur.execute( - '''CREATE TABLE pubkeys''' - ''' (hash blob, transmitdata blob, time int, usedpersonally text, UNIQUE(hash) ON CONFLICT REPLACE)''') + '''CREATE TABLE pubkeys (hash blob, transmitdata blob, time int, usedpersonally text, UNIQUE(hash) ON CONFLICT REPLACE)''' ) self.cur.execute( '''INSERT INTO pubkeys SELECT hash, transmitdata, time, usedpersonally FROM pubkeys_backup;''') - self.cur.execute('''DROP TABLE pubkeys_backup;''') - logger.debug( - 'Deleting all pubkeys from inventory.' - ' They will be redownloaded and then saved with the correct times.') + self.cur.execute( '''DROP TABLE pubkeys_backup;''') + logger.debug('Deleting all pubkeys from inventory. They will be redownloaded and then saved with the correct times.') self.cur.execute( '''delete from inventory where objecttype = 'pubkey';''') logger.debug('replacing Bitmessage announcements mailing list with a new one.') self.cur.execute( '''delete from subscriptions where address='BM-BbkPSZbzPwpVcYZpU4yHwf9ZPEapN5Zx' ''') self.cur.execute( - '''INSERT INTO subscriptions VALUES''' - '''('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''') + '''INSERT INTO subscriptions VALUES('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''') logger.debug('Commiting.') self.conn.commit() logger.debug('Vacuuming message.dat. You might notice that the file size gets much smaller.') - self.cur.execute(''' VACUUM ''') + self.cur.execute( ''' VACUUM ''') # After code refactoring, the possible status values for sent messages # have changed. @@ -187,21 +170,15 @@ class sqlThread(threading.Thread): 'In messages.dat database, removing an obsolete field from' ' the inventory table.') self.cur.execute( - '''CREATE TEMPORARY TABLE inventory_backup''' - '''(hash blob, objecttype text, streamnumber int, payload blob,''' - ''' receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE);''') + '''CREATE TEMPORARY TABLE inventory_backup(hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE);''') self.cur.execute( - '''INSERT INTO inventory_backup SELECT hash, objecttype, streamnumber, payload, receivedtime''' - ''' FROM inventory;''') - self.cur.execute('''DROP TABLE inventory''') + '''INSERT INTO inventory_backup SELECT hash, objecttype, streamnumber, payload, receivedtime FROM inventory;''') + self.cur.execute( '''DROP TABLE inventory''') self.cur.execute( - '''CREATE TABLE inventory''' - ''' (hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer,''' - ''' UNIQUE(hash) ON CONFLICT REPLACE)''') + '''CREATE TABLE inventory (hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE)''' ) self.cur.execute( - '''INSERT INTO inventory SELECT hash, objecttype, streamnumber, payload, receivedtime''' - ''' FROM inventory_backup;''') - self.cur.execute('''DROP TABLE inventory_backup;''') + '''INSERT INTO inventory SELECT hash, objecttype, streamnumber, payload, receivedtime FROM inventory_backup;''') + self.cur.execute( '''DROP TABLE inventory_backup;''') item = '''update settings set value=? WHERE key='version';''' parameters = (3,) self.cur.execute(item, parameters) @@ -231,8 +208,7 @@ class sqlThread(threading.Thread): if currentVersion == 4: self.cur.execute('''DROP TABLE pubkeys''') self.cur.execute( - '''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int,''' - '''usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''') + '''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''') self.cur.execute( '''delete from inventory where objecttype = 'pubkey';''') item = '''update settings set value=? WHERE key='version';''' @@ -248,8 +224,7 @@ class sqlThread(threading.Thread): if currentVersion == 5: self.cur.execute('''DROP TABLE knownnodes''') self.cur.execute( - '''CREATE TABLE objectprocessorqueue''' - ''' (objecttype text, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''') + '''CREATE TABLE objectprocessorqueue (objecttype text, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''') item = '''update settings set value=? WHERE key='version';''' parameters = (6,) self.cur.execute(item, parameters) @@ -265,15 +240,10 @@ class sqlThread(threading.Thread): logger.debug( 'In messages.dat database, dropping and recreating' ' the inventory table.') - self.cur.execute('''DROP TABLE inventory''') - self.cur.execute( - '''CREATE TABLE inventory''' - ''' (hash blob, objecttype int, streamnumber int, payload blob, expirestime integer,''' - ''' tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''') - self.cur.execute('''DROP TABLE objectprocessorqueue''') - self.cur.execute( - '''CREATE TABLE objectprocessorqueue''' - ''' (objecttype int, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''') + self.cur.execute( '''DROP TABLE inventory''') + self.cur.execute( '''CREATE TABLE inventory (hash blob, objecttype int, streamnumber int, payload blob, expirestime integer, tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''' ) + self.cur.execute( '''DROP TABLE objectprocessorqueue''') + self.cur.execute( '''CREATE TABLE objectprocessorqueue (objecttype int, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''' ) item = '''update settings set value=? WHERE key='version';''' parameters = (7,) self.cur.execute(item, parameters) @@ -335,24 +305,15 @@ class sqlThread(threading.Thread): ' fields into the retrynumber field and adding the' ' sleeptill and ttl fields...') self.cur.execute( - '''CREATE TEMPORARY TABLE sent_backup''' - ''' (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text,''' - ''' ackdata blob, lastactiontime integer, status text, retrynumber integer,''' - ''' folder text, encodingtype int)''') + '''CREATE TEMPORARY TABLE sent_backup (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text, ackdata blob, lastactiontime integer, status text, retrynumber integer, folder text, encodingtype int)''' ) self.cur.execute( - '''INSERT INTO sent_backup SELECT msgid, toaddress, toripe, fromaddress,''' - ''' subject, message, ackdata, lastactiontime,''' - ''' status, 0, folder, encodingtype FROM sent;''') - self.cur.execute('''DROP TABLE sent''') + '''INSERT INTO sent_backup SELECT msgid, toaddress, toripe, fromaddress, subject, message, ackdata, lastactiontime, status, 0, folder, encodingtype FROM sent;''') + self.cur.execute( '''DROP TABLE sent''') self.cur.execute( - '''CREATE TABLE sent''' - ''' (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text,''' - ''' ackdata blob, senttime integer, lastactiontime integer, sleeptill int, status text,''' - ''' retrynumber integer, folder text, encodingtype int, ttl int)''') + '''CREATE TABLE sent (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text, ackdata blob, senttime integer, lastactiontime integer, sleeptill int, status text, retrynumber integer, folder text, encodingtype int, ttl int)''' ) self.cur.execute( - '''INSERT INTO sent SELECT msgid, toaddress, toripe, fromaddress, subject, message, ackdata,''' - ''' lastactiontime, lastactiontime, 0, status, 0, folder, encodingtype, 216000 FROM sent_backup;''') - self.cur.execute('''DROP TABLE sent_backup''') + '''INSERT INTO sent SELECT msgid, toaddress, toripe, fromaddress, subject, message, ackdata, lastactiontime, lastactiontime, 0, status, 0, folder, encodingtype, 216000 FROM sent_backup;''') + self.cur.execute( '''DROP TABLE sent_backup''') logger.info('In messages.dat database, finished making TTL-related changes.') logger.debug('In messages.dat database, adding address field to the pubkeys table.') # We're going to have to calculate the address for each row in the pubkeys @@ -369,24 +330,16 @@ class sqlThread(threading.Thread): self.cur.execute(item, parameters) # Now we can remove the hash field from the pubkeys table. self.cur.execute( - '''CREATE TEMPORARY TABLE pubkeys_backup''' - ''' (address text, addressversion int, transmitdata blob, time int,''' - ''' usedpersonally text, UNIQUE(address) ON CONFLICT REPLACE)''') + '''CREATE TEMPORARY TABLE pubkeys_backup (address text, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(address) ON CONFLICT REPLACE)''' ) self.cur.execute( - '''INSERT INTO pubkeys_backup''' - ''' SELECT address, addressversion, transmitdata, time, usedpersonally FROM pubkeys;''') - self.cur.execute('''DROP TABLE pubkeys''') + '''INSERT INTO pubkeys_backup SELECT address, addressversion, transmitdata, time, usedpersonally FROM pubkeys;''') + self.cur.execute( '''DROP TABLE pubkeys''') self.cur.execute( - '''CREATE TABLE pubkeys''' - ''' (address text, addressversion int, transmitdata blob, time int, usedpersonally text,''' - ''' UNIQUE(address) ON CONFLICT REPLACE)''') + '''CREATE TABLE pubkeys (address text, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(address) ON CONFLICT REPLACE)''' ) self.cur.execute( - '''INSERT INTO pubkeys SELECT''' - ''' address, addressversion, transmitdata, time, usedpersonally FROM pubkeys_backup;''') - self.cur.execute('''DROP TABLE pubkeys_backup''') - logger.debug( - 'In messages.dat database, done adding address field to the pubkeys table' - ' and removing the hash field.') + '''INSERT INTO pubkeys SELECT address, addressversion, transmitdata, time, usedpersonally FROM pubkeys_backup;''') + self.cur.execute( '''DROP TABLE pubkeys_backup''') + logger.debug('In messages.dat database, done adding address field to the pubkeys table and removing the hash field.') self.cur.execute('''update settings set value=10 WHERE key='version';''') # Are you hoping to add a new option to the keys.dat file of existing @@ -396,7 +349,7 @@ class sqlThread(threading.Thread): try: testpayload = '\x00\x00' t = ('1234', 1, testpayload, '12345678', 'no') - self.cur.execute('''INSERT INTO pubkeys VALUES(?,?,?,?,?)''', t) + self.cur.execute( '''INSERT INTO pubkeys VALUES(?,?,?,?,?)''', t) self.conn.commit() self.cur.execute( '''SELECT transmitdata FROM pubkeys WHERE address='1234' ''') @@ -406,29 +359,13 @@ class sqlThread(threading.Thread): self.cur.execute('''DELETE FROM pubkeys WHERE address='1234' ''') self.conn.commit() if transmitdata == '': - logger.fatal( - 'Problem: The version of SQLite you have cannot store Null values.' - ' Please download and install the latest revision of your version of Python' - ' (for example, the latest Python 2.7 revision) and try again.\n') - logger.fatal( - 'PyBitmessage will now exit very abruptly.' - ' You may now see threading errors related to this abrupt exit' - ' but the problem you need to solve is related to SQLite.\n\n') + logger.fatal('Problem: The version of SQLite you have cannot store Null values. Please download and install the latest revision of your version of Python (for example, the latest Python 2.7 revision) and try again.\n') + logger.fatal('PyBitmessage will now exit very abruptly. You may now see threading errors related to this abrupt exit but the problem you need to solve is related to SQLite.\n\n') os._exit(0) except Exception as err: if str(err) == 'database or disk is full': - logger.fatal( - '(While null value test) Alert: Your disk or data storage volume is full.' - ' sqlThread will now exit.') - queues.UISignalQueue.put(( - 'alert', ( - tr._translate( - "MainWindow", - "Disk full"), - tr._translate( - "MainWindow", - 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), - True))) + logger.fatal('(While null value test) Alert: Your disk or data storage volume is full. sqlThread will now exit.') + queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True))) os._exit(0) else: logger.error(err) @@ -444,21 +381,11 @@ class sqlThread(threading.Thread): if int(value) < int(time.time()) - 86400: logger.info('It has been a long time since the messages.dat file has been vacuumed. Vacuuming now...') try: - self.cur.execute(''' VACUUM ''') + self.cur.execute( ''' VACUUM ''') except Exception as err: if str(err) == 'database or disk is full': - logger.fatal( - '(While VACUUM) Alert: Your disk or data storage volume is full.' - ' sqlThread will now exit.') - queues.UISignalQueue.put(( - 'alert', ( - tr._translate( - "MainWindow", - "Disk full"), - tr._translate( - "MainWindow", - 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), - True))) + logger.fatal('(While VACUUM) Alert: Your disk or data storage volume is full. sqlThread will now exit.') + queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True))) os._exit(0) item = '''update settings set value=? WHERE key='lastvacuumtime';''' parameters = (int(time.time()),) @@ -473,18 +400,8 @@ class sqlThread(threading.Thread): self.conn.commit() except Exception as err: if str(err) == 'database or disk is full': - logger.fatal( - '(While committing) Alert: Your disk or data storage volume is full.' - ' sqlThread will now exit.') - queues.UISignalQueue.put(( - 'alert', ( - tr._translate( - "MainWindow", - "Disk full"), - tr._translate( - "MainWindow", - 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), - True))) + logger.fatal('(While committing) Alert: Your disk or data storage volume is full. sqlThread will now exit.') + queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True))) os._exit(0) elif item == 'exit': self.conn.close() @@ -498,18 +415,8 @@ class sqlThread(threading.Thread): self.conn.commit() except Exception as err: if str(err) == 'database or disk is full': - logger.fatal( - '(while movemessagstoprog) Alert: Your disk or data storage volume is full.' - ' sqlThread will now exit.') - queues.UISignalQueue.put(( - 'alert', ( - tr._translate( - "MainWindow", - "Disk full"), - tr._translate( - "MainWindow", - 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), - True))) + logger.fatal('(while movemessagstoprog) Alert: Your disk or data storage volume is full. sqlThread will now exit.') + queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True))) os._exit(0) self.conn.close() shutil.move( @@ -524,18 +431,8 @@ class sqlThread(threading.Thread): self.conn.commit() except Exception as err: if str(err) == 'database or disk is full': - logger.fatal( - '(while movemessagstoappdata) Alert: Your disk or data storage volume is full.' - ' sqlThread will now exit.') - queues.UISignalQueue.put(( - 'alert', ( - tr._translate( - "MainWindow", - "Disk full"), - tr._translate( - "MainWindow", - 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), - True))) + logger.fatal('(while movemessagstoappdata) Alert: Your disk or data storage volume is full. sqlThread will now exit.') + queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True))) os._exit(0) self.conn.close() shutil.move( @@ -548,21 +445,11 @@ class sqlThread(threading.Thread): self.cur.execute('''delete from sent where folder='trash' ''') self.conn.commit() try: - self.cur.execute(''' VACUUM ''') + self.cur.execute( ''' VACUUM ''') except Exception as err: if str(err) == 'database or disk is full': - logger.fatal( - '(while deleteandvacuume) Alert: Your disk or data storage volume is full.' - ' sqlThread will now exit.') - queues.UISignalQueue.put(( - 'alert', ( - tr._translate( - "MainWindow", - "Disk full"), - tr._translate( - "MainWindow", - 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), - True))) + logger.fatal('(while deleteandvacuume) Alert: Your disk or data storage volume is full. sqlThread will now exit.') + queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True))) os._exit(0) else: parameters = helper_sql.sqlSubmitQueue.get() @@ -574,30 +461,11 @@ class sqlThread(threading.Thread): rowcount = self.cur.rowcount except Exception as err: if str(err) == 'database or disk is full': - logger.fatal( - '(while cur.execute) Alert: Your disk or data storage volume is full.' - ' sqlThread will now exit.') - queues.UISignalQueue.put(( - 'alert', ( - tr._translate( - "MainWindow", - "Disk full"), - tr._translate( - "MainWindow", - 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), - True))) + logger.fatal('(while cur.execute) Alert: Your disk or data storage volume is full. sqlThread will now exit.') + queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True))) os._exit(0) else: - logger.fatal( - 'Major error occurred when trying to execute a SQL statement within the sqlThread.' - ' Please tell Atheros about this error message or post it in the forum!' - ' Error occurred while trying to execute statement: "%s" Here are the parameters;' - ' you might want to censor this data with asterisks (***)' - ' as it can contain private information: %s.' - ' Here is the actual error message thrown by the sqlThread: %s', - str(item), - str(repr(parameters)), - str(err)) + logger.fatal('Major error occurred when trying to execute a SQL statement within the sqlThread. Please tell Atheros about this error message or post it in the forum! Error occurred while trying to execute statement: "%s" Here are the parameters; you might want to censor this data with asterisks (***) as it can contain private information: %s. Here is the actual error message thrown by the sqlThread: %s', str(item), str(repr(parameters)), str(err)) logger.fatal('This program shall now abruptly exit!') os._exit(0) diff --git a/src/dave.png b/src/dave.png deleted file mode 100644 index e8d7bd0b004741caf27eb657dbe0a66e72a8f2eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmeAS@N?(olHy`uVBq!ia0vp^A3&Ic4M^IBzMRCsz!d1|;uunK>+RKpyoVJ;Tn-BS zbXk1Gr97I|-Gg;sB-gfdtqtK-e>> import logging ->>> logger = logging.getLogger('default') - -The old form: ``from debug import logger`` is also may be used, -but only in the top level modules. - -Logging is thread-safe so you don't have to worry about locks, -just import and log. """ import ConfigParser @@ -40,11 +28,11 @@ import logging import logging.config import os import sys - import helper_startup import state helper_startup.loadConfig() + # Now can be overriden from a config file, which uses standard python # logging.config.fileConfig interface # examples are here: @@ -53,22 +41,14 @@ log_level = 'WARNING' def log_uncaught_exceptions(ex_cls, ex, tb): - """The last resort logging function used for sys.excepthook""" logging.critical('Unhandled exception', exc_info=(ex_cls, ex, tb)) def configureLogging(): - """ - Configure logging, - using either logging.dat file in the state.appdata dir - or dictionary with hardcoded settings. - """ - sys.excepthook = log_uncaught_exceptions fail_msg = '' try: logging_config = os.path.join(state.appdata, 'logging.dat') - logging.config.fileConfig( - logging_config, disable_existing_loggers=False) + logging.config.fileConfig(logging_config) return ( False, 'Loaded logger configuration from %s' % logging_config @@ -80,11 +60,12 @@ def configureLogging(): ' logging config\n%s' % \ (logging_config, sys.exc_info()) else: - # no need to confuse the user if the logger config - # is missing entirely + # no need to confuse the user if the logger config is missing entirely fail_msg = 'Using default logger configuration' - logging_config = { + sys.excepthook = log_uncaught_exceptions + + logging.config.dictConfig({ 'version': 1, 'formatters': { 'default': { @@ -126,29 +107,34 @@ def configureLogging(): 'level': log_level, 'handlers': ['console'], }, - } - - logging_config['loggers']['default'] = logging_config['loggers'][ - 'file_only' if '-c' in sys.argv else 'both'] - logging.config.dictConfig(logging_config) + }) return True, fail_msg +def initLogging(): + preconfigured, msg = configureLogging() + if preconfigured: + if '-c' in sys.argv: + logger = logging.getLogger('file_only') + else: + logger = logging.getLogger('both') + else: + logger = logging.getLogger('default') + + if msg: + logger.log(logging.WARNING if preconfigured else logging.INFO, msg) + return logger + + def resetLogging(): - """Reconfigure logging in runtime when state.appdata dir changed""" - # pylint: disable=global-statement, used-before-assignment global logger - for i in logger.handlers: + for i in logger.handlers.iterkeys(): logger.removeHandler(i) i.flush() i.close() - configureLogging() - logger = logging.getLogger('default') + logger = initLogging() # ! -preconfigured, msg = configureLogging() -logger = logging.getLogger('default') -if msg: - logger.log(logging.WARNING if preconfigured else logging.INFO, msg) +logger = initLogging() diff --git a/src/defaults.py b/src/defaults.py index 32162b56..d10f9000 100644 --- a/src/defaults.py +++ b/src/defaults.py @@ -1,24 +1,24 @@ """ -Common default values +src/defaults.py +=============== """ -#: sanity check, prevent doing ridiculous PoW -#: 20 million PoWs equals approximately 2 days on dev's dual R9 290 +# sanity check, prevent doing ridiculous PoW +# 20 million PoWs equals approximately 2 days on dev's dual R9 290 ridiculousDifficulty = 20000000 -#: Remember here the RPC port read from namecoin.conf so we can restore to -#: it as default whenever the user changes the "method" selection for -#: namecoin integration to "namecoind". +# Remember here the RPC port read from namecoin.conf so we can restore to +# it as default whenever the user changes the "method" selection for +# namecoin integration to "namecoind". namecoinDefaultRpcPort = "8336" # If changed, these values will cause particularly unexpected behavior: # You won't be able to either send or receive messages because the proof # of work you do (or demand) won't match that done or demanded by others. # Don't change them! -#: The amount of work that should be performed (and demanded) per byte -#: of the payload. +# The amount of work that should be performed (and demanded) per byte of the payload. networkDefaultProofOfWorkNonceTrialsPerByte = 1000 -#: To make sending short messages a little more difficult, this value is -#: added to the payload length for use in calculating the proof of work -#: target. +# To make sending short messages a little more difficult, this value is +# added to the payload length for use in calculating the proof of work +# target. networkDefaultPayloadLengthExtraBytes = 1000 diff --git a/src/depends.py b/src/depends.py index 82529269..0114ec94 100755 --- a/src/depends.py +++ b/src/depends.py @@ -17,7 +17,7 @@ if not hasattr(sys, 'hexversion') or sys.hexversion < 0x20300F0: import logging import os from importlib import import_module -import state + # We can now use logging so set up a simple configuration formatter = logging.Formatter('%(levelname)s: %(message)s') handler = logging.StreamHandler(sys.stdout) @@ -113,7 +113,6 @@ PACKAGES = { def detectOS(): - """Finding out what Operating System is running""" if detectOS.result is not None: return detectOS.result if sys.platform.startswith('openbsd'): @@ -133,7 +132,6 @@ detectOS.result = None def detectOSRelease(): - """Detecting the release of OS""" with open("/etc/os-release", 'r') as osRelease: version = None for line in osRelease: @@ -150,7 +148,6 @@ def detectOSRelease(): def try_import(module, log_extra=False): - """Try to import the non imported packages""" try: return import_module(module) except ImportError: @@ -211,8 +208,10 @@ def check_sqlite(): ).fetchone()[0] logger.info('SQLite Library Source ID: %s', sqlite_source_id) if sqlite_version_number >= 3006023: - compile_options = ', '.join( - [row[0] for row in conn.execute('PRAGMA compile_options;')]) + compile_options = ', '.join(map( + lambda row: row[0], + conn.execute('PRAGMA compile_options;') + )) logger.info( 'SQLite Library Compile Options: %s', compile_options) # There is no specific version requirement as yet, so we just @@ -237,8 +236,7 @@ def check_openssl(): Here we are checking for openssl with its all dependent libraries and version checking. """ - # pylint: disable=too-many-branches, too-many-return-statements - # pylint: disable=protected-access, redefined-outer-name + ctypes = try_import('ctypes') if not ctypes: logger.error('Unable to check OpenSSL.') @@ -250,11 +248,8 @@ def check_openssl(): if getattr(sys, 'frozen', False): import os.path paths.insert(0, os.path.join(sys._MEIPASS, 'libeay32.dll')) - elif state.kivy: - return True else: paths = ['libcrypto.so', 'libcrypto.so.1.0.0'] - if sys.platform == 'darwin': paths.extend([ 'libcrypto.dylib', @@ -305,7 +300,7 @@ def check_openssl(): ' ECDH, and ECDSA enabled.') return False matches = cflags_regex.findall(openssl_cflags) - if matches: + if len(matches) > 0: logger.error( 'This OpenSSL library is missing the following required' ' features: %s. PyBitmessage requires OpenSSL 0.9.8b' @@ -316,13 +311,13 @@ def check_openssl(): return False -# ..todo:: The minimum versions of pythondialog and dialog need to be determined +# TODO: The minimum versions of pythondialog and dialog need to be determined def check_curses(): """Do curses dependency check. - Here we are checking for curses if available or not with check as interface - requires the `pythondialog `_ package - and the dialog utility. + Here we are checking for curses if available or not with check + as interface requires the pythondialog\ package and the dialog + utility. """ if sys.hexversion < 0x20600F0: logger.error( @@ -430,6 +425,7 @@ def check_dependencies(verbose=False, optional=False): check_functions = [check_ripemd160, check_sqlite, check_openssl] if optional: check_functions.extend([check_msgpack, check_pyqt, check_curses]) + # Unexpected exceptions are handled here for check in check_functions: try: diff --git a/src/eve.png b/src/eve.png deleted file mode 100644 index e11ff6f58c713de06df151cf2349605ae4ae5cec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651 zcmeAS@N?(olHy`uVBq!ia0vp^A3&Ic4M^IBzMRCsz!c=^;uunK>+RKpyoVJ8Tn`HT zbXk1GrF=hE-vq9r4iQbhGa(83Rl8MBRx#AS%w$nWa5&J=;0VNwjLb}IAk4x8!W`_ -in that case. +.. todo:: hello world """ import hashlib +# We need to check hashlib for RIPEMD-160, as it won't be available +# if OpenSSL is not linked against or the linked OpenSSL has RIPEMD +# disabled. + try: hashlib.new('ripemd160') except ValueError: diff --git a/src/helper_ackPayload.py b/src/helper_ackPayload.py index d30f4c0d..acdbadf7 100644 --- a/src/helper_ackPayload.py +++ b/src/helper_ackPayload.py @@ -1,28 +1,22 @@ -""" -This module is for generating ack payload -""" +"""This module is for generating ack payload.""" +import highlevelcrypto +import helper_random from binascii import hexlify from struct import pack - -import helper_random -import highlevelcrypto from addresses import encodeVarint +# This function generates payload objects for message acknowledgements +# Several stealth levels are available depending on the privacy needs; +# a higher level means better stealth, but also higher cost (size+POW) +# - level 0: a random 32-byte sequence with a message header appended +# - level 1: a getpubkey request for a (random) dummy key hash +# - level 2: a standard message, encrypted to a random pubkey + def genAckPayload(streamNumber=1, stealthLevel=0): - """ - Generate and return payload obj. - - This function generates payload objects for message acknowledgements - Several stealth levels are available depending on the privacy needs; - a higher level means better stealth, but also higher cost (size+POW) - - - level 0: a random 32-byte sequence with a message header appended - - level 1: a getpubkey request for a (random) dummy key hash - - level 2: a standard message, encrypted to a random pubkey - """ - if stealthLevel == 2: # Generate privacy-enhanced payload + """Generate and return payload obj.""" + if (stealthLevel == 2): # Generate privacy-enhanced payload # Generate a dummy privkey and derive the pubkey dummyPubKeyHex = highlevelcrypto.privToPub( hexlify(helper_random.randomBytes(32))) @@ -35,7 +29,7 @@ def genAckPayload(streamNumber=1, stealthLevel=0): acktype = 2 # message version = 1 - elif stealthLevel == 1: # Basic privacy payload (random getpubkey) + elif (stealthLevel == 1): # Basic privacy payload (random getpubkey) ackdata = helper_random.randomBytes(32) acktype = 0 # getpubkey version = 4 diff --git a/src/helper_bitcoin.py b/src/helper_bitcoin.py index d4f1d105..d56e395b 100644 --- a/src/helper_bitcoin.py +++ b/src/helper_bitcoin.py @@ -1,19 +1,10 @@ -""" -Calculates bitcoin and testnet address from pubkey -""" - import hashlib - -from debug import logger from pyelliptic import arithmetic - +# This function expects that pubkey begin with \x04 def calculateBitcoinAddressFromPubkey(pubkey): - """Calculate bitcoin address from given pubkey (65 bytes long hex string)""" if len(pubkey) != 65: - logger.error('Could not calculate Bitcoin address from pubkey because' - ' function was passed a pubkey that was' - ' %i bytes long rather than 65.', len(pubkey)) + print 'Could not calculate Bitcoin address from pubkey because function was passed a pubkey that was', len(pubkey), 'bytes long rather than 65.' return "error" ripe = hashlib.new('ripemd160') sha = hashlib.new('sha256') @@ -33,11 +24,8 @@ def calculateBitcoinAddressFromPubkey(pubkey): def calculateTestnetAddressFromPubkey(pubkey): - """This function expects that pubkey begin with the testnet prefix""" if len(pubkey) != 65: - logger.error('Could not calculate Bitcoin address from pubkey because' - ' function was passed a pubkey that was' - ' %i bytes long rather than 65.', len(pubkey)) + print 'Could not calculate Bitcoin address from pubkey because function was passed a pubkey that was', len(pubkey), 'bytes long rather than 65.' return "error" ripe = hashlib.new('ripemd160') sha = hashlib.new('sha256') diff --git a/src/helper_bootstrap.py b/src/helper_bootstrap.py new file mode 100644 index 00000000..1710b09c --- /dev/null +++ b/src/helper_bootstrap.py @@ -0,0 +1,84 @@ +import socket + +import knownnodes +import socks +import state +from bmconfigparser import BMConfigParser +from debug import logger + + +def dns(): + """ + DNS bootstrap. This could be programmed to use the SOCKS proxy to do the + DNS lookup some day but for now we will just rely on the entries in + defaultKnownNodes.py. Hopefully either they are up to date or the user + has run Bitmessage recently without SOCKS turned on and received good + bootstrap nodes using that method. + """ + + def try_add_known_node(stream, addr, port, method=''): + try: + socket.inet_aton(addr) + except (TypeError, socket.error): + return + logger.info( + 'Adding %s to knownNodes based on %s DNS bootstrap method', + addr, method) + knownnodes.addKnownNode(stream, state.Peer(addr, port)) + + proxy_type = BMConfigParser().get('bitmessagesettings', 'socksproxytype') + + if proxy_type == 'none': + for port in [8080, 8444]: + try: + for item in socket.getaddrinfo( + 'bootstrap%s.bitmessage.org' % port, 80): + try_add_known_node(1, item[4][0], port) + except: + logger.error( + 'bootstrap%s.bitmessage.org DNS bootstrapping failed.', + port, exc_info=True + ) + elif proxy_type == 'SOCKS5': + knownnodes.createDefaultKnownNodes(onion=True) + logger.debug('Adding default onion knownNodes.') + for port in [8080, 8444]: + logger.debug("Resolving %i through SOCKS...", port) + address_family = socket.AF_INET + sock = socks.socksocket(address_family, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.settimeout(20) + proxytype = socks.PROXY_TYPE_SOCKS5 + sockshostname = BMConfigParser().get( + 'bitmessagesettings', 'sockshostname') + socksport = BMConfigParser().getint( + 'bitmessagesettings', 'socksport') + # Do domain name lookups through the proxy; + # though this setting doesn't really matter since we won't + # be doing any domain name lookups anyway. + rdns = True + if BMConfigParser().getboolean( + 'bitmessagesettings', 'socksauthentication'): + socksusername = BMConfigParser().get( + 'bitmessagesettings', 'socksusername') + sockspassword = BMConfigParser().get( + 'bitmessagesettings', 'sockspassword') + sock.setproxy( + proxytype, sockshostname, socksport, rdns, + socksusername, sockspassword) + else: + sock.setproxy( + proxytype, sockshostname, socksport, rdns) + try: + ip = sock.resolve("bootstrap" + str(port) + ".bitmessage.org") + sock.shutdown(socket.SHUT_RDWR) + sock.close() + except: + logger.error("SOCKS DNS resolving failed", exc_info=True) + else: + try_add_known_node(1, ip, port, 'SOCKS') + else: + logger.info( + 'DNS bootstrap skipped because the proxy type does not support' + ' DNS resolution.' + ) diff --git a/src/helper_generic.py b/src/helper_generic.py deleted file mode 100644 index 368a6c54..00000000 --- a/src/helper_generic.py +++ /dev/null @@ -1,114 +0,0 @@ -""" -Helper Generic perform generic operations for threading. - -Also perform some conversion operations. -""" - -import socket -import sys -import threading -import traceback -try: - import multiprocessing -except Exception as e: - pass -from binascii import hexlify, unhexlify - -import shared -import state -import queues -import shutdown -from debug import logger - - -def powQueueSize(): - curWorkerQueue = queues.workerQueue.qsize() - for thread in threading.enumerate(): - try: - if thread.name == "singleWorker": - curWorkerQueue += thread.busy - except Exception as err: - logger.info('Thread error %s', err) - return curWorkerQueue - - -def convertIntToString(n): - a = __builtins__.hex(n) - if a[-1:] == 'L': - a = a[:-1] - if (len(a) % 2) == 0: - return unhexlify(a[2:]) - else: - return unhexlify('0' + a[2:]) - - -def convertStringToInt(s): - return int(hexlify(s), 16) - - -def allThreadTraceback(frame): - id2name = dict([(th.ident, th.name) for th in threading.enumerate()]) - code = [] - for threadId, stack in sys._current_frames().items(): - code.append( - '\n# Thread: %s(%d)' % (id2name.get(threadId, ''), threadId)) - for filename, lineno, name, line in traceback.extract_stack(stack): - code.append( - 'File: "%s", line %d, in %s' % (filename, lineno, name)) - if line: - code.append(' %s' % (line.strip())) - print('\n'.join(code)) - - -def signal_handler(signal, frame): - try: - process = multiprocessing.current_process() - except Exception as e: - process = threading.current_thread() - logger.error( - 'Got signal %i in %s/%s', - signal, process.name, threading.current_thread().name - ) - if process.name == "RegExParser": - # on Windows this isn't triggered, but it's fine, - # it has its own process termination thing - raise SystemExit - if "PoolWorker" in process.name: - raise SystemExit - if threading.current_thread().name not in ("PyBitmessage", "MainThread"): - return - logger.error("Got signal %i", signal) - if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant? - shutdown.doCleanShutdown() - else: - allThreadTraceback(frame) - print('Unfortunately you cannot use Ctrl+C when running the UI' - ' because the UI captures the signal.') - - -def isHostInPrivateIPRange(host): - if ":" in host: # IPv6 - hostAddr = socket.inet_pton(socket.AF_INET6, host) - if hostAddr == ('\x00' * 15) + '\x01': - return False - if hostAddr[0] == '\xFE' and (ord(hostAddr[1]) & 0xc0) == 0x80: - return False - if (ord(hostAddr[0]) & 0xfe) == 0xfc: - return False - elif ".onion" not in host: - if host[:3] == '10.': - return True - if host[:4] == '172.': - if host[6] == '.': - if int(host[4:6]) >= 16 and int(host[4:6]) <= 31: - return True - if host[:8] == '192.168.': - return True - # Multicast - if host[:3] >= 224 and host[:3] <= 239 and host[4] == '.': - return True - return False - - -def addDataPadding(data, desiredMsgLength=12, paddingChar='\x00'): - return data + paddingChar * (desiredMsgLength - len(data)) diff --git a/src/helper_inbox.py b/src/helper_inbox.py index 654dd59d..95214743 100644 --- a/src/helper_inbox.py +++ b/src/helper_inbox.py @@ -1,11 +1,10 @@ -"""Helper Inbox performs inbox messages related operations""" +"""Helper Inbox performs inbox messagese related operations.""" -import queues from helper_sql import sqlExecute, sqlQuery +import queues def insert(t): - """Perform an insert into the "inbox" table""" sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *t) # shouldn't emit changedInboxUnread and displayNewInboxMessage # at the same time @@ -13,13 +12,11 @@ def insert(t): def trash(msgid): - """Mark a message in the `inbox` as `trash`""" sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', msgid) queues.UISignalQueue.put(('removeInboxRowByMsgid', msgid)) def isMessageAlreadyInInbox(sigHash): - """Check for previous instances of this message""" queryReturn = sqlQuery( '''SELECT COUNT(*) FROM inbox WHERE sighash=?''', sigHash) return queryReturn[0][0] != 0 diff --git a/src/helper_msgcoding.py b/src/helper_msgcoding.py index 76dad423..cc632ffa 100644 --- a/src/helper_msgcoding.py +++ b/src/helper_msgcoding.py @@ -5,11 +5,6 @@ Message encoding end decoding functions import string import zlib -import messagetypes -from bmconfigparser import BMConfigParser -from debug import logger -from tr import _translate - try: import msgpack except ImportError: @@ -18,6 +13,11 @@ except ImportError: except ImportError: import fallback.umsgpack.umsgpack as msgpack +import messagetypes +from bmconfigparser import BMConfigParser +from debug import logger +from tr import _translate + BITMESSAGE_ENCODING_IGNORE = 0 BITMESSAGE_ENCODING_TRIVIAL = 1 BITMESSAGE_ENCODING_SIMPLE = 2 @@ -25,24 +25,19 @@ BITMESSAGE_ENCODING_EXTENDED = 3 class MsgEncodeException(Exception): - """Exception during message encoding""" pass class MsgDecodeException(Exception): - """Exception during message decoding""" pass class DecompressionSizeException(MsgDecodeException): - # pylint: disable=super-init-not-called - """Decompression resulted in too much data (attack protection)""" def __init__(self, size): self.size = size class MsgEncode(object): - """Message encoder class""" def __init__(self, message, encoding=BITMESSAGE_ENCODING_SIMPLE): self.data = None self.encoding = encoding @@ -57,7 +52,6 @@ class MsgEncode(object): raise MsgEncodeException("Unknown encoding %i" % (encoding)) def encodeExtended(self, message): - """Handle extended encoding""" try: msgObj = messagetypes.message.Message() self.data = zlib.compress(msgpack.dumps(msgObj.encode(message)), 9) @@ -70,18 +64,15 @@ class MsgEncode(object): self.length = len(self.data) def encodeSimple(self, message): - """Handle simple encoding""" self.data = 'Subject:%(subject)s\nBody:%(body)s' % message self.length = len(self.data) def encodeTrivial(self, message): - """Handle trivial encoding""" self.data = message['body'] self.length = len(self.data) class MsgDecode(object): - """Message decoder class""" def __init__(self, encoding, data): self.encoding = encoding if self.encoding == BITMESSAGE_ENCODING_EXTENDED: @@ -97,7 +88,6 @@ class MsgDecode(object): self.subject = _translate("MsgDecode", "Unknown encoding") def decodeExtended(self, data): - """Handle extended encoding""" dc = zlib.decompressobj() tmp = "" while len(tmp) <= BMConfigParser().safeGetInt("zlib", "maxsize"): @@ -141,7 +131,6 @@ class MsgDecode(object): self.body = msgObj.body def decodeSimple(self, data): - """Handle simple encoding""" bodyPositionIndex = string.find(data, '\nBody:') if bodyPositionIndex > 1: subject = data[8:bodyPositionIndex] diff --git a/src/helper_random.py b/src/helper_random.py index 9a29d5e2..bb173d1b 100644 --- a/src/helper_random.py +++ b/src/helper_random.py @@ -2,17 +2,10 @@ import os import random - from pyelliptic.openssl import OpenSSL - NoneType = type(None) -def seed(): - """Initialize random number generator""" - random.seed() - - def randomBytes(n): """Method randomBytes.""" try: @@ -58,7 +51,8 @@ def randomrandrange(x, y=None): """ if isinstance(y, NoneType): return random.randrange(x) # nosec - return random.randrange(x, y) # nosec + else: + return random.randrange(x, y) # nosec def randomchoice(population): diff --git a/src/helper_search.py b/src/helper_search.py index 69acec43..d6704731 100644 --- a/src/helper_search.py +++ b/src/helper_search.py @@ -1,6 +1,6 @@ -"""Additional SQL helper for searching messages""" +#!/usr/bin/python2.7 -from helper_sql import sqlQuery +from helper_sql import * try: from PyQt4 import QtGui @@ -8,17 +8,13 @@ try: except ImportError: haveQt = False - -def search_translate(context, text): - """Translation wrapper""" +def search_translate (context, text): if haveQt: return QtGui.QApplication.translate(context, text) - return text.lower() + else: + return text.lower() - -def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, what=None, unreadOnly=False): - """Perform a search in mailbox tables""" - # pylint: disable=too-many-arguments, too-many-branches +def search_sql(xAddress = "toaddress", account = None, folder = "inbox", where = None, what = None, unreadOnly = False): if what is not None and what != "": what = "%" + what + "%" if where == search_translate("MainWindow", "To"): @@ -36,7 +32,7 @@ def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, w if folder == "sent": sqlStatementBase = ''' - SELECT toaddress, fromaddress, subject, status, ackdata, lastactiontime + SELECT toaddress, fromaddress, subject, status, ackdata, lastactiontime FROM sent ''' else: sqlStatementBase = '''SELECT folder, msgid, toaddress, fromaddress, subject, received, read @@ -66,16 +62,13 @@ def search_sql(xAddress="toaddress", account=None, folder="inbox", where=None, w sqlArguments.append(what) if unreadOnly: sqlStatementParts.append("read = 0") - if sqlStatementParts: + if len(sqlStatementParts) > 0: sqlStatementBase += "WHERE " + " AND ".join(sqlStatementParts) if folder == "sent": sqlStatementBase += " ORDER BY lastactiontime" return sqlQuery(sqlStatementBase, sqlArguments) - -def check_match(toAddress, fromAddress, subject, message, where=None, what=None): - """Check if a single message matches a filter (used when new messages are added to messagelists)""" - # pylint: disable=too-many-arguments +def check_match(toAddress, fromAddress, subject, message, where = None, what = None): if what is not None and what != "": if where in (search_translate("MainWindow", "To"), search_translate("MainWindow", "All")): if what.lower() not in toAddress.lower(): diff --git a/src/helper_sent.py b/src/helper_sent.py index 60c4772d..8dde7215 100644 --- a/src/helper_sent.py +++ b/src/helper_sent.py @@ -1,15 +1,4 @@ -""" -Insert values into sent table -""" - -import uuid -from helper_sql import sqlExecute - +from helper_sql import * def insert(t): - """Perform an insert into the `sent` table""" - msgid = uuid.uuid4().bytes - temp = list(t) - temp[0] = msgid - t = tuple(temp) sqlExecute('''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', *t) diff --git a/src/helper_sql.py b/src/helper_sql.py index 9b5dc29d..2b558f62 100644 --- a/src/helper_sql.py +++ b/src/helper_sql.py @@ -1,39 +1,17 @@ -""" -SQL-related functions defined here are really pass the queries (or other SQL -commands) to :class:`.threads.sqlThread` through `sqlSubmitQueue` queue and check -or return the result got from `sqlReturnQueue`. +"""Helper Sql performs sql operations.""" -This is done that way because :mod:`sqlite3` is so thread-unsafe that they -won't even let you call it from different threads using your own locks. -SQLite objects can only be used from one thread. - -.. note:: This actually only applies for certain deployments, and/or - really old version of sqlite. I haven't actually seen it anywhere. - Current versions do have support for threading and multiprocessing. - I don't see an urgent reason to refactor this, but it should be noted - in the comment that the problem is mostly not valid. Sadly, last time - I checked, there is no reliable way to check whether the library is - or isn't thread-safe. -""" - -import Queue import threading +import Queue sqlSubmitQueue = Queue.Queue() -"""the queue for SQL""" +# SQLITE3 is so thread-unsafe that they won't even let you call it from different threads using your own locks. +# SQL objects #can only be called from one thread. sqlReturnQueue = Queue.Queue() -"""the queue for results""" sqlLock = threading.Lock() def sqlQuery(sqlStatement, *args): - """ - Query sqlite and return results - - :param str sqlStatement: SQL statement string - :param list args: SQL query parameters - :rtype: list - """ + """SQLLITE execute statement and return query.""" sqlLock.acquire() sqlSubmitQueue.put(sqlStatement) @@ -50,7 +28,6 @@ def sqlQuery(sqlStatement, *args): def sqlExecuteChunked(sqlStatement, idCount, *args): - """Execute chunked SQL statement to avoid argument limit""" # SQLITE_MAX_VARIABLE_NUMBER, # unfortunately getting/setting isn't exposed to python sqlExecuteChunked.chunkSize = 999 @@ -81,7 +58,6 @@ def sqlExecuteChunked(sqlStatement, idCount, *args): def sqlExecute(sqlStatement, *args): - """Execute SQL statement (optionally with arguments)""" sqlLock.acquire() sqlSubmitQueue.put(sqlStatement) @@ -94,15 +70,13 @@ def sqlExecute(sqlStatement, *args): sqlLock.release() return rowcount - def sqlStoredProcedure(procName): - """Schedule procName to be run""" sqlLock.acquire() sqlSubmitQueue.put(procName) sqlLock.release() -class SqlBulkExecute(object): +class SqlBulkExecute: """This is used when you have to execute the same statement in a cycle.""" def __enter__(self): diff --git a/src/helper_startup.py b/src/helper_startup.py index 8374261d..1a1119f5 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -1,13 +1,16 @@ """ -Startup operations. +src/helper_startup.py +===================== + +Helper Start performs all the startup operations. """ # pylint: disable=too-many-branches,too-many-statements +from __future__ import print_function -import logging +import ConfigParser import os import platform import sys -import time from distutils.version import StrictVersion import defaults @@ -16,37 +19,45 @@ import paths import state from bmconfigparser import BMConfigParser -try: - from plugins.plugin import get_plugin -except ImportError: - get_plugin = None - - -logger = logging.getLogger('default') - # The user may de-select Portable Mode in the settings if they want # the config files to stay in the application data folder. StoreConfigFilesInSameDirectoryAsProgramByDefault = False +def _loadTrustedPeer(): + try: + trustedPeer = BMConfigParser().get('bitmessagesettings', 'trustedpeer') + except ConfigParser.Error: + # This probably means the trusted peer wasn't specified so we + # can just leave it as None + return + try: + host, port = trustedPeer.split(':') + except ValueError: + sys.exit( + 'Bad trustedpeer config setting! It should be set as' + ' trustedpeer=:' + ) + state.trustedPeer = state.Peer(host, int(port)) + + def loadConfig(): """Load the config""" config = BMConfigParser() - if state.appdata: config.read(state.appdata + 'keys.dat') # state.appdata must have been specified as a startup option. needToCreateKeysFile = config.safeGet( 'bitmessagesettings', 'settingsversion') is None if not needToCreateKeysFile: - logger.info( + print( 'Loading config files from directory specified' - ' on startup: %s', state.appdata) + ' on startup: %s' % state.appdata) else: config.read(paths.lookupExeFolder() + 'keys.dat') try: config.get('bitmessagesettings', 'settingsversion') - logger.info('Loading config files from same directory as program.') + print('Loading config files from same directory as program.') needToCreateKeysFile = False state.appdata = paths.lookupExeFolder() except: @@ -57,8 +68,7 @@ def loadConfig(): needToCreateKeysFile = config.safeGet( 'bitmessagesettings', 'settingsversion') is None if not needToCreateKeysFile: - logger.info( - 'Loading existing config files from %s', state.appdata) + print('Loading existing config files from', state.appdata) if needToCreateKeysFile: @@ -113,10 +123,9 @@ def loadConfig(): # Just use the same directory as the program and forget about # the appdata folder state.appdata = '' - logger.info( - 'Creating new config files in same directory as program.') + print('Creating new config files in same directory as program.') else: - logger.info('Creating new config files in %s', state.appdata) + print('Creating new config files in', state.appdata) if not os.path.exists(state.appdata): os.makedirs(state.appdata) if not sys.platform.startswith('win'): @@ -125,6 +134,8 @@ def loadConfig(): else: updateConfig() + _loadTrustedPeer() + def updateConfig(): """Save the config""" @@ -266,7 +277,7 @@ def updateConfig(): 'bitmessagesettings', 'hidetrayconnectionnotifications', 'false') if config.safeGetInt('bitmessagesettings', 'maxoutboundconnections') < 1: config.set('bitmessagesettings', 'maxoutboundconnections', '8') - logger.warning('Your maximum outbound connections must be a number.') + print('WARNING: your maximum outbound connections must be a number.') # TTL is now user-specifiable. Let's add an option to save # whatever the user selects. @@ -289,26 +300,3 @@ def isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections(): return False except Exception: pass - - -def start_proxyconfig(): - """Check socksproxytype and start any proxy configuration plugin""" - if not get_plugin: - return - config = BMConfigParser() - proxy_type = config.safeGet('bitmessagesettings', 'socksproxytype') - if proxy_type and proxy_type not in ('none', 'SOCKS4a', 'SOCKS5'): - try: - proxyconfig_start = time.time() - if not get_plugin('proxyconfig', name=proxy_type)(config): - raise TypeError() - except TypeError: - # cannot import shutdown here ): - logger.error( - 'Failed to run proxy config plugin %s', - proxy_type, exc_info=True) - os._exit(0) # pylint: disable=protected-access - else: - logger.info( - 'Started proxy config plugin %s in %s sec', - proxy_type, time.time() - proxyconfig_start) diff --git a/src/helper_threading.py b/src/helper_threading.py new file mode 100644 index 00000000..6b6a5e25 --- /dev/null +++ b/src/helper_threading.py @@ -0,0 +1,46 @@ +"""Helper threading perform all the threading operations.""" + +from contextlib import contextmanager +import threading + +try: + import prctl +except ImportError: + def set_thread_name(name): + """Set the thread name for external use (visible from the OS).""" + threading.current_thread().name = name +else: + def set_thread_name(name): + """Set a name for the thread for python internal use.""" + prctl.set_name(name) + + def _thread_name_hack(self): + set_thread_name(self.name) + threading.Thread.__bootstrap_original__(self) + + threading.Thread.__bootstrap_original__ = threading.Thread._Thread__bootstrap + threading.Thread._Thread__bootstrap = _thread_name_hack + + +class StoppableThread(object): + def initStop(self): + self.stop = threading.Event() + self._stopped = False + + def stopThread(self): + self._stopped = True + self.stop.set() + + +class BusyError(threading.ThreadError): + pass + +@contextmanager +def nonBlocking(lock): + locked = lock.acquire(False) + if not locked: + raise BusyError + try: + yield + finally: + lock.release() diff --git a/src/highlevelcrypto.py b/src/highlevelcrypto.py index f392fe4a..02fb85ab 100644 --- a/src/highlevelcrypto.py +++ b/src/highlevelcrypto.py @@ -1,10 +1,6 @@ """ -High level cryptographic functions based on `.pyelliptic` OpenSSL bindings. - -.. note:: - Upstream pyelliptic was upgraded from SHA1 to SHA256 for signing. - We must upgrade PyBitmessage gracefully. - `More discussion. `_ +src/highlevelcrypto.py +====================== """ from binascii import hexlify @@ -16,13 +12,12 @@ from pyelliptic import arithmetic as a def makeCryptor(privkey): - """Return a private `.pyelliptic.ECC` instance""" + """Return a private pyelliptic.ECC() instance""" private_key = a.changebase(privkey, 16, 256, minlen=32) public_key = pointMult(private_key) privkey_bin = '\x02\xca\x00\x20' + private_key pubkey_bin = '\x02\xca\x00\x20' + public_key[1:-32] + '\x00\x20' + public_key[-32:] - cryptor = pyelliptic.ECC( - curve='secp256k1', privkey=privkey_bin, pubkey=pubkey_bin) + cryptor = pyelliptic.ECC(curve='secp256k1', privkey=privkey_bin, pubkey=pubkey_bin) return cryptor @@ -34,7 +29,7 @@ def hexToPubkey(pubkey): def makePubCryptor(pubkey): - """Return a public `.pyelliptic.ECC` instance""" + """Return a public pyelliptic.ECC() instance""" pubkey_bin = hexToPubkey(pubkey) return pyelliptic.ECC(curve='secp256k1', pubkey=pubkey_bin) @@ -48,8 +43,7 @@ def privToPub(privkey): def encrypt(msg, hexPubkey): """Encrypts message with hex public key""" - return pyelliptic.ECC(curve='secp256k1').encrypt( - msg, hexToPubkey(hexPubkey)) + return pyelliptic.ECC(curve='secp256k1').encrypt(msg, hexToPubkey(hexPubkey)) def decrypt(msg, hexPrivkey): @@ -58,38 +52,36 @@ def decrypt(msg, hexPrivkey): def decryptFast(msg, cryptor): - """Decrypts message with an existing `.pyelliptic.ECC` object""" + """Decrypts message with an existing pyelliptic.ECC.ECC object""" return cryptor.decrypt(msg) def sign(msg, hexPrivkey): - """ - Signs with hex private key using SHA1 or SHA256 depending on - "digestalg" setting - """ - digestAlg = BMConfigParser().safeGet( - 'bitmessagesettings', 'digestalg', 'sha1') + """Signs with hex private key""" + # pyelliptic is upgrading from SHA1 to SHA256 for signing. We must + # upgrade PyBitmessage gracefully. + # https://github.com/yann2192/pyelliptic/pull/33 + # More discussion: https://github.com/yann2192/pyelliptic/issues/32 + digestAlg = BMConfigParser().safeGet('bitmessagesettings', 'digestalg', 'sha1') if digestAlg == "sha1": # SHA1, this will eventually be deprecated - return makeCryptor(hexPrivkey).sign( - msg, digest_alg=OpenSSL.digest_ecdsa_sha1) + return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.digest_ecdsa_sha1) elif digestAlg == "sha256": # SHA256. Eventually this will become the default return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.EVP_sha256) else: - raise ValueError("Unknown digest algorithm %s" % digestAlg) + raise ValueError("Unknown digest algorithm %s" % (digestAlg)) def verify(msg, sig, hexPubkey): - """Verifies with hex public key using SHA1 or SHA256""" + """Verifies with hex public key""" # As mentioned above, we must upgrade gracefully to use SHA256. So # let us check the signature using both SHA1 and SHA256 and if one # of them passes then we will be satisfied. Eventually this can # be simplified and we'll only check with SHA256. try: # old SHA1 algorithm. - sigVerifyPassed = makePubCryptor(hexPubkey).verify( - sig, msg, digest_alg=OpenSSL.digest_ecdsa_sha1) + sigVerifyPassed = makePubCryptor(hexPubkey).verify(sig, msg, digest_alg=OpenSSL.digest_ecdsa_sha1) except: sigVerifyPassed = False if sigVerifyPassed: @@ -97,8 +89,7 @@ def verify(msg, sig, hexPubkey): return True # The signature check using SHA1 failed. Let us try it with SHA256. try: - return makePubCryptor(hexPubkey).verify( - sig, msg, digest_alg=OpenSSL.EVP_sha256) + return makePubCryptor(hexPubkey).verify(sig, msg, digest_alg=OpenSSL.EVP_sha256) except: return False @@ -109,14 +100,13 @@ def pointMult(secret): Evidently, this type of error can occur very rarely: - >>> File "highlevelcrypto.py", line 54, in pointMult - >>> group = OpenSSL.EC_KEY_get0_group(k) - >>> WindowsError: exception: access violation reading 0x0000000000000008 + File "highlevelcrypto.py", line 54, in pointMult + group = OpenSSL.EC_KEY_get0_group(k) + WindowsError: exception: access violation reading 0x0000000000000008 """ while True: try: - k = OpenSSL.EC_KEY_new_by_curve_name( - OpenSSL.get_curve('secp256k1')) + k = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve('secp256k1')) priv_key = OpenSSL.BN_bin2bn(secret, 32, None) group = OpenSSL.EC_KEY_get0_group(k) pub_key = OpenSSL.EC_POINT_new(group) diff --git a/src/image.svg b/src/image.svg deleted file mode 100644 index bef2b802f2468540919a67585378371a2d45b5a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 704 zcmV;x0zdtUP)v8@ueDm&3YGweepB6;gR*&<~0SwgM6ufIvX%Q2D!=9_OFJM>8|)fPMlSQiBZy*}#&Q&)e#8{y}{9@5P}a zEv9%nn_?Fz#@vZ_?J*#(mA1& zU-YVp_xv7_FaGVPnp#ak^qMIq&Qx&!9+}rjQ0aQxvk~jS*}mi?FW&zinKwI~tu{n; zB^^&^BX1|QzJGL3zRWk`YmkvXi`Y#v+VWWOG&l5b)xNva@BE#(SwBm)>i*pNPGu9= z>+dmn>6;m(mvxp=-_&{V0obsi9_Js$-_Ebf`gtnW%}r7^w)^*he6GKxye31mb!(v? zm!{U;;Onbn^3}gJ@<5|p>U_iN?_v3M%nU%8O6FKoi_bTX&adYuZAeY2#9zCm_QY$> z_p0CdJN$ZnvX}CyjeI}mqZ^BrN#$PkJO6jQ#?+uOz2tG_Wjo1+|DwnFf8*bskBzT0 z^jb`p^L23@U+qr6^M8(CoS$rF>)*QEGa2m!wBIYYH~r4viJSFvo@I=euTtvPg7-&< m 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 diff --git a/src/images/account_multiple.png b/src/images/account_multiple.png deleted file mode 100644 index 112716197dbe10f0191e2cb2f03b11e623e9af62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9798 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 QA{c13Im8JGjX{o5? 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 diff --git a/src/images/avatar.png b/src/images/avatar.png deleted file mode 100644 index b006bfa2a69bcfce8d50e0ef220452aaf490ee8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27865 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 IM6N<$g4k)%&;S4c diff --git a/src/images/back-button.png b/src/images/back-button.png deleted file mode 100644 index e260b08bd191ec7badbfa32baa1b1f10c1125251..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52318 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

>+H{M~b8>%pf3JKtc-k{y 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%0D5`$twgTSVjp;W&a%weXFx{XI`>KYXf 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 diff --git a/src/images/black_cross.png b/src/images/black_cross.png deleted file mode 100644 index a71b611b37048579f11a3c33f81a271b6ca9235c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5201 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 diff --git a/src/images/drawer_logo1.png b/src/images/drawer_logo1.png deleted file mode 100644 index 4152cc40edce2815f0acd9ec48d233dff917ece3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2041 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

da1Z@@=)C#bc5oIsGy)A7 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%0Axy_!V``!*DX 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 BLgN4c diff --git a/src/images/loader.zip b/src/images/loader.zip deleted file mode 100644 index c80a3a17e22d05832db089959679ec1c995e0cb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15918 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 K`X3bl!2bc@Mkc@j diff --git a/src/images/red.png b/src/images/red.png deleted file mode 100644 index 2570e26a8f573f1f342b44fd541f2020bc9f0709..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57642 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 diff --git a/src/images/right-arrow.png b/src/images/right-arrow.png deleted file mode 100644 index 8f136a774a2f1d83fc4c367a4c49d32da82eec49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3145 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 diff --git a/src/images/search_mail.png b/src/images/search_mail.png deleted file mode 100644 index 7b38e9b40e3f57aeb8d27ac00f77cb1a3cc151c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10555 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 diff --git a/src/images/text_images/!.png b/src/images/text_images/!.png deleted file mode 100644 index bac2f2461db6556140398a6cd73595b7e30d603a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5035 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 diff --git a/src/images/text_images/0.png b/src/images/text_images/0.png deleted file mode 100644 index 2b8b63e3a79f5359fe81085211f5bd2cb84aa784..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7321 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 SCbXY#0Ha%`H>-6WBmWD_4en|H diff --git a/src/images/text_images/2.png b/src/images/text_images/2.png deleted file mode 100644 index 0cf202e95b89b345d8363939a8ba195b05cfb542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6916 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 KMNUMnLSTX>U6tto diff --git a/src/images/text_images/3.png b/src/images/text_images/3.png deleted file mode 100644 index f9d612dd8b00cd754006110d0365087fdb3b32a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7265 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ñU+Fza+h~R5vpg8_LIVMa5TU~B_MS$~w*1qN_?($zvY%RD*Nq|uP0|UrN3ZDTv z(Cn0g;-{LQ^BS>jY4`1M5HHP6Ai!^+sq;2jK*Gn8a7 zzT6~1N?@280ZlMFrJ`Waof@}*UY%?*kA5@pZJXQqm`|}XX@<_)7w!^8IlMeO9Olo+ zV0+yuL}t4miuV{LTG{Qu$^l`Ebgm0TN?oi0C$^1H9KbPe?N?k-FxXuCvYR--{nZ(c zBtzlj#0%$)xT)TF>`QahJrkPs{qTPR&;e#{%RuKlypLMqGrUsL%tSf&>lL@GH%GG1 zeoL?d2bO^Y-#-^P7o;fPZ54T8lAsP5RvbAs?azCW`ylOk_Hul>`2Gd7dN}%U(lUaA z;_a?q4Zd*8oO9QIVBXM%W&G`@NkjnSc88^kCtZiim~Zn(ckAsYvgrRuLR1N^(9D1g za;C33YzXCm?{yC~Iv5xJM4`7U-tKzO@jq~F@3h^%DFTmKauy}{#pV*iA^wauF30kB zdTFe{|&MDJ_KWO$Ar9e`rECPIYWy@Pv1iELwx4f z`IW)$X59 znGE zE%w_++WE$>P=Q>U6=HH>g30nq^;g}8@^p6C$ncZee2)0qn@;|5U_~2tEI75Dc1nvk z7V?m)J;to-<`mpFZJ_@Xxmw@(u&+Mz2IKw3$|Ao65tFN75{L17F_(K8yEjQ_L7;6^CIp1+!zjbOy>nX=yemXP$m-BmEeEl91hv4;Bl zWuTEnFAf*qXU_(nkcIkUbWN|8Si|dN3rx>U1Mbrqk50(LT9YXMjAmyPd@CZ6`{X2V z<1ukh9M8g{{(F9ETVok2;}-fGc{Lrt`MgkaUJ|S`!q*_@~*%Dm^i4oUhTzvH}{>Kslsk5Bw;$wbBmsl z#^AVNI=l1uViI2Pkceo3nJ;ahD2<}z=ht>A&7NzLIneY%p=w>=&5tO6u9m)Lt%hyb F{{ionjlKW? diff --git a/src/images/text_images/6.png b/src/images/text_images/6.png deleted file mode 100644 index e385a954ba4c14f366fe1ce4c8c848d5351207d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7644 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 E2Ua8%FaQ7m diff --git a/src/images/text_images/7.png b/src/images/text_images/7.png deleted file mode 100644 index 55fc4f77d428bb159e85a6516fc53ddea20c8c3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5941 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 T^j#y4E-5M%r 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 diff --git a/src/images/text_images/D.png b/src/images/text_images/D.png deleted file mode 100644 index 2549ffc2e8bdc6e63dad4ba8d03e20e1ad08b4c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6381 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 diff --git a/src/images/text_images/E.png b/src/images/text_images/E.png deleted file mode 100644 index 5d6316114ef0eff37bd721612d3c9112f89b5c4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5009 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 I#Wv#q07IPYQ~&?~ diff --git a/src/images/text_images/H.png b/src/images/text_images/H.png deleted file mode 100644 index 279bd1ce6db1edf17782fdb3babb05b5cfc39ecb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5054 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 OU~F*fdX=7Y-2VXhe*nn< diff --git a/src/images/text_images/I.png b/src/images/text_images/I.png deleted file mode 100644 index c88f048d7a0a28879958c158d554a7457d21481d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4713 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 diff --git a/src/images/text_images/J.png b/src/images/text_images/J.png deleted file mode 100644 index 1533117129f4e267b4e475d10a41eb7fd378f7ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5841 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Ν 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 P0T}2#zE`8;^zQ!vHTMmM diff --git a/src/images/text_images/N.png b/src/images/text_images/N.png deleted file mode 100644 index 2d235d0618e32ec6c2d4d0f2f488a4c1e5289011..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6509 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 O(3lvR-$WX?MgJd&$OdNs diff --git a/src/images/text_images/O.png b/src/images/text_images/O.png deleted file mode 100644 index c0cc972ad641d61181a66c2858e783b6f6ead93a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7912 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 S?#+Gx0000Y`X9O diff --git a/src/images/text_images/P.png b/src/images/text_images/P.png deleted file mode 100644 index 57ec50124111d42dffe70bec13bb3d7487843791..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5914 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 N002ovPDHLkV1kMUAfNyM diff --git a/src/images/text_images/R.png b/src/images/text_images/R.png deleted file mode 100644 index 090646f5d6690043e424755a6f039ad23379595c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6404 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 diff --git a/src/images/text_images/S.png b/src/images/text_images/S.png deleted file mode 100644 index 444419cf0d38b0b6f03a567558a54831fab69811..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7826 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 diff --git a/src/images/text_images/T.png b/src/images/text_images/T.png deleted file mode 100644 index ace7b36b257305def81f8856ac85fdbe798dfa6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4793 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 ShpVT13SCXZM^)E&HB3ksGXp`uS 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 K6jAaPq5lIkL3H8( diff --git a/src/images/text_images/X.png b/src/images/text_images/X.png deleted file mode 100644 index be919fc4b9003ea5d3e15c7bacd1aad66a292c8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7367 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 diff --git a/src/images/text_images/Y.png b/src/images/text_images/Y.png deleted file mode 100644 index 4819bbd197ec6177f5a2cc3d575e77a108a1f405..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6459 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 diff --git a/src/images/text_images/Z.png b/src/images/text_images/Z.png deleted file mode 100644 index 7d1c8e016888f107ae07afa9f570de3945b86ba5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6166 zcmY*dc{tSV_qLBcYj#EZD%M(bKosq)9zY%k~`iVCDH~mNZ@>K0hc~`_iYTM($-&+-LfuZsqfv zi+>~B7Z9UCxZ&LQizgC}?JE1Zvwk?lC_*9N5vHRm=90nWMde_Gap|GTr;U!fI+ALW zdQt0iI|#Eg3qd}`bElSGj^+j_>6nnLv$$vOG}+sEhz@Qtd3N*YqT5BugQw;d=a{&w zS7osUKyIsW0VDC6s#oY*mL@4ypEPc>=ANf3mFUBOvr(#@!NHWYDBjtnU%YQlKB~*P zmV`4tN=BZ3P_V3gWvKCL)wV?kcMOQyy3J%gQj-`E6#GM{@tGi)_$Y2-JtC>=N-gM&~kt-J8a zlG$1_ss7fw!~tSiNl8?h2r3wMKk#1DrJuI+6q0cB_eR(Uy}C(`Zn5SBxkYyuJ?cFa z;I0geE2*^m<@=_>mpmB1hrTuJSJsGhEn&IL#WugW7naS*#tX9JuV6#{jK8_X$uju+ zYi*6i3yn&bzu(cO%ltICUeMAypCTUFDZc}IRQq2h*P{)-&Gl{9Nut*+|8CEI`D3N( zmOZ!7?yM^94w~EZ%8LBgqaIHqgQ;Kjjjo2$D$YN&iVo$4v)u^x()}gh)2H`KWj0ap zJ=&wgh&TSI>r}*bU$N&O?{v$6)aKBCkT30@(oQVob;EN2e_F6h?ytUvwOd7z`5!>* zfcW053!WT+l$tTp@o5WRQb{;N1x6H$ zv!rgFwK7$gav#7ve{p@u;Y~TLJeWQd_fO^!v10VP7m0W6{tc;wuZ?laSAO60Oq5$3 zG-wgcyeL>-UIA?W9_(Y0O3>#g8S{eRT>Z@vK8I=hRW_N!+_!^yG-9f9cpv&#q~SIb zJ9An=>?=)=KHo}FS(x$bS~cDB{k)OmRMha{d&T66RKIE0Xa04$7nMaHYNjnndK$CAaprE&%JeU->janAKfjxC ze-9%(ha2T$(qja_L<+X4r}-*biM6=zsQQhpDs&+8tI#a7bRq63cH1X=RnOnjHL|(N z7qHCDK45f2gn0e6&U{|px*hCqeI>t6|9Jy38*0Uyv=4cIqYdKa1se;INnA*NOg*xJ3Q+B2a?`GK;!^M^Y^dZdc7X{TrWDe5 z5{fG52Z(*+fgXSsBZ);T8-wg5mN>yThP?{;XwkxOpDA>9Y!wy#Vw5Lr#vlGLR`@r( zV>5&`?}=-rseB8ro_6-Y6>8fZzwhOB$^tnkzwU6|Ufc&;Yd(BF7NCjO`k~^aDgO0v zNL@=wjAmz&^ibSJwtet%2a#Ul@xnj+=IKA2IX_5fK3S7{KULU*7TCXev5A*lt*ofP zOQ>uR`tOyd(MjkY7O~0Jr6N-Zsse*8GkMH9=mgDrrkS_9yx&-*;8g|p2qF@u4?U22 zS4&Vg)u$9}|BjQhysrGbOMehX{NdR)S8k}-_CJ~PLY7S&7km7r@m5OM12#+(ULQS;e&2IFf~lIt?4rrQF{^G zH5DQAEa#z~HrvBxrZzO=ryrR8ENtGZgF~L$Q~}!gkn$M6D}fKqhsD`f_R)~+hfvG= z(BF;6w+{|YtZLG2PT%v6yUK45VMd$ix}N$C%dxwlFs-EdkU|vSP|*&Zj85R*1aAB| zTwP-^UUf5k^wMKqZo=0z5Ue%bzR~rFy9*aPXT>wK&p-B<6<04! zG4*9`1%i~|Z_0EmzgVNeko(ZPImXI7W|MVhA=;O99oNM1Ky95Bb2%N0OB25mpLL|y zj+A^Xd{II|Ao8&4I8H!$Z7OUdb-Jvlk(gd`wz3DcjLYD)l<>=+z-kf`i%}EF8EO_^ z#-=*FgrD^6_)m-F)*f&1;_9n+ox|%YKf3OhOOK41-WbKDr;69?0MTC?&^T)?gqyK< z!HHQ1X{I0B80%_TJ3d~NyH48=3BmIW7`uS{@-Iao?gVem<_{bH+}Ie*Aq>wCH+;U7K`PYp2S8#7FLlA#iXyuI7T06In~v9sKA{86*N)I zH-_6thzQbRz$|Yzkk0m0M-9q~yii`9*nDsKlb(!VRtHn5RyD?tTo&*4ai67-8;@8= zt5}tUK0R4@=Sbc{-W$1vMG58f|Iu#Lf953(Pkn}OPY@Z3KdQW~Y2ie7)~Q_Tf(L$0 z>^5ya`F>++(Gna(*zFGVH#bfFPD(hntbh5Xiw0-7t-6)+B3G~ZIfqU3pdgV%1p^* z|8Y^CG{>u#rF!WnVcZ}S{NmD32|Lp|fWZDCIUp~kM*Df63bK{aS&Lsy{x-0q$nE|# zu=c~ZeWi#p@JpaVztV^J)pAprwb!U8iYR-tTom8x{jQy9P4WZd0EhdLy^3%%&u6RW z6G~W__4Qp?}FFO<7S`=!AC|+_${o`SuBx5mYXA2Gt?fY2xaI6pHaiupy z>*+$49`7|4CElb%yHA0>i8^~fzjTURIyC>o0Y0;KA_$ES?u3`0JDTOXbb?Y zXkCo(eOjdVAL5JBFj26}mDx6Vp9vnI;|$1)JY-$si@05tcTzxe?q|!W?^`@DV zVRzWAOI6gw4xx~9-mtUwBSPow9z?j{hga1u@kb**m0N}Ue zc~?;HWRpe2WB>KtPJjXgbh5YzK+oHY@d?NC=P9!VC7^iN_XUOPe1pA>Yt_)LEFrMS z9$RxGVHfX(cX}(pxSrFt$RppS;*aASfANvDqECH0uj}^-pp^Gxd$k4QHahD4f7SMC zAIFQRE%WVZ;TqEu3%^jZ16o5k3 zT0JT$0&p%3onitLnACad#n_RnW=?mO11bRy^yo&GpTWS$j(2n!z1qxiW>GXG0+GSk zs8&t$6w`?xeSxKZmq#H&FGCODGX$NC5UG{tIv|-m?$UYxtGNuF)`8#>h6^u(5vD=6w$!W9 zAt=PBDWsZf=LS1_+5FWatCM;c)>Sq>d)LVzlQO}OB66onXIyD<#@PXPXQ^nzzN=7| z`AYdWX-Qb>7;Gn@lPD2!<6!dwfFuQ|L!bZep$p)bmHw<{6%X+I_J3toeqN1Ilc!da zJbjT_H}BjuDr=$0(f+=~daQVKeyu{6<25h+X`k^@X~;u)&*0cg>_2u>pzObovy;c{ zEy!pjO4JRYKYebuLr7I^sV_)cERIrBs6xfaG%iOh32nmlEGI|Tvryj5Wu)C!oNEtI z=_O)V;QRW`JJt8d-;S_L7>$nhJPG;&BrCb};>N65@LW`2GA1sxHpWGMS?K{omQ4|K;~b> z2>=Lm+PmSIWo}z6VHfOhM)qdb-1Rs!25AfMTlNhW31mnK6OTEU5(|t#C*&`kVj9(u z%raG+K<8q(Zo1S5V8Qa*a9pl-wPR4-yrUV1Jv?abCJP6<4x^fBk)tM5=Ri5q92aHKBb2 zhA^Cen22(`U|3%((7}0joEA~h40T4aZF>NS4{`5 zr|rcB4aW+a1lc|C_pIvG<|3!1(D=6f zoJX@MYyr^6!`(anbqcUlXN2!{33jfpehU_n7W-v#%iB4PN198sms?QxpjsUyUk5@> z7f-4~Iiw!$Ix8~TL1P!B?C&AhYBaDT zJ-~txm3X7&&0W2D%gHuo{t^L$?*B!_Aw4-H zGAG3}ptOS2NTqyDn+?lhn{aFwbYhkw(ADb7m$?8nq<9}1xIMGC#`RW_WaiGvKQtyp z7O%y}nb_9~NM#Bl(cG#37_j91`d;-Q*~`;5mO>>gDKbQyv@WvqS!wI|7U}N=v)^Kd z`xdxs4)Fji_)#3j!JrkXN&@)>5o(r;h*S*`H!<6j?!r#f6M14EhG5_1^hB6{^reC>(yD(^Xg|xEfAjo*q__#=pkGBqc^be{ zFI}*b@LIW6N4WSXKzl~1Sj^bBY<+oN&`|AAc~ZcDq;Ln>wNs%@vT7@{op$c%(?R{V z8jk9?{O&!Nrw>u~-H7cP9&hna^^wo%QBQQv!rFzLl6n(g$i=kvR+F3Ux(eT@j@+K7 zJABAD+CsbB|c|U%Z_i57^#wY)kgK@AZcv^9P>X$iQUqf(21G$PCvL#Hq z%6ln4B=m1B=W6b$L+*+Uv8p~Zh{*p48Xbw_r`C6=q`~uu`76iq znJ^xh+a*0fvuT+@8F$Fx9Y_;e4MR$DO+Ycyy@3SnGnjn+mT`kOfP?)cMNw-K_5|#n z)T=GkKNMC|!V4&3bZ99R1^mtlE^3nIp%`aD%=0!r5W_-IDR*A;WEt$CPZEb_?U@+@ zn!kQ%o_x^_*dOdaxt%KfpqXZ_tA|7Ff8r}c;_<=c6<-}6?3U!72LgcI zohufezjJrG4TW_>STHVwe<&sITmb#`jCl8<0M{`r`#9HI9;nBw=Cy58YV@4NZN9hgN^@Cf}P zz$K;Mn<4-nh5M6&ctmP)UaWy!-h_Qf0_wU3MjdH-=Bjb&LxrcfL=vuczl1b%ne)0_ zsK{B-3UKT7K#{6nlTUkS^>8e;)Ig;Q z#Xd6b4g?;$#nvm+=YQC)OAAETHZ48p-*mel_ln_%aPoBOJnU;~5YAtEx6PXQm*}-O z;DIf~+VYoL$BnQWL7i^WmWpQ*qg&D=y@qsx_FIK+;n<#b{IE&TtKPzoL*;dnZG46> zgwL7`-}w1=vgB)2S8zkrBO`*?fIL0p5`D+HRP_ZQDyKAzPp`gECRe8ti!XOz{O<=?{EF|tx5I15^ z?>>U!4NMf^-Lv0pLMI>pFo%hd||G2kL3DibjU=7-DRz=$|ag+PV9*DN!Kbo z$<#=WeOxC>(CifMw+Ktj++M->u!8IAgQ*|eRtml#&)C$#w(vnSeL24B$t8;|&Nu2A z(m{^QqkY;l2nK@CR88mk{e8hXYu2T8OO4W5pJuuT1u^2%t}UVA{Iiu0E@#!u5R-$8 zf`y7Nwe)0MdqE3JxRyTJKg$4H{n`^j7tnd6M+oCfEs7}g0VOYGnE8l*wT}Ge3*~Tg zwGHe7He_d!1oG|wrkJi`Jf1Af+jN9`PX>64@>};+*nd89S8m>uqO7DfuMsV}Xei6( ztJ@NN3N)^+)pwm2yTlSxC&iuPKDBl=@hssQgQ_pDe3M8X%O%N(%mgB;1y6( zzP<1N^Bj(cWoKvhH?uRdJM%uvxR+Dfw0x_)!}i@pfm$;E5*aAot)vD>jr zR01roiEqK=Zpc00)OO)Sao~;%^PRoz(bZNJ7_^{ZjXa+b#Qzg@>y})V73>z7X6({@ z_0P+Hl{hn^c8AH0o_iN{A#D83kN*Y_@z@4L7pUlOuzmOc4?TeIuJXS({K;M>DQ0)KL?cas9#$$xZ}8nnZ`e z!QQMT!tr-WAZXF`M1@_ zP4a&t1B!4HT+RX*DB<8T3*+j5c~fob?IA*Ou*_yy#~^;sGE-4lC@utE2o{W{b!Was~kD zCZ4~yP_=QN8?gLeo3j$lbVkJNz+g4oeTw^^O<8ZA z&QFP@Lof(odei06%C5ZrG{s#A0A!$P_hyv}oPZ=O3k}wrmlsoF@5#V4BP*AOzcACt zSRsg)PRGrTwd59nc?M%4KEj>hf9-Q%H~>hG`_lnT<*wEzq}f1Qjl?H;U_S-icU2*C z3*H+Yc5=HBix(tH)p3&{&?*TI?RwYt@DsXX)wE3kP*R&~W`9jnJruuec1=F8W#%rYM1bbEW;KPK{~ViRg8! zd`)!7V=xSLgfKX^)>mnjMTeYuuA8^2ltOI4fKEF(_e!Si>(F%t$O`&GY=YYm^m5gu zzYfXc_~NXe-$mfxhQ@z``QhH2d2NJQe`&9O>tzEY$~a4|YaXphZ)bdQHXlTA2Z9vG z_7X_C9-sX4R+yx{KG*I9v$Tcx>X1hgEnRe|_TY3s0Q~XwgEXX`=%!N9p2zy~p{@cJ z?$~?0=dc;3*R5LfU}jfB&OkB_5d@#}u3qquJ24c^ku8ZnWh|45R~p$09P=7R`U$cYj&4iIt-}TFpXjNf}pWnlRf0( z>$l&3T(#9JGlsDEfH7;sxTYIrwK<%N;M|gl3mY}jUEK`WvU_m2@OcHG_>R9!$cNy` z!(RzQOomN#?RNtJ(VDeN;>s@8a&yT>>+=6b%o84dMc-(@piA&Qls<)@|DuwJmA@x8 zembW-_~7*Fu&zbu!zozrjdYv3xVgcL{)_gfmjH;b%MTV`eGKxuj()=57E<;n3t*_& zgnK?SLt|JG*7g#`rV_q+Apk~|d~5UWyA^0;xTkJBPR|49O|ePpSrgXQ*)a`q?ZhdK z_~a{j5Z7im>BO-n9e3snOssY$OrC;68*8m#*aXu!Jr(6JezL`v0&I)zA}x>ZmnoA} zf$aSU23mizfeTP9Z%jCl7dDsLSx(TPRgeLMx_Hl;pcki?Mg@jX_RLbi;mS?1-@&^4 zzBODuDAueuXb)Wb2Z#3n>W0G%pPY?x)Cd5QZS-Hl_;t_s(|`VUhEEQCQm_HXrU8%h zYX$Nr6+jIcU!-pd;6qT~QB+zS^O})!;Y(o#z!EA zfK+Yj`HTBwc0yC^>vrYZTu3YkUfp7`;~LF9SD;??a+g2=_&}vGC2?fI6_2BK?Xcwh z*y5@9Aei^zWsk>Pdvip_yzaB;jAm70dm!P5bq5t+D`zdKGsb?7zXi_$Gn_*g1h8i}5j{{+-VvL*U?%cT=XR3X9{#*dWO(hV% zkOddCbv)-==2R;ZwLlG2cZ}8lYP?-oOqMwUL^yw+HPI~-SQ9W-J&-1)#fK0LPL7Rw zHTtGlMqw4e>Jmp~A*g$?F+u0*CX7ese*c?>N8|qu=>lOCUh#bM>c5rH>c9p;YXd?Y zPWl%&>gnshGwBIXLXf-Am`6&8WXDG3q+pu#V^|;RSP?!po1c(zd&Q%4tOhlWTPR6< z1A?1;a!T9Sl^=#DZhTI-N28$wgUAeIcnVJaVUJYAC#e%Rv{DFxY)xMQdM+y}N2>NU zV?gUHT$9Q`j9(pzTjB|MjfhPwi21#Gb?VX`Zpzc&wO@z|7Sue!S_;zun-CJ4$aKMn z!?y*qzCuvMXIx{)9anmW@BBf-)v`JE{9p&0BK<`{Mv8jAVh#oF$*wtln0ZPG2Pmnh z&x(^#HglPTw8RiXq|ZJMn3kn|{|R=#cA9(*V8Lf(bgu8{0AAmJNx-~vXI2=^xy z)fn(Hd#Uf;_|Pk4!p}pYVs92zzN?0f1(A7Q7?-=~me{Z*xQF!fo2gS`#_H+#nBEU) zw>>vO`3u~Q6#xOg&x%gDQJh~zbn;Z$_avJf21W4Cr?Lq;(j{;FbZx{vx|u=_AvkLW z8_s2O6TIHLi!SHVyt01IdqXj0Tk6yA8%J*6?}{P9a3JR5Ii~`2%2##oh>7aCs5rGu zF0fef3nTT_VOdv)Wxj`dDgyUn*)U8gGP0=pgi^;80>_geNLK6qK5+G3Q47Brof~iK z$aw-`<;-hR+cIK)P_)~bEZI4zGmC2Fj|E{YPW^pI$ExzusDGTRpyV|! zF2wA7&-i&`le^o4sa5KJ+EjH)Y>2F$lBZzTpU)^f`ZnG4DsBpOgg6M0r!~ZR3%5Rc z_wJglJ9X*Fvx1oiiD7vOC3LM;HHKyCwi2A3PY*?lenLszaQ6V5m zW(Ty2whiIFM_1xK>%jF#klWUj1A-{5(>HceT2;?Je~mPz1HZ3o_V4(+6II~Ngz1#$ zHoiKwE`cwX~+h^0_Gi;}o^2D*+<0EFS^ejM&^NM#;4d2tehcstU>;mj%bLAh?M zLA^b{?^Oea?$P|O&Uk8)JVkBffpD8p6gvpQ_7z6uuE)rI<1|O35^M($a9>XhdKjBg zt#jWZu0u7LN#)JH^21P)}1hk99f}JB)xK6?(+n}`Is=U8fTjB z=Y|69HqG)Al=lU>8fiBH_0N80HMot7iwC5>=@kZY{G0hvdn)@yVkldI!?Yt z0b=}p-H$U_R7#GeYN(S7l0njLQb0_P)Qm*eHIU{hj@_1Ye2Fa3fgt?u^+-m**AuyC zkW&vl2}Jem{yuMdbRwGt*ma6Si91945IfXO3>LUd&C*_XQlbX)kpT;*v|U_a`r?~N zCNOXlxo23`Is-x)C;L3FjCPndThZHky6K}5XIyv-NU6IAdG)BxRlWn^%f`o1)6^iF z&n(P04%2?GK9Lf<*pNOykxC3Avt`w-4&^a0t*&0;)#C&;SOg`oEk98;wdjg_4nQdV z9nt@RrYYcS7^Z#B;p)=vVlrLkh(dvMpKm7LR$~rBKCQlfp8jnU>c#`IrxI!9q3d#q z!R8ABM*m;-Z^$BAAUhNFv~LY<4G6v~U--+^CjqgyewllkLZuSq{?&qzjOopTZ_New z+yL_@Q_lZmzS10G6sC>K=2ON&J?;M{uZ z)Mgx*_YiqEVKrW6#t=ZR5V$XpZpNhYoYBVEWnkUF`61j3Lp#ga|3r-Et^d!FE7bIm zEeOucOd2%p{nLdm+?1k=09LT zbHoLR^;p-P#L-B&G^{+7u+< z$KZI$j`le^zI35Q+oz=q{6E=(C5`fqlEjBL+X1@*F)~sJI^i0pUGMW^L@RzUHro7n z#*T)xx`4Ej97W)CaCNgP8JE%g|JgK~eio)p!kRuDG@hh|oWqa{flwe3_mDaL5x6z+ z6}*eYi?|KWW+9FJnQQPJ^h<|EGv5F4)}IC^^F2$tsV#;*{mHsO6 zW#@LW)l^CQ#@t911~4}7YE?m09rE0!b|z`rJQ5F|3G9(7S{rpry9h>ky143{!IdhG z26eazoTs0J$Phq>3ZOHhE{M|E!0ukhfNtw|4-KszW<#B}fdQ|xs9re!7wa&ht)mV% zCgz{KAwxKkmd<7FOOyq&; zm=_rZf;pCp{&cUe2=u!tlLEMN4ZyWFoh5^vk;BH=YT!3VH+EqMsJoGwKGYg)!7RRxbSMjONUYcDIaQ3><|6>Tp177PPXi_1HFW9_=F`(t=q!q=jQU?++h9{qXO29X?(K#nwUEDlKD0#XSXU5A&* ztoTb_;6FNCU2`Akkw**J8t2qwXcEEQHl2EzJ-uZ%{m+>g014zy`2EcN&J{#?KVH1E z5qaB);r4izKi&f$O=S_yH|FPTg5^%TeWo+r)Y}V)s$mMfN9$Pv^W`m@`>svcr)Te5n|63j27Q7%R>^ z!+|cY90CBiga*x{Jp-plYg``)%Y-+V-uWRc+`O^zm7N%zUhX@T-OXf~&Bp`ezJzdJ zY{jJ21b;DVWiIylagg7zeP>0foQqGU`$ZLIO;Ohzs!KqKANE=MD4nIp-8$C7v^Cd! ztB^Fta!|a2!1Zb>R{=pF#kUvH%N0(OZ~dZ5RZF6G4%GmmwY_69_fNSsf{u3NnE^S8 z=1Y(rNK+Tf1D~r*&`Gs^ACnAHcvkn*hWueohvMxU(T$lTz*r;N30-)7gv?me5trjL zxXaA+nKQs_q7JD9A7glG`ib3uV(q^Gw@bp7-qB_fWNH6~!4bpM?|#ih?aOdKEU&sM zhBjppc-6%P6y;QD3{sNMepuZg#4uNte<8}FmzRKjx6jIAs4v3!U9?{IEz}SSYmH#$ z6RKV$(G6hg0l4%2bbeV% z1iNvth5AFSBm(51wP>v8i}ZV1nc+yh?@qT0?wC8=;8rcNM)0ja?9WUlVJ8gg){tkS z5vRj=`=@AZtItID=ppzey-j1iI}bWE_l+Zwiw8D_bPIDKXImo}91jyR%G1V>4oX0nzKyH?}EizF6YJ;SMs~vBs+*(fKL2+_~W(J zC9=eZXN0iv@gOp$MV@IPSC;fx!BKgcc@sGiI3KSZohH52g9<*uXEQ>3(p~p+xOhmR zh?wc=DWnGI5l|~7Pg#y~q={}J@fBi3%8nV{4BO~(dEc6{OfPMU`DW4?VapWR~9aVXjlCfN7NI^iB}$hr}uW^ zF9XfeuPW^MB;zHb>;V&@MeUV$1=`tpZ_vsUZ5UmZClu#*7(`3h+Lx$A;{Kw1!-Z%M zD*-;p*Hw1dB`m}aBrjyoNogxwO0{IxBI(B$D(iMtMGzqkO|a9VWOacyA-zc)D$&p0 z=0hRF+o}L|*>V4bqFHt3bVaer5i<>PVu(2?ILwHki3Ts*iiT!rN$3Ed$pk{t8_XD9;zzj zBh1L0YItflG&Nr+k6A7ZH|%@7k&X9lboWzpnG3C-Hz6`|Y{0_%rTBZKuSflg8V>d; zI*kavDojw14l*?{oBx= z*Y3VLJ9VZe(EeLGmzNu2QHedu2dnXM-1lf9_{=8VeOE6ajzi%m(PzK?vSEZ>lf;>t z;ZEjV_y0Q5pu3gpvP!2pF^s^=c^aJzK8FuU-|Pn_Pf`+y+2oK$jP7Pb0JTbuN4>4o zYZ&3zRWi;2>D}jk8_UJ_(y6~+(PMIT1liS?-)DP;&d5A@Q4XhPy%@`rctPDnHy*)W zUp_RO-AaH9k-fh{eu-pM5vlUdbo8vT zA+pz79%l1~6`Qh@fp|Y!JnERff(!Pfw792_@IOU?$X}Z8>#ssU(G7pHr}P%+Oa zTW2PHnfN

KepZRfi#jPsHD(WJwo@xIyv2(eN-^`1TrS?8!E5b19A{`NmcP`!KY z=|1E{Cv`Uohig*7+t?2mGj`%5K6 zC@f(R&iZSxqC(`oSHU_3X-uqC9j0M)^9YHB+{b@T69>fn_`v@3HVxh)|$LcHXO0SqY1?m$f*1FI}_3KC_7eJN66hmGbq+ zIImdOvDF{2A1>+VPCR^U`U-=&U9cYxuTYLtc8@#T%7V`Y9~)x%8|Qx9c4nK?CLSfU zgnql#1cc~cUbm0iF=c=DqV9v3qDOrFbYAWl zdH1bt;oEa^?AY-D(^B)Te=N3pnyL9AC9FHJz~0?(T{5*QT-tnorQ*joWGMv~_S^e+ z2gnvIW2{`QKHWLJljm69V=k~277{u|!(n@z?pR$fhx$$KF?6_gKBl=3=cQ)EfHE&vEx! zf7cnC4_{PN*eP1PtAA!*QNCr{*O_SHDe0?-(~9%V|JSXEN=fmDJUk3}w#|}rErE&o zPmw-n6=9Aajvlx9g+D5H4ni}UU!L4y$a&Nx>)q_y_X{Yt{>q?bA#GIuqu@fp;aj>- zlTDAV+rbl1f>`*m2}gv>-0rGw^Ej`LRZs!_1(%DRNY0@TE-7R1LA`9{PsPdKCv-O)^Ofr~9}8YwUh4(_yZ(H~fnaKz zLha=DyQK`tS&c87K~jHg_xq#4OGIdXqj6E0aY@}=$-6&V20=D47Xb^BWjE`(ujP0q zAJxjtN(58yfwxBE?-L3ie~XpaebTG@_a#X~`egFLpJ%G7_C5rWAMHzs(;azPSKTQq z`uC~lb!%16(Ke_wm@L*ltQbPI`vz(kM5vEyZ@q1f^8t^l{Kk7}5>2#wUaqk>XU#}O zAFXZFf+y3s5$%f2(OEz3wAbbn?sGpHlCCow9zsx-Q^9mvGp)D)UulgWY3o`;<#l!! z41yQ_8I{-?LYXiyZn7lq_!hexuRN2=SilEQZ-<;bo(ImVB)glMpM%dk9I`TW#KB`D zf-HK>wx=9roJRTSZN-Fjft-0ZtGzquqtMSwb8irxSTZ->s672FkfIMB>v)O1b38Xj zBDGr9t83Cd3?q%N=ANTKbv3qqDqyOr2Av+D;B7-||GJn#e`BdvHRC1(_c$2~f1id7 zDR!?l*ikI#ak{-B+5Z4MAg!sE`R+QFP9(b9@rnj!PNsVGf@<#S;hrJC`zqn z(FxmJeR1OATI+Y<&EKx<#E-(2q;4nMj#?MIkqCr4W$D<0Q^qrZ&>rvrC)#WB(8u?#6*Uj4R8N0gmpgV$aMCp;3w-BR2 zk9Fy(sPUG6p6@QHV=s6%hnuNSc!Zau^n;|7zVQDnqanF3rGQt}3Lf4#a|qOrYTHY? zKHQd$)cH2bQ*2oRo;swRB-aFzdw&!fkPJ?1sq0KG4Dh2N)l z{=tUelKjOUDK*Xk+F&y@dz#Hb1;G{k^{fySZM-90@L8rkF+t4WLPYJ&MRi+eJq`p{ zS8$YWdO=dh<=y1&)rzW?gh84;e&Oefd=>O5kG@3Z2$yg@y9JtCiYG$ohjRA3d;;Dy zeY;!Oh)xy51r?#~{o~rL@!iyehKCcl!_Qq*^!FcwH>zVE7w;sT6HxZAE)Q7RSxx&R ziwh}MDKGB0EnO=1kj>gD3yx-O?|KvigV5enED&cp)K+1c*OMCb^^7%p(covm*D)2C?sgsIJjvklC&}#OeNj$T82{kKRQh~v9Q znzHqYXR~{}BRxoMol1J>+ajb;l&MR^9u3yDYI?fs;7&8qXMDhWHRmhJ+T?I>tjjkk z0xFR@#gTJ6XC|j+P5I_W!y+!(w7@v?nnXT*Royst3f?Iamc(n-Y1iS319!RS4O4zk zu*;_uvF@wBE!QvG>M++8X2FKKO&Z4=4{5yb@=K-W=8;T_46*V;@aU5fCzA0BHS2T1 z>)J_~Xmc2(-LcX3O^z0B@$Y+~@_d8%9Vph~Q&ZZ`bf<5_rWSaY@Y5c;B|f@01cSc1e-5+a9BI8<-n6g2#ms-Z&s`6LF7-BbZ|%D0o4>1ga*hZ%29C>X{GDoh0^^`S z@+K~XGhieCsO^Bgo4V{|VSBtW=?26ZvG;O=Xp{AB>`S0eC`s?0pHOcQT znq(7X(_eW$uki3$g=&b1A|d)m7VZmGB(iZxL@YFg&$@VgpPCx{i`_j46|2 zZhn}Mofcovc}egJ1}{dAI1bw(8&%uGOp#tQeg|6jv9J-k#UpG5JJTr?G(KA%4$hJ9 zId~yOhD1WTJ#WTWcM~bDw8bS1ny-<{kwlR84+oQX)O1(MT5<)ksX7vA^f2OD#)^%m)Tp>^xkUGAV|V>N9V7HkByh*H0Vuh7zz zG)~x>xb|V-5~sN>tuQ#={NdH_>rzVPWy354#s@K?MvjJ z1C6SEXSre&)UUq)N6-=%oNI+o1hM2by80GZeqAucS1MvJ4zuKi$YieS5XtRv1H^y0 zyxDo7h{;4b+-`F6LGSP_qz@0}83gZb+Vvk+*e9mdu!tZ@+*qPuf*ds@SE#~ie(7LcZwso?lgod4&x;Yqu0X@DGRh8dFW zRt)DJ@tpkJLB@o!P~^p}gO|7n7KdD=^ca-UVrjl?*bmpWXS#A0&`NW9K>zcngGcy8 zXaVgK$rszcMfYC85HTo+nk}neDswR%Wab#lMztwo18iQ7n)r(8&2X~vcR$0{^AA3a z0&;hd1~J&y7-z2&5cRpm%Qz%sbPqAVpb3BEZ?ssV57-q>l%)&*^A-ySP#Ky}*4wpTH4r z4XsF%wjS_W2MN8pdxqq&V*1VnIdq-S9z8e?&l1@!^lN9wg^TjbP;c!zTF zG;U|jM4H~dJX!^PkV?eC6p^ot*UnBGFz3`_T!ATIDQk1r4e-MPaf5ca2L(>HH9QD& zveJrE`rkqnFJ4G)ofS4n-yx%3nG|vP-Qp?vbx;$caLxtMmvLz79}aGVTe51hLMz0k z!`eegM;uAyriTH#<+GYTD+_ikXRAQZ^FKd<0rpNOtJ?&S0$V4D19_eQlYeRkcr4h2 zqjJLmORGYAd!ShpHn%N3tkC9i-o`JBOI0jONuO`n_6&qwcq#D|2gwas044QGVzBXw z|JJioU>tDOPoe{Ns4s%z7(7e4M5Z+tJz{Tmx%YAgjf)ye3WoP zByi7vSbU2l-yNIG2y;3{olA-fD`7a-K^+%emKw#Baj=L~KI6SJkw4`mcX^qK-q0(r z{^#(SpK^PbjHlTnBZ=@;o=N_6d-Qj*n3*4nbBn$m@FbvY41nMH34jr}}*ut z6$(X_Ft*{gfIf%mau7o0E(vQ>2toAO!jsk4%E&+2XI#8bPG^0Zo!qIGIw2 zD~sDP3kygCOExhaXu?HGdM4v~ArTOWNd88psae4J1;=?v7~X?Z(F^(g5PBqdO9*NU z`pJ)+w|?l2^(!;xNp2@DI4{UDemx3E94Hkdi~L)5(FM^qJ-zQ_w20KXU2<+`h?nMo z*FjtVZ?Rw;tZ9`!s zn_G4Jois;I8%yz~E*`9R>5=-xrx?W-+KcG+47C4e3bs;c?o@CyUtCbhCKQ*=(4Z9# z1pMd8pt~w9%-o2wFWa*EDh9xVOo&D(!by6#iCOuX-BY&N!`C~AK;{f;(mT@O*lNIQ zkY~XN#$;Y-0fEqsl2#d$^I{Prh)|F%0oV8*q}Fe@bIyR|JQDwK+2C*4F%v6OoTA1v zzf;vQ3oxTdMm_@*A!~^aUJ)q#-A2MHz?}ckjaoK22e`iu4TWtPAb?OC8shsQ6!8?u zDW_Q^o`$REs;Bc5+cLL#2?Gx&cx(nt8pV=&5lPfV-tm91$!>-3VHa@dJ!I!+{{5W+ zR|~+yO!ld%-$8Rj?0X0-uD;#uZ;RBUu_|!dIoH$Db^Q~Yr(gBbuJUpa0vo~ksmSBD z?dCipDvK-ozMmO07MlHOT=rz32upVGNy>&B@;4b4Hre}V_Ci!v7rOWl5S?Xcf)?N# z@$QxJ=E$mH1)nT#Xt}IGVFFOZTJFbm&uzDfU1i2>?5C6R8UagIc7->A`w7!ln@|sb z*z?#?#U8F0;B*)8>Yk(_S?@67nIZ>Eth{tVwzE6Manay*L<5ME4yA0Hpx?_uxdy*dlL4 zxyB3W0Bwv3Ozs2hkP~Z|Y@L8HgFXkWIdfKDFS_u}y^)rTMib{&y7=|5HkeF*GHMy_ zME|!KoYE(ID`@{J+N%$AUtryOPLc;BtA1||^$`_+#_@nkV{z}144>JZLWp+inoa!#|qO*9|SP zVo8?l+pvO05ULKt6&`=_Gta+GGq7c#^eYK>W%AncCiUt14E4n}rHT0pC9j zk4lH)FsB*s8O2ae{AGF2v5UL+#H)suk{oedJi?GJM(?SoWQZ8mbb3o%PKu@28Vzo# zr_d^1IZ%>YMw>>sh~en6zrp9Fj)F;x;U6&G~5 z3*3b@I~2PF{=9d%s|ntJKMMtn&n=!}lf#;6YI~mWt03`jXiXsS$?o3we!W!L5-bA# zG8+>aDw`qJA;=n^x|LH7tene%GofV@yelguO9>tF;j~s7gDePag9RF zv+?W8pv!8JxZ@*#TGG*SA_Z~fXFbt>$W_dm5~5r^#BLu1V(bx%1HXq8wrKya!J<6|G zMpPl8CIVM)e35-n%o>RcP+S<|Z~INP3aOjAM+L#)>UpTFcw%l2M&<(cxpdEpWDNl* zw!aTmpq)=aVj<8~xlAuD5J8BmLw0X-OqLXk9fz(i)2PD`V#;-$zZhH!=EzAcCYCF= zFiivAsn+z${;%91Cxf80=gT{4A`!TNlwlJrM@C|ym19R#fteThQtB~r-h|_eHCSnz z(@fwJ2Q4)7$)D4PeHFkp(r`_$EE0hQC~s}PYm>maIk6=f^s~hd2HyoWUUyC#rZw2E zP0E5B<0!^7=^ou^R}?|uu_7- zOKi!{;$?;#qQ$y4iMuso?TZSt#OAwZUviSz#8Spys~Btqj<1gtU+~R6H3@jSy3m0^ z1qBJ>n8rea^C2@m^9vi}emBDGzgHCa@6I|8s5)W4>t)7~6`)iH|88B|drDkNiiU28 z3^%+OWT%IA#+LoyCWS;`$i93Zb>$?rCQS_hF&vQL()o0cF%#N5Nk!Mibz?J2@}Kvf z?w2ruspsYH*8!1kP;QSF>dh)em^R||zDsIxnZ9Wx-d8K$8><$aH#qaZ1@!+?4g(FB zxjo^Sx*tB?udfx+7c=idv6&eLJ}UC8N71dk>p}(^mHoNPh=Y_7@3i=QKQF-#VrnVB z7iPc@nn{=$mV|>3X@Oa2{BvCxwgp@LAwJ+ohUo^uKK&sJ+Pasz-&g>BtN?u+OsTKI zUjB~Or!niZ$3cT{CH_V)H>xw!cPL!jElj6#&_jJbm1w9zI}cFXC%M0vFH-M*!wkqX zXT!7|Bk+EWT7fpRKSy4K2-(1%(;z4ORp`lQ%Z251P?7JO?DG5dEGG=m{xkvoI|^&k zZUC#wA)z*pnBqvhU$bxKY$eVy#N7e?r>1+lov^5tyX#N>5&;XM#^By0NL0 zKG}%mVWXL;iSn66z-c@XUXmou)Eti&Oot7D9v!8lD75&L8(?c+@4g)P+6`h;5uT(a z@xwIIAXv^LtD3by8_*kO;JPxSwNSslznN2(fRn2UwrO|P$w7U;KcFur?E(Ey)AfJC zX@Fkg&bsDzOan`1??Yi9VV^=`bml48HLpBfxHjXc?HZWNxPCtmqbyM~-rz4{;cf_M zK=|NI3{aN!wllr*Y`*du4C@yMfXr!4x(cApoD{B|?}UwpV7yXk+QrX-c@d;P4z4)o zUWH!u+Q+#|y$tn(y3GUkf3Q3xYbuFeL^|%v0Sm{~(R^tYJwH2c3|ffb`84KSpvw?` znOxBR4|f%U1-D+#G(37DD*>&Qr8y>D(nf@qfQ~VqNW5?R`&i!um4R8=f?6>I!*n4@ zgK0mN*8dhAQj(DUx-*c6x~w$oTpZQG zylu<%SNlAju%~?84FU zru{oO==cSbxba$Zd~A~phODB|Nqba+h(J|4cFOc~!nhA&v|)IPrq)in!& zX+H1VuNMmCfkqypXi04|XgPB6$l@OZzFm=caFYcWiFi{P5%~7^x}}DgB@BzKqIzml zn>U~@5;2dw*v8cZ3yO&J_%T1TNsVQM$I2Up=_Exl!XGTyNJKBfMc{1UYpy>!kdkC{ znz{sBR+aCd;J;2S*+ptp=qqZGeoPZE5VT1g8D2S0fEPhD@7)_hPKvNE8Npq@>kOLx z$oU5wD$0N4yMmN-%nzFH{GkEQO?3kOe6Rc<*;yA<*Ysj2wro_{(;+E4$;A(H#`F0j4jMOxnDTsNk4`5z;yiL3K@i1l+W5x(FY931MM`Ms+}sMc339 zz@ktg`eNS_H1Np|7opzhmx)o5l4+UO0NT5N)-w$qEBFzxbXE(i`X`8bvNQJ*TL1EbS@))?Nim+E%%KdZrX8#`Ito`ohL>aj z+1xc~|1SFjH!Fr~_z?AnnUQ&|&1UuuDUeLd{S#XAgk%+pn+ENYL8pm8(X_y``xTxG zf(sFER|9D~2xr+@F&j^RW_4qCcld&b0Wxm`YEqq>_;?X-|I9fo#DoCD&$dWM^PVVl z!YnQG-KBy-L=8P8>zA7WVs>}uB}ks#?|#!Mz>G!Z9FP8_aSRm7=l-P{H1Jc9A}U*5 zF6F%hS0TRNQSRo!Ae4lbG;d)2L<8Dh8&puE{sk~1-m7jugmIDf8qCr9l}Su#&q{!s?vCEC`g4fkC-Fi; zU{O_sU_#n_vM!}eqgFm+Tj|Q|%0KnV^CjVf@yGaha1k-%?~J4z>7jKeF()2FSv7CZ ztNyTLcJpc|Y3BR^I1w%LGbRZYlcU*Wv56;T5_bBeoDP>uZfV_n?b7+}1>nOg;UMuq z?QW`U;mDTIw)YI-n1-RZk`E&G2oq1rU2{ltb zDe)GE*>KAfuAI4E*8wV%cl0->GE3$-f7lfHDEJ^xM3>0)h4ZkBNevcRYE3j=PFkvo zB?l$jOBE-J*=A{7JHGS9Q$eE?e864B za|mpCl_?7JcvtbuJJC1OdU_YL73or@mPfuUejFh#@0wFif~ZV;?oXR_6WuNEq~`t8 z(Rt#pUQ@sL@tAXuon8t>plWn&?T=Z&3SXFpRHg=>Lnv(9s%HpAv~Rv;sw^lyNpe`F z*+Uuh0Jx$}SuC=AknuBy1*=L_jVONfP-lP9yy)4&ALhGP@;9yAT{U~t{y|bjkc&R( zuhw+tc&2{O{BAn6h_WX`g_A_)(3G!pexLf`-}?8NG%SZEDmQ@>hQ8T8scKOYi8CmU zOh|s|nYc^4zmulmnAg>;zgNJWCCXAZ=5hbmem8bzgL3VHAO5*0T6Uo=UnyO`i9B!wuXRA8~E!lK^s!P#b|Ik0bN)3=M(O-i#`78UoX ztF8UGrLYb^A z1Qcb{h8{Vx>x@kGFkKZWjGKJ3yRt_CYP;bY%h}wtJRa$S_0z?Rgmc)47bIU&x!<#= zN9=6)^=~$1OWgB7n0XsVIXKFV%PD`#t5XNw?Axzr{bg^7BRHO73gKmfB|W=EbSdrH zJ#-3*J5;p1PsN^nUo=+%j8{$9pKsB2M#h#W++1l?5kfxtohHm7wj>g8Px!rjuS$Y= zP$ALH4qr(gjtI&K4t|t9Qpe89mih6b!1TVlil74Ccsx1UN=2L)pb~sR^Ceo&EYHV`ot!Pct^8)$XNCU7|m^QufbLd45Gt7KO^92dua#V!H%FAanKn!l_O9I~I9W_P-;iqvCzKQ!ynn;MPex^qr!B-HN! zq%ME6_8(!ZMQ{iNG1$o_7f+EJpSz~))E*0$@ToCUJd<0M0$)Y6x7bTeEXax6<(kCN z6HhIjzLTfupS8z3%74RfG2=@Siag~^br?T$Mhvuq58X@G{F$>w|IUB^&Zr>xuqTcW z`ONFGZ;V?3EG3o1;V=g>M1oiIgISa0A@wd7AG29S64iB9I7`mjVj43c{!T6!XH+8suL2upBs#)OuqZ3Zud8O=Dq=)No$ z))-P6p~NcRd-BPV9#%Ox(j~|a`8W6S+qMa#sgmb&vfKla zw^F2{L|i<2*Oa`ivAMIa4Xc-9{GcCJr5hd9QfR6{wDAwO0MmjaiVQ`K*45ZvkF@Xd zx&n4aAFj#KP;ZYUs_Q#ls194Xuwq;6hZpf1O;5#jf|yiv1txD>9XtY`RD_V;m#{LY zAE2}J{E#4)dsN(1BYo>z>jIplL&NSF$wq5L0Y1thr)%d}k|C}sbk5k-Y)J1-Xn5Vb zRVNe^$ro}EKN{hwHLJya}=y?jJ(|`l1X4O9q zB~r!=zxPN@=t_~;~UU(-tmpIA9m@shStIcwdU31Gfq4& z!7;XC_t5RVgxYp+WiVNAl}LS{+MPSUu2L}ArwKpSx95!ezdFt{tf}P-_W`6SO+o1pP(ct-fgmCvQVvae z4WWqi7J3g5LiHj-a!og04InMLJhr!CcR3BJO1yd`{8~{p8f2d?Ad$G%$ixh z_dQy4vgv_2E6D<*75hi72ZB6ShSKyjYlDCzsFAZZw8OeRFo7|M?{)f%Jh}jj^{o{F zQl>3?_Du6~;X`g2&i6jDaqN42)C}s)igM;wHFYc&!9XSvV2}sHDRoUpbyAaRMxFj) z$uq8VvQN7aLdXE+TwD2of0I36<98wM+Lc@-I?#0TTH+alU}vpN$`4uTX|FoH$&8et z4?iyNDQPw@F*8E$ox90?C@~b;W|;@Ia}TrBr+SWrKSLsswoiKFl#OGNi9Ua)>ixSz zmr2(1(;Wu7Rbm6>xo-c&-``n~&rxi2{^fVqBnC3*Ua`Owa(R2+jTf*2H&)pA@k(K$ z9%@IlMV>4(f{C^SFp%#b zWvg9QlhdX39rEG)g{+UO!R_q;T$R znrCka1*otTCV1=EZ#{6rFJrbX1D-W1UEoa-ez4kM5OYmSw|0qnR6`^0bw}y7%R|zQ zhxxbvB}GxUriZ%7+O8P}&sDBuv1`}y`|(#X?RysOYQUn8M+AIR!J_-mUixxY#*rHa0gG-bv=72btPLD(?0K`i3|e`Y4~CzYyOKrHC6n$?3;|CmvqDr z{(Qq0Jw_q+p8SmRI00V0BkCiWsc zM z8%lyJ%tfB_xt|vvmDYiX9Gvu0IHTW2Z768wiwrwO6&B7FVFn~r4M~UP)S{2}L5lFC zmg^S7O&;}r=}1o6C;bre_q88z2qdZmp=Wm|PW_`;RgMqX_6Ud|morY#j#1av)8yAg zr!$yT7vQ!(8;@E4S_WIB{m8JNjEMaKMM8eszD!2zwd^?G7yI@321TA~I;Qou6ZlIx z6FMT1z0E=d0g&1spxOfAR@UAc$r7U8X&Xn?Dn^BbRYW2x^vB|*oblCX+-|+bG13;= z?muwx3hP|o$N{@qC#!Z!&dD5We`3avW&*0n%(a8N>h_h<4h9+`buQ*k<+ul*KIf9n zdwpJL{XAvhSZILFZ>VME)NkW1JSfD?cEyNvp_1rn)$VzZE+zA;#z#Eme9vAj=P+e-XH(VKVsdGT8bZ< zCSb~tq;yE7SxUKP?JkGEp&w&qDvo`nMWgmNt9o54gzCx4pV~nQ!^;LnQ2K?+%!ccM zj{{+^hol+4%|A$^r%}5JB=wj=O`BAu(Us2ccT$~0U>Oa;B8z6oY`5-3iX1|WD0P>0 zp+**VV-IyaQdAT_d@~$C9jQg0ImH!c*Aqp=UXaN89lmYHR_I~$ z^@?1lr6YMc~Gj-MNS*>J&jRi zSer3;!(*+tqr;fQW&__$8GVM9Tz19IoERz&W3hSCvL({-m`jvD08u07?yhsYhC|f` z-(9_`FHLzXR&lzH>$o}X2W%ssGM({UCnt}E`Q2}t?%l@j(r1pa=wQ)RlyC}7EJ{K& zf+mf*?wc6%8^NP~sh5jh2ru!-O|hDiZC_WYLcecSeBGDN-)q-P*wY!0t_)>#Q#5nr z4hfav`r5>EYBX|zM!m`i&Jd6!;A#=+l&}t)x4b2=*|+*Tu~se)L!tI< zNrW1Wq%|XWMRL%rewMndVvzN=XnSJeyPTdxUg$to-f)EzM4i|t9>3%Kl33kfxr;)F zsh?C@e=Ud};wOxgQ2ScHg8VDE+!H-BSYmCbtGO0KKPK050kENNd0UO=T{*UP&B#lT z5;awo-dP2QblGvLZp1~wT#Gp6c!^2Q_fsyBOH5gF)CmsqU0roeq1!2Uy{4dFTlayl zB`pf(BV-_Nu|9f>semU)&TdG$-fZKmSr%Q&rPycFm0S~{3F!S@dD=rMt>^P>e1K+5 zJYoOCwUUyG?)v5GueWa(0r?2ZJ6?ccEd~ALv}s#z-`+;SQQIpSCwe|49g2iEJgIm9 zQMcvP_{_WO`&eUFjZprs2fZI$-9|UsFw&i((nq{Gzm1*xBxj3GEi4k4gsk8@64q6#pV9*qe7X#1L`~ zXRLh~Q)!;9ueFDYxwytn5J0POWY?xQaOo5p&<)?WDJ>j(uLV&{%oll#YGErQOc8@# zH(X2<8-o&mN!gd*x){<2wz63(QJ1|dQlPpuW{S-FU{jekn=bfgsz`VvRJ8+ZUijVy z7EKae-4*C&yw&wkq~XNs#WyjK85}jtG|0r`R7Fz1>Rdx$vcqfpe~?Ma$8zbI`TYr) z+zv%6u{#R8Lbc6S!$H3|OtP~$Ps*eI=*>1B7wh!3iLhUL)gUd!eW%s+ z)sjQ`oIb`T-j3eBe@5XNYO*Tj;wBY-+T1{vH(;~RQd0U_=6heNr9&fXwxCJ?mKw3jv|(vYa{a>oR;tHqx;_2L0KYk={SV~}Szz%3*Tf&Z zHHzcb@cjIAP6a%3${=aO0SpqxfS~-^>1Ye>Iq$3rw&Lxxn=-i@axVxOW2=K&1eh#*% zyW^#Bm!bP!_*H$aZDjKmzSm>$7DeS2j?Ub~g^=V$%DEMOd|8OneBvKycV-)vZp?=w z5v!Y7=f8|i@MxxXAq7`C*GF{pm*FVYw-O?W3Pwiw1jc#_9b5iYuhRk8xaB#`HTi6Hb?#0piu;}!} z+>&UIZYIb--|kX5{A0_mx&N5(KgyBg`pADKlH=ZyHkrpNwuRHxA`6s~!b}fEMGh2Q zbyaR9R;F0)nXAq$0V-j|vEWI-MumxsB3O-?BjLCcM|~&~2lx9u&R_W|y9Vc-&|%}G z+d6ZJ&>jbuD`d#L=gy1YaWnAdV2NS{6LeH>QZ%^jurcWg*CxgMH;pyyqTfWOO}{Wl zebR7)ZS}3i!{7>=&u{liA`KZ6^Af^up+V6sPhZPWt7NI_ z(i})jRk&ZbxM(&qnRq&slSY$#I$Oy^ZTq0sy7CqxM#5Nj`PFk`u8x zBa_c%bNTK!2iUDj+8Kdvp6 z*4)e@5XiQ23UfyYc?z3Kgyr!>>$J(Rsoro&ZrymXiOnVM~L>ulps07GHXdM!{$Bu#xc7o`4XJ`KdTQPmBi4O?5Si7zUa)U%CO=s4)_ zRPmWD>drNa#M+H@j?r?cWRvOH2RFJ#a8Op!E!4N|#*gR#7K}#uvD{psu3ch1W!1BC z)p;`!h=T*dZyG@ke@U^=aa{^c^B04c+elmWF@|XFY2vTB(k-uEMK?aHU2D##-a4Av zjIheFaTJ3-57~SAN+Xrm`Rw$nBrB7VmWYy&i;?BLjynk`Nz$CPy~+3r2HnyR28MkV z;*#u}7Y5w3E71iUZlk{LcXk{ymX8*7K@7}tkgz@Ol?TKp2>IX$VMk%;7i8U9eLl;! zH(s)Dw>#5)70Pj$25!E zurkr+GFV-^QDhaDm=(THHi>W)fWCWU<~JU8echmGnyX$sHpPf6!1v`6U++p*f^-XT z-Gm~`>ejvq-dJEpAoA;{tK0rj{X!F!EEUwcE01b1yKYUZT^A}~rHB3j(mIk@gJQ1A zk^P>hvS1kbj1ge67d>?>vq-3mQ!lp))SQ+i6BA6()NeHG@Z3r4VPvQ>7N$4g zIkv28olS`$yQTKJog49*A*k>fS8fluLdCPOI`{wXkY!FUYRx_jVv%2O;=&NL?o=6mm`ooFNuMG$>n_6e*Y5qsX@m)1Xt0fk7wuwAJM<@ z4Hcwqu&4h~^2#Z)2`C8KX~8*r+vg=?G8q5!s%qR$XvVSpwj6{y$<&Xqn>tl!_@qw? zu;+|}kz3&`V^-w>^4b%HO{r5SQmYO0w@?6!`OH#R*gqS>P$fI9f8YRUO7x)ckn;Lo zK#A$1kN+^+YVcXwa(G2e#f0cNy8U09mmqJW?@3Z4yVd>nxMR24<&)gB3egZzYQg%( z0Eir_*S@d@qGG0k+Gp!=uIoB$kU?X{V0q-PAxO;T@z?#3=$n2}t^+u7-gSL;6VD}J zbyCtsB_Tn6_(2mEZKh=`!MGV%xo=S>-~*)tE=S)H@*A_8jJ^R3w~MdKV1AITEz&e? z9pZXn!2m zWy-#+1^!0R8EX3N5#nU=^nLVkjDd+wM3107Bt0$fI)iGmUA^?u{q+T6%kh;56i-3j zF%e6-ve9Hw?cM^ zI#;-2WC$)3Nx40Qk|qBO>sGQD|UA3FXQqtcctJra$9pWj_h#mg`3}oSHQ_{rSA&&#j4k$ z?!umt_P-mrVF;m%ziF~4XHqCu0}Ei&8F$~_puvGMceuN;!Ar`SVlOTI(oNN3O7qv0 zFMGQVCV~11l(~|PkEUj4G(?!t?#GR!W-vNJR0iP^D0%0zblvc|;9s3-e)<0+ZTau^ z-P`@1@#}P#FOK{_qWO5pxZRT>p-Y#cOd)B-o&d9Z zISrU*k34RjP&_67PXgP@?UUBSrwqyD%p9WR>AoS6O3tE5Au8&4fbvZGJr03B3tq*N zKjwO-!pPFqN4b^^1n{?&X`td7u*$E_|Mzf0;AY}`ACYaKMhHI!SQFHFaS>~vZKT;o z!K7a58#cuqecnNRSngoiK)PXcl^aci2XpU^O!L|6Ey%^$t(Y{=Xa;_1KqF{+??|_a z>QQ7-oJ!$6RZE7f47FV$FER^}J=yJ^bpMi_I~S*EKc2lze_Ik#DXz`Q-M|@kTe8*4 z%6p8G*F=?{g6T2!GJU?yq&|Qx!Y0=P4~mJ(ehQEW3ubevk*8$5pld7zUOTzUiZL4jlEAarvid5~Bmc?DRoqdVP?&#-&)p z+dPXHZslia-t^iv`-6h(WMpbJPmepsCcnRlLbt8wa=)=~y*p4&ruJGYXv9nf8y|&M z#K6{`Z!R;nk;Pv7D|s84l@3Rv6(d9nGgqKEK*{Z%J16^?k_m zhbK-%F<`w)d+EpU{!iiJ&cX0Ikgw7G78dN3y+)r9Eh^(~X!{419Ohy;HN0x!H70Z+u2n2H5N5#~~ z*4oET#>UGId_ctSKX@p5|BjwXfgGBm;L_PYO_O*z?W+T7I zwW0i@%bxETclhL9PMp4w{`S6d(TQKkTfUM7$Spr?{@I5-T_MZ(_3XiK{u|u2?#S65 ze5GEyOZec~Q$IXDSeuoYaaeUrP)gS2g!K(;8eV+5@%iZ6pTESOl>EDIcIcKu>D!kI z{5=spUM%+F)8qPgIwO|n-R(-3-J-~_v;TemCxQP-;C~YMp9KDYDgk9zb;0_xe5+vl z0`*SL=oG(D$C>2lByNtCBh@ZB)0cJdE$GU@E1KiS=mJcmcY5$&rWa(}x#8cbC=G|o z+~xVB7ypB9f=~RUrEI=e3z>bEp72SMxJEkF7DP^BdtGlKyTwcX1Q*rz3pT+*F<@MEA#>FW3y!*{!%UG4K+otOi3ot{L*`LX!MDxi0=8&*ke6$_pu*wg(Rx&!AQ1P zT`OrQ6CSt@#b8tBsU(9+DTj`tr^rzV~=}Y$x3^* zawF;as9oCBszuhZe{ZrnUKM59dina&GQCOu+aUZ_R4g_L3900VBXslgq-Y6-`BhT% zir7f|mVPy8RWu1-R>U`>wM73jPfxb6M`s*7vp=uVnUWqOU z0-=fZ{3!?Da_NXXS#VY2L*?-omAPF?6n=VSTK$FDqL zw8~c9L15|~yCGR1_hP&z7kb18Y))Upo{_a`_Xvwdb{=*94p;$Jc|t42XMQ2zk)qhj zGYTp>6GX~Iq-MCrazVzXhY3#*o^8n2CLWad9Ymr$-Sh~x#aQ;U?qzZ)PeaYh7bUWq z&x**!pFAC`G&iB;-xJG6NJrb5)FgdZX34e2K=XZ5ySjD5>KKL!Pm#rw%*u$Ptqefy;R_;r~vVht|^AvS>GKoZ1V9$bRB)Fg|w(k z(o+T&%6yh&rPJiDm=JywY0wdb8yp}s7>61SKxppJM3R0VYSrfMA;ReO2u9l-8$rA zL=XII_tz#5Z@ywfgo+;a9wdEXmtUEl&VT)M&6UoH*NPF^(hJw^Us8{NWtjXUdY3$f zskqwXvZ;c4JKl%G9%=rB;C-wTC?$Uxg?A?Oe~(ZZpyXoJMV;CB9wqK?T`Q6oRaAU1 zC!T-7JGe8Jqd*B3>6OGDu5BhLiE~S+`nb(MFljh%K-WrWU6UGC+%k9Q2e=nLro6oB zUU!TXMq0-W;1Z475g)cH?DNFXcKu`w?7&!TAIcjHqdRLO6gm`{#{NQ1@MD3Hjp&~v z`ECk*U2gQIs7^EDynnAkXN&-G6=QK}Uqw%)QD>IO%Sn`@cOy=YZ=y$}a3h^PvEant z)g^IPi`NOdJ*J?oX`ezE5oN~Ggu?>K`B|gJa508~5hBWj z^JaYZq(AvbyF2bBF&4b~vkMz3A~s94u$Hn+y)wYt^o*APv#S3;LenScUify?hgd;s z2YVVt>?q7L|H$mNwJSaQjE_L!&_qpTktuAf_t#xWmuioD=!R$c9&-+>J80tDcWhma z&dTU@tmU9|vN5bh4{Bi>F@39ezjJ%-9!h5|c|;>kpAQ}Jb|v-;3;;xoSxaE&N33hn z_3N={nNC}J!$1D(Sxgn^PsMgc$>&FL5|AVUx|au2X;2}|A)^-l&MY}JcKy-`kuyY3u)%qKhLnKRHu3e&q?$e zMK9-l+>X#~w6dVRyroQheb`#MXAD*q*IlG-8nw-HzU}Z?kS~dLJ~R;{N5#dJUYx)! zcFa4n^Gk$6AG&Dv4j;Rts&vwH@iaX^7yE?sgubg{8Iy@BeviB{xr4h&(%s5cQ9EUB zMru*Bo-YR=805Voo?w$pDGA9FW-^GQRO6%gCEX&I!6U>h5mnnEhoxCsYsoM);Je@l ziccZLe1iBQaAN39rVumzAJpU&gfkX|sb;q+A}JFrkR6G#vRv;`I>>l)TRS;h2k-f} z(-@=v5qA9d5?0)b=_$fkN@&fIopy;TYWGdZx#@(QZeVLERZpdq{F%F#>6@eiPcQjp ze>K{upv2Xp!ruvV;ktn(dUgB+-2fgDV~iGtdtaO-HhpJkVyBD%TN~r<>p_gWjtd@i zus(s1+|X0nQq}1)@0}UYpmNy(ywvup?7BPwrUW6jLxk9FhBM@i`Bq`6 z^-2?uG(EsnbN+GsTGf&`5`+_-*jAgThg=0&_B4(N(yAyTDAzSJI*a=M6H%9n6(9Z# zEgv(mC2PpRhn|mpc8LW(X>VHS{^~}nm)J4b+{TX-o;Rnvp7m|}brD5#SjzMX-j!3m zgEOh+BmX{j2O)sdSO9sKJ&>K}kmII6biKTIw?8uHGj>4N6pbu}5pn5}v1g zoR9-ubDx{8^N-RMJcuSxe#4s$KGNEv&VOS30ba{~AF&qb_D$`cuNj0{RU6c5j@)~U)4$aWQU%fW_bcmj)Z*O2Ns zv;RL_MnuT|epTolE1A)jOV%Y+B()?CPoPP=7g0!iuU?_65cs=?H=M;jMVCub5fvvk z{NfmXaN}X!wWd!MBh3lNe}XtgxeeXe`Nw0Ig;$)(FNB1J0|awlQhwOm+a1#P8yWp^R5D;H5e^JOB9Mupl^8fO?6!7IHb&+p4lP zvu5_W5e}H4PMmj8b^HX}JcW}a(RyNAzbSbi+b8?LJOzt}QEsAvG`glLn?aT#%VJhX zV-nWd;6)vd=RSSq{P{m(fN>o^o!d{kGTJ5LBP-MD>FDeyeI(4>67L>v zqMZ&`9oMH@&@C-2V%@p|b;Crw$L@CN>5E5ifUn_G@~7;>xwI_L-98Irv6sTS1(n!T zx1gYkO$Z(E5j|hTK;IXQ-LsRl9?ly`8J8CdsU>?Lzk|NtZNBuY0S2>Yq{2O zZ({YFZqaz)xSCL?&raed+Pbj-Et5|{n#HYl!jnlRi;1C8QNpa+8*G$;p^w1Zy9pwf z%6sNpm%S%kHYqLGyQKtGD1c|jL+hLi3sZpo!#@# zP0NR;x@_2hRV^sb5Y=*2<44U=%{ zy~q6@_Es^*p21>MNhXCh z*O$H+*h%HPjtH~rZ@4Kieyq>QfT3u<4-A=pe&(X`m(ZR;K%Jr6m%rjKRU`@YqXHK1=Lz%S%jobmNXyn78kU z6{H&i<83etPzVaQ&AU_{T{Dnt?CtL{jUPr*?pbL3Yd*(*!;M@7GrxV&mCn-fjn6VG^Ov8fklJo7TPzhbtqc=-L=)rmF<{m zs>2w>a=TB+tsMf*X*fWU*Step$@S|#!=FBVDp5+m8OykaifCL9v1>iwyAOQY=_{8m z9jK|fx%@G|ZeU}Vqg*dRoY8{85`mq;2})x|iXw%RpGsKSsj~KM%It|u^I^n)x&AWI z1$>xRD~5Ffi%;~LeZyZB>DnTj!9oa|AN21--;+!|iPL33-h1UmfqYZlXpucG)Nu_W6>J6;)^Kam5PI!7JyIyZ}}bfXaAlN-!F4PMV|4SX=Je zsHttiSm`4l&EgSvHi1U;sOJ+SXNvC`Dz+|7XZsc*bU4mU_F1r^6uQ8g*u~UsE1s|V z=X^#%;GB4-lgn^ZeR6WL-&199D(u(Wi%u<72!+0bhm~x@)ryiB`S8xf{{Pg1#nIVp z_5-hIiQyjE@71=9Qj=%i8*)93ueINLa3wl5cPOjzLv;S?iF~pQ+IrT?*6lqI>5iX{ znkf)m%gwukJtHifXB=fN&2+@EZ-xEce4))3vvJ$@?GjQ_QsW~=#>T?zmTeBK6>qX% zDzFn|^*Z0v8~jYbg6DkLT7J(L3t&bgC|j_hV>o2>n^9W~01k^YtlAjp6)Gjff);a&vP(aS4riRvG^R_n^;?1eB*Q*|_#qR8~p}YDOKF zYc1-oex%Yh@_66G9k`=JfJkr-aqr7bp&ZS;xpq_c?OnF<{_TGABLqW34`TGR#(6j9 zcot1Wj%bS@+mSqU=ul-^(n0Xd($fw{gIWaL&D^@iyWhkOlrr?2A1{|6%QKsVZ z%6r~zH%TsPT3V~4s~cYEF%wiAyshFS-3S(@ZG3?ud5J}V5>qLe`}7d_`^q<)lnnVg zHmPZ9T3)^S5*Dryl*Rm(W{Vld3m(;4js{b(BP}hhS~1~o;H9ci!2^9%KuaTMd>-d} z8hf+5`tJ?}JFygI9u`M$s|Y2Jtb;p}8CXx!{hLpp?7qHs_xmf^%{qJ?^f}Oy?0ord z>|bBlV*e_AIhUfm>##`nywv3UVns!TcA3>pm*wA99BU*bQVE}u6uJpv@C%Vk?Hbdj4Bwf`vu0RR zt5_WjXmQvzDY(3@YpTw~ZriqPA6j)cbk~ycw$Oc?>4MC@&%uwLrCZmfSX{jLEN_=d zc1Kx2aB+H2#Vfd>WGk+`mbmk2it7RpUz(MPD=C@qnKegTRbpZ84R@KEE~)ls|5e^| zTxss~)EV~e2t}{F`gBW8wukkrf(PbEiEZMz)bL_A@biyghSMXh(Z0Lg<0+-L0he8~ zV;!|(4Q*j$O~fqQmeXD1Omylj8?sqOo1gsh%c)bVe*J65ZxN?{y82^G3~kl#>iMIr z0$ta*y1eK(38y%@J~E%&m7gtt62B~X`R$$g)qj#puRn?($etNF@@0I{a_AYe!MS$k zFwMddamY4@uN<1;Mp@e)edc1C@kWN0L(o>QC{VNvP@T zd=_l{0jW09;jC@(;`G8ok5Xz?{4|yBOs&G{Y_*zk44`JzdHQKr*#z0G?fP2x>1$DB z27^(%PF?h&`C|$q%H0ll^??fQwUVzY)a-n?BqSshWR-mQLQq=JrpoSy`fQ1=-u(@Z zb*hOf2k-g$bykE*Fu9!1exC)ust(ve4QjQKM)mS~Pi1PGITn&@uvovATQjklz_{D3w z-ZHl<$Y30ZhfbXK{C;Kwxfu7tVt5L$nkH71Ir?ht{5Xh_lan(vEG)6g>c#_dSrXm@ zH{OFH%hQ7%8oIQ!LnD%M_PYRb-r}mW&z19ZNMW^owZmlWj9a|thYp(*6;QhJ^5%#0 zCp!3-b0|+5*yM1BcGfo7Z?yw~q&n_6ge2gbrmg%e#?!{BS<3d^+rJ_c|K$!RDggK- z6}y%Lk78vn*MI)3y=Lv&B#E#RyPx5!`zvdUg>_bvf%ygMB%gbb-Rdp3ckkZX1CAG# zmloMyvWw0}e*8g>v2ffO@$O9G)U48)@eVgS@SMj|WfO1x=1oFV05YVQsO>19U8wgV z=ca-_T_Fz0FO0sa<#FtW_{8e3O`2GmAJGL-I@4d0iE{O+vJFT{baMk zqP$E>qy{8NCgwG<>Tr}{hNdF3Ql>S+WU*hj_CT%Ti8Kn+1IOaequ3gb(U$UwnL>jO{}I z0|yZNnC6B;1Mky~J&ntQpA)qDocwC{jfEpM2z41i-$mKuo`9PKnAVABKx7ZZX+~GQ ze}BUHj)x<Y*zqK;OC_hnRXU9zOve%asqj1Nbs8m<8hc1bl=8E8=APL?=7!M zZ_am>i}Ja{p6Kae_e7_H`R$`dCHTVberhz0$-|^WuxbO(kxQRM=`s_-P+h=D6{|JW&W<$7v9+6qEF5eaq?hG z3>;pH)BCXnYbQ!10;Z+ps}uCi#L+hrM}KLsdtxZKyvOMdiiflyQH0j&-PZJiQ1cg* zr=Qeinja$5d-LW^?E!`MqWR(SO+K@4`u#5VFl;o&PvSyAT`+NGu}}mXb5GBvv4!<& znjW5!8#evN6P3<{+6WylSkm*8_9iY46fart_8fiH?-zBoyCO8%AX_-vd+rj5(nO%1 zz9ID^c)wmP>`XG=7=2fw_budifjOa*bd%+<8_Ox;MYYX_M+SV=KXkuO)yN(&iN3qA z0pM8OqlW0vWbrGq9a+zS2#2-0CY850?n=~hubLkzj{f-ZV*#Y$V0_*T^TW(CY71ke5g zU(JP}wi|6J>j<-+d>1TG=-i86kOh8vrkbSX{zWj_lkPn5rE9Q09h<&*SZ4rUy+Tn0 zooKGn@e+GXp32Qf>AdEB@AmE6;$mW_!E!b*c#{x<+UD$$tM9dQDK{(f$_lw!{L}zI zODdT;-K4HYdh)unyCcYL$*6 zsXJ~SD-_whd9!~{x|M@N8s*WtH4g2?BIrPVSj~$AWz^wB|M=;}5g#Qv*Wu)<-d(B1 zOYYLPO(78KkPkhLOcj0+V)Wbxk@V^~m$zf`2HCdG^3fM}N!z^N8z6rMPU0$9Z;W_% z$spzyy_yoW9O~6WE=il`K21(KIsdLjNYamxq(le=1Z$AwMlP<-KwV=d*5e%H=miWZ z>o1*6xsD)74Z-^Roi*4PEqsX`TiRh`RPdNS5@jM-9wbyQ!IDQ#$c(!CIX1>=LXG?r zLsSb3Pp&!!&y4CqBy63gNSI=A)BR2x`Ynh?+YX<*pKi&rVAA*19`G7?5}^2@A=7#y zzjZMM=m0<6Pk^mOm_-%#TuTm;n9#Jp@#SNsrUPB!Rq`$X<`abKocQ#F9!0PoQ=Ia@ zl#8TULMl})NZ>cXnQE+B?xW{E)nDs2@H|^wQc^qe(@a&gQnY%wbQd7{xkkeDReC1X z+W--flFUm}n}BnX<|@oRS>>~{IUQ`?J}1fw0ca<8U>{(Z|7F<}xOq%K!6{@rjXgnd z>I!T!9N0Z9*}Ky1w2x~yW?eBDE?!>h_tUA*b53F{+%TeMX=D6f!PYl-)3WZ4?AWiE ztV!x&6lV5m13F3emAB~;8fl5(OiD_WjlHI7lTC_?D9@a|p}=NoV{AIxY9 z>h#2d)5U?8){-rP1qTxDzh-P+n|QW9+s*`npUuf}QylemSvVZcgxYC}OLUmUe@4&= zdmW_!F=!JGyw#1iCmf`iulw(x+^}63Jg8-wIg{T1@XK7=%}r?_(Ek_Xm&NAi-Z+-A z0K^HZTvz2qvh3Sm^D4M!fZB8fWKUtW)n3KscLk}f@IXb5$puvXia8#NrfGVO2IvJr zLCX%4y}ec~o)eW^8#kVf%V@ET_6nLBsOy>Rt3g(;23GGwcy96MOM9T4q8t$JKjIu3 z5@IiJ_t*97*Zl$lbiv^)KyM3~RF1>*<=@b4o8-=7rG;N~Z*XV-fy1-=eQYQ#PIh$u z6}2sat4*TZWYrgWd3ev&MC({;&mU$AQCkiV!_(T}J zYZWKlU{pKVZlB&+zB8BX?M0EPmzI_$YRyK-v|QV}OUAYW&ZHB0X6PNck=UZ=%Fh zj9MiSY66S5zrH2wF>Pa;(|)^uOVL~YrBPo$fB$YxpE)hSPc|c2bNmv`*RWC;PWijXro%MiI=0TOR-tO(AT?S` zkb0MYqYOl91kw82of@ISXyAilb3@!9}%03!0xkh#vHp( z!KiDm#|n;LX(^D!Zr|$0T1FEg$6%~TE5#M}Sy%xFA{yYHvY3ZfLR(6L+O6xWtzU5M zYE_g%_#bz-osF{(^qvTBH3u)i@3U}q#S1*0!W>Aw6N@sPPZNm}1zt+jOith--EO8} zbTTk0b*jr*cEX`lw#;}1~5d1}3TTE~+UXQXItC%mv=J1_Wd?dBVgzxlFO8)SN09dP^ z%i<&Q0ULKocRtTIzE!CU^(uGHb*zJ3K4{ z&5{j1{JELiM2sU)D1@Y__JE-vBKi=L$NS=O_W)z1JMv#AKsHs_|IC3 z`YJBXb|f3+OBXK=*#U|Qqs=8(61XdbCy*dgGZ5yL+rGXMii*at?p-=B&H=3CaH#38 zR2_GrcLBEm|AKl67L{RAwFfF*j(ClDpjrvi(K6XB4`qBYl^7%OuD@VuLb08fWpKGJ z#i%~*qAEaTkaY`}w*JP9=5so7Fjr(`W%aZ# zuGrmV1Y+MNl;0)RTD7{_Hk@gUK<1t)a!s(;n!NGGF&PD@h(l>v6q2UGl!we3}U1pmZ;yu+R* zGqE0(Z$fzmFnkLmc-3>CKDgnOxh{PKG@0KMoTHK z8eo-GIGfD4gYhd>pom#Un_XqJl2VyJUlRDBi_|D$o|#duKO0NISHn1EbruO&up#l7zd zn*BvYAb4dRo+2){uU;2pdjyA&lwvm&GPQT@-d*+ip%N!6P~y827^px#qHWGYfSK0+ z*JWsqvJ%fGB}(-Erl~Nct&?hO1UNj-IE>NIYl;16U3Bw!h+R+r#*G`hI+N{z3-z#~Q$dt($TP%__hMg_65WTi7!lzl zZ>fWeoGwGCs_4P6!AWWFapLI51(^x`e?e5NvgvophdT0kM2_1iqo_>OHg}E8ECz;} zzq~X*F|xcgQp+>>pmlj^Mlavx3KVR0fll5d?_zl3en+(?c6m99h^6*a6m^vc_mo`c z1dDi~xZV3Sgj<>(E)9#$ZzJ=h`o~Ml%SSM&hiWQ{py}EFXY32?Mar>`En1vZNSu2l7Gb7bggF%)E9Y8n^R5qpwLBTsfd2GrW8VPvA!;CA6rl(Wr$izN z##KSN#-Z~)Y7U$WHTS^>6~R0;M>>hY8}A?Q0y^&=ZHFpw#<_oMZ*`arv^Dq%@<5ft z1&Dh^v{EtU=C;OSA0MC@DAeVWWw2|TJc!-CwOO`&cVmK#q~yb~u`#q@NGIWSQ*mJ< z$K6#Rw-^oxj4$l?Znvit&WfC69H(hX7`gUSFg+M%>h2B&;y4PY!}8)x5BO$8a|@}Z zSpDt6alDgR5iWz8JQj2=ObsS~ z#_~F3iR5)D1&Zoj5G+#QlrPBv|JNN7VVz9C_#vI-_h6l{rfTTbVsreaOH43v#?Ue7 z4*XP$hAI5~{Io4gf+6W78pvDtg2(sP_xPne~h{raf zOFXUU3UxTiKR)YHO)SwF7|o20dmc=*p4!9-f2vrQV|e7G3nj9jYgXT5dXQOqZx_OY zDNMJa?A-l2Mr#+3AA8z~!Z$HA>8BCLNJvNkOzhAAj3XMeomeocjP7?9{7~;B-!v%i z_H*UfG^b3B-^B&f;8$2b5BrGL=lc5r>f{Arq6oqZa^|^lL z!TISSL~$yqyRjs##If#DrT^8;BNg97iMB){OCT6lD(3K`wE_&#xVGHYZ$}~fMK_`D z_}%RyNY`WJH`w~syAabDt;I~E&wYvVI&5ogRDq7Em3ZU8TYZtN?+ zms{FYu{1qpkH;bpSG!L15F|ChP}T)mU6W>h!hur&o8jz*n^%>g*GA25oC~7r`EE^ZH`t z7bk1L=9^Iw-s?1OX~a-h?mFtJ`+><2ln@s`6Uk9m3I8)4(MFJhhWI(`Mz=g)egswf zlAfNM2%*=1@2FS>L;Ix%Mk$`dqd2KLy692b zI0T%4&WaAiv6ce2?&M40bBTJ%0vceccE>J*`4Ou2;LsF3k3hvZsfs3R>DErS#fBw? z_DzCn2k%dpQW07De-uPcF_HON<%csM!HjpQQJ3ig+&JWP1nX_xVVN2J*I12o-d>@#fRpE9B4<(**SF(Y!47L^*gHx5>=SFz2 zzme0awveMY>A{g8784m+OcPN<$0@XaIo^>3R2Hm$^qEG3P-sjB1apVH7hB_2gb!NQ zPBrnfe5aq+^o7{@-rXi_7y=Vy;3r;uf z%d%@lId{N5JxujQgNbwM1;Z52Uzd|~Q>$=WFy>`!Y%C6>#*ctH3t`*Ls5JN7j;#fi z+&S(^Nk}kWy@IxtfaqBu92qAEe5`=bW>jqeZ(v%)SJd!tS!4DX>UDvly9xaW%yhmM zi?7YHZ4Qf+bJej_?odbd#(3Pb5!J=Jk{%nRP_qZNtqJaUduOxW3)A1gsi^IHiTG>A z4J@f`DpdXD2q#lhK!aiIKGmR37>7bsSb!-*EVpvsJR=$SOBUo5xZuv|e*4{RRS5ql z0CaNLQm(YuJAa#!HGG7Ireecw5s&X#NnvtYhz*?!>&yi)q2l?S&4QrkIIc~bdeDdu zEV-YkX3_=-#oT;C-3Fvy&U4nDP>e#^3KOOk^&nT5aUDe$-=s|BSnJcC0f?j2(r{U$ z%^kbwx#m1_0E9DxLU-pV_x^-_u3o)==1>Yy`26QaC(jusRL7t%2D`F!&Tob;CnyGU z{mINP%m0BPr(TaZ!fp)1q5s_jQ%(r+k<={AH4H_t1uEr>F!{i7LdF~fV-2YkPIu$% zfw8GShze%iT`YGN;8|R%>&xo&^PZmas2>VE_8=~d#fV^Mw|Myo#NDHrP_#!i2TNs> zbGZ%|@hKo|-#2$f7F{xh1LS1VB2@=Pf5-&Vycg%-oVzTVM8?8pK|3adC<38~At9l- zCPba3IBydqY@`n`?x1$#bgV)eTN!_I$Upi4LYyQKlL~D0-|7T6KIr$G`BcRb3w^Nn zIPQXQ^~%-Md~Y^Q@(~ZjmXl)~b?w_7Xv?O6inzO8e}gci+=?ULTxBUa0Cv8MkFOHO z7xW@Iye|D)p%7u-!2!1(v)ajUCOHz&1MNf@T>!FLbg^{tXNh5S#!HKv0>KFuO{9|z zP)oRNt@cVo&0{Gs>(o@=G(oAMs;$iwENE68@vfEcFB~!c&BETkI_X>pDu7pZ z1Slc@;7S(r0F$0vjm2OhA839NbXm6B?-`cV;(3+ci*g;;qM&IZ7p209XJI5?nf}ZV z535cmHYlwHU8~q9k9eTGOW`x~A&w{73K5ZJEJg1eA|FBxUT*I0donHWp|P5zMI)nl z?^-yFI-@!3jR80b?ieR}@ zbRaT{i?$u&lMMXcvQ>CCrG%=a?k5GAEQU=Acf#}&{>A-J<&Uo-6}^Q=IYR5WJG0I> z3934$QL`9Nt=Y@U>%xxRnKxm~!pOC`>l*jQx<03sS%bZZzoG*fVpk~=n!s&!14(mo z)$()W3#iE6%Y)i1G-ELlsAL5}hi4}*Z^bUVf(PK`b>c|D?I0><02Iv8(1_!Ch0Z{H z>eLR@-l;ysjYlkiC8T!9PTsez>liS+Rw8y55m9?t0yF0~$O=4qRHvq{e$n3k1?WTr zzsh9Djf#=VBIh1#m>AlNI`jYCjwsoB4J1FIxjd-}o_bW7?t>39dk}k(!ZtS1-3{37 zEbqJ9ymXP?he_GWwl)++g1
9bJgQ-Ljsc4!hN#4Mp>G*UQYj3!kCc~qfu4eYEW z7|#=0QW*wFIJ9B5Q>&i zuJ{0>abSXa_GNsoojyxFK8X^EUP0zw^cp;?5{)Ous5~dqc;-UEJZgM}X^St9n`zm=tqK9tZ>ZK_lMt6#PA9o8Zl#&A1dKebCLoc(r}sLgR03PS0u z9L)qkmkye(J||!TKoiRnw;7bv<$22{fSxP(_f+?ESB3{~7Szy&wdrJE%)gg#A=(OF zULXdJly|}4&s+44S@jNVh_NBTooe)pU=QH>9pK%AWc|!U%Ich||Ic|5Je*a%#TT~+ zA-QNBx$FW=g5w9tb17+;o(e*Dgfu@AP z+e79+J^wbax_*gdQIlC>4 z0T-gJO451$p{39RMP^4j&R=LQ*a8#Pb=OM1g8XRB8qYs&W}#l+vL-y|Bp%*4=u9sN zGgomwkqM>gD9pw%Os=Ih4|YthgcaI9nsr&SCZ zi@`J2RyX*lFkuGjXn2P*z7XqXqUWF%SCddh+IblpIx3-*M2y$$gjq`Ajbyid%-j9< zFDuR0v(jL!uAeLBQ49D@G^Gg^hhm-!eTu4xsbs?|Wa_5ELw7pdV6Mr#%(3l|kU`dA zUv55>17%Vd3Sq>?v;q@SxaJVh9?ufjKa&G4!5KvSDr- zWwlifyr{Mxk;@V9nS5;J5bf6@D_35gSQWWk)>3%u4R-Fz zy!SX})oG63PK^l%TQv+n6)?JI5!uX`ju^h2pI>!yT0dVs?5RSQpw!NN-!^hcsXtkF zM_{Mf8L5_$ziD-$9OkB`7FGP5Yc?L_l9=%7W)~V;SAKKbt(P*BqjPk&a~?LXY$CgN zD;m=5|C~_jXc|74QKKOX?EqEF&o|ns7C}hpiLX$uHo0{ssBCJeWI9x?Zm26f2Z#F2 zDQLE7?zJ&BXdllx%G0NiN?5%6dn=E)`H8+QG10w)gB5#xdFjwsO>sJT3Hq|Zol~FC zvArCT$L`&*{pmL}pbhK^md}@zlr)FN^D~LduVS1Q^?|-rCvl;wh>5+On_(-r6AOC! zeV^84zLo-UE2lc%LVm8%TZy^%+1`_Ky)ie@TuAJrS9Wh`LozOdU*$(jIMLJEsZj?} z$oniJhzz8qd$^qplM2#NoXygf{%`8SXQiOm*n4(q5<2_6>i4Konhwf+_vt%#?i`0G z+g+`)NhosFq!#LKLV>H;rYYwo9Ec?#D@nEN1LVah%3eoOioKIC3sYhU!(+T(_dGcs zPzA{`66Z|@uL&ZK@g{3fT#>0f#CK{#cjZI?$JeV6e1sxT9cn^({p3zvG;&vXF_?Ua z&LzTk=2OgXH^)C5N;QWUb`HZP91)P9*%?`zq#LYpVCXq{o_y&L8ua_jPn^!-*g-{j zWg_EJjbD#)z}JhxM&ghGeB#M8%_heMBAxa#kRkO74GRSfG+vMD+BxHzgBo(ZTd_vn z-?UJTHN;;youESYQStZIL*nM|?|(X=9NF93`<`Ph?|ofkw`U-Lflto&JRGqAijH6b z+}@xy22-lgtdQ@Jt$wm|*DgnBAO%&$uU4T)7-0b@5dz4`mQS%;>s}TiYb(^YoMm7!lesXnqOaq}kR% z^%usd+Js92jP5}0_|+5L>@w11QLbZ8kVgF0-AFH!JFrR>E}o+YQf~)wAGkEy_6n8W zT^g@sBdHo>UOqbwD$U5s3eq@m#f{EM&j?2C>NzE>(Wn)TUW$vfkY79Z7MfHNW~F{e zqpjp<0@-Wv9<-VacGqQddRbTTW(V7SQ}jRr$U*bJz3b-5Zn8|;r#<_IU~U^P-*71o zmjA=%>x(^*hTzw!KOJ~h7-^oWt_1sb3MWLHvmg10PKaMpQJh|vt7CqXU0#?#pnlZn z{tz)MZ>Fu!8-2Y&Rq*rr;%#scxr(jGVqN`CiXS!-T;hfjw~dC| z+TGVoQRXBmIeTSWbv8v#ZsKErx1>nH=vXnrcs&J+!5#Ay1d)qPd4 zsi}Lv;6iF`m_Kb$usbhsrT{?X2w49KSSkc8jU@=vMF7v6^aV3|w4h#~`BZFb_e{Y| z1eji%7rO@J5ifL)dW>8zYxHC)o~+{1ws^m&GBp-B5-OI<&bHlDjU#QHs*qrHzIel} zYH4ZN_i)MFh#o6cq@O)rKkrqZ;*GOvn| zT{9_un_LfnP0P5MuPqY(4jFCtw;v#2FTT1@&c9ezW_wdc!S?@#(7QsIf2y}DUQ9dx z=Juxp4|}xXkAFBZkp3obzoNPXyb50*0&lX7@y4$Mfm_CEM211J@S(<|0)4ry#p2ZC zo2HOQ6$d@uC(G@t-@C@{t1Z~)WhRK0t9LS^(rm$>d)&Z(pi!>G&U^V7J&Olrjaf!y4}@Pp{FC3)J8^K}U1^&)A=SpM99{*X#?eu|@~|r77~RISMZ+Mh+l!s(2^e&+pZ) zn6gOw*Xwd2YM!(tdB!~PryN9oq5w8r*)pQNFm0$i0voL!Foe0S%r|Wtt2I$y)oE3U zFK}&t4!-z(AhFiC>9<>_G~RKN3SYy{zKW^P2e;jnQNGBvTmA^@qsE_paxxAckH#lx zoZKfoJUsfg(DZAy;=YBWE%hpZ|2rjRz}+Gz?y{?Z<6u9WMJ9@K@in-QaH#%vLkkkl zbt=hy05-)v8m{Ca#4JUqaJkRHN7I)%!WJD5X>|%VbOlXDK~z^nvmkw2NOQ)n zYiEU&To3N1eYm=ck4ENsXnrp5*ubN3<4w(z-V*~eMf^eLow58fK3VL-vmCTMrz+W= z9jxo#7vV1tgerQuqmJ081Ek5qs3Tij!?0^0CrKB!jF)u_c~^C(#?BO&q;qbB*AxI} zz0qp~>ZO=}Ew~i4NEvZXcVG4RI$zN0Kx&l_8Tp*eCRHmnLv|+H{^w>;mQ66~{#Zsj z>-2Gv5}!+q>~53s$+VesAL$w4Ys=;xZ3HyZ{swP3Sp@KnvrLg_l}(XaOZ$~uX<<}; z?Cs`f5~Qp~XrZLFde5U*T}2{SkrXa^L~kw5WGNilO?wV5qhw?!MkfbN2>5xN(<8GLk$jER2tiTE~>hj!@Hbie2+0ka(=VUDP}j<32}LTc?-}c&DPq= z>OIV`L<9ce7rm&~EdrkFP$UOwYVfAUJG+5PY#B!K$bdbmrIN<|usS5g(skx--*9Cr z2g$wij$l+s^wMM;Y}n;}yDxtfgw#Z*HKft@Jh>7u(`rtDr%gaR^|tNY&X@1z&x3wi zC*6Bv>-J{N4&>W*DUg(lMWJEzX&p&!@Wuw=_pOV~t$|e}l44W$p?=rSusJEJj@?-8 zWYkO&LsC$0DvG5q?e)B6vQFPMh9kzrVHID0UHp;ujieWET!7mrpL_Z1-eZ3I!O~Qs z;EhOL_ufZ+gM&bsNRvtmR}Xq$r27|ful;JQ5u-A+gKnNZIQ#X==o(V*Z!oHY9ODLf zZ{6NsX=xU{6N}`If2Qa*lT%cP-8T7B<1233%td8iJ_+)Oj~6@3(6We~Iud4X-n5>B zbjlHc{+V%CIPX0$=7*m*t1Oh-G-gg(XN}hf>DH$H-Sd{y;C%AU85vn-)55e{Ykqh3 z&6(~VpH2I9)`IT^GSG}FjbNZTPV1Eet_@|@AsAc)tvu5rkuJY#uvuh}gs+{Q@y=q` zk5;gilodz&|Bw=lf54i=(h>!Yg1N}Vzv#Y z^;xIxo||{>`Fn20d-!kn{S`EB{y}SMi`uvyb%A++r2Nj%>Ej>IHj~_&Zf!TV0$5TBk%fZ$O=Np?CoxS8@VLsS(YYvn~fMyvr z0BLmqr6N4U%v>poTDnh;R&#KmOEBcaQ#km(uIHrK+Y&Z0}9amqPn2Y0EXd%r|CB9KMTVTqG5)US|wr;b4IZVtU z=qtBgqKZo}vsHbSpG(BNnQpw_S-g*JNWXW>065g@U_%FL-w#llHZ38=K>$na7;`de zU%L5ePc{Fw82-VK15}tfI}MpJE$Zb&m7FC^C-EqHUIRyFJoVKqpzE)_{`=7~BYB6I zZq%@ozREuBKTrlk_{p+j%ngVR^zK1_ZY7E{aC9udNB%g!mlOCBk~>R=5wWd9)@C~= zWiY3eEGx}acn19U>s5SeQne+#IH!e99hEI+6!2&<{n{2G8yVdk6&6oKXCu`D@yQsE z=?3f6!;sp-;1n1}wP28lNfamdkza;}h7iPhd4#CKC&u}osl*h6eYsc7ksTR^dgwUA zi1UGJo(;m_3Hx)L;#mqOEH?H#opC|lm+ykIZ&Yn)=ilVu(#-upRjLN-g*UHC?0I}w z_+TVZ9shafywZu|=)67aU3(R@=!Z{;KSrwK9|nR|j(SHF&KOo^MuvH`*EH4I+8Ufa zDbMnJp6z?De5W5ja|%{JnpyaTDF}1yXhWM^$KGuZ)*$V_@b<5tWCxPdL6xKzixj%2 zEVEuLN+m!nMrFiZnmJ2WItbV*nYXsFsepIFR4qwcI$E#89yP4#8yKGZi~@pJyZ^<( z=We2vm*Th_j1p9v=0DeMb|~Rk`>=|%-{Ql=1NGLag?NE0I`9YA=(_+P3gR&;tzSbr zKaqo<4V>Hx2Kt`ha9gD8+e!@WU#$k;NSd`TKIx!FpNAh5Uf$0~+Un#&w`L5UK}RqT zHgaL2?8r;9{8lf9oALAC~oDL}G3*CIsKIFXi&B*sK<;>xc* zAr2WXulH;_TIOqB>eB&G2d{f52j7R;RB~C|KqBmEy@MCk*5m`cc8OlTqP# zu9ML_Fme8?u%Qu$dvYY@t4b%u6`2wMw!aPA%{ZKQeV+y3&b)Y%zM6XMAz(J%HG1}~ z;5f8P;IZ+t=(U^aX4h8K#CBRwQr^1gL03}$q(k{3@xwZ&cp;?|4j1U#fl!b>7vda@ z6ib{_((nm54H@x53PgX&D zpY(Whdt>>Bz(W#Fz14sWsVjY-o`p(YIs>kN=I-o8SJFsJar$x87Gl}5y$W4|E{W{B zcf_J90+8`_jbNnH8O8Aj0RUf8{PAUY0}?Dk9RRyL7ESf1jvobAOCtk%1oJhyL)8~#`ZvsO`0Wrwf%g52^Ka6CZd-hP zah^xk!Tk0n{-vsUn9l1NFBf6KK(4AF=i~-NT>UBi@km5dF$cis4TBs#ML8*xnksZp zIp!Y-dwJIH@9*KEI9VO@+wlM%VcA>#XvDASjqfHFtRfCV;Nn-5hgyWE<&IY8IwK@> z*v7ZW^G$(+q(byEHF{}39p2zW6+Wo*o^*6{gu4DjRS)_PRn_u*Z)5ngRFI0KLDvnT zXA+udr#?x5n%&YslWb~t%??@~4wY4SSEfe`zs5BD8Fm907>S1(H-em2E3 zi`~)1Zle66rpkSG>u8FfzI+LSa!lN_XZv6|cT1<%1v5v-3Av7Wpp&t&t?Xp@ODL1s zt4J>jy(2oC$adR?Nm&m*Zk+o+bbSdpmFwF7i=rrYqg2>sAsSSYd1#Op8A54LRHT_i zREDKaX%Mw24W>duQJPR#)o!3d8l)6O8ImcH`Tx7$W$$yo?>qnfUDy7u>um3OpZ9+5 z;djq@H^LpyyO7E;`7sWFw;eX3;oi?eil8kzKK|6w_(i>i-Bv{p$7W z2>c>ktHw1=6-_rf0{Rf9bpg91=8a+Ea{Ucse58Bf1k^u#$sMa)mIsAVZ1_RX*Zupx zcx}cn^X=QWJID=tTV5VjSXfw6AEwL8KKP9z%juj~_eUI@UmK@G%2_k=<#3g8Z-kwxC*hM3GMQayXN`en%^lMd*FzF~`7JGgyCc*!*-M2R$^#ea;yGyD_7=7aMOQWdeBuJ0{05WYu3r^=Kh69&JYm1UN4!a9uR9KPdAOmsdM@J4MBSXP z=Qyz#kl{7tS`|)Jp`w~KEB`PacpU@BJ_L#O%Hb%ouRCJbGSH&DqHDDXk5jj}HId^4 zL2R2SruRBei9e0&=?v#;uK-TcFdWJL)3;gVyYDlW;O$s-zWNn+2k=VUG%-EuFNFJc|A> z?o-=e$-gm`YC2i%yfM7JH)iI8r=S7$hKUSMsoT$SP?fXI6uTT3z5Bfy%=O*-P_1#1 zzwj951Wf&2ny%4%m3h5?sS;?>Nz_%E>p#-4}ZqUAJuZ|Ow7KDIgOxqb5 zy)k)LlfEK?(N+ANyHPpoj@OW4pJBCv%N%WG-7K#m_NVAz%xxzh319sF_BLPsS#Hd9 zPV;tGeKBT0L6u@ox~t_!se{x78iv_WAH1 z1B-a zx`$MeP@f^3;tIKcad?E%Y{bci$?JKgHlYc)v#>~U?zR^y0;f zmAAIMxofm_^JXsT93zVCojZTNVh`A1RoCjEzDt_<{n6F^Wo_dxPZ86*re&tQGRmdD zWKx?9VppU_!^o%5!jCfgmu}s<^`W%Hy>pL+#WA~<*LRl@IO~N3ft4zI8!!ukZ+%+& zf=|eJtpd6!MliRo@Wz*l?#}b>xo2I=>3Pqmp;WFGD&++bOgr_7vV~TiuuWbxhm&ymRNy z-QIiEuDVRyTUmY=Cdz*Ek1>2x2ZI8?U1zmDtIjT zr~W~^!PLG3Y1iC$?69IpoO`fL>Dg+Ha6j)?TX{b4rax@h$p0QbY^uC1IZMxwE7siG zRtv+4e*`Mir%!LvtIPd*s|~X&_EEQB$q~+W?hMP;A9Q@gygqy{=G<}bIys-91?o7a z#P(FHlDC3?6f3_w_3zDXOVmir$;t6Df0J{r`U+P; zloDZQl}~L*1213h<>gha(f388^^r!vOW(Dh!nsx_(YrM9#tqGI6-)JK1fKy!OQ5H36zZ`gsT<9I#J!}l5`er`aagU1&n?xg>G_3R zt10ESo6+=T2@9uU9TW9tE|Y7)G)Ei}Cj8ZrZ*3jf%bpvrd_0w>idV3-zd>pg+*XOy3ZkM2?w(<`m0!nT@zgyViF5y+HUx<%aa_aday9?lcLeaB*v-7XdiV@QnXch;>ypF1V z&oNWhz3E}$dh7P>jp$F7)7-d(g%>E4gQmJe^ItHns|Hj3W<<|#t>V~)--9NstpT;H zw_0TUncv8LJa$L&mG<^_^f%7DdiAO4al+ z^?uG)U@~t2!L~!89G`^m3%ja)9T(0*;@6$#m_9!ETsUk^1K8T4uQD*gmEv*Y?iG0=}{YIEA(rwZxbwv|dN;iddUnkmvM zIr|NF#*)%?Gk6MB_L!EO8(W>g(KscYoG}osd4}PZxf#RuiIBMVMc3W7Erv_<^6{ zQKu51+imhda;NtvT<%{g4VT<)zY2oe2xK!yOUo7h)aGq%bCB(V<8lsEFi48>G*>{t zrbKNSB-=f_XAgPYJU#e|aS_Jmtr}c$`f5a$r)!scEP!raEBxv$1t?NF1z4?NX=#~g zm$G9GzlhVh7Pw^mMEybLoxAy)xjm(B^QfC_7plU(Vg8vqVmtUps|qtXH(Kfcm{YZ9 zPr9|V@Q=1L>==GxtG!Juh<2t;(dYU3?x=)@*>t~zGTMlbR+nSjb` zyM||~tSP;n4s3HxSxnF7`+JH#%+B9=aJ71BPL3fYZV7rtC?#@8T=oq8KyhAAy+d9> zlF_eZ1GIF5uhNwAzjAY<5^_AG1Whn_z4P4oO{yzTx~$?q&d`11O&wa8aQGrbPILCA z;IV*ewDXsc$c|KaO7e?mcH0zh@tyV#kJmiFSpj@}Dm*vDHf`Ad?h@DwdTf z5T>XHq6Rijodph_nCs>Sdx-Zpe&wigvXZ@q2qbn&XcQ~@PtO0s*Jy8Kn@!$@GyB-ARpK= zUZ{ZX#V04L)kOQOrP<41HL39DmaV&Sn^9+_6>w=y- z-Nwu+b0OuaP?$c2dJZh0KF?PF7u#~GgBMd9hk z{47F+Q0Gq+s0vf`Z*pQ>mh<=F%e{h;7*SOv?HxmQt0S<#;|8j4abcGR9xg^U2=NaC zr~a-|oE_aei}-HzDDd%RZ3$JN-3@qj8^uWwt38b=eiRphQV696DG2F0(r}=fkE*UV z*A7&Z|2*%ONzR^uD3q=1REMiiXL(8v%WWxQ-h}t`N!>%674g_wL=_P?+$XnC#Mx8#lbH z-sGHd*~mwfk7=6&NgHFPx-zO-iO7u{SRr6S>-8}ID?)PjE=G*c=;zs@YIL4Vfw4Zu zabuxPoc6flAoVg0bVmoGsHA}WU>Y2U30a;(>F5eVYETR1vjqbRvBI)dmHQSBQ0;W6 zB>Vh&PN`~VFDFeBc-%_*`u3nr5 zeL?+_)`y&Dh}!ngnD!0DqD54<_B={g^B=Haa{TxE(%jR=UGc^RX!i_7Zaa_Gh68IG!?6Tdjmzue@e0fxc`U4^TZHj5QhFf5}TUNb#aP(F|dU(`Hmz7|; zTo)6G#i5HcIQc;b_0_jyaPecC_y2WJ_qDEO8To;nu-4dz1BWCP$l3rm(7?l*(G`m;3eT*(SOChoCeWOXJ54U;oa(5Gp4X-Pg6whOVD z*DH;{&Sw*WFdzSHWy6-5fWkeYq#U|}ZewhJnPL9B0p)N|N*3;-7U3u;hl`{fik-^$ ze!r@Vao;E&+##va@Pi|p_`OY+S-s9g;@w;n)h%WHbv{DxNAwI%1CB z#N9I*ZgF0Pm%~+yGtQXFv_%LBjLi}5z+pXY~610Y5DlMB_gBWDxG(#vEGVh#C&WgSoS{|@Vi8ui@AKUVUq zmdj)V8y5dWr41*49a$}8Rr09^{`ssY$oJyFmo2E!1`*@4G>RU#)TaiF^BxAT&F46H ztiJda_p$2ARZzh+a+Mpd;tB&Ggu(TN)&Z^I1dG9&b5)QaGY)H+7-u#N84jDIRpHN3 zKgW-kykq~Ca@nxa$RTVjN#G{#!i(Y1qwnB6lF!De4tLe=T|3RW!JjroUev}K0+o|w zn7_Sl{449wCmToK@Tx1hhx#l^VTuoHwxFTDCO)iB-QTM5v!cH{un0}p7B%)Ce{xk+ zJNMwe_HKACQahnWxzmatO&EuiJQ@&Y#VKK!+k zn4U?6t`Xwh`^eu|Ag#+G9gqCB(BFt-o45+~zF#SaA_mQ9;S%RNJ(~KsM1&dR>BQg3 zRhW*eDl+)F}U~Voy;f9Bl$;SycP$T=_^UF`T*z>DE@a3rE zAfFOJ;w8~~TEmCOY$2JvRyM}L@g$kc&0Dul1*&?+k2+V~2nDzd+F(k&W?pU>J6L@icJhiE?pw>sKs2I5k!!W2bv@KJ&Hva1`cxx= zlqb}nZCNP1pIr4MOgpCZ(A4nfN5N%7a7o)SG9;5DL&${21|)=AkscX%<}6~K`l?YL z^JDgWJ4-I5Fb|w&W+H0CbBhyu9je7mv-I@fTaN}nK%8tEW^sZ&3fSD61jrTV;QxJf zMFDD`S_d5Q((tI5wA2qGQ;^)ZSv?mE2w#2Y4%Sz{3R~s#X^$I;2n0Lv`pbjUiAnwI z;Q1iNb~>-~d>+@#%&aadW#8m{HLe2kA0{QZHeScCvz&guOA_f&@A}u}9uJ4h&04>( zjywRK!gbWWIAVl<7MxpHo$_ep4J@HTYuB4dT;2|6Kr5dGvZG>uFC>*9tmD9=?vN z5JG788eS8KjI+rL1lV5Zx|Mj3?0rIbf)M-6b@RU!#X7MJ>Ugbb)-P8+ zd$M{fj`}W}Y}GrJtK4s@Wybk0;c#t5e2zv{mz0&Ag+>utn%_3SwOJ@~-Bsoq=~}gj zjLoe4YK}2N@`7$nRLdy-;O?*>YsEhVZ|fFm1yl{dC_eu!T5KF0UVTo8WJg))OrmkQ)b%Vh8%?D1zg@XeSb)r)0~j=$6By;R)uJ0pojJE_=RIuofgw;0yM>BV+IN` zZmGECcF4fDe~q$wO8rm5$5)~k5Gh4x1C4a8{Da)I!{Bcxst8%!}fgv(hp6d~} zAr~C8m}35|5%{DL+K$uEIST!tf9Q?ZZoLM_cj@7N>iO_-m|6wMn13xH*r|LV*Z>U{ z!D1HIIfUF?Py)(oa-Lr4KzLI7qnBOX=4iN(h@mh6{BJ z#HF;-g*72Oy{Qgr3Ik+%=7+jm!0OK|NVWnbH@bk#U#el%C zq#JIeHQRFIGv?-rPt$l9mgpw( zSzYz1npoF^z|RZrr6<19HVy_#vT*@dDHL;nKXD}@3-8~*C&NYMa!^6*>rh0@#3_FN zTdKQK^UU|%J^w%oA3<@z%D*jcoHP)hJd8Qa|E$M~REp>V)jk1B<<#+xyVkOPCLk+y} ztB-eMZPQuQQ)^-(3&mySxw#RnoYt-(dtYm3Y%zOAeih*|a*kjE&a)L>6!_wepNlv_ zlvfEC2LF?l=h~1O=9Dwu7*oTKIzfhHSvw^nG2|r+p#z~J)~Y=^HSH;sXvU6@*$|Bm z+w8t+KTgvn9Vg8&W&Ik2?Hf*3|BYe?T-=aJ;XQxX0tnq*gO!vCNWsr|pT*pn+|C#7 z@LM`v`F2>A1=8ojgSecA=qzWm)okS>ziyu(XBRbUPccv?<{wBaxd-5KwtrU}_0YkF z?XdLR$iD-eReUEz88h3ja7tC=2=D+?L;_N8MD>)ATa73)>q^|(m{mh@;jFsU8{kz+ zJP9`boyA$!PW8*AAewqVH3{S4U99k-Dr^dd3(Nr7zw`Z6@+oa*V@3L5%i{&yQ0rD_ zl63sG=YyfD)ff*cgeq-8fn7;~1#H2GM$;`$5)gyU9{9L|)5}$navi}nq9_rIhUpy&WXJrT$t80O#Pq$6h-H~04|U&iQZET?lhe;(mW_-R>~97rVrLcFuPn92(^ z3w4z8a9yBTj~)M6I2E?X?H*Sw@_S~I3evMr!8yBOifDlHzn$BUZQ-#!90ap>)396u zJ+ty?T@Ymkudd=pDOBk) zO%HKTw|(`f97qlNh{gp%C+tGeo$#7&FNKZH?fI%v!?&1`k6a94N-07n2T(r$`Wo?T ztu`Us*(&)<$&w-GP9OX~ESZr2J<6!xit0fY3>8e-(ubn>)sMjOujisb|3kcC{sXV$ zbxEAfQ_kD1p*ekkFS7@NwSqvygFbE|qDdRJ6;E54!3mb% zy@ItVm+w*O>aK6k^U>e323Gv7N|sJO3pkv{TSzd)=^rEEcs-$z<11_9Xo?5HpJ$~b zt|Tq<%TbhUKSP46fTIe9YNGACNuAM8(Opw?Qg8MVrQ(BVZumbL8yhwFVx0|c#^Xm>qEmf?do&tAXv>Wt7z;Sl>I?PcE)Qz*?cUg%0 z9&R|&*7AGF;xo%qm$x9=V&~xSgeM|)aToi%`ik>&x37n*ia1B$VXG14BIPFSalss} z;#sp-9In}eK^dwgVaKJpE3wfBt|r+bJyX1xpRoUDZG2ekad*E1$YRw-y!H;4FYM2& z{ex?}uGuRN)eI}7Bg9t6FR*RLe!G~AjM;Oyz5642GM(CXUKWBBD3{o25Z0km)=?;5 zq|EJoEV730m2gGEJjnayB(;4oN@`Q5ZouunRHGMizUF-Tv=*^}`$z_2mW8#KRsCF% zc;1uv1sv|dN7}{8T(c4p=NZkXI{MU192{h&#!jmQ%yC9x-b-EKFC_YRx6gvbg$5lJ zJ=u5kWs%*Bf*128!^E<2;P2w&KXqqKzNWPK?2lyue4{I9 z$eW2#U1*@IFijc~An7+jXPo?GuKE(wmm>Ux1V^cIF~8Y*9M@4QOJKDJlWY3->F*&( z5T#~^xqn45AlEO^e%aB0ZK<{VZt@TcC?ifk++4D8-T% zgHK~KBxX+pvCR&uf?i9ln1CZq7lXS{NQuO7i`0y~p4QsY?6-Q(cXLy9SmQkgiHQ)a z5m!W1#O_`MrR$~~kv_puP91edVwlJwad2i*QZOR_;rT9?FJC@fc#__$_PX)o-Q=rR zzrtk=wHonUygi$-hJ`T>?j>JU+kl0YWs_y}vI48*;^<27s{bab6p4tGZ;x8p8 z9;|znv8T@X zZgpwN*)P5d?%HKdhlorU41#8G3$$XzR`JqJgA*FSPL;?bB{p5OAbyZs?&G6PGpo^a z;^cL-QZ7#6odVc_9~NcK_k0oHEbSrUvE0KV17Zunps?W3uyv^G7~sZVsiC3LNR&TE zJmjKXgyG_)5)DVBPjZG%#MNXaA8YVlBNlY>{`CBM6xbvu9|1RR*|KGddg~XK8*Tgc z;q+9hyb>d8@ph|9y~>Z^3Vz=Ku(O(jEAOjdM%>sbp)a_lC`&_@Ma~s>RE!a|zp-WK z5zG~o-P9m=X5RsQ4!6rBm+nbbf>$Pp${@JI3X=miakPY~Bc_1cX>u@a!3(!vUro`pjiE z;P7Vp`!$LlD)QEe6+Sx3w; zrl~u6rq`r12fdS{t1fckQ#APUty`y1 zpM-gj@}SZJ!6|_?Jzg&(EyYimuQkT^kKbOP5)v_{8#X9W9!B`N$-HtDWBT=XS0vrJ zL+a6;vEx;kLa)DeV&B{_KW^}EKRin1GcVu2FQ8SeLY}gX`QF(04b!c^A|HnX)=EI{KN)E78JDG$y}=DoBOm7vZ+nufQwTcy^dzMM>|=z|JVhs5=!Db zc#U9w<+wNlJnrxBKW$BR#6R*sc_MLRiBsv@w~H(-hhqnA7}TVUhgh?QiAts^KS7C1 zX~fZC%|ottsFBbKi1qBUss185mGu18)JZd)4!1n|V_I2uOjeM!Lzd|%pbRXTb-m0VV zVjQkyhR8T+gRx+13?xHs`3e-S4Hz?BXYBk4Q80WD<}?^$U*$W4YaY^+XU?~MJM{VB zT*mQ_^Zc~N#vKSeKArVs;sO$gP*xzG(oQP`nSARKBQM(7mP(XM_lOmbDu+xgt>NKk z)@T&BeJa|}vM2lx7)(U0{w1%!+h+A@3+@rcrR+~A1O1>F;s`}X!DA9Z?qbHrpsm%8 zD#2{^f6xx<4$2$axOmmFWn?m4V1Nc>D&84z1IuKM{|wJxn3T}y?L7OMp58)!!eZ%K zKBw2g)x|m?b|OBQnvCHvdVV|WwkV0cqR!z(=h{%n@^7B)#H6&;h0ny<)*}@6 z`puhJ&H`Sokgv@=U`}^E8sp%B?oybRA0jIJoa{9?#L!>{AS`N?vysO(oE!z!o40IP zkG~qAv`jLv2$Hl%D3b)mH}tZ^Tr&uBL@N8{<{8W?-Xw5zH#!`U_nnH~#vMYotV{Rp z{&5E-0OKh-PPT>T&bX5fiFn4cWr0$WsH-3wnji;Jn~2k=Db6M&b%_Kei>7F3_!txo zH&*U8h_1@wa03sz1M7JCwu|iw!vF36$0kuE8HMWuNU8S-8Vy5IQq*bYJU;f9$Q{vs zup*yRm+k>vSl8?=HoU3Vam2fmH*<51F!yEAzJ2;IZ=+@RU1yp5>wc7)QONRoV1FNx zOYD;94Z_3)s$>;Qp8Q->so-n^dLhCm*gsfG2SEg(M5&Q#>8UdAQ=&X4^!ZEOn8v42ye38}VnjJW!5NG8+xHfbMf^HdQR);YIdGf!B9ZO5DC|0w z9W!POsoLq6N#GgA-UxI%C)lF5xm%vbxNcQ&(3P z+LvVK=_@n-)z!5Z{5}Ep#i~+Y@R8m*2J=3-{4NKL;z4Ad9L>o*Vamv3IOYJQN?|1a zzmjO56TzJU2!1!{2n)gak_VmYanIF$VrK^TSc1y1;G4H?qu`{FDdJ7P8B zrf7wzG#MxRO)O8Ud!z=f6KE2h?(NY;=3qVgyarwx2?GnqM`>cwu7}YA7Xq_-lSvBn zT5pTVp6vbZF_^YCT~1D>y^#YCIUsa?AER$*ql=e$eRk0IpbxxHm17C%vLrrID>|N6 zmB03T8k3WggKK&D>5~;qkf~|zMppb4t5M*v4l_qkfuc|1&s<`ph#A$rh$-X^Ndy?u(n9~SNw$S`-@jKOdHp%IuP(Os`}bpo+>gfuj|A_DV78Ulr*ir0 zUo%p?Dj>_bSb2y#V4bfKc0#zM=GO4xP8jtL!FijaXId=oDA{nFbTsBI^Er=n6*q}k zg#q@|7MGpXxQy{?YU=EIks{OOXhk%u{HdJ6%ss&AdPUtlWEMFHES?a zWG2={FAAL~7tIpN>?6u6Nj=NU%Y#n(LzYMci~vTnO`%IVS}Haz;J;(hV|$4o$K)*|hxOmpKTSFpcOz`noSb9i$<6B`289T!BtF!IyKSPh?`ggTk!163v(m zKzB3flchS>wsGa)2$A!+8_H@dg(rGWYpd{XlAVyb3mPyg5<;W$br?yW=c{Kf))z4g zA`T@$(X63xi$-)tiICZK8iIGJB+)|li&kS{04~MNJaQR62KjG?Jv~pHx-s8Lp zPS)PNdpB*{#tF~2S-NzDkjjd*duBr#=A{f^Z*ATY0iVv>Rzq|y*q&peSuA2NW_n$> z4o>I>guRwv=`(+%@qDso1&SX(ek{ijeF~&aJsT1neZWvAL@b7wirZAA@fkm%7%6&# zXKfaounl3_IdkWFmT*;t+N#9q&C8efVGk{7tr*PrX^}{=ZX$Gv6WMRu06EEG*N4|hr&T|hbura ze7UJYTG#obWPjF{*HfPS^feUx67(M-ExG5ugaM9g+#Qr9=oFN}uf$~XKM-pBOc@Z= z>IuE1HZvK6W`=U{wBHh>mE{|Le1FwWbfdf|Bg((Sqr`sE?XwDYni?6 zAL@SmI1c9AD)6m5QYp>ld!1qF?j%<^!dZ2uNPnKfMl6ssz_g#&rKOtxfPkTTzRiDP zJzxzgmcjtb#qCeZzf|Vh#hhW&mI=2$qI_caSP_S<_-WADVj+1R47v z6`^cpL@UHTvA3mYxs%+Odf7aceW$v&-k0a@1J0T_89D5v3m1aWTq%T@1smM&wTRm#SLGLN60RFW^M@)oNQ+wl+qfQ0>DNhrpz6KeL)|@eW%Lz?$!aR#oPbG<&(6T1an<|MtgB*>Qu0 z$p8YlyHhbXAi(2Ld5fhdHR>0GR9(9a4Gk&9O=(OipdUg!gX~4EDGZpPR0O{%;bxo2 zGoEzZc#oXn=%{OdqCHGv*tkDfg`yUG4?K;E1{!0B2!f=u=rtukd5*k%z-F91drQz@ zLH`J-PG~x^O{nS@Lanbnbdwwh{GdrQc+yZ1D6yCDc*)Bu`s(+NH$=vq|8Pmf%?R}FItj=^Hy&8G8o@{g@{oBwl}p!(^L5)`9aw;v3^MxNs=wgh(l%QWPp?sil(jO-q)R zAVNdgLF1l>#>KCyEI;4BEm{?{j9#in?kQKaR;61(&&1T(tOU}&;`TNVwd>lk_3M6@Be@I?;mxE4xCM z31|j9Iw?Ub$BaBF#iOKhTS$47bSI0B6%|8ddH4Onvc)AO576u-)O^3<;c*^CMjvK` zLRzjoMaJh|#|;j5B({l7|Ttj0lt0`#xub_J!ZYFO2oolzWj9rrIfHQtAdWWSi|e! z9W;m#L!>!B<2rb!e8T_vX!tH!9$*cWDrC04?IZMVXS&|cqt6`KBRwj_qM zH72K!+q>D&M)C^MGG&;`3(5>b4(~XtEF^7J!q*|*;8&wx@fkzdNxzAQhzC&ok1u(E zeA0xz-Hh)aI$}B+h%Et|qU?x=dDAf{Q(eSz<=}Y0Lxddn(_O(Pc$USyTzzfx;Q&l@#!sP9x# zlVeU_tc442-<&qMQN&0N407%qL}L6uE@{HOHnd}DZZ6?qLcT)ur zy_|Wjp^i5X<3$}V2@ym>F z0#y3flr5AoJqCio``)x;$2YWM3hj8;BMj!q#OxDYEQx?B&NAUssyeSo(pV?*|S zWJ_Y#A;=6EEksMfKOp{&yIyDsvjEMbXAXTw{vp3DfQ0~Gk%(}tv=DSshN-^(B2eLm zP~AhVp8coi;Y^*_L-olSrp2JGcmb4vvWej}ZDOf9jh&=|I^!Z6)Vz4teUDikhA)cc z*$9`t>pF0)tfV?T#BuHYUQ1l1u#7H<3YOE2lzzOqjFj56o8ohRHBO zOAaskGuBOf5#|BzF|S3=lYQY!2UDihHg~VwxZwul@jfi{U+`@yCq*qwEH3mCI@Aea4+sH#y=&yG z1`oArl-4>}(RVjDk3tg9@5`uIHh^e5IRIm*ZI>;31p6e6Y)kgM+Gh+5@Krg_8GL=v zMRMkZ|C%_FEJyr56J=7qh_}Yu+1`=Koaj4+z2d6Y;m|tvi^u2Z-ncUz=pXF>O_2U7 zjJRO6t!+>}0yXHDtHSYj8-(2%lR1RwZ2u=qXUUhzf{~TqNll}1ZRO2PBTk(XMyAyN zl#o%VPDxE$k2&OEt6KtPK^iH#guX8mpgofR_%}3tiw5vB`aUzzsj?nZ(^&shogoO6 zl5!LnWR9Nc%*Y1KRg_wWO=J<%n3NsPlRSpmP@3xB@lx!N9zAA{2>yz1bdGl1Q@|A^ zYy%KclNUolu7m)}1@I+Tiu(?FC-VA>TP&*sdb@s+ACAVA*(^HVa|!6;zXTGwX6CGm zS+dkaaps8hvBTcHd-s&0X}7npW^qjGQ;0Fed}!P^dDhGTSmcLtnu;MZYPzFVbbSgO zQw_uB7VGtvz##MB$_Ct(j0aR~_3PbBltxyoyRMhOip zQCVPWYRc+c&!?DKGY%2{0f*X0q?8F}B{6g?S*D1KYvYbIoH3Gi|2p&)>=MSFQ_d82 z=@O`&ysz!08PxB(zmoww2K9}3I_M4*rTnshmD3Q@>#(d0sC3`2&tDEEM$5dMj)yaQ z?)|hfxZLyE^tQIPg$Vu}XlUZ*vB>FYC0)~?L=#O9PnelPl(?hn_8)-iHTqY3dn+w& zz1x^Q6((Y`P5-Arpfr9pJs0uIG;WNJHkg_s@z4RtnapCU4f~npw#fp z(eGG=H9A>G&jcpQ?4Ef$rz-;x;>X9kk@fXk6#Sa+v!N>ab*pc0yKwJbIZ{*4MYnhu zKto>Sunz@$i3}GU5ge{O?SgZaynek9VRMKB7;-a6WP1Vmzv0W4ExU)xW5O+BI|lC% z+k0R&c-3=1Veyi{H)idl_e#uEaBmoTW6K+LESK8@jXe%?U)Ve9%103=@f9X-?gn2; zi@pkSqF52<>&UR5_iv11UGtj!$j>G#c9%WyVMb=K^hZ6i?0se+|l^ae))2}n3_W>&eJHx1kZyI2dCFt zf|n)866gx;(t4E9L}3u+KhCM*1C$cHplz}!k0jTH(H31JeCu=4m~{{9#QUnAF8L35 z3fB})u$^PWL36w(D+Ljw>});E)EosHJ_BVFX6*Bw0`~dlD}!!}jB2@Ie+I*J(B3y* z#q!)=$S01X5I}9d8SbeY)o2#Gc4=bv5UT*pSDBefU{r=2!as`ABLI3X5gy5ya~KO@vi;En60N-#(YvLHAh6= zM9V0A)TOIek8l5Qd#NyG>Wz1V-XwsCW`vzW*EnbRlELFy&Cwd|)QF4tmF~{SFtPA4 zSMJ%Pizph6k0kC${u8d(|41*ZhOz<&SJ39b?h!95l+}og-A%= z5S_L;8?Y?dTflO}(|6J#BCGJecFezDYG?OQOvZpMWsB$#CIHmfya9Q4A9z!Pd|2U? zv|>{xwj$q=GYN7@_jcf+ZURA}P44bVmo6Q;IN50ym_^SKqw_YPU>WU1q~=Ctie|Dn zE7^uLJ4b${oU`sVsmqTh@E%~l&N-CJ+x$lfU+a98@Xu&=amLg$Qj|56U!L6T!ScqW zpTCb2#;_Bc#)J}YAmWCM>6gDDX~E|IQ7F zk>%+*?_!^16E=L$hns-=tpR4sP}FUPnp#PRK@#p-1&>^Q+ zm(WH+x%Oz}@Q9UBhUZFFzb0xI>&Z$#gYiyIPp?6hIs!ZhxgTqaCK!B$br?9k%Zivp zfgN<~K1`;-9H%+(d_yR5&{Z7c*UClo0KsTio<46XYrP9L8&yxi2Pw9P8(#HP_)mxQ zKg;+OF9Qrxz|p7a6NUdp(*^~MBw&`1SIBZ?pqGeL&<0-Xzs*1L_beXmREPK%7@|(Q z8a)dMsi{;~;*M5eD(!^b)gf=1+o>#OAlfiUrLrcAMWg?#T!NwGGNx{KqU3*c^yGI# z>_xw`eoNcuJ&ucT>4C>3pnmY#6LdW}sNws&f>(J*QH!p`!+eu}lnNn@0J7KWlro}hk5 zoUPx%#;sj1O=VGV#d7n=o9iD*E(%kC51T$AQ{fDoy0`t*`eF%))l)k3x$-{A-u>?) zyx`xwEG`xdRgDtBg{JJi?PRnhC|t6R#X$diWV5B6)yq`j-0&lw+0Og zItN<<5w9B+Jqfm^9Q8O4OLN2o}iHQ~25Ts4d1oZr_9fYIs zsL=p{G$TDF?;AW%R) zdP;*W1uF)~6N;s9IL}RkL5_pA9hX*{gYuSXgklO23_sE$-=@@v%WJk`X&EZb{&Aau zRD{U)iwh+4F$xz2fkq>U{v)e~>zFN(ZC>N7a^i?3vDix?e!moLGPvyfls7UxXsh6u z>R>!hXL*g0Z1mDip9ZN1#Zp`r=7*A%T=PC5ZWI8IMsYGakMpe>M39G)BYg(7>OcUnW@Wyn#LP7Z#`ut(*ad2=rQPl#MJc z3dG}Yp(g7y?~{hYpvNb3a>0_^p+8p};pcmU69uI~vhfRAEdlb`6TG94x@>Oq!P*eN zH&W%IjzjNFKq(qOVIu3;B=k2ZJC80#37j<$u52`ty(4SX+QM8EZ6tbh2+VM^9+Gb1 z25!-?5qo}AI$r|DM$av3=OXsVQDR-|K8Qw$J!6?XVl}I_+X6lfP7~iD*0tWw^Ssk? z_>7K~$900g&T<}i%}Ds8PlP|p70(=%Ik9%wj{KDaSIwoVJyGaleJR)JJa?wTyHTu$ zD`)Q`A#dX(o1qP%()p$_?R2&W#tq#jav67~uHm-dhQZ*}`LkkH_wcu&#|T7{7tbJH zP3PBZyLe4VAu~>Y_cpKjY4xIgF%3V=&yp+7`Km*#!SP?AA(AL4s0@wztOmmuVFCG> zqON|l@Tu0mpe>a(tYIpUVL4Q9qPxg4L7rJ~^?qV|h-89s7jX15)?Ybk5hH#`6h%ci zVu7OY0mmF<;dZEgo;vf`v12(Z%kbKX#<4vw-FZ8O*#XX1S>ZA4e+IcU4Z+yGDF{X! zC0_2*xHn1SX|DHLv70Qzsr9p*Q5Qdcl>8sbWK8Gb%Zq4;^=Mhu-cuDSm2)%hsNkEp z!PD!kU*Z3Et$1uEv9Q$(d|F_N-~IAHN+YE3u-Dj1Ej-KZdMdoQrN@s+AEvn({8=0L zMm&(gbA_v`tJnO5^&|5TGDQIt^)CR`AKk?(T4c5m?Yn~lyZdkWxX%kH^^WOxioP*u zNRY=Oj;FLGiW9u_>b$b+emj(paeJ(_?C!0H+g?~YZU5}*)G*kw!PIH~k7X6xu0DUe zW0|ARq9@DT9HU$OOqSX#oi|8#!H{5+KcDnD{T014VnIn=V@Fd*w}Ha4wGAQXRP8N) zL^gfz==EEko`!L+zN@RMs@@EJbFLq=6$RyJqhZb*+n8r$eXc)6imCO8kB_J2AKr_U zWwv5-5yk~GysS-Ksp$A*iu0+Z62JnxSWAv`XC#NB=TV=2LT8OdNi#1OX+bP}b#P;t zd#R5Dn@b~Iu3%RRuMrbRm`bnV99=9FEhvoEzp?(&(R$3P_4%sMwmYzSC?hzFrdGxy z`&?gCa!Yy^!<%s(X?u1*QanF+F4p4yg`w$!x-DI<2{=)$I1SN2%5U7of8#Zx4G`xj=eu}&FFXbG2eh&=HSr&wp{_e+R7&Sy4o>=rz9{+qSr=0r zrlq9?rMt^Oxu~%nad#y^^;hg^?X~>YnIfBC(ei90V>JiHc1(PK$^v2Jh~&gyjoNkcbO+P{%I^|;CqW4x1|9#F!+ zFP2FOy1Tl{1MxSvP=Dcq5CZ;Y#$wN1w88BoZHN-=%i>_=)?xJtbGJQ3jKC2ijy)Dl ztoqb`#Qg6UHMtsaoxB&0d2$C^DFnPm1)}tEV!)1)w*A|1cYEgr1_pjl!e-Bvw4>0Z zhECqR_FN9*hjt{n2@_Jm;W`^oK5(_-K(0#uX%l zA_o477c(c|0S?iGEeec4e{#?!$CQPuwJCC{M0a(COzzYZExVuZ;nx%YUob<$2DlZWPJ54W1Sjz*x-Y+QZD^SJqoqqLwxqh>XpWr9D8wQ zZy5&VokQ7WF1Q}^-qJ`DXp$!QyidDID^3zzZ z2&0>=(B`}B0WBUoO%`L0w=`4{&-I;Q|5IsO=hsko31-#oxpPmW{Cl~ZeQUD>BTy9n z{<++Kzx5aE^8A>%Su_!i{aE$wOEPG4F0T;n)=Xvp%E*K=?aQ>OCJkXkx^dGtzh^c2 zb05=s#@cB_)V|o4b9(%0zk|O_kIU2^*+*0qdy)I+V5Tx`j=w|#3HI3Ip`jbG_5^Z; zAt+3bl<>)ovegKtJ2{CkmU@6&H)xk#h`F{(7OQs)F}s8LlRKj*KQh>|zNx9mRCWy( zlQT9CWQMZ(&Y1Y}#GC-HM0&?*IV?*XE6!9pv3q{z`1$Sok~oVgz70+pP=UeoaNZ+C z9?s_WQ4N@_;mQg-!?>bz>lAb)UhkmVX+nY@%?dt7>s$%FJX=QxWdm>RA$Jj;lf%;S zjXIb>!7& zbMJOhfo`GSyZNHGhG94@+aeBGZxm%JV~L61ziqRauW>|#=_{+Obf&o^_^dnMs>hfy z%p5GlV2aaRxx2A>oVMZZdN%zIeV11Vkpn4c(tYNh8;AtA=(2u{Uy^YN%#Hvc6{iyy zgnm)*>Y%q5vOjjoNm?&g9@o8R(U$I`;0$_f`qr)=mm?oCOyD-;c1fPR7bRZzb(3U@ z=g1sjnC*L=_$MLlNG(4@E`TIWkA|qN%9H5r;V6t2VaAhc+VrZOlbWKG5_0@_VtP9E zl{0ZlSrQ*-HR26){Wp{Aem;}OobTpBgQ@iKtJtUPUb&m9s;H!l!mrYl9?yK`NP9Q? z_t7pZ>BF?x57X7oC!<2`y^a|2@di`eD*%o#=+8X*f_%o;vyOIqu7Y@eW_VAbeTq)RJ0k`-2;YeH~2HrN?>mozA+L z5&4dxkPUxusUl!*U#l$RY*l`saU3>fy=6)DQfTdT{8`nvwQKBRV&x6z0=fn>o1WWo zXQYQ-zJ^sW_h>dC;w&k4m?Kh%wD1`k(DFuZS*WtEasK^!>{}TdOsM6($C~l-*y9LR zdAy6^>2B%a#JX}9kq%m609oVBozwev*ZTDru^}XG>)+f#qImN{ok&hg`Xz=beER#h z@9AlqyR{78%$hTvlUEBJ@=`aDHE+d z*YP7$7vOEami=C%nYa-XUJ+@qZ+a$?=E7s^ww32xZj$DFL`tjH-!kvVwjNgvMsUwV zCVK;RMz0$9-!-0MLHwJcc!N7s&&q7C%@B)AvB~(0FVgswPqz*7Ex3ir(#h8_m;eiE zjZr(Cijh{ed(oxzthb}WDSD~vT#PD@NtYI3oY!@V;&bk7w~WWC$&k>{@kJucH*S?f zRof#nN0zi2tnK!tA`SN*Wjc{xlo}^T|4+#Nv=*Qh%`)BW?$1v8({&~sF@(e zE~N(>MN{dzb#m$4mRtG5mYdnrJTXk_V5FQ$l`1GeXm1+jFC#=T4YTeU6Zi3!8CUc! z9*s8@VaA5KO((H!o6Y{0EnT7>9kF8chuOpsky&E+x3=M#>Tfs;jkluN66{&LP=HM{ zwNTNz$lLss8{cs)6tv($GnRUrG-c^<10k%~1iwZ)VPea zPk=Ypf>`S#u}@PmXi=qJVu2KQ26y&qd8~oyX{9r{XQ>|#t>Mm|In&udf>|+$CNV&J zleZC3eTj71Hv*M$cjoviBHk|n+nlAH&b8#JWT-U?r2K4N^Ujhdvil+QSr<`R*&fKSWLW0 zDOZwSQ&f^fqK*p&QBNaZcp8i##a@9q{vyBsHl;%e+#UoCG)S$rgoMtpdi!#L#Wo2d5;X?CFz&;a~c+TU;(@NUsGEVe+ zhl1wlVTmYwx#QrU!3Zv|f{u;i93b9#POg}VyGK99+$xV(EDnF1ZY#>vYO$m#Zd+|Z z|5;va?}wrz_+tkMO^KrYmZ^t*6>#?6g$g_A?Fopw7Qsqp({H^9Icd?+q|RnAB@^wPCHh zJ#NTjBYQ(1cVBwhVxYUn{&LGi;NUp{A>Btg4~Y~}y7a9+Tf43-F*_*Ac!d(oCEIIA z;HdcHxwR(-tnBY-u=ZPPi7j1a_zed#1lgtUIjdp1v5&-v#rq6X>4R-L7pe0B`s22W z?j1d-Oil6>YuDcW$ARM&z5>d8_W#Jb5^yTpt-Z~a&@3`EC=E)Xu#F|5LP)mzE_y7NOopZkHIv=n1eV#SmYpr{6 z5Qx(|lE&dkizMhuw_;EbfQM~6g|!fV-^u46bUnC6IM06AD zz7XfaQF!vNf4R$N@gjPal)uscrdt)M7vaq+x0<|1d}Rgmj>=&STFX+wa1{8ECQiQ5 zIyexFB*Uz!<-TPk?lif%$Ax{2R3h;wt0ub#6%#2LnVSej)^JWTe|8eRQ@3N^fE#6* z9+|JsxVElPp(HK4k~wm7WYQ!y9Se~X{alQ5-N1Odd449*rg26~Qa~L|2V?CJwHAt! z{X_#zV<0#K@;octKmml z@w4Plve76PT_uC0yy!G@Y1f(_p8ezQBByr8PNI)Ir$zspQ=-rxiiF4FGco63Y=Cyd zAtYg$J;R2aw0$ifpMsCHY}Q);2p&EXDaUBcnYoT0+UA^d=SG9}MqiS;?XW)_`Ru04 z+x*BGCFGD`>V)fNR>_9rqH`Af+^hEjX9e;@9No^o`UtXkkI%?2ehio*_R}M>`&u_w zx=qftE}Jr*%qo@FS6u8FRAlL^YhqNGgahNnw_$42Oy(trK#t#e3k+u!$sS?O2cQ#k zK7?NUs7z0T5M47#N#*^VDE(ZxZhuK}3|{ArPUBv^H+UW9CcSq4G5j9NdPh9SC91oM z;C~ymv`CF@aXiH8y2e~*E%Kgh8Ci4+6M{^GiMmx` zejA9)(``c77w0eINajJ95o4Q6irz_xNYI`hiG_x@kq!iUdtj!w4op~Z|G#`V9icL` z_q;ZW35?tq4jw*17w%*JwL3N@YTHH(th2-X< z^2yCbB`D{*o6Ji>NC?(MA`G>@pO*_WlhKHxWG>ngY@=2;O)^L$6|b*C|w3lR5cB&c!48 zdd-YQLn_$4H2hD@mf%JL>R^3wTL5Pv^o6oZ3goRH?6F2{!V+zS&1HCE;esKfH7j`F zjUMluRKk|!bSR){{SvtvK3X~p{+?A)s~zX(rjscgSU`H};7ZQdbmu^Yvo!!w93O*f z#HOkFNpAV7yqb>{{zb0yLChco`T`jgc1}M>#`ta$JN`M@e9~Y)KRNu|2AZHCrb$iL zFG~@ghfAb*4TA-bguUhc~ZaV`AWjI5VIB;M`b zx7haXHbPlg0!*&KUY5oL569+kv?)Wdx1WqzKz&baqyHyFMw5dbn%~e<3}YX?(rr8G zCyDTl_ni&pnYx4k5&I~36Oh0A1aOi`$|S%ER0urStX1E+_zgH3H?Z~JqZtBl*BA`F3FuX>c<5|L5z;_6 zcc>;gjg_~O&~eM%L)b{AuSkFG9r)<#k0(R~H8FE!^4&QNCS!K0TOAlmJNd+7%eQ6U#U8#6MC0+&+w9U&i8%9Xoc+ z0MWd2e=EHXvG;;A+0Lqt9k_uk(d*a7c*2U%%2m+MBEq)yqnHaQ;?Qu`u3fW{Z+ri^ zlT!`mV4&>vTjl$$W+*Cl06$b(GDY8EqP%>n*^T!DHK--*3K8UI-MFKWi`?Occw$>- zcZRZZ)_~i(6dP;on5~rq_5Q#=b_0gAw?uQWL5~bt*5E_#`@Z#;^{4q`3~~q3aYS*t zp%85-?%WPaJx-ry><(@VONpbsu>XcgRHUS(!#j{LW9^33tDGFwg$pm>mGiew(Qlxc zaKs-QVF9$OEBIOGf6W(Wt%~D;I-QScJP;sRE;biMftD${J)nk0d3AK6sFt9J!9DG9 z{2tf;A8fDxhO~3xf8x^#n7UV_UkeHfIslffC|oog$b59T6n1ucm_=$VXypzl(EDyr_SUUi8Qh!|mPXv+O~8LKYL&F6x)}esiy4^%ExYXijD)2D z$JbqN<7$Xg+GMhha)x`fqxkkCr(5DTJmB28^#YrI&?29@x^1AgJyVaqzFP&}=G0;~ zW5x^>P0h;~_+8t;%Fq4q!OC;VwKUEiit=`zgAucLUFdf??uk;6Q)gFdfDYg=+|J4! z4i3rgW)(kv?19$ag)CC1>&*f_jlChR&iy$Lu`-hc@T7w&(vD-ZDG5x;>}zfw8MtO2 zdd`WV6JO3OO=ynP?C&iMh(=$F1C-e4jNC0eXS0dvtOC;pgeGHf_Z67 zQP06)jlwx+S2XTj6{q3*00s*?HmJXZ9d$m+~|6>tb^wSNEm*Chj= zaAg`j=nti#$VuJQI)3k%oowjH1_7>oE)%Z`w53q0Mkt388LR9skN$&{Ou^Ktqo;88 zCpMh&^@M~px=uiF$pzMG0o?9@7@$o!Wy=KC(`kCo_wiGBxCdw z`k*Zl66hbl93GyBUUciIv_@OMuCkS8X5n{v4 zQ&Uw9#qVphE;SDE=_Oz?ckbN5g$De} zS1qi=t?VQPgyyYn@Hj;Q2<>Ad_Wq~nqbk#6apT+hbX;+#*;fhEP=HRRrKi`kCL-)w)k3ZQ?wE<(UX$rpHfvKoOeYB&Rc8iza`aLP_@v8`pRWl0kwi*z zm=5#v!v5jEY1uEEjRZlh`H!|aVevE#;g@M{`i|})M<=jjlS9x1faNJ(bOU*FeEXVP z0D9MyUJ~JBDIJ`|(YC>%K$L5GUa2Rk1`7LOTA?tYM}j+rm{yb4_~f;YRGCa$qaQ7%|Me0=lcB zrL{3iK&=kMB5$(wOZ(ejDF7+Q69^!+vO;+L^MZ}84%8l0U4}jWC^nb$C zfFcgY8;!h4?tyakQfXCluHuSMlAvt9X{@pV9|UZdZU7$?OcoTiC!#h_GW)zYzo393 zq5q)W0-ck)W3^u4cdsyi{S^wfNg+2VrQ|h0G)^J7Ru_wvcEIPQf|bKly!A6EA`2iW z;04G2$8$K6qe#tFnJU^1s?=E7lR-JWV4dtL@ao)T^EFPf>v=AD7gBxzCw$ZFvzm<7 zJ|&zohyu*zz_^KL7@?3j8*i43sN9o>fY3^6eAbUd@f-IX%u54$v$e_e+(qN&!1sW` z)D8d~>l)@8kvO}NR{8j_arQR~_Vjufd)M?hoGQIWgqr#BU~I_LVl?2Xa@*3)-|v;{lx!w%k0KCs=x@*r-cP*h2Fe@ zs->=OG+?pjk+CZ>V1p=B&Cwfb=P6`~$|o(`M)t!5wsMT#u8NaK<@>u$bA7zCI(LyvH4 zB&bv(o6kiQCf1nU#6}k+t&k#n)Se@sTCn-tKq|K@i%zB9J*M9V;(z#6P6T(@Cj)g> zHa`_`@>B1dJfM1fmcJkE){NrwI7iHL^qP^4vRYp~f+Au2dLB;8qn5 zZ-Y2Vk~xd@jM!_8&%(Tlii!%Ssi_GPa+7^jyqy-a95|p&s}jWJb#0;qJRbeOYAO%P z&QE2E-kFqOIIv`Yz_?zHjxIoBM+eG-S$LQl;B+Dy!)thB{}oh7ya9bi+zNC$OkrN6 z@S4dYoC#$w6msEy4RiqQO3BK;efQ3?8hde?W!RPUc_YQd>Or@iM{pyaQ{Op_pi?D5 z^2Y;G<}bQO`2-Dr8hZKi<&omz-!|6tt@9kQsSd+sM5L>VZ=@v)xLbYD`O*?6-0kUq z`Zob|Y2XuO*$=5@OrBH}q({Tm4Vc<{g8+*LCYxm*zoS(@pv|6zlQd_dr9kn!+j2SY zTNmr;F|dE2E#baldT-~wrUC^;UcyC-hniD|W)BVy_Lf}Aw2WFJu^)7E9f{_Cv$0Hg zW3+!?6SOe+Psy``{NH@N_uQX$rXOKUsErqgAwYOU#S<^*Ay9*B6J4~YxXw3F;kcoZ zsbhUW*LqmDqb?&DG0$X9G-s)&{&eMeK?=S9OWovtV@FdRZCy))IwO#dWsA&wfEijF z)RU3>>{GNR?6rsq3p(POl=ZM@`vIl+7@c64(UJG1u#YZ-_A)UAnlqIV)g1mWB-WrH zbrW8+aXMKe)$&V6vh?i$YA##048CtFw@re3mUc2`_Ww*ayRsNN2yG~WrQn_^M~PFS zzn2?^A}sSI1(in>B!N6vWcvB?x^(Q%QF|fmaXNMhbU;woHx%6lHiP(T8=Ag*k$hT5 z35;`*W{yLbj-$Y))cMEL+lPMB8W$^d zQU0!9rkOnz)8o9_2Py_EmJbCL zwfRb>z_wS{6GV)zBTwPm!-x(Y4Px71L^1x6ToB~dh2?8IcJ7=>?vNlJ@!P}xRHJ*T zP@sjn69?4rwvt|vcP-?*7_huRUAkFav{mi$c zkk8?Ile(v^%P{zq8bpU~Tu zf(Z>(R9hJ|JexlZ@F}tga=zp-QM-CYdV|pQo84e?zy(2%_ox2$0?^V^wusf_)7(ey z+bPe2T_txu-|PRhDg}De&e^|uC@!aM6(!Ko%pHi~h9c`7=(6K_dXBiw`g=O`PGL`4 z7-x#GEqwY4ZL=lH#3ol#QxikmxyokUwzoyJIM5U`G(m| z*}bL=CK>yQQAQ_oJW0Z@(V%R2wssF%urHw#VjdjDPD-U8)RMFOsgtDt1m5@g` z`t4b?j;Y?&REjL1jV*Lz?(X}Tsxn^L8%&o+nn%`-1cpB!v*1R$L+xi8Fmjw)5TpXY zg$Zt9u8AxqserHGEDwx!xz0RCm1(gWuRP<*6F+2}Z;;ZvW4G4Y1pS;IO55Ny{~OWH zr=zjH8{f1(TJ9YbX;rCtD5R(MeRJUQht(fD?Q}hEA=M=Hg(P?nw8JdNex*1Ak-pcy zpOu#h@PIzZ*nk%CPn52i`;ihbCjyDXB97xxW5*(=HCX=`8-*w;CsiiDEW-XshfC2U z=z!V-l#32abMG{iJVK$P_7u57vzo_DUkcUPX^VB4RQ4=3`0fxT(UD^2{SjN_@he)e zZSL2+rWZ+VB&cta*diKYDU;kzX`$7X(d|q$eaV#dNa_@=#j32BZHS4;jRBiUa*v%e zI9S8=gR$iu6f0rpe_9=;OZ>oj#8yaV(Lb6bErdN94^S#fp{R3BGz033Jg%ncPx9vk zqpeWRu#6ITdXyj-47I`TqASXVZu%D8P(muNfm7!AaM_=<+5=sA_#WyYSlgg)PFNb* z{f7bl56fm{`|cbtit%I8ut<_Nv%-24C&Wr5^C)89U<>S@L^1)xeHTN92QUVoQVZOfLa++ICy0~3RY^ypCAq_7AYR%UOyRL5Z?hSXC-M?MLt=bj4mJ$RfQ z?C*9USSD1jH&h!`CuN%XZ=WdyoC~!Z?zBSXLY=YW=!6#d|6X%$lOA+pZZDSCA)Xlk z#tC5AvU$aqo|$ODVT9oEZjKEBx-KsBcfY@hMmD!!$sPZRRnz;ADohGJ(C5W%{c3VO zbdTw;(5o{FvJE73&VT;=8F)nl=rYPQ^(%v;U!}(Iv%;`M72UkM`{WjP#~5V%@uF>I z-d@!E+F+l)5|wp`>leYZy-{f#*6UZb?QOF z@-L7ZdAD$ozZq%I(3_)fcKsjA-4IeVFb;L|&!2_4aUUHx`I&FBT5m;a7x<|iAOAqq z54T=`Y!7}fX-%vn9!cH{_)?ci3gx_wi^y9eWj%66-v;CFP+aRMK2sW9Brpj884(%M z*`AA(d3iK+U_foiy~a!>EHqea(>JV#qdZjkGsK4u6L+dp|D`9S!^Mi#*EB zRGv|B{^f{IhbgTbsE8S~{;%l||8F`(%eEGPMekQ^k ztIbb}$f+X2-Ud4hl5BYC85*ycp1}lcN@2BC3y0oJL<$K?1^4aff zS~ID!XP=eE9~*)moU?>BKo+X}O!`6(c%S1|Rw$^NJebk@c`COeKNvPwoUjDI>Y$m+B8MxrG8?=&-;3ct<$om<<2=QE1_5s z9qN@r+VKY_M=R36uS;1sVZ-iWvDlA~_mfe*G&FHy@;MHuSzrvioOHGeskl)6dc5U&NT|Cswkjp`^kv0%Qq^o z6Gk2IOEG|hdixdj(R5ANpxmV##S33iF<`N74t~ld8~n+7`(xI(cLu-~LgZ z@dS_dHmQ6o$Z{FM9LA4I>ff~V2Ag~gqL~!7z~hg!nQTw>Q_cS0o_Px^@}Eg?_Pos< z?epN#_Ib8%bKAM0%rUFR^sXfTm0swV!WMcQjZUp0*ZDA%1R_37+hlTat&wGW7vu|T zAkXFI5@~~?xpuLsyi$iRT74EYY5`KKRFT&W4Yi94$YdWX?M9ii;j27%|9{cRBDDHa zy-;I3BN6YZ#&{Iq04h@;blc8UrmA|LshIe4wrzw6}t+WH{mw!nzZwYhyhKlkO zJeSQXy5I!D|G!DnbZhFDD{5j6;%1YOHzq{Oh8L~tgzaDjg-Gg&F-Khx>rh-A2KRua`tn%1wFvoA2hjMrG$VO>k z9cL&$B46|2j%}ZP`m8f`b(g%?V8N}E^~kK;+_(dJ7hvkPqyBS_a_)@}o!(*ye^r#g zrfWcJ9S4k_BfuaV*Y^7rrxPcAIV|jkSzw9_Dq94(_y2C8U1dq`VG$Jy*ga_cE9%R| zfA&qy)q#fJdA{!oah;+3l}AuJNHXd5T};nW+)zz;SZ&L~!5wceX|`1Zbh9Ja6Kj}5 zR{yj$pWbT><0CWMDY3Iu!NBBaLGIQcO;b@FcuTb~n5uegI7}=E3h|;IUIF*Bwr``MX?NEtTcCXz8Q0*IH!rbg^{Y-G~0Fd%hg*h77?3MQen`%+tM}~qIqO`S-z7F`B)#RcU$9Cr zMA$(p#8x;(QFgbp8}np%Kq@>FVvKBDM`mvtP+aruM(M2E+LL18jyy`kP z-B*J$_B%X=;bEWigz2s2`xdn+7EiglGGftbT4BpRGVUixKJGnyNbpn)t~cTY z8QsyFT~Mpk6&u{S_>dUAyzWrXRzh4Nx7>M+4EyR=;}=T`CNII z;-hlgTgGS)c9yDv=eziGQ2j_>zDII5SSBtPeeQ}ry4?9p@X2kdP=(z1=! zF#&QLiB_XV$yp++etFEs`AnY(SdB{>UU!XHjeFC3-6hPyF&o<1$%Efu+g~PjSIY=N zD^VMXr!tX-iKX!pDwX^n4!?~BnF!>}_?pG>kf~yqkyahUMH=NCdnaf!jyZ@&jB=cp z7Rx`5bAT$&bp+R_3r^NIL2I5_cUn&hT$T+XMsL9>h!_m& zKWMOkm>EoM*jj1Ca*s2>fVP-AqreuWfgN!MONp@x1okIFrig{_y1yKU0hS^FG}Cdy z>!<8309WKvyXJ|j1b_1Xc)p_ure7cHee_WIi;FW3p4TAe(I&^J+HJbH^Lbs=c$pmC zQk@Y&*@s2q%fvNuRs}Z%vbU66|5044#CDfpi3M)@FtQI&O#0UlEwq5n0vk%PYy4s` zGRP29J4BcfFm5)foW<;N*}C421|y@h!iLu@HkZVkX!piLy!Plgj{WUWyx20-JV+~0 zo`2tF)t#tvt&G;bj8tzC`-Ixer+LSOYfE@Sdz_xBFj1rui^K9z^Q0USMnT^XAOo>> zUir7-IS_Mic=Dbn@?j&jC1sa7w7!tgs{>2j7K~_tC&4i1oUlzn&Lhb{@8T&K06sF7 zk*)cn6EUEj2e!eP<3xj!Cu!aSE+P^KT25Z)-}RBOM#x9jVOP zC*)9EYaF;xUzBVu@UrL77^`%*>BO<@8qc@D_xGMxr*d05?)|X`A80%uf2FFwaIFMd z%k-fyva)#KZAoLJ1M7_=ZYDWz43x^A4N-ap8AD6mZ18rHAppV&;T|8=HOuv z_m8kLm;cL2yJ^-Vo5!HjqOeFx)*z_@u==bCCn>W0@v%Or{#3K@^7w?BeS!|fMa_Kc z_-~OQ_yGO_ukRK#^C}!K%$WHpGOunH$y5!a1HYWa=g(#@9oOn>c~J)mIgMyq&K^HW zz2d%9*ogB%)wN0|Iz}`_b?S*>n< z?_P#3%DbA9GH>~{F(6X;@c}0GRP!|1DjnG#PnQW|5($Cz+03i;l?M#22k;8^Ymkc= zCgpJ)Lu7B85(iO*&{&l2*^^oK=>X`jtw zEbMxOw#K-v#t!kI^1Lu-J=U0dV9+%RKHT(zho$e>rq@nQCuR69vRbmQ)G8${25%K+ zoT;O|cy)Z*mx)_cZuO{Tc65fySQ1d$O zVfoNw20Ku=R+8~uy>(+ztKN6wpQ!+&&V)>h8eN`K9Sk`YBy(bsS?_Z+Uu=n(SJ|!$ zZs{u_Q(zw3Og;W5&9*aTP4Ac7aCs}Ms>4m$-p+ogV$mk}w+QO@30}a#2TK#HXUK;^d4maxx zz7)fpv%2ef(G0CmqG)DR(J<{%vP(U;i!|;3Jcjhu$Jck(r8h)GPBDyl9s2 zj8uLyK zjIwIyb%lgYI(Xt9$gr>kaOE|NDJFQM)e%97@m}WLLJsGK;&Os!kRxrW$%>)UKY}}V z^hY#ma)u_~HJp9+bS`9+hNuvh~;X`N9n8K{-H$$-{3!BxX^d_a{DT6=vtJ1IkI|8$L$ zmM5d)YX%L;87P=6f&0bgHR@$3c0I3}60w)e-+vyawb@B<*NvwD-AM*v2F%aEP47~_ zJ!&Rj!of7-!E>zf_R^%J)qdTZK>xTn(ejs;p#iL03XkCIlyO>6G2>FFGJeY2O?*CR zy3Tm?Z;pp$0$cuhG_m|znL$|ZT zO~5$dnUJ_h#)2F&wwvPD2KAri#gl||KG0DvJ)iF0pn?{N#)(N=!KeKN^BY$X^EIER z2zG0&R{YnLGr|t%gbkFN?hB^TopqvzskpLoC8DJbx0dCsj_UYxtOt0<`m(?9+G2}D z%P=*^G2lZu7IO8Yj-ZVM$eET(^QZE^jeqNbr?@x2n*|Rfl8QxIW_aZoha zzpR+>2RYQZlZK#l*4*D_k2k#%8M8!wMF{r@tW@uIN;K;KQL2rEM*&wZ6Z}{zV)M&V zCtvSd-jQ)C+7PjM}&FCV^UDAzK}5l>V>ID5sTt!te17g9)nc=T1~lhd~{Z)ljJ^?FfJnH|r7xZ&qJaus7JhJGA4K7P_?c^Hu+X@1$=#tCZl zPyizfuqz7{iHWj?p0(yfb>=)=c$9Zwudm7~P#bC8}ipWshCKD&MfMITrMd^=~eff|OgzS#N7}92|g}Z zZf-6C=L=tyw*4ejC~5h}AG?KZ#R{gDg?a^Ej@Pq;8@ZmGd=dr+NF3GSJ!H1$Qx6>| zk*{uDx{Gh#F>&xvsaY~7;Nzuv_ES{~Fu@R{u*-5*E!$J|_yYI{^XgSHGBS#hVO3=> zDRC_&3)9u8)>K%&hm3ay;w7S4TYe2*57ugmW=yl%h_JCdRbbw_D@E*e%Tq)1nC~ks zlh@*TplPGZES~vf1YG}k*`;|wmx5-+>v`pcVXXnrJ#9gG2+tc`O(Wfq0eR*eGTwBp z9@{Nhy&t4N((OsHD(a62D6t9;hDitd_`!!}?g;fJ(m;=KWj|NP@--e4 zpW39#Ha3s@1RVnwamW4{KY1v#$YUXKn_quF_f&)oKrk5q%R;xR#Sel~xD{Z|b#!)a z0Qc)R#Lsl=U*o&y)`%Y%6Ippr{p{af0K*c=PeMwQ2fgnjdpF^%f)U1ULFxqYkP%bG z4vNi~Rfc=*6#>Uso)Eyj3n79@~;sB!XW z)EH7-8jGfYi%?e9(BKEHPywyaQ*=_1FyG3S2r7r$k+u{Kpa#jfQ6w zp_JGs4$@j;H2c7*c}%~p%1E+(JF)R68LfHk*db#NYT-qN?&zHP6VB|3c36L*)3SNo zp6C_c#KeDNsYr2!mQUx*f3}Xe)j>`Way+F1ay z_L-O7Af$k&-|N5P@#szbW{48iJVN*l?H4rF!FUlY0)e4YArt~`yfM_5n+|ur>lH0ttZ=wjs%Y3BH`Y#40XCYFiV7)NBZF;73nQ_) z2yz8v5R7zcVNaRcidc|6W%4Dh4Hz9*0E~U>%V9C0HyzME(vXS{vHj?7j*Gjo&o?Mb zNbZdIR7Wf85d$^Z>#qhk{@8@Jh5`7ovF;7*Dz=1EX73K-+<;fhG-MlMLv`ZMM`^Q7 zIL&WIx_#6Z2~%|ldE3Fh$iR&VI3pS=eq$2ut-DE#r(RQ4W1%5Vw7>0zgd>o#zwk)$ zWcO1~7^gGn<^_7UvIv_(Wv>IigCElzBoN{g$O{~g0O-ZBvX4YR$V2qox~4Sw?D#*h z2pZoTHKdm=Dq=#-J|@<{)4a|$6n3+p`*eoJ3>-pM;otklZkf^Q7P;veUms0lAB$gk zgMWA61abs>L6l0~2&BsBD!cl1=P1H%Mdv-5%w871=&2kybIWEi7ZrU#C=6@F^H6kM zNDUy36Q%XhFG;o(^D{2!lBE}RjU84=X2;Ot_ns-6KHVf>43!QE%Ac`GnKrl;yQ*c= zy5!xvcf(I!5*TWSKWk<(FH7?s0&xJ|Tu*KD^R7E*gy1JO?gf(B-!e^`UX7nTykP3A zCq97}^yg4?Wb0i&9?Zp7U@ABHQodNnb+Cnej%5tbHFCbUw^Rq%%45wrh%#oOpI!^H zKp~>Xx#~@o%X}`~Q4l+{K5&NpT;21bnn(h+VOt$_UQi8;9U^>8%!B!IU2k&`7AGk> z^RKyTu(TrGU6JNRJVtiCz`CY4G}zLCc40c;YC(Tv_C9Nl@S7#IT)s?%v<}W#iN-85 zr4}8Kz^}Q#p&pp@H^Ab>tFOuk&fqU=oQyzGAa^WdZf#cj%${>8v+I^~g?8a>L`fD( z6R1W>$||vne}{dCO-ZdUf>3{Hg5LfGmtc>#tkK~7EiZ>*wKpNs>rGOV!BCkrhv$RC z3_{8mg*X?c0FVv_ptd^E@~Py)Cl5H)rZ&Pp@M3vqre#;@YyB(ml+5Ze#5)IXt?ckS zjrvBCd3x10{L@phd=ik-v;=IJftdsF<4xNdki@Sox$dpnwgJ|#w~SAXb%v3D1m8VB zy|Px^v8qEP1NS5_sgZGs&1byG#`?6&xtMw!8+Ld}khyN}A&O*-iluxIgIeF+Hk{#) zA6Mq2)wVwSb$87h9JJWwkUCAH(g9K|XUjXNl_CGUcp$|^ z*kzq)dG*N?Ep|x3sw=Br_vKTpc%@TQ?g%iikBPy{f^D2Xe9)J# z<|tgTNSu$zgV_e5kyK@F+&Xb+yT>RKwm^oyR2buBAS@C9X>@cI`BRd+HW= z3kx;0Uxci_h*r=X$m>KPJg6So112wC-KhyD@S_ulbf!F{($MY;Hf6J!H0;z&#UN4F=EHdW*rCq=`R@MQSa;7`9Q)3; zbQ}oV0D@=WYKscfT1Ll?j%eWAZBauCrkU*=jOvMUX3x|$*H_}(mKqgb`jd4waLk^< z5hjT;Li)bm$G>-=wiVy_`QE=VhA z5V%t?Z9TqzeFhI1;RbzoYh4U*rR#+jB{CPs8=D_BJ0(75GmNv0?tw7iR?CcXGZ6ct z&tWJ88Id6l)Qq1ysjVgmF_D7U;p6cM#aT!a?^{3JzW^1f;bUju+q2TKt+^M76#{xq zF&n|i6XGCReP%JY<0PUx3L+gl4osxITga3-Z#(w*26t8$j964Sy*?))TQ+|E zIuBuo)nb$)B0I%Q8pJ;!v}3`~twB;e0X@iMiQChoLmR_hTfx4?TPYFZfqo-+&-+cn z%d=P3R@EwT#?||m932xQR&YfcQx2iDtNL%+rP%FOtuMmBBJ9oNTen*yQ6w7wkh2>R zInt8GYk%{&Tl#ZWF_y&QUR3<|r11c-PnmEIVM130!VHe)ak7f#HZcwTt*X!*J;qGm zlop~YPCaNXXm5S-0=It|mDY@ILI!z8#Ro=3+H8!ySP@etf<3+TZ_ia%LJa#cgB3A` zh=2szE-;0SLB=O;Un@Evbh77x#$oZ>jmC-Tzmn|+PmmFucd4nR3sL4?ksYBSd-Y_Y zu1AvRW_#F=haDtD)B66d@lc2@=us?ob(=-SB7rm}%g-6sP|>4Ta_o3?fQkr4Go%4c%kQ=Wofjs5QoQB}o#j|D6IWSxvV?6uDJb7a&`S`}!^; z@{FteaNIq-|2tlqIH4Yd7Oi^n+Rzk)EyR1%I5Vm0g}wk|p_+?EmmCfKXd=JP;uYAm zsTK`J32E7DDfLf-#2JTzZ&$0co$9Z)*(w7_Tk)D%-wVLO5Q;7IM*|+L%W9tJxWHB&we9Dp5!CQLUwE0}(PLkFeg~CSROEtcgGzlL&}oW%;+w)Mg^c%~UwoJe zUSSB(41q!ss5wwl0YZ;1Ecfv8GRjGuqbdK@mi5i>DA`V?pnra0`p?Oq^yMc4Egcy; z!*mO(eUv$<2PVd!jv#YXUnLU1`yPYTBi2LMPDuU3YPVm%^>a~JV=_y8vg7Ngh6BdW zZzCEt?^MfMNpw+Y0KFT(YUZJUi|gK&301BLQCw|YGGG08WNP_c8*H^S#m@97$^w)> zsidZ*se;MgqsKwosugyP&Tz5U@FqW>;)umlx@bz-M}B@Ob*$F`D-`3(-10Bm7{B%4 zbdwjKtn3#Str+k+y4IiyG(WjCfY?~S@f-G8st%-$OwmL6V^*-tXA~&zZj-|!)71io z1{#N5epgjRt{21Vbr|fSAg_~eyS;GRK1gASyjQqKWWS8PF9i(1=&_Li$j2Dj>7`Ho zbA8FSFJiJ$YtDDsnd-F#)u_(?^Dc1>iWz@0n+Ktb?3c%jNtsyedn$O3MOZ%;kO1|g z^_9Q{;=XRGxH?YFVr1yw>VI~T17q~rp_?N7cH>H~) zHl|FTSYLbleOcLsNZ_cSW7gWY0L>zS6ZrY*rSrg{GOz+p%xG0tLajnC9U$3rJ$V?t zQ=Ko<6=v0>2vtuW^36@Uf@I_ZEzmIW^788Z*P->XvWEA4g~J3ZA6uyo%rFU|ORR7ApN4U{_W0mR*yX`V|kW zVB);(i&NBX_QZ0Zpdqak_OLsP>!*v37RsN7#~Sz9=c6?SJvDK_CU`|)%*gC?a=LCa zZ_TZBabHKyNomL+7>Ja0@@ba%D7}62<1txq39tj(r@8Jn7Iq$~n^e=YtjA$XSF-Ii z+0r>^DUuSoDcpCA`}6Lu8(6Wfz<3W`@k!V{oGT=0GioSZ@V#y<@_dVB`}y&7F|W{| z)MZDHsqB8QgsRP0*=g_o+a?pGrGv6iRs2?OX9eEVH4XbR?u_c02?(qWo5G6!pzSJ3 zr=%C2;FZDDM$2Etf*+|Z6iA49RR=_G1)n7UUntmw%->vl=_adc)U7%3d%Q>N6eO1k z$v~l8$@Xa&gGdZ-&;f>UktaQllXaF4ync3@3guT7&5krSH!r6#+imY|to|GmwAQ_g z6H+645}Vk(BsDYND}MLHc;pN{>e09qc7BK2o~YxwBMuPEGl1aTw&fBbd{IBJR?0a znet_ylDb%wlyb4J{_D2NN3Ne+AC{#)mY8@30mg2@rr?bU$GP+F?Ye<3-EFjjb4AG% zkd?I_%4&GlHH(_DA@(E z?Q$MW0)e+qDx352%*2t&pa(EA50i1he%e(ku3uiZbt8n>%gPMGhkZ)VmX2LM;FYk} zV6M%h`7}7(`O9+^5x@)#ilr#R)#FJe))B1EF?b(b}- zmle6l*X5fUsE{Z(SMc{JuFkHqRbywYG^RP5rOMkyz;BKo}n~8 zlU)!PPF)Cxj2rmXmr_X5r@}i#%NWVPm@7VyxC2Q1$z3X0WrItSg8C}`9|$Tf&DOxfj?Chn;|{r|S3Bly_dL*#ssvU6UqL(Hr%#ip(jlBb zL-tekcw`vy&p0Ud&TdtGA84U*D}PH9Pkz> zVnkFlpzx-DnP2vPS_n+xozZ~Ty|o5t$ke0l)14N*H);3P=hlt(U91Kyvr`+XN!xS8 z6w~FtUOL>~0zb9m^Yg=0GKylO5O`mcRVg$sC=T$wiS#_P&=B{m!yZdcs?f|k2%S(` zz8V*KN9iV4qYKF!8%A zYOHvFX@K*_h3~0foal3XdIyZq_j)L6{j;uao`Gx<9UqwS()r7wcjyoa#qh#ZABk3X z>|RvIO3~FlzT3Kz#raO+TpYfd+3U5}d_`IXP2Yx%oy9Afls!SQuH2(0}6v61}L%!9F;!zK{0$M~vY@N74v@Q8_tEtQ2M7j(d^(*7r z`Rx(vQ#{e8H66_$#lBwTM*rp+S&B@aA$kfb z(*VFJ8BLV|zu`9@{t-imd!w>k$F6%=>9(RXbJJbdudnK$uHpg85WyL-qw$X8qyyED zbB7-OA6K(|Ki*5lv-w?Hw*s=YYq)B$Y1PySbtKrvZa~tzbu%i=DBYsKiwJ)7MT5Z- zk(>P21zLedDa=xSz*05N3hw`xllj{g82Pj&*fyK84El22udZLrbq|%H7gx@$WILRu z2|6u%zCY|++ZyUrjSO2uHE{3CRMDH#yWnsc&l|tt){&dJ*n)-5o%XiwDUXIGF^6c< zm*E~b_NDX3L+{YWq)`_)&DYmAR32m_xoAmvVV8yAhc7wE6-$~v+soWO;vwVN$$pk} zg=kdjD043H>}~bfx9^+Z-puj5dl|Hy(>`g@X3rd1uaQmPDj^b~z*vrEIpK~)A4%c- zWUBZNEFJK{V^9`7i#Zr47W>Ru?UKtP4KDcyqXp38xOpVJ;HD7k2LUE!e?IkF8uXu*}qIu-@-lc?#Uko;j>HfnQ&yDkFm-CxVTsy^A+K;i8(jv1hkf${Yx>v@lb_ zGL#M%%|4p=>@j!XnTUKm+KvHD?pZa|FFj@w)0dC;YknwrgB2Pi`KK|Rnk5(?(j7af zRUK^hvxdcdZG8E0z4}q>(7HacXzUzRY*tQCwv`!r42^It8M{je@xG2UrSz!_@_bCg z)n*ZCwy=jRSF2Eud!XmLXi7g%x$^Fa2HAd5cU%JA>=fyuw-0F9aXQZVx!omPz%UyW zN%DeCvNyg=)r0f`B+UiKb0``k_%@ZowJFk~2t4nm4$qF(e~^9YTy&_cW~ik`{Pm2D z|5pDQ$=}$fK4bPOAk{Q~#h)Cc`=xvuQe=!s&OjMY{;cOFANp0mwffn(dh8Ac?2<=hy-?XJ{m86Z!VmHiTi|K#YzK_K{ zZRO)^44G@>xa|^ck5FY|3^dM^Jx$z)c6FMFHd%IR;^?6bH^Y-9t%je%7Q5l|SU;!v zpWaetMeGtp+2XHW1Om6Rw(>DHTzQ^YXnJTO#&DkzkF0T5^(tTBcA;2L(pGNYmHdFe z6i3^4(=gliOZl9?2mm6(Ea^rhAGwEyk9}^p!oEdd#Gez(w;PkSVC*`;cZJr@@t!zS zCR*|7Y-}5V!8GzIY@%2s^TX2GDPPLxtvh`mVPPHE4Hv2xgHWR=O{n^BFF@;&tRuC* zPQc&d7tU*OgL_Ob-`_R%_zh{P@GKE8ItRtAucsz8BG(`;=NIlG?>E~+is&;n z+aJDketl?dqGey)q#YChxIGh+Jmhe{Z>9y z&H9N?M4C6H0{kcPdt(3 za9VNM_2h^$o3ht^Dc3_B;Z*r(8_3E{?CfeJ7Zp9+Q!yr5^^rf42YM@UwNY84$F2jd z+F<^x4?tNN*wZ1cZ*5e3H)jIwNSggMuuNaR{reQ07E-X#swZ9nP68PlZq2|NU+ev^ zvf08U*?3%HL6yP4vXxf1Hr#KPSoDt^%CS$KPm~$xh}fX|V-XncNktp3n!$Di?q(+zviNbL<<~$_QGUxi}EWWYph@y>&P_U15SmBm3 zo2u-L{gQDwqUw1EE zd{wlA%ToKWOAIHo=oD+nt9D%b_nChsvgUv)>X;_`FV^nD?ngRXGaa*mZzs2xS#V`F zc)<|$8tt7qTv0X zNw8UVOa)5sQ~34DgNR+LD@2X%_i550G}S~Aj*y{6&pP{150$2Q(iqwm_f zZE}$y7C}tvxpu z?Z!<<+FP;}DGA_AMTeJk#8I@z*kMH>Gc5J@XZOVJepE4R{ z3|_pL5i4XRU`a55f|$dTK%w~ZDuP-D&BnHsQT1t-d}R@;<-xgY_)okSI3L(V{fLkN z>vLyqy;R5VpQdqAuu1nfIz#Dand5ziNw;$k_-`?jVK}k#hOK<6Ci2EVaKmUx!Uv3D z5<>f4X_U-|)mvP+=cp^Re=gvC6c)NTDYrJ5$getomBED!n2s}PB`2qu&z((-v@Ql> z5(?+loVz<-V&+8?d8_kBHVC*l(g>d=m-qLv0!{4xh^Fg5Ponn*Kl*M~iO6_K{wKj{ zGXq9sGZTb~LkwCTyxre}RsYJ?el%tzAy?%669P@*CFUvnU zdKR_C5JD5*w}ZhCg(o#iuRL?ssbt?$5&ZEntp31OK0Uz@K-YsEVYTI7bM0;p3Q2r_P3}!8cNRyRZNEM$v}dl}vGV@4!|!@qu7c=oZey4@#Z^{t5S)dtoEVbccVQnLrEmEaK* z3vMTCPSCnq^*gIAjhHfxm^7jAj+5`R8jOyvy1sXMmCam%4CZpxTx|Km1Mh2WG9GLg zPTIATIoY7P8Ao=loxV3*T_BaYtdd%d;YuP-0>3e5@L-epfHflpF?(XabDdj%ZuLt2 z-XEeTAtRh)6?-yv((2s2H!R-CK(BrKi~CB)`Mj~PX>eT zX>Nv|uNtRXNl93yraIk_leNL7!mpLKo2&*O79YOtmXh-O)I5Hcm7aJJU!b+CpWMc- z@22bb4HYyl!Pb}&b}9b%nqub2%iD-1e~oPZQf$a#eb3=zv*yn!KQ%A#TDME-_^5#7 zraUt+sDCW|pZ2aTtf^~TFE_QcMNPZAE0k2y)0<~2pjIFy7|@OT*wzA8bK??-qJk9? z6v8!t?O*oKKL4sEN!3%N5r^T8pFQ!li z|3HaE#G-SI+v{`HtE5$yqC0Rmh$P=7RysZwp!7d=bbm@?BOx~79Yk(HeKaXB6wH?C z&*aDgQj+7`5JcRp5xa}kp3=7kcdK)mcc5*{oAzUfoM~P(YYF`c(Th*@k;{&(wjMD? zDubw5t1B|5Q6i!HdB$vxEZ!|Q`=u~@CAcq-+H`Ze`Nubx&bE&=DZHvNO45Spt7Iv*g&X$$nb z)dgw`&IoPL0bgI=X!&M@yRYrQ%pC+dEXTq!1L;I5qJ3Ubym2!NM}GrBCgle5rt)-l z!hgB`x?6Oj=p2Gj3ebQlNk5pdqP+uUpqFIARKR)@N0!Kb`GTlM~))zi%LClbgLz3ojQgsS_F=H|%n}8#cag1&`;f_BZz#RNf5o!! z!9Dc8xx6nSy73WZYMO1Q@x@Tc<*cLs1DA;Xq15SXadv|UCuWNBfjel2Gccw6r;^2Y z|NctaS8VOrM+i@;MPuhIOo<$R`cPk7T-WL6iDoSAmrYbwv@~P^&U-IWw~6VB z$SLrLZA4W;&2;C*rU@Zpue@Y9w1rMtz{^2qOR2q$oeyid|V{ zJ&zAnrrn>-isO)-AW3FmFEA*#PFn|X}Pwv2tGsu~cU6Z-6O{0o9?9Q#o1>#Cl78-0A`nn(U@NnomqH_I1x3o)%zEhVwSE{4Tpz3B z(o7l^qP8x}9e_O#Sk!Ea!HNDxXjO?c6*3BpOZ90WJV6zzpgugm-2hS7-nyv&QDH)k zKmA~v`gO1YX}^ng_CtP*)K%ykM_6FS=185VZ4GYF;lXsg=2#L28G0>jcnuPBX<{I| zYeczP>8Z4#DaQ*q&h0k5zzT0-Dl#Hps;xy^K;7nDCXdC{e=%2cZlw;tnY0R4^}QoG z2`}4qAxaTd0SI1waya|e^gT?Ozw+dFhF6$hngW`;3t~83A94jt$FB$20Z>(DVOhVxm%<3=Nmk|wnPZ$uX2`W zs@2Bwamg`z*LXGE0JFu}I*NhG>8d=NGQ4&k&HSNX<~?k6i(~s+J{!GLT(=iEF(%TD zw2`z60j(O%<4)9`tG_y6{l-+^H&zpp&ZVJxWDY`%hs?3>;uBd-EX<93QQ6$Pu%m^b zo7U@Qh`zws&Jr@KLe{sSJ~%jgX%09-OJ<06OW!^=V?ORQI@? z2{i?gS6+QQM}PjvKa<^7s4v$4Ue1CHl4$eEw!PpeVw+TpW2WE%iDVAn=i}nUp}wRh zhEFaCVlHkJy>!+zh$Gca{1Yf7`E&ux%8R5QFD2}m8tg#}aqgIp@Kg%+M34D9=3h|H zCJxtO{f1~~IM=1gxkoVw@}ggVQepC#xY$-(g8~rEOt!EE>-U8A?1KtsS)fMS58`c8 zSM`|+6Mo_+yMfSjK=B@8JkuqWt>$mo_iL#TyF;pZDh4m>4K`Xk6CGUua!nuM0g!)t zhYW^H4J`fyYOelfA{k;in(Ee+#&LxwswcKyG<}LsZp#+opC7CQZfnPW2PXE6q+KI- zTp9>x1Bg*HC6YZ_C{%2CmRZbt7d+y6_lA1eY}u=!z zZ^#o6S?cj+rgNXQIQu=IDLCa)S%3BH4R9>&hic&|zM)9q-P|yu1OejJy2&g3LS>AZ zVYCjqZh(kDSVET=PEgJHl&aME&TJ^qi0W@#)xr)%)#x7fwf+Xtd+?%@?ukB+Z@4Mg za@ucI>;-Xw}o&2^ zth)&B?bccKHol=j@F{Mv;{d8@!jO&ilRI7MB2gz(-vbT=z4>~D{;a~pD2l&LNK0yi z-2f3+`!TIZU=%@>lm5OM-GNJtjdd8OT6)k)H0Ad|cT12Rae%${h>n z66bX1`0i)lo^I+ZwKfd8e*_>&{$k*Wz2mvgJ9=@jD};{xt%mE;x@ltn51iw#PoQ}# zF08|+$5obc%2I7H0`ND(ZBoQ6&-9W-g&xeLbiGoJ96cChe5Sy-ul-RY?#%0`LMP0l zQX^tGhS~>VK0jYVBfLkE!N<|seK6FQQ8f$@9G#rh$MOv$YcJJx9_|AHk3AiaLbl?B z;hU?KK#FRWUnsGEA)l!>-wSqw*g+&N>PHJF?{Ax-u}^frX9P)%W>%>Aj>E+pte5`4 z^amc1syTC#13hM&{`&hBut&*@2{$Zel+D!HR?X$U@4!Z67C!yU%3O|A%IR@HL0{#4JGgh< z5f1B%bJq56s3_kw@0-z9-hmSD#~!79_*pU-$?ys9Nmywa^F3B)Rt9f^?FEs9Fqwc_ zU*DXnoXiGQymf?XsN3ns@Mdc}6%BA29F_sn;H~nwj4ClVR#^6qq_yN})1sPDtK}P# z6WOKH_s*7UPZsY$wYE(?(XZnhK2G{+LMK5BiTthP*b)18Lp#V{!4Uu)$dq!SswMn{Pk#DTsJC5|cp7`qng| zu48H(jGey*IhT8Oxm%`AH&Y<%)`3D7P)uMf* z8C=-$>%M?q=h8uyG~e#3R}j{rjQ&U04#i(xpYt=xu#v1qDZ z*?{H#kZx|o!G&0e)5J=*^r5(0D^Ww`pM%oZm3o5zvn3G zbsv2QW7;l95-z%Zg(c4+*%!u)Yntd|r%u!gw_M&mCQB`fqqk{!!ztzBL$M zN>f~65R8$Qq(tLHhYqntxV`X(F>mF<`i{fVap+D=k1>Np^65*_ncS%rmNSkP)C~C( zTUMgq=7odohu0k-<#@4{3VpLzgWVj9qN)6CJwOnx_PicD#n}^gTly@Ni{>TePQKov zKiZ*v+r~cUhI;C9wrIf28&d0AGpJ}NR8L#=NdvYOmQAkGI2bd0)lcT_?RJSmMNz9u z;mCj-J_4~y_`MVJn_uk5!@md~NJ?Y~Zfs(#?cN9ev zGhuh~l(Nr%17tPN>{BGYL3limd8GN`S~xn(>2OWYX#_**T_Z%JVeOPqUma^eY#K}% z8b6n>aJwJcBL;E4k8nGTokrV>b5*sey!5WipQ9!Oo0D5uR$SS9)<$$U7u?OFa{C`* ze#_G0(DOFq5V2&0+dT!JQX^lZh33X_X7}pY^*%dISz~~gT(6kA!e8taPKbzh6W~PN zAvWC@-Qu@>DQo!!IFpsz%%3g!D`(G8Q2yJXgZPPcFA-b!G9EsRx&u0Fh5GF^NinDg zC7;iu@j2J-KWA{Ep}a}#xHV;EOFP-qLm@C^kef;^wngg-OVH}_H$b4OEf6y+0EWMZXA3>E&oXVHvbCw z$N0}*e=_hV1Aj8`Cj: + canvas.before: + Color: + rgba: self.background_color or self.theme_cls.primary_color + Rectangle: + size:self.size + pos:self.pos + + PushMatrix + Translate: + xy: (dp(2),0) if self.orientation == 'vertical' else (0,dp(2)) + canvas.after: + PopMatrix + Color: + rgba: self.divider_color or self.theme_cls.divider_color + Rectangle: + size:(dp(1),self.height) if self.orientation == 'horizontal' else (self.width,dp(1)) + pos:self.pos + Color: + rgba: [0,0,0,0] if self.collapse else (self.indicator_color or self.theme_cls.accent_color) + Rectangle: + size:(dp(2),self.height) if self.orientation == 'vertical' else (self.width,dp(2)) + pos:self.pos + +[MDAccordionItemTitle@MDAccordionItemTitleLayout]: + padding: '12dp' + spacing: '12dp' + orientation: 'horizontal' if ctx.item.orientation=='vertical' else 'vertical' + canvas: + PushMatrix + Translate: + xy: (-dp(2),0) if ctx.item.orientation == 'vertical' else (0,-dp(2)) + + Color: + rgba: self.background_color or self.theme_cls.primary_color + Rectangle: + size:self.size + pos:self.pos + + canvas.after: + Color: + rgba: [0,0,0,0] if ctx.item.collapse else (ctx.item.indicator_color or self.theme_cls.accent_color) + Rectangle: + size:(dp(2),self.height) if ctx.item.orientation == 'vertical' else (self.width,dp(2)) + pos:self.pos + PopMatrix + MDLabel: + id:_icon + theme_text_color:ctx.item.title_theme_color if ctx.item.icon else 'Custom' + text_color:ctx.item.title_color if ctx.item.icon else [0,0,0,0] + text: md_icons[ctx.item.icon if ctx.item.icon else 'menu'] + font_style:'Icon' + size_hint: (None,1) if ctx.item.orientation == 'vertical' else (1,None) + size: ((self.texture_size[0],1) if ctx.item.orientation == 'vertical' else (1,self.texture_size[1])) \ + if ctx.item.icon else (0,0) + text_size: (self.width, None) if ctx.item.orientation=='vertical' else (None,self.width) + canvas.before: + PushMatrix + Rotate: + angle: 90 if ctx.item.orientation == 'horizontal' else 0 + origin: self.center + canvas.after: + PopMatrix + MDLabel: + id:_label + theme_text_color:ctx.item.title_theme_color + text_color:ctx.item.title_color + text: ctx.item.title + font_style:ctx.item.font_style + text_size: (self.width, None) if ctx.item.orientation=='vertical' else (None,self.width) + canvas.before: + PushMatrix + Rotate: + angle: 90 if ctx.item.orientation == 'horizontal' else 0 + origin: self.center + canvas.after: + PopMatrix + + MDLabel: + id:_expand_icon + theme_text_color:ctx.item.title_theme_color + text_color:ctx.item.title_color + font_style:'Icon' + size_hint: (None,1) if ctx.item.orientation == 'vertical' else (1,None) + size: (self.texture_size[0],1) if ctx.item.orientation == 'vertical' else (1,self.texture_size[1]) + text:md_icons[ctx.item.icon_collapsed if ctx.item.collapse else ctx.item.icon_expanded] + halign: 'right' if ctx.item.orientation=='vertical' else 'center' + #valign: 'middle' if ctx.item.orientation=='vertical' else 'bottom' + canvas.before: + PushMatrix + Rotate: + angle: 90 if ctx.item.orientation == 'horizontal' else 0 + origin:self.center + canvas.after: + PopMatrix + +''') + +if __name__ == '__main__': + from kivy.app import App + from kivymd.theming import ThemeManager + + class AccordionApp(App): + theme_cls = ThemeManager() + + def build(self): + # self.theme_cls.primary_palette = 'Indigo' + return Builder.load_string(""" +#:import MDLabel kivymd.label.MDLabel +#:import MDList kivymd.list.MDList +#:import OneLineListItem kivymd.list.OneLineListItem +BoxLayout: + spacing: '64dp' + MDAccordion: + orientation:'vertical' + MDAccordionItem: + title:'Item 1' + icon: 'home' + ScrollView: + MDList: + OneLineListItem: + text: "Subitem 1" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + OneLineListItem: + text: "Subitem 2" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + OneLineListItem: + text: "Subitem 3" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + MDAccordionItem: + title:'Item 2' + icon: 'globe' + ScrollView: + MDList: + OneLineListItem: + text: "Subitem 4" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + OneLineListItem: + text: "Subitem 5" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + OneLineListItem: + text: "Subitem 6" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + MDAccordionItem: + title:'Item 3' + ScrollView: + MDList: + OneLineListItem: + text: "Subitem 7" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + OneLineListItem: + text: "Subitem 8" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + OneLineListItem: + text: "Subitem 9" + theme_text_color: 'Custom' + text_color: [1,1,1,1] + MDAccordion: + orientation:'horizontal' + MDAccordionItem: + title:'Item 1' + icon: 'home' + MDLabel: + text:'Content 1' + theme_text_color:'Primary' + MDAccordionItem: + title:'Item 2' + MDLabel: + text:'Content 2' + theme_text_color:'Primary' + MDAccordionItem: + title:'Item 3' + MDLabel: + text:'Content 3' + theme_text_color:'Primary' +""") + + + AccordionApp().run() diff --git a/src/kivymd/backgroundcolorbehavior.py b/src/kivymd/backgroundcolorbehavior.py new file mode 100644 index 00000000..bd98f129 --- /dev/null +++ b/src/kivymd/backgroundcolorbehavior.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from kivy.lang import Builder +from kivy.properties import BoundedNumericProperty, ReferenceListProperty +from kivy.uix.widget import Widget + +Builder.load_string(''' + + canvas: + Color: + rgba: self.background_color + Rectangle: + size: self.size + pos: self.pos +''') + + +class BackgroundColorBehavior(Widget): + r = BoundedNumericProperty(1., min=0., max=1.) + g = BoundedNumericProperty(1., min=0., max=1.) + b = BoundedNumericProperty(1., min=0., max=1.) + a = BoundedNumericProperty(0., min=0., max=1.) + + background_color = ReferenceListProperty(r, g, b, a) diff --git a/src/kivymd/bottomsheet.py b/src/kivymd/bottomsheet.py new file mode 100644 index 00000000..901322b0 --- /dev/null +++ b/src/kivymd/bottomsheet.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +''' +Bottom Sheets +============= + +`Material Design spec Bottom Sheets page `_ + +In this module there's the :class:`MDBottomSheet` class which will let you implement your own Material Design Bottom Sheets, and there are two classes called :class:`MDListBottomSheet` and :class:`MDGridBottomSheet` implementing the ones mentioned in the spec. + +Examples +-------- + +.. note:: + + These widgets are designed to be called from Python code only. + +For :class:`MDListBottomSheet`: + +.. code-block:: python + + bs = MDListBottomSheet() + bs.add_item("Here's an item with text only", lambda x: x) + bs.add_item("Here's an item with an icon", lambda x: x, icon='md-cast') + bs.add_item("Here's another!", lambda x: x, icon='md-nfc') + bs.open() + +For :class:`MDListBottomSheet`: + +.. code-block:: python + + bs = MDGridBottomSheet() + bs.add_item("Facebook", lambda x: x, icon_src='./assets/facebook-box.png') + bs.add_item("YouTube", lambda x: x, icon_src='./assets/youtube-play.png') + bs.add_item("Twitter", lambda x: x, icon_src='./assets/twitter.png') + bs.add_item("Da Cloud", lambda x: x, icon_src='./assets/cloud-upload.png') + bs.add_item("Camera", lambda x: x, icon_src='./assets/camera.png') + bs.open() + +API +--- +''' +from kivy.clock import Clock +from kivy.lang import Builder +from kivy.metrics import dp +from kivy.properties import ObjectProperty, StringProperty +from kivy.uix.behaviors import ButtonBehavior +from kivy.uix.boxlayout import BoxLayout +from kivy.uix.floatlayout import FloatLayout +from kivy.uix.gridlayout import GridLayout +from kivy.uix.modalview import ModalView +from kivy.uix.scrollview import ScrollView +from kivymd.backgroundcolorbehavior import BackgroundColorBehavior +from kivymd.label import MDLabel +from kivymd.list import MDList, OneLineListItem, ILeftBody, \ + OneLineIconListItem +from kivymd.theming import ThemableBehavior + +Builder.load_string(''' + + background: 'atlas://data/images/defaulttheme/action_group_disabled' + background_color: 0,0,0,.8 + sv: sv + upper_padding: upper_padding + gl_content: gl_content + ScrollView: + id: sv + do_scroll_x: False + BoxLayout: + size_hint_y: None + orientation: 'vertical' + padding: 0,1,0,0 + height: upper_padding.height + gl_content.height + 1 # +1 to allow overscroll + BsPadding: + id: upper_padding + size_hint_y: None + height: root.height - min(root.width * 9 / 16, gl_content.height) + on_release: root.dismiss() + BottomSheetContent: + id: gl_content + size_hint_y: None + background_color: root.theme_cls.bg_normal + cols: 1 +''') + + +class BsPadding(ButtonBehavior, FloatLayout): + pass + + +class BottomSheetContent(BackgroundColorBehavior, GridLayout): + pass + + +class MDBottomSheet(ThemableBehavior, ModalView): + sv = ObjectProperty() + upper_padding = ObjectProperty() + gl_content = ObjectProperty() + dismiss_zone_scroll = 1000 # Arbitrary high number + + def open(self, *largs): + super(MDBottomSheet, self).open(*largs) + Clock.schedule_once(self.set_dismiss_zone, 0) + + def set_dismiss_zone(self, *largs): + # Scroll to right below overscroll threshold: + self.sv.scroll_y = 1 - self.sv.convert_distance_to_scroll(0, 1)[1] + + # This is a line where m (slope) is 1/6 and b (y-intercept) is 80: + self.dismiss_zone_scroll = self.sv.convert_distance_to_scroll( + 0, (self.height - self.upper_padding.height) * (1 / 6.0) + 80)[ + 1] + # Uncomment next line if the limit should just be half of + # visible content on open (capped by specs to 16 units to width/9: + # self.dismiss_zone_scroll = (self.sv.convert_distance_to_scroll( + # 0, self.height - self.upper_padding.height)[1] * 0.50) + + # Check if user has overscrolled enough to dismiss bottom sheet: + self.sv.bind(on_scroll_stop=self.check_if_scrolled_to_death) + + def check_if_scrolled_to_death(self, *largs): + if self.sv.scroll_y >= 1 + self.dismiss_zone_scroll: + self.dismiss() + + def add_widget(self, widget, index=0): + if type(widget) == ScrollView: + super(MDBottomSheet, self).add_widget(widget, index) + else: + self.gl_content.add_widget(widget,index) + + +Builder.load_string(''' +#:import md_icons kivymd.icon_definitions.md_icons + + font_style: 'Icon' + text: u"{}".format(md_icons[root.icon]) + halign: 'center' + theme_text_color: 'Primary' + valign: 'middle' +''') + + +class ListBSIconLeft(ILeftBody, MDLabel): + icon = StringProperty() + + +class MDListBottomSheet(MDBottomSheet): + mlist = ObjectProperty() + + def __init__(self, **kwargs): + super(MDListBottomSheet, self).__init__(**kwargs) + self.mlist = MDList() + self.gl_content.add_widget(self.mlist) + Clock.schedule_once(self.resize_content_layout, 0) + + def resize_content_layout(self, *largs): + self.gl_content.height = self.mlist.height + + def add_item(self, text, callback, icon=None): + if icon: + item = OneLineIconListItem(text=text, on_release=callback) + item.add_widget(ListBSIconLeft(icon=icon)) + else: + item = OneLineListItem(text=text, on_release=callback) + + item.bind(on_release=lambda x: self.dismiss()) + self.mlist.add_widget(item) + + +Builder.load_string(''' + + orientation: 'vertical' + padding: 0, dp(24), 0, 0 + size_hint_y: None + size: dp(64), dp(96) + BoxLayout: + padding: dp(8), 0, dp(8), dp(8) + size_hint_y: None + height: dp(48) + Image: + source: root.source + MDLabel: + font_style: 'Caption' + theme_text_color: 'Secondary' + text: root.caption + halign: 'center' +''') + + +class GridBSItem(ButtonBehavior, BoxLayout): + source = StringProperty() + + caption = StringProperty() + + +class MDGridBottomSheet(MDBottomSheet): + def __init__(self, **kwargs): + super(MDGridBottomSheet, self).__init__(**kwargs) + self.gl_content.padding = (dp(16), 0, dp(16), dp(24)) + self.gl_content.height = dp(24) + self.gl_content.cols = 3 + + def add_item(self, text, callback, icon_src): + item = GridBSItem( + caption=text, + on_release=callback, + source=icon_src + ) + item.bind(on_release=lambda x: self.dismiss()) + if len(self.gl_content.children) % 3 == 0: + self.gl_content.height += dp(96) + self.gl_content.add_widget(item) diff --git a/src/kivymd/button.py b/src/kivymd/button.py new file mode 100644 index 00000000..75016716 --- /dev/null +++ b/src/kivymd/button.py @@ -0,0 +1,453 @@ +# -*- coding: utf-8 -*- +''' +Buttons +======= + +`Material Design spec, Buttons page `_ + +`Material Design spec, Buttons: Floating Action Button page `_ + +TO-DO: DOCUMENT MODULE +''' +from kivy.clock import Clock +from kivy.lang import Builder +from kivy.metrics import dp +from kivy.utils import get_color_from_hex +from kivy.properties import StringProperty, BoundedNumericProperty, \ + ListProperty, AliasProperty, BooleanProperty, NumericProperty, \ + OptionProperty +from kivy.uix.anchorlayout import AnchorLayout +from kivy.uix.behaviors import ButtonBehavior +from kivy.uix.boxlayout import BoxLayout +from kivy.animation import Animation +from kivymd.backgroundcolorbehavior import BackgroundColorBehavior +from kivymd.ripplebehavior import CircularRippleBehavior, \ + RectangularRippleBehavior +from kivymd.elevationbehavior import ElevationBehavior, \ + RoundElevationBehavior +from kivymd.theming import ThemableBehavior +from kivymd.color_definitions import colors + +Builder.load_string(''' +#:import md_icons kivymd.icon_definitions.md_icons +#:import colors kivymd.color_definitions.colors +#:import MDLabel kivymd.label.MDLabel + + size_hint: (None, None) + size: (dp(48), dp(48)) + padding: dp(12) + theme_text_color: 'Primary' + MDLabel: + id: _label + font_style: 'Icon' + text: u"{}".format(md_icons[root.icon]) + halign: 'center' + theme_text_color: root.theme_text_color + text_color: root.text_color + opposite_colors: root.opposite_colors + valign: 'middle' + + + canvas: + Color: + #rgba: self.background_color if self.state == 'normal' else self._bg_color_down + rgba: self._current_button_color + Rectangle: + size: self.size + pos: self.pos + size_hint: (None, None) + height: dp(36) + width: _label.texture_size[0] + dp(16) + padding: (dp(8), 0) + theme_text_color: 'Custom' + text_color: root.theme_cls.primary_color + MDLabel: + id: _label + text: root._text + font_style: 'Button' + size_hint_x: None + text_size: (None, root.height) + height: self.texture_size[1] + theme_text_color: root.theme_text_color + text_color: root.text_color + valign: 'middle' + halign: 'center' + opposite_colors: root.opposite_colors + +: + canvas: + Clear + Color: + rgba: self.background_color_disabled if self.disabled else \ + (self.background_color if self.state == 'normal' else self.background_color_down) + Rectangle: + size: self.size + pos: self.pos + + anchor_x: 'center' + anchor_y: 'center' + background_color: root.theme_cls.primary_color + background_color_down: root.theme_cls.primary_dark + background_color_disabled: root.theme_cls.divider_color + theme_text_color: 'Primary' + MDLabel: + id: label + font_style: 'Button' + text: root._text + size_hint: None, None + width: root.width + text_size: self.width, None + height: self.texture_size[1] + theme_text_color: root.theme_text_color + text_color: root.text_color + opposite_colors: root.opposite_colors + disabled: root.disabled + halign: 'center' + valign: 'middle' + +: + canvas: + Clear + Color: + rgba: self.background_color_disabled if self.disabled else \ + (self.background_color if self.state == 'normal' else self.background_color_down) + Ellipse: + size: self.size + pos: self.pos + + anchor_x: 'center' + anchor_y: 'center' + background_color: root.theme_cls.accent_color + background_color_down: root.theme_cls.accent_dark + background_color_disabled: root.theme_cls.divider_color + theme_text_color: 'Primary' + MDLabel: + id: label + font_style: 'Icon' + text: u"{}".format(md_icons[root.icon]) + size_hint: None, None + size: dp(24), dp(24) + text_size: self.size + theme_text_color: root.theme_text_color + text_color: root.text_color + opposite_colors: root.opposite_colors + disabled: root.disabled + halign: 'center' + valign: 'middle' +''') + + +class MDIconButton(CircularRippleBehavior, ButtonBehavior, BoxLayout): + icon = StringProperty('circle') + theme_text_color = OptionProperty(None, allownone=True, + options=['Primary', 'Secondary', 'Hint', + 'Error', 'Custom']) + text_color = ListProperty(None, allownone=True) + opposite_colors = BooleanProperty(False) + + +class MDFlatButton(ThemableBehavior, RectangularRippleBehavior, + ButtonBehavior, BackgroundColorBehavior, AnchorLayout): + width = BoundedNumericProperty(dp(64), min=dp(64), max=None, + errorhandler=lambda x: dp(64)) + + text_color = ListProperty() + + text = StringProperty('') + theme_text_color = OptionProperty(None, allownone=True, + options=['Primary', 'Secondary', 'Hint', + 'Error', 'Custom']) + text_color = ListProperty(None, allownone=True) + + _text = StringProperty('') + _bg_color_down = ListProperty([0, 0, 0, 0]) + _current_button_color = ListProperty([0, 0, 0, 0]) + + def __init__(self, **kwargs): + super(MDFlatButton, self).__init__(**kwargs) + self._current_button_color = self.background_color + self._bg_color_down = get_color_from_hex( + colors[self.theme_cls.theme_style]['FlatButtonDown']) + + Clock.schedule_once(lambda x: self.ids._label.bind( + texture_size=self.update_width_on_label_texture)) + + def update_width_on_label_texture(self, instance, value): + self.ids._label.width = value[0] + + def on_text(self, instance, value): + self._text = value.upper() + + def on_touch_down(self, touch): + if touch.is_mouse_scrolling: + return False + elif not self.collide_point(touch.x, touch.y): + return False + elif self in touch.ud: + return False + elif self.disabled: + return False + else: + self.fade_bg = Animation(duration=.2, _current_button_color=get_color_from_hex( + colors[self.theme_cls.theme_style]['FlatButtonDown'])) + self.fade_bg.start(self) + return super(MDFlatButton, self).on_touch_down(touch) + + def on_touch_up(self, touch): + if touch.grab_current is self: + self.fade_bg.stop_property(self, '_current_button_color') + Animation(duration=.05, _current_button_color=self.background_color).start(self) + return super(MDFlatButton, self).on_touch_up(touch) + + +class MDRaisedButton(ThemableBehavior, RectangularRippleBehavior, + ElevationBehavior, ButtonBehavior, + AnchorLayout): + _bg_color_down = ListProperty([]) + background_color = ListProperty() + background_color_down = ListProperty() + background_color_disabled = ListProperty() + theme_text_color = OptionProperty(None, allownone=True, + options=['Primary', 'Secondary', 'Hint', + 'Error', 'Custom']) + text_color = ListProperty(None, allownone=True) + + def _get_bg_color_down(self): + return self._bg_color_down + + def _set_bg_color_down(self, color, alpha=None): + if len(color) == 2: + self._bg_color_down = get_color_from_hex( + colors[color[0]][color[1]]) + if alpha: + self._bg_color_down[3] = alpha + elif len(color) == 4: + self._bg_color_down = color + + background_color_down = AliasProperty(_get_bg_color_down, + _set_bg_color_down, + bind=('_bg_color_down',)) + + _bg_color_disabled = ListProperty([]) + + def _get_bg_color_disabled(self): + return self._bg_color_disabled + + def _set_bg_color_disabled(self, color, alpha=None): + if len(color) == 2: + self._bg_color_disabled = get_color_from_hex( + colors[color[0]][color[1]]) + if alpha: + self._bg_color_disabled[3] = alpha + elif len(color) == 4: + self._bg_color_disabled = color + + background_color_disabled = AliasProperty(_get_bg_color_disabled, + _set_bg_color_disabled, + bind=('_bg_color_disabled',)) + + _elev_norm = NumericProperty(2) + + def _get_elev_norm(self): + return self._elev_norm + + def _set_elev_norm(self, value): + self._elev_norm = value if value <= 12 else 12 + self._elev_raised = (value + 6) if value + 6 <= 12 else 12 + self.elevation = self._elev_norm + + elevation_normal = AliasProperty(_get_elev_norm, _set_elev_norm, + bind=('_elev_norm',)) + + _elev_raised = NumericProperty(8) + + def _get_elev_raised(self): + return self._elev_raised + + def _set_elev_raised(self, value): + self._elev_raised = value if value + self._elev_norm <= 12 else 12 + + elevation_raised = AliasProperty(_get_elev_raised, _set_elev_raised, + bind=('_elev_raised',)) + + text = StringProperty() + + _text = StringProperty() + + def __init__(self, **kwargs): + super(MDRaisedButton, self).__init__(**kwargs) + self.elevation_press_anim = Animation(elevation=self.elevation_raised, + duration=.2, t='out_quad') + self.elevation_release_anim = Animation( + elevation=self.elevation_normal, duration=.2, t='out_quad') + + def on_disabled(self, instance, value): + if value: + self.elevation = 0 + else: + self.elevation = self.elevation_normal + super(MDRaisedButton, self).on_disabled(instance, value) + + def on_touch_down(self, touch): + if not self.disabled: + if touch.is_mouse_scrolling: + return False + if not self.collide_point(touch.x, touch.y): + return False + if self in touch.ud: + return False + Animation.cancel_all(self, 'elevation') + self.elevation_press_anim.start(self) + return super(MDRaisedButton, self).on_touch_down(touch) + + def on_touch_up(self, touch): + if not self.disabled: + if touch.grab_current is not self: + return super(ButtonBehavior, self).on_touch_up(touch) + Animation.cancel_all(self, 'elevation') + self.elevation_release_anim.start(self) + else: + Animation.cancel_all(self, 'elevation') + self.elevation = 0 + return super(MDRaisedButton, self).on_touch_up(touch) + + def on_text(self, instance, text): + self._text = text.upper() + + def on__elev_norm(self, instance, value): + self.elevation_release_anim = Animation(elevation=value, + duration=.2, t='out_quad') + + def on__elev_raised(self, instance, value): + self.elevation_press_anim = Animation(elevation=value, + duration=.2, t='out_quad') + + +class MDFloatingActionButton(ThemableBehavior, CircularRippleBehavior, + RoundElevationBehavior, ButtonBehavior, + AnchorLayout): + _bg_color_down = ListProperty([]) + background_color = ListProperty() + background_color_down = ListProperty() + background_color_disabled = ListProperty() + theme_text_color = OptionProperty(None, allownone=True, + options=['Primary', 'Secondary', 'Hint', + 'Error', 'Custom']) + text_color = ListProperty(None, allownone=True) + + def _get_bg_color_down(self): + return self._bg_color_down + + def _set_bg_color_down(self, color, alpha=None): + if len(color) == 2: + self._bg_color_down = get_color_from_hex( + colors[color[0]][color[1]]) + if alpha: + self._bg_color_down[3] = alpha + elif len(color) == 4: + self._bg_color_down = color + + background_color_down = AliasProperty(_get_bg_color_down, + _set_bg_color_down, + bind=('_bg_color_down',)) + + _bg_color_disabled = ListProperty([]) + + def _get_bg_color_disabled(self): + return self._bg_color_disabled + + def _set_bg_color_disabled(self, color, alpha=None): + if len(color) == 2: + self._bg_color_disabled = get_color_from_hex( + colors[color[0]][color[1]]) + if alpha: + self._bg_color_disabled[3] = alpha + elif len(color) == 4: + self._bg_color_disabled = color + + background_color_disabled = AliasProperty(_get_bg_color_disabled, + _set_bg_color_disabled, + bind=('_bg_color_disabled',)) + icon = StringProperty('android') + + _elev_norm = NumericProperty(6) + + def _get_elev_norm(self): + return self._elev_norm + + def _set_elev_norm(self, value): + self._elev_norm = value if value <= 12 else 12 + self._elev_raised = (value + 6) if value + 6 <= 12 else 12 + self.elevation = self._elev_norm + + elevation_normal = AliasProperty(_get_elev_norm, _set_elev_norm, + bind=('_elev_norm',)) + + # _elev_raised = NumericProperty(12) + _elev_raised = NumericProperty(6) + + def _get_elev_raised(self): + return self._elev_raised + + def _set_elev_raised(self, value): + self._elev_raised = value if value + self._elev_norm <= 12 else 12 + + elevation_raised = AliasProperty(_get_elev_raised, _set_elev_raised, + bind=('_elev_raised',)) + + def __init__(self, **kwargs): + if self.elevation_raised == 0 and self.elevation_normal + 6 <= 12: + self.elevation_raised = self.elevation_normal + 6 + elif self.elevation_raised == 0: + self.elevation_raised = 12 + + super(MDFloatingActionButton, self).__init__(**kwargs) + + self.elevation_press_anim = Animation(elevation=self.elevation_raised, + duration=.2, t='out_quad') + self.elevation_release_anim = Animation( + elevation=self.elevation_normal, duration=.2, t='out_quad') + + def _set_ellipse(self, instance, value): + ellipse = self.ellipse + ripple_rad = self.ripple_rad + + ellipse.size = (ripple_rad, ripple_rad) + ellipse.pos = (self.center_x - ripple_rad / 2., + self.center_y - ripple_rad / 2.) + + def on_disabled(self, instance, value): + super(MDFloatingActionButton, self).on_disabled(instance, value) + if self.disabled: + self.elevation = 0 + else: + self.elevation = self.elevation_normal + + def on_touch_down(self, touch): + if not self.disabled: + if touch.is_mouse_scrolling: + return False + if not self.collide_point(touch.x, touch.y): + return False + if self in touch.ud: + return False + self.elevation_press_anim.stop(self) + self.elevation_press_anim.start(self) + return super(MDFloatingActionButton, self).on_touch_down(touch) + + def on_touch_up(self, touch): + if not self.disabled: + if touch.grab_current is not self: + return super(ButtonBehavior, self).on_touch_up(touch) + self.elevation_release_anim.stop(self) + self.elevation_release_anim.start(self) + return super(MDFloatingActionButton, self).on_touch_up(touch) + + def on_elevation_normal(self, instance, value): + self.elevation = value + + def on_elevation_raised(self, instance, value): + if self.elevation_raised == 0 and self.elevation_normal + 6 <= 12: + self.elevation_raised = self.elevation_normal + 6 + elif self.elevation_raised == 0: + self.elevation_raised = 12 diff --git a/src/kivymd/card.py b/src/kivymd/card.py new file mode 100644 index 00000000..d411644b --- /dev/null +++ b/src/kivymd/card.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +from kivy.lang import Builder +from kivy.properties import BoundedNumericProperty, ReferenceListProperty, ListProperty,BooleanProperty +from kivy.uix.boxlayout import BoxLayout +from kivymd.elevationbehavior import ElevationBehavior +from kivymd.theming import ThemableBehavior +from kivy.metrics import dp +from kivy.uix.widget import Widget + +Builder.load_string(''' + + canvas: + Color: + rgba: self.background_color + RoundedRectangle: + size: self.size + pos: self.pos + radius: [self.border_radius] + Color: + rgba: self.theme_cls.divider_color + a: self.border_color_a + Line: + rounded_rectangle: (self.pos[0],self.pos[1],self.size[0],self.size[1],self.border_radius) + background_color: self.theme_cls.bg_light + + + canvas: + Color: + rgba: self.theme_cls.divider_color + Rectangle: + size: self.size + pos: self.pos +''') + + +class MDSeparator(ThemableBehavior, BoxLayout): + """ A separator line """ + def __init__(self, *args, **kwargs): + super(MDSeparator, self).__init__(*args, **kwargs) + self.on_orientation() + + def on_orientation(self,*args): + self.size_hint = (1, None) if self.orientation == 'horizontal' else (None, 1) + if self.orientation == 'horizontal': + self.height = dp(1) + else: + self.width = dp(1) + + +class MDCard(ThemableBehavior, ElevationBehavior, BoxLayout): + r = BoundedNumericProperty(1., min=0., max=1.) + g = BoundedNumericProperty(1., min=0., max=1.) + b = BoundedNumericProperty(1., min=0., max=1.) + a = BoundedNumericProperty(0., min=0., max=1.) + + border_radius = BoundedNumericProperty(dp(3),min=0) + border_color_a = BoundedNumericProperty(0, min=0., max=1.) + background_color = ReferenceListProperty(r, g, b, a) diff --git a/src/kivymd/color_definitions.py b/src/kivymd/color_definitions.py new file mode 100644 index 00000000..c81bd731 --- /dev/null +++ b/src/kivymd/color_definitions.py @@ -0,0 +1,360 @@ +colors = { + 'Pink': { + '50': 'fce4ec', + '100': 'f8bbd0', + '200': 'f48fb1', + '300': 'f06292', + '400': 'ec407a', + '500': 'e91e63', + '600': 'd81b60', + '700': 'C2185B', + '800': 'ad1457', + '900': '88e4ff', + 'A100': 'ff80ab', + 'A400': 'F50057', + 'A700': 'c51162', + 'A200': 'ff4081' + }, + + 'Blue': { + '200': '90caf9', + '900': '0D47A1', + '600': '1e88e5', + 'A100': '82b1ff', + '300': '64b5f6', + 'A400': '2979ff', + '700': '1976d2', + '50': 'e3f2fd', + 'A700': '2962ff', + '400': '42a5f5', + '100': 'bbdefb', + '800': '1565c0', + 'A200': '448aff', + '500': '2196f3' + }, + + 'Indigo': { + '200': '9fa8da', + '900': '1a237e', + '600': '3949ab', + 'A100': '8c9eff', + '300': '7986cb', + 'A400': '3d5afe', + '700': '303f9f', + '50': 'e8eaf6', + 'A700': '304ffe', + '400': '5c6bc0', + '100': 'c5cae9', + '800': '283593', + 'A200': '536dfe', + '500': '3f51b5' + }, + + 'BlueGrey': { + '200': 'b0bec5', + '900': '263238', + '600': '546e7a', + '300': '90a4ae', + '700': '455a64', + '50': 'eceff1', + '400': '78909c', + '100': 'cfd8dc', + '800': '37474f', + '500': '607d8b' + }, + + 'Brown': { + '200': 'bcaaa4', + '900': '3e2723', + '600': '6d4c41', + '300': 'a1887f', + '700': '5d4037', + '50': 'efebe9', + '400': '8d6e63', + '100': 'd7ccc8', + '800': '4e342e', + '500': '795548' + }, + + 'LightBlue': { + '200': '81d4fa', + '900': '01579B', + '600': '039BE5', + 'A100': '80d8ff', + '300': '4fc3f7', + 'A400': '00B0FF', + '700': '0288D1', + '50': 'e1f5fe', + 'A700': '0091EA', + '400': '29b6f6', + '100': 'b3e5fc', + '800': '0277BD', + 'A200': '40c4ff', + '500': '03A9F4' + }, + + 'Purple': { + '200': 'ce93d8', + '900': '4a148c', + '600': '8e24aa', + 'A100': 'ea80fc', + '300': 'ba68c8', + 'A400': 'D500F9', + '700': '7b1fa2', + '50': 'f3e5f5', + 'A700': 'AA00FF', + '400': 'ab47bc', + '100': 'e1bee7', + '800': '6a1b9a', + 'A200': 'e040fb', + '500': '9c27b0' + }, + + 'Grey': { + '200': 'eeeeee', + '900': '212121', + '600': '757575', + '300': 'e0e0e0', + '700': '616161', + '50': 'fafafa', + '400': 'bdbdbd', + '100': 'f5f5f5', + '800': '424242', + '500': '9e9e9e' + }, + + 'Yellow': { + '200': 'fff59d', + '900': 'f57f17', + '600': 'fdd835', + 'A100': 'ffff8d', + '300': 'fff176', + 'A400': 'FFEA00', + '700': 'fbc02d', + '50': 'fffde7', + 'A700': 'FFD600', + '400': 'ffee58', + '100': 'fff9c4', + '800': 'f9a825', + 'A200': 'FFFF00', + '500': 'ffeb3b' + }, + + 'LightGreen': { + '200': 'c5e1a5', + '900': '33691e', + '600': '7cb342', + 'A100': 'ccff90', + '300': 'aed581', + 'A400': '76FF03', + '700': '689f38', + '50': 'f1f8e9', + 'A700': '64dd17', + '400': '9ccc65', + '100': 'dcedc8', + '800': '558b2f', + 'A200': 'b2ff59', + '500': '8bc34a' + }, + + 'DeepOrange': { + '200': 'ffab91', + '900': 'bf36c', + '600': 'f4511e', + 'A100': 'ff9e80', + '300': 'ff8a65', + 'A400': 'FF3D00', + '700': 'e64a19', + '50': 'fbe9e7', + 'A700': 'DD2C00', + '400': 'ff7043', + '100': 'ffccbc', + '800': 'd84315', + 'A200': 'ff6e40', + '500': 'ff5722' + }, + + 'Green': { + '200': 'a5d6a7', + '900': '1b5e20', + '600': '43a047', + 'A100': 'b9f6ca', + '300': '81c784', + 'A400': '00E676', + '700': '388e3c', + '50': 'e8f5e9', + 'A700': '00C853', + '400': '66bb6a', + '100': 'c8e6c9', + '800': '2e7d32', + 'A200': '69f0ae', + '500': '4caf50' + }, + + 'Red': { + '200': 'ef9a9a', + '900': 'b71c1c', + '600': 'e53935', + 'A100': 'ff8a80', + '300': 'e57373', + 'A400': 'ff1744', + '700': 'd32f2f', + '50': 'ffebee', + 'A700': 'd50000', + '400': 'ef5350', + '100': 'ffcdd2', + '800': 'c62828', + 'A200': 'ff5252', + '500': 'f44336' + }, + + 'Teal': { + '200': '80cbc4', + '900': '004D40', + '600': '00897B', + 'A100': 'a7ffeb', + '300': '4db6ac', + 'A400': '1de9b6', + '700': '00796B', + '50': 'e0f2f1', + 'A700': '00BFA5', + '400': '26a69a', + '100': 'b2dfdb', + '800': '00695C', + 'A200': '64ffda', + '500': '009688' + }, + + 'Orange': { + '200': 'ffcc80', + '900': 'E65100', + '600': 'FB8C00', + 'A100': 'ffd180', + '300': 'ffb74d', + 'A400': 'FF9100', + '700': 'F57C00', + '50': 'fff3e0', + 'A700': 'FF6D00', + '400': 'ffa726', + '100': 'ffe0b2', + '800': 'EF6C00', + 'A200': 'ffab40', + '500': 'FF9800' + }, + + 'Cyan': { + '200': '80deea', + '900': '006064', + '600': '00ACC1', + 'A100': '84ffff', + '300': '4dd0e1', + 'A400': '00E5FF', + '700': '0097A7', + '50': 'e0f7fa', + 'A700': '00B8D4', + '400': '26c6da', + '100': 'b2ebf2', + '800': '00838F', + 'A200': '18ffff', + '500': '00BCD4' + }, + + 'Amber': { + '200': 'ffe082', + '900': 'FF6F00', + '600': 'FFB300', + 'A100': 'ffe57f', + '300': 'ffd54f', + 'A400': 'FFC400', + '700': 'FFA000', + '50': 'fff8e1', + 'A700': 'FFAB00', + '400': 'ffca28', + '100': 'ffecb3', + '800': 'FF8F00', + 'A200': 'ffd740', + '500': 'FFC107' + }, + + 'DeepPurple': { + '200': 'b39ddb', + '900': '311b92', + '600': '5e35b1', + 'A100': 'b388ff', + '300': '9575cd', + 'A400': '651fff', + '700': '512da8', + '50': 'ede7f6', + 'A700': '6200EA', + '400': '7e57c2', + '100': 'd1c4e9', + '800': '4527a0', + 'A200': '7c4dff', + '500': '673ab7' + }, + + 'Lime': { + '200': 'e6ee9c', + '900': '827717', + '600': 'c0ca33', + 'A100': 'f4ff81', + '300': 'dce775', + 'A400': 'C6FF00', + '700': 'afb42b', + '50': 'f9fbe7', + 'A700': 'AEEA00', + '400': 'd4e157', + '100': 'f0f4c3', + '800': '9e9d24', + 'A200': 'eeff41', + '500': 'cddc39' + }, + + 'Light': { + 'StatusBar': 'E0E0E0', + 'AppBar': 'F5F5F5', + 'Background': 'FAFAFA', + 'CardsDialogs': 'FFFFFF', + 'FlatButtonDown': 'cccccc' + }, + + 'Dark': { + 'StatusBar': '000000', + 'AppBar': '212121', + 'Background': '303030', + 'CardsDialogs': '424242', + 'FlatButtonDown': '999999' + } +} + +light_colors = { + 'Pink': ['50' '100', '200', 'A100'], + 'Blue': ['50' '100', '200', '300', '400', 'A100'], + 'Indigo': ['50' '100', '200', 'A100'], + 'BlueGrey': ['50' '100', '200', '300'], + 'Brown': ['50' '100', '200'], + 'LightBlue': ['50' '100', '200', '300', '400', '500', 'A100', 'A200', + 'A400'], + 'Purple': ['50' '100', '200', 'A100'], + 'Grey': ['50' '100', '200', '300', '400', '500'], + 'Yellow': ['50' '100', '200', '300', '400', '500', '600', '700', '800', + '900', 'A100', 'A200', 'A400', 'A700'], + 'LightGreen': ['50' '100', '200', '300', '400', '500', '600', 'A100', + 'A200', 'A400', 'A700'], + 'DeepOrange': ['50' '100', '200', '300', '400', 'A100', 'A200'], + 'Green': ['50' '100', '200', '300', '400', '500', 'A100', 'A200', 'A400', + 'A700'], + 'Red': ['50' '100', '200', '300', 'A100'], + 'Teal': ['50' '100', '200', '300', '400', 'A100', 'A200', 'A400', 'A700'], + 'Orange': ['50' '100', '200', '300', '400', '500', '600', '700', 'A100', + 'A200', 'A400', 'A700'], + 'Cyan': ['50' '100', '200', '300', '400', '500', '600', 'A100', 'A200', + 'A400', 'A700'], + 'Amber': ['50' '100', '200', '300', '400', '500', '600', '700', '800', + '900', 'A100', 'A200', 'A400', 'A700'], + 'DeepPurple': ['50' '100', '200', 'A100'], + 'Lime': ['50' '100', '200', '300', '400', '500', '600', '700', '800', + 'A100', 'A200', 'A400', 'A700'], + 'Dark': [], + 'Light': ['White', 'MainBackground', 'DialogBackground'] +} diff --git a/src/kivymd/date_picker.py b/src/kivymd/date_picker.py new file mode 100644 index 00000000..5194298e --- /dev/null +++ b/src/kivymd/date_picker.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +from kivy.lang import Builder +from kivy.uix.modalview import ModalView +from kivymd.label import MDLabel +from kivymd.theming import ThemableBehavior +from kivy.uix.floatlayout import FloatLayout +from kivymd.elevationbehavior import ElevationBehavior +import calendar +from datetime import date +import datetime +from kivy.properties import StringProperty, NumericProperty, ObjectProperty, \ + BooleanProperty +from kivy.uix.anchorlayout import AnchorLayout +from kivy.uix.behaviors import ButtonBehavior +from kivymd.ripplebehavior import CircularRippleBehavior +from kivy.clock import Clock +from kivy.core.window import Window + +Builder.load_string(""" +#:import calendar calendar + + cal_layout: cal_layout + + size_hint: (None, None) + size: [dp(328), dp(484)] if self.theme_cls.device_orientation == 'portrait'\ + else [dp(512), dp(304)] + pos_hint: {'center_x': .5, 'center_y': .5} + canvas: + Color: + rgb: app.theme_cls.primary_color + Rectangle: + size: [dp(328), dp(96)] if self.theme_cls.device_orientation == 'portrait'\ + else [dp(168), dp(304)] + pos: [root.pos[0], root.pos[1] + root.height-dp(96)] if self.theme_cls.device_orientation == 'portrait'\ + else [root.pos[0], root.pos[1] + root.height-dp(304)] + Color: + rgb: app.theme_cls.bg_normal + Rectangle: + size: [dp(328), dp(484)-dp(96)] if self.theme_cls.device_orientation == 'portrait'\ + else [dp(344), dp(304)] + pos: [root.pos[0], root.pos[1] + root.height-dp(96)-(dp(484)-dp(96))]\ + if self.theme_cls.device_orientation == 'portrait' else [root.pos[0]+dp(168), root.pos[1]] #+dp(334) + MDLabel: + id: label_full_date + font_style: 'Display1' + text_color: 1, 1, 1, 1 + theme_text_color: 'Custom' + size_hint: (None, None) + size: [root.width, dp(30)] if root.theme_cls.device_orientation == 'portrait'\ + else [dp(168), dp(30)] + pos: [root.pos[0]+dp(23), root.pos[1] + root.height - dp(74)] \ + if root.theme_cls.device_orientation == 'portrait' \ + else [root.pos[0]+dp(3), root.pos[1] + dp(214)] + line_height: 0.84 + valign: 'middle' + text_size: [root.width, None] if root.theme_cls.device_orientation == 'portrait'\ + else [dp(149), None] + bold: True + text: root.fmt_lbl_date(root.sel_year, root.sel_month, root.sel_day, root.theme_cls.device_orientation) + MDLabel: + id: label_year + font_style: 'Subhead' + text_color: 1, 1, 1, 1 + theme_text_color: 'Custom' + size_hint: (None, None) + size: root.width, dp(30) + pos: (root.pos[0]+dp(23), root.pos[1]+root.height-dp(40)) if root.theme_cls.device_orientation == 'portrait'\ + else (root.pos[0]+dp(16), root.pos[1]+root.height-dp(41)) + valign: 'middle' + text: str(root.sel_year) + GridLayout: + id: cal_layout + cols: 7 + size: (dp(44*7), dp(40*7)) if root.theme_cls.device_orientation == 'portrait'\ + else (dp(46*7), dp(32*7)) + col_default_width: dp(42) if root.theme_cls.device_orientation == 'portrait'\ + else dp(39) + size_hint: (None, None) + padding: (dp(2), 0) if root.theme_cls.device_orientation == 'portrait'\ + else (dp(7), 0) + spacing: (dp(2), 0) if root.theme_cls.device_orientation == 'portrait'\ + else (dp(7), 0) + pos: (root.pos[0]+dp(10), root.pos[1]+dp(60)) if root.theme_cls.device_orientation == 'portrait'\ + else (root.pos[0]+dp(168)+dp(8), root.pos[1]+dp(48)) + MDLabel: + id: label_month_selector + font_style: 'Body2' + text: calendar.month_name[root.month].capitalize() + ' ' + str(root.year) + size_hint: (None, None) + size: root.width, dp(30) + pos: root.pos + theme_text_color: 'Primary' + pos_hint: {'center_x': 0.5, 'center_y': 0.75} if self.theme_cls.device_orientation == 'portrait'\ + else {'center_x': 0.67, 'center_y': 0.915} + valign: "middle" + halign: "center" + MDIconButton: + icon: 'chevron-left' + theme_text_color: 'Secondary' + pos_hint: {'center_x': 0.09, 'center_y': 0.745} if root.theme_cls.device_orientation == 'portrait'\ + else {'center_x': 0.39, 'center_y': 0.925} + on_release: root.change_month('prev') + MDIconButton: + icon: 'chevron-right' + theme_text_color: 'Secondary' + pos_hint: {'center_x': 0.92, 'center_y': 0.745} if root.theme_cls.device_orientation == 'portrait'\ + else {'center_x': 0.94, 'center_y': 0.925} + on_release: root.change_month('next') + MDFlatButton: + pos: root.pos[0]+root.size[0]-dp(72)*2, root.pos[1] + dp(7) + text: "Cancel" + on_release: root.dismiss() + MDFlatButton: + pos: root.pos[0]+root.size[0]-dp(72), root.pos[1] + dp(7) + text: "OK" + on_release: root.ok_click() + + + size_hint: None, None + size: (dp(40), dp(40)) if root.theme_cls.device_orientation == 'portrait'\ + else (dp(32), dp(32)) + MDLabel: + font_style: 'Caption' + theme_text_color: 'Custom' if root.is_today and not root.is_selected else 'Primary' + text_color: root.theme_cls.primary_color + opposite_colors: root.is_selected if root.owner.sel_month == root.owner.month \ + and root.owner.sel_year == root.owner.year and str(self.text) == str(root.owner.sel_day) else False + size_hint_x: None + valign: 'middle' + halign: 'center' + text: root.text + + + font_style: 'Caption' + theme_text_color: 'Secondary' + size: (dp(40), dp(40)) if root.theme_cls.device_orientation == 'portrait'\ + else (dp(32), dp(32)) + size_hint: None, None + text_size: self.size + valign: 'middle' if root.theme_cls.device_orientation == 'portrait' else 'bottom' + halign: 'center' + + + size: (dp(40), dp(40)) if root.theme_cls.device_orientation == 'portrait'\ + else (dp(32), dp(32)) + size_hint: (None, None) + canvas: + Color: + rgba: self.theme_cls.primary_color if self.shown else [0, 0, 0, 0] + Ellipse: + size: (dp(40), dp(40)) if root.theme_cls.device_orientation == 'portrait'\ + else (dp(32), dp(32)) + pos: self.pos if root.theme_cls.device_orientation == 'portrait'\ + else [self.pos[0] + dp(3), self.pos[1]] +""") + + +class DaySelector(ThemableBehavior, AnchorLayout): + shown = BooleanProperty(False) + + def __init__(self, parent): + super(DaySelector, self).__init__() + self.parent_class = parent + self.parent_class.add_widget(self, index=7) + self.selected_widget = None + Window.bind(on_resize=self.move_resize) + + def update(self): + parent = self.parent_class + if parent.sel_month == parent.month and parent.sel_year == parent.year: + self.shown = True + else: + self.shown = False + + def set_widget(self, widget): + self.selected_widget = widget + self.pos = widget.pos + self.move_resize(do_again=True) + self.update() + + def move_resize(self, window=None, width=None, height=None, do_again=True): + self.pos = self.selected_widget.pos + if do_again: + Clock.schedule_once(lambda x: self.move_resize(do_again=False), 0.01) + + +class DayButton(ThemableBehavior, CircularRippleBehavior, ButtonBehavior, + AnchorLayout): + text = StringProperty() + owner = ObjectProperty() + is_today = BooleanProperty(False) + is_selected = BooleanProperty(False) + + def on_release(self): + self.owner.set_selected_widget(self) + + +class WeekdayLabel(MDLabel): + pass + + +class MDDatePicker(FloatLayout, ThemableBehavior, ElevationBehavior, + ModalView): + _sel_day_widget = ObjectProperty() + cal_list = None + cal_layout = ObjectProperty() + sel_year = NumericProperty() + sel_month = NumericProperty() + sel_day = NumericProperty() + day = NumericProperty() + month = NumericProperty() + year = NumericProperty() + today = date.today() + callback = ObjectProperty() + + class SetDateError(Exception): + pass + + def __init__(self, callback, year=None, month=None, day=None, + firstweekday=0, + **kwargs): + self.callback = callback + self.cal = calendar.Calendar(firstweekday) + self.sel_year = year if year else self.today.year + self.sel_month = month if month else self.today.month + self.sel_day = day if day else self.today.day + self.month = self.sel_month + self.year = self.sel_year + self.day = self.sel_day + super(MDDatePicker, self).__init__(**kwargs) + self.selector = DaySelector(parent=self) + self.generate_cal_widgets() + self.update_cal_matrix(self.sel_year, self.sel_month) + self.set_month_day(self.sel_day) + self.selector.update() + + def ok_click(self): + self.callback(date(self.sel_year, self.sel_month, self.sel_day)) + self.dismiss() + + def fmt_lbl_date(self, year, month, day, orientation): + d = datetime.date(int(year), int(month), int(day)) + separator = '\n' if orientation == 'landscape' else ' ' + return d.strftime('%a,').capitalize() + separator + d.strftime( + '%b').capitalize() + ' ' + str(day).lstrip('0') + + def set_date(self, year, month, day): + try: + date(year, month, day) + except Exception as e: + print(e) + if str(e) == "day is out of range for month": + raise self.SetDateError(" Day %s day is out of range for month %s" % (day, month)) + elif str(e) == "month must be in 1..12": + raise self.SetDateError("Month must be between 1 and 12, got %s" % month) + elif str(e) == "year is out of range": + raise self.SetDateError("Year must be between %s and %s, got %s" % + (datetime.MINYEAR, datetime.MAXYEAR, year)) + else: + self.sel_year = year + self.sel_month = month + self.sel_day = day + self.month = self.sel_month + self.year = self.sel_year + self.day = self.sel_day + self.update_cal_matrix(self.sel_year, self.sel_month) + self.set_month_day(self.sel_day) + self.selector.update() + + def set_selected_widget(self, widget): + if self._sel_day_widget: + self._sel_day_widget.is_selected = False + widget.is_selected = True + self.sel_month = int(self.month) + self.sel_year = int(self.year) + self.sel_day = int(widget.text) + self._sel_day_widget = widget + self.selector.set_widget(widget) + + def set_month_day(self, day): + for idx in range(len(self.cal_list)): + if str(day) == str(self.cal_list[idx].text): + self._sel_day_widget = self.cal_list[idx] + self.sel_day = int(self.cal_list[idx].text) + if self._sel_day_widget: + self._sel_day_widget.is_selected = False + self._sel_day_widget = self.cal_list[idx] + self.cal_list[idx].is_selected = True + self.selector.set_widget(self.cal_list[idx]) + + def update_cal_matrix(self, year, month): + try: + dates = [x for x in self.cal.itermonthdates(year, month)] + except ValueError as e: + if str(e) == "year is out of range": + pass + else: + self.year = year + self.month = month + for idx in range(len(self.cal_list)): + if idx >= len(dates) or dates[idx].month != month: + self.cal_list[idx].disabled = True + self.cal_list[idx].text = '' + else: + self.cal_list[idx].disabled = False + self.cal_list[idx].text = str(dates[idx].day) + self.cal_list[idx].is_today = dates[idx] == self.today + self.selector.update() + + def generate_cal_widgets(self): + cal_list = [] + for i in calendar.day_abbr: + self.cal_layout.add_widget(WeekdayLabel(text=i[0].upper())) + for i in range(6 * 7): # 6 weeks, 7 days a week + db = DayButton(owner=self) + cal_list.append(db) + self.cal_layout.add_widget(db) + self.cal_list = cal_list + + def change_month(self, operation): + op = 1 if operation is 'next' else -1 + sl, sy = self.month, self.year + m = 12 if sl + op == 0 else 1 if sl + op == 13 else sl + op + y = sy - 1 if sl + op == 0 else sy + 1 if sl + op == 13 else sy + self.update_cal_matrix(y, m) diff --git a/src/kivymd/dialog.py b/src/kivymd/dialog.py new file mode 100644 index 00000000..cb6b7601 --- /dev/null +++ b/src/kivymd/dialog.py @@ -0,0 +1,176 @@ +# -*- coding: utf-8 -*- + +from kivy.lang import Builder +from kivy.properties import StringProperty, ObjectProperty, ListProperty +from kivy.metrics import dp +from kivy.uix.modalview import ModalView +from kivy.animation import Animation +from kivymd.theming import ThemableBehavior +from kivymd.elevationbehavior import ElevationBehavior +from kivymd.button import MDFlatButton + +Builder.load_string(''' +: + canvas: + Color: + rgba: self.theme_cls.bg_light + Rectangle: + size: self.size + pos: self.pos + + _container: container + _action_area: action_area + elevation: 12 + GridLayout: + cols: 1 + + GridLayout: + cols: 1 + padding: dp(24), dp(24), dp(24), 0 + spacing: dp(20) + MDLabel: + text: root.title + font_style: 'Title' + theme_text_color: 'Primary' + halign: 'left' + valign: 'middle' + size_hint_y: None + text_size: self.width, None + height: self.texture_size[1] + + BoxLayout: + id: container + + AnchorLayout: + anchor_x: 'right' + anchor_y: 'center' + size_hint: 1, None + height: dp(48) + padding: dp(8), dp(8) + spacing: dp(4) + + GridLayout: + id: action_area + rows: 1 + size_hint: None, None if len(root._action_buttons) > 0 else 1 + height: dp(36) if len(root._action_buttons) > 0 else 0 + width: self.minimum_width +''') + + +class MDDialog(ThemableBehavior, ElevationBehavior, ModalView): + title = StringProperty('') + + content = ObjectProperty(None) + + background_color = ListProperty([0, 0, 0, .2]) + + _container = ObjectProperty() + _action_buttons = ListProperty([]) + _action_area = ObjectProperty() + + def __init__(self, **kwargs): + super(MDDialog, self).__init__(**kwargs) + self.bind(_action_buttons=self._update_action_buttons, + auto_dismiss=lambda *x: setattr(self.shadow, 'on_release', + self.shadow.dismiss if self.auto_dismiss else None)) + + def add_action_button(self, text, action=None): + """Add an :class:`FlatButton` to the right of the action area. + + :param icon: Unicode character for the icon + :type icon: str or None + :param action: Function set to trigger when on_release fires + :type action: function or None + """ + button = MDFlatButton(text=text, + size_hint=(None, None), + height=dp(36)) + if action: + button.bind(on_release=action) + button.text_color = self.theme_cls.primary_color + button.background_color = self.theme_cls.bg_light + self._action_buttons.append(button) + + def add_widget(self, widget): + if self._container: + if self.content: + raise PopupException( + 'Popup can have only one widget as content') + self.content = widget + else: + super(MDDialog, self).add_widget(widget) + + def open(self, *largs): + '''Show the view window from the :attr:`attach_to` widget. If set, it + will attach to the nearest window. If the widget is not attached to any + window, the view will attach to the global + :class:`~kivy.core.window.Window`. + ''' + if self._window is not None: + Logger.warning('ModalView: you can only open once.') + return self + # search window + self._window = self._search_window() + if not self._window: + Logger.warning('ModalView: cannot open view, no window found.') + return self + self._window.add_widget(self) + self._window.bind(on_resize=self._align_center, + on_keyboard=self._handle_keyboard) + self.center = self._window.center + self.bind(size=self._align_center) + a = Animation(_anim_alpha=1., d=self._anim_duration) + a.bind(on_complete=lambda *x: self.dispatch('on_open')) + a.start(self) + return self + + def dismiss(self, *largs, **kwargs): + '''Close the view if it is open. If you really want to close the + view, whatever the on_dismiss event returns, you can use the *force* + argument: + :: + + view = ModalView(...) + view.dismiss(force=True) + + When the view is dismissed, it will be faded out before being + removed from the parent. If you don't want animation, use:: + + view.dismiss(animation=False) + + ''' + if self._window is None: + return self + if self.dispatch('on_dismiss') is True: + if kwargs.get('force', False) is not True: + return self + if kwargs.get('animation', True): + Animation(_anim_alpha=0., d=self._anim_duration).start(self) + else: + self._anim_alpha = 0 + self._real_remove_widget() + return self + + def on_content(self, instance, value): + if self._container: + self._container.clear_widgets() + self._container.add_widget(value) + + def on__container(self, instance, value): + if value is None or self.content is None: + return + self._container.clear_widgets() + self._container.add_widget(self.content) + + def on_touch_down(self, touch): + if self.disabled and self.collide_point(*touch.pos): + return True + return super(MDDialog, self).on_touch_down(touch) + + def _update_action_buttons(self, *args): + self._action_area.clear_widgets() + for btn in self._action_buttons: + btn.ids._label.texture_update() + btn.width = btn.ids._label.texture_size[0] + dp(16) + self._action_area.add_widget(btn) diff --git a/src/kivymd/elevationbehavior.py b/src/kivymd/elevationbehavior.py new file mode 100644 index 00000000..19d7985d --- /dev/null +++ b/src/kivymd/elevationbehavior.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- + +from kivy.app import App +from kivy.lang import Builder +from kivy.properties import (ListProperty, ObjectProperty, NumericProperty) +from kivy.properties import AliasProperty +from kivy.metrics import dp + +Builder.load_string(''' + + canvas.before: + Color: + a: self._soft_shadow_a + Rectangle: + texture: self._soft_shadow_texture + size: self._soft_shadow_size + pos: self._soft_shadow_pos + Color: + a: self._hard_shadow_a + Rectangle: + texture: self._hard_shadow_texture + size: self._hard_shadow_size + pos: self._hard_shadow_pos + Color: + a: 1 + + + canvas.before: + Color: + a: self._soft_shadow_a + Rectangle: + texture: self._soft_shadow_texture + size: self._soft_shadow_size + pos: self._soft_shadow_pos + Color: + a: self._hard_shadow_a + Rectangle: + texture: self._hard_shadow_texture + size: self._hard_shadow_size + pos: self._hard_shadow_pos + Color: + a: 1 +''') + + +class ElevationBehavior(object): + _elevation = NumericProperty(1) + + def _get_elevation(self): + return self._elevation + + def _set_elevation(self, elevation): + try: + self._elevation = elevation + except: + self._elevation = 1 + + elevation = AliasProperty(_get_elevation, _set_elevation, + bind=('_elevation',)) + + _soft_shadow_texture = ObjectProperty() + _soft_shadow_size = ListProperty([0, 0]) + _soft_shadow_pos = ListProperty([0, 0]) + _soft_shadow_a = NumericProperty(0) + _hard_shadow_texture = ObjectProperty() + _hard_shadow_size = ListProperty([0, 0]) + _hard_shadow_pos = ListProperty([0, 0]) + _hard_shadow_a = NumericProperty(0) + + def __init__(self, **kwargs): + super(ElevationBehavior, self).__init__(**kwargs) + self.bind(elevation=self._update_shadow, + pos=self._update_shadow, + size=self._update_shadow) + + def _update_shadow(self, *args): + if self.elevation > 0: + ratio = self.width / (self.height if self.height != 0 else 1) + if ratio > -2 and ratio < 2: + self._shadow = App.get_running_app().theme_cls.quad_shadow + width = soft_width = self.width * 1.9 + height = soft_height = self.height * 1.9 + elif ratio <= -2: + self._shadow = App.get_running_app().theme_cls.rec_st_shadow + ratio = abs(ratio) + if ratio > 5: + ratio = ratio * 22 + else: + ratio = ratio * 11.5 + + width = soft_width = self.width * 1.9 + height = self.height + dp(ratio) + soft_height = self.height + dp(ratio) + dp(self.elevation) * .5 + else: + self._shadow = App.get_running_app().theme_cls.quad_shadow + width = soft_width = self.width * 1.8 + height = soft_height = self.height * 1.8 + # self._shadow = App.get_running_app().theme_cls.rec_shadow + # ratio = abs(ratio) + # if ratio > 5: + # ratio = ratio * 22 + # else: + # ratio = ratio * 11.5 + # + # width = self.width + dp(ratio) + # soft_width = self.width + dp(ratio) + dp(self.elevation) * .9 + # height = soft_height = self.height * 1.9 + + x = self.center_x - width / 2 + soft_x = self.center_x - soft_width / 2 + self._soft_shadow_size = (soft_width, soft_height) + self._hard_shadow_size = (width, height) + + y = self.center_y - soft_height / 2 - dp( + .1 * 1.5 ** self.elevation) + self._soft_shadow_pos = (soft_x, y) + self._soft_shadow_a = 0.1 * 1.1 ** self.elevation + self._soft_shadow_texture = self._shadow.textures[ + str(int(round(self.elevation - 1)))] + + y = self.center_y - height / 2 - dp(.5 * 1.18 ** self.elevation) + self._hard_shadow_pos = (x, y) + self._hard_shadow_a = .4 * .9 ** self.elevation + self._hard_shadow_texture = self._shadow.textures[ + str(int(round(self.elevation)))] + + else: + self._soft_shadow_a = 0 + self._hard_shadow_a = 0 + + +class RoundElevationBehavior(object): + _elevation = NumericProperty(1) + + def _get_elevation(self): + return self._elevation + + def _set_elevation(self, elevation): + try: + self._elevation = elevation + except: + self._elevation = 1 + + elevation = AliasProperty(_get_elevation, _set_elevation, + bind=('_elevation',)) + + _soft_shadow_texture = ObjectProperty() + _soft_shadow_size = ListProperty([0, 0]) + _soft_shadow_pos = ListProperty([0, 0]) + _soft_shadow_a = NumericProperty(0) + _hard_shadow_texture = ObjectProperty() + _hard_shadow_size = ListProperty([0, 0]) + _hard_shadow_pos = ListProperty([0, 0]) + _hard_shadow_a = NumericProperty(0) + + def __init__(self, **kwargs): + super(RoundElevationBehavior, self).__init__(**kwargs) + self._shadow = App.get_running_app().theme_cls.round_shadow + self.bind(elevation=self._update_shadow, + pos=self._update_shadow, + size=self._update_shadow) + + def _update_shadow(self, *args): + if self.elevation > 0: + width = self.width * 2 + height = self.height * 2 + + x = self.center_x - width / 2 + self._soft_shadow_size = (width, height) + + self._hard_shadow_size = (width, height) + + y = self.center_y - height / 2 - dp(.1 * 1.5 ** self.elevation) + self._soft_shadow_pos = (x, y) + self._soft_shadow_a = 0.1 * 1.1 ** self.elevation + self._soft_shadow_texture = self._shadow.textures[ + str(int(round(self.elevation)))] + + y = self.center_y - height / 2 - dp(.5 * 1.18 ** self.elevation) + self._hard_shadow_pos = (x, y) + self._hard_shadow_a = .4 * .9 ** self.elevation + self._hard_shadow_texture = self._shadow.textures[ + str(int(round(self.elevation - 1)))] + + else: + self._soft_shadow_a = 0 + self._hard_shadow_a = 0 diff --git a/src/kivymd/fonts/Material-Design-Iconic-Font.ttf b/src/kivymd/fonts/Material-Design-Iconic-Font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5d489fdd1a04cf2169af5e4d29d2929432a73f04 GIT binary patch literal 99212 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 Bf0O_K literal 0 HcmV?d00001 diff --git a/src/kivymd/fonts/Roboto-Bold.ttf b/src/kivymd/fonts/Roboto-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..91ec21227866ca9d1cf77ec13660b7b85ec900dd GIT binary patch literal 163448 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
LHSO~mym3X1&gqJoFFVN5m7hX&lHq;}_pq@IA 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 literal 0 HcmV?d00001 diff --git a/src/kivymd/fonts/Roboto-Italic.ttf b/src/kivymd/fonts/Roboto-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2041cbc002be810c50cc6a69e4e02b39f3457318 GIT binary patch literal 132440 zcmeFZcYIXU);GS(IWv<&64HAny(g1Ql1cBq_Z~<>5(4SH_d>wX5fB0CAR?dw77$Sp z(Tm7cY}ioIi-_IpRmjYF*PbMZKF|F<&*%4f-~TSUzo*P8d#}CLcdfnlK0z2Eq=SYL zMdb;xaq(J?T22Tz>cQE>gv^Yb)$gZ12FHa6Z8(>ZlNasaY<(ILY>E&Uo{{72`^+)d z41{nkTwk6an^xF(s}qj(rxD_>FKMV~e#mlLA3~<}@RFaF*7wxB@#*jXLdg3(!iMkH zR##O0>v&`}+{~Ud?+DaxO#!3>>GTX3i7^(-UaFn4nnRTsQ{r4&hBuJ8z3ZxHc%caGZmB_zft8 zIH4pi8)+2+ke3|f%rRQOAZUud=^@UzY~7sl2A4`E&L4a(dV8=IruB#U)&|(W2oPUB70Ox zN72jlC@SLe(TKI3-SZH$;prt`5cu(X(T=99j;0ElD>obh#uOHe-$p0qv%t* z9-X6)BVFjvXGOZ`gvbExgu1*fP7%gAPvpW^ASt&C1#$MT z!ganE`Qv{gFRlc6a)HQ-*dr@`Ir8V4kb}4x<%x|^0{$10lcPcszZhiRi=z1^*uIBK zuu9P2Y*9FU0-Ml&>_m&P7~jS^WDmx~UN}adLLZaw(Mu#-_!?;{e?pon3R^8G|3sQI zAL3gxr->Nb(qGZfWFguQb%^1|geUlHRLe_+^H5K1ek0ViTe!wQgckF)XcFv1ldDIG z++N`a`YjrVdd6@;$d%JYqpZ$c2Wlg$(FB(-JWbz65!_)^4s!d53qa}cdopK?R&a4> zDL;y$_#TuYYD6{M3Y5jUqopD{RKtIWcJpzlTT&rhlGLLZQ879J{T9uAhy3{K!UJL> z;RxuUBbxN-*<(Z zp!4xu50cRokoU8~YW^6O@Lj6K$#R?;s1tY+&JvRIeH$I^M_F?w-=71QJ*Li zbh8uM`60>|>A`hTPy&#js2sMb!V657!G6+3j|k^Q&%!;;a1758eT14sB9y^JATN;s z_Wus@;GPzq{F>Z6S-$Vkm^J7rqBBSVA+=AmbC!G86>w z%i>=_Z_v{yMZ!bdzeKly7e_@HofI8G8$|ojT2Tx-%XOkOz5!(XAn0!odJOC$3a(Eh zBEg(nhI|-b(;47VGh_yGh$6A58~jBx*!UN~ONFc*VwLci#9z%vRzxKnr{GKIhv;p( z0o}sCp&71T*bla7#Z{pMZYi>&Z$WtmjyHh*zKX2y7s!pC5q{;u;QSuonNQ$1IM3|{ zyNpwBn*e{>4)!tz+`;^p6Ue0+`nm>uYz^vX{uKOV4d}g0&B4sqga76ukT)w_ zBMM_alWY`zVSf1E7VypRzFFTqw`G3${sQ)>_Q}jI|EYjKWFn%;W~`Sva>fpWAv7Ct(2J7Mj>Ga7+@t0(}IrkJ_I?{KH}p;P4O@hs zzda3dWw99a$NzTAVm1~xF&$xjHy^vP_=&}E_itGo!{Qco9K&LkrNUF{!uWyl&A%(a zL6q^&eTDJQ{pB9_F#fr}Fy6VpFy6WUJ&fP(FY{b?-@Dj*)x5{JZ@$cOpf1$GbhaKs zA=}>1iHsNLi@JV{ALlu8zK)C|=L_S?`wNrHJa^vThPiz;m$LTEaVg_dRwRbVSZz1& zp(XsUsD-Qo`))@M@Fv1{d;;+0Y9v+v4l%siKA@kN?lB!^G5cTRb*3ZgeudaveGQAx zS=`2AHSo*o7!Beub==8po5i*ePqSDWep||7G_}pcRvn`;n}qm~=_q@i`k7!ejDyu< z28hG%)sI~V*F*hc?yncmVo5fZU_8L;$HonepP0?F_>0wp#rnV%YEFT=u-_<))xa*8 zJ*xQ$#tAG|W7o{<@?W>}x~(2xv2m9^yyFmRXEu((|Fe3rF~&WvDil*Nwf_AowW_5?98lMRbgS!~Jn@4bVK!JxhKHl^-I zXrDSpf;gVV^7HrIdp5|B$%e^Ny`ATjxtMT1HiWpSoyDOn9#-4*U$!hZ=2-j+F|j&s z1=+K{W@9mR9L?h1x%&OT+RnH4|L>N`lJ!4qb%4Kr{42lyuaD=)QUBBSue>@p?wTKe z{k!eF?){hT6!^F)h)0>tfc~m|2ODRAEwFJ0vj^5E^L;hHWp>AGU|u)w#oBDFaT9z8 zDJ+cFIK=y!+$U*oOIUz?tXXFIvf}83WW>bqi7TX7=t1KV^I`f9EujcL-8mEFagB^ zCZagNBor@vi;__SU z$`Wp&e3T7XfN}r}Q7&K+%7dIiG0F!lK?Q)Ns1UFW6$v-dB2)~x7?l8)qf)>MR3`ib zRiZ_JOVDD#DpU?w4fqwRK^1^YQ6*q4S^~HXRS93B<)|944%GnGqosfis8+av8qqSq zCbS%|8Px%{pnBm8)QTDa+fXB5J8A;#K+VGEs1vmScA-|lZqx?Y1Na&0MeTrnr~|Mc zbpj5cF5x;FMBRWxs0VNu^#YEdKH*a|iuwV^&;Z~#8U&m`L&7I$5)A{cKqG)tXcTZI z8WTQ7tI#;$184$p8chPO2K)%EK`Q{)qA9?2XeHo!v`Y98Z9oqIZbZ|7o6u^&2hkeg z8rqE30&YR;0Joy`fDfS!!Ut#@+6eeC+61^AJqWl1Z5G}~JJA-vN6=QlUFade-GJ|* zJ!l)?Ui2{FKC~ThKiVO@iw>ZjfCtedfQQg7z(>(;;T?1s?E!oY?FBr7_5nVQ_6t|h zQFH+C7&-`e9329D0zE3cjh;k@0iQyT0iHld08awGg-)Tz0iQ-k0iQv~0G~z2g}q^zo8caFQJzJ-#{-5m(XQ&9uV#Zyn-$O{vEw4{0+T@ zE&{%dUIV;}UI%;!{Y`isy^AgZzK7lbd>>r~`~bZvyoRo!D}W!OzXN`R-U9p>@FMyI zy$$#&x(aw5y#x3edRKTAeU9D(`~tlXcmsU^_$9g~TtHu;4*~yyJ_5XnJ_h_6eImSq zZlO;Bzd_dlZ==ruzeS%5=h1fvya4(h-2nUneF^v@;LGSI^cCRG=pTT;pqqgIL|+Rp zp=zG8!^aG$0{V1G+l=V-50{R&c(kQb1~h{*xe3T-2vF#30T|(*xL<4Td04y8`>>CWM8wzY24lEl9>>3TM8VhV14=kDp?3oO#nF?%~4lJ1o?3fL# zm{kq|R|;$gnIB*{@PtH@XcHY`M9hgbu_aPsM;wSfaU{;fmADW$;!Zq? z2k|1_L`Hmx50Mjp;ztxDfCQ2tTn}tk3Cy?@Hv(sk0naVN1Hfdp_yORd5j+K%o@u-q z__7_3;R!sBUc@VbAA7*U#({YTfnn?M3bYZg0voMEy|@`s!V?KG1BO|TEAbM%3@^vk zxCTw)H6#S`Debrix8gRufmY!L)QOkkI^06UM3;z&9$7&2i2*Sr3yBFag%%nUOJYSV zfYY`Cr!)fJ>;RtW0%myx7>EN>&ZhRd7fbU{~m=Oz*O%XXmUL~)QkIByzQ%W_cF14qt z=rr9xchlqaS^65iOy8pKa*mug2e~M&l5666xJm9Z_a65d_fH=4dc1)(wvMo#u>R5d zXY1c>(xh5aBdN92PU<9;N#)XDX{a<-+AbZE?voyr9)(-IU%tz!1VJf4rtw~DrJ#koKpu|+Kb`|Nx&jvc0}`+v z*2hlR1^eJ29EEdnIj&W=b{9Sdt-XV1h$(2zY-=w-Yu|^~qI<0!ht{s48|hy91bvRa zPX7+AMVu2StCR?NNON8kxHeG z&{|(<(7o2~h1Ndyr`DFtwRYist*wIAVrVT4i-Z|yE#^EpCy0X(_)x^yL3ja-KMqPH zlu#(aPy(R@K#@W5g=?_t7u7#-2T1B9_}^Ytg(?yqR$f)^SDsfMQ|?vnQSMM~RZhT_ zSxKHMSbD@Sa*uHO7xz_IKnoXYON!?TycTM@nv?}sT);syntO3p*M3gzbPHGd%a=#TwB_Q)l; z7RvwbA2~309q=z!f!*<7`(j`X;4?HtFz}f%vwyHhb2N-bz$zIFSQ8tFg~ov8Y=P(O zf$1E9g(iU6e1O~Jz-#^x6RiMlQ!sXec1#hN#zQL!L956zvYgbBdeT4|AvT&ut4SB> zCOxE=^pSot0MXG}GDwEVFc~4EWQ_3_*+4du&14JNN**E(P65M9-|AW z4%KBmLyf5kHAP3M88t`8s0FozSpzHd1hqy_QX48oPf=TlOiofe;1LJvNS&xNb)l~4 z1?o;cV5ZIuB8`_I!Z;6+#Rc>#^@MohHQGq!kiqvum#IGupbE%CzX{g;cN$EaXb5_X zhC+@#jE1ADGy)=qchP$^66QGHr%^PT#?V+AN8@P%#0=MHB25CH{}nL9O_~f|{ucTM zMsBykuYZTWr>W=%nnu&nk2C}QL^EkK%|c3=jZ`#;=F&Wx52gfzEm}ZZXdxz;VvaMX zt+Wjo#sC{)Bic?oXcz6o_Sk{5;iQ}yFs&1CtqXSLEI3Q-hTSkqq9i&5a7>D6-U}7g6fg?Fv&W_XL7IOBS1CF8(s9Ae8FxgtV4oBk{PM0``aah{w9?&5gxQsALzJ#F}pmjR#pA1@OMEcqWVqbBbE zc$xorng4j1|I1$H{?N%9MtslVc>EH+N;rsTib*G#CfmpwUl4yHag)SKvL*eJZIUCBE0UWUp&E@Emo!D1 z<(i$E`!t`?ybftnQ!SZRyjHH(a;-tFX{~KqziG#6PibFWV7VZ9!I1^m7R=}b>lEwM z>O84)UDr*wUH6>s=X#NPje6Vkj_O_3`);B6Lf?h$3r828*XQ(I^jr0xGcY!YH7GXt z&CtQ{sFBD>-^jt}l+k%(V(egCYJ9@@CF7q=^h~@=a!qPYj+#7Ya>?WqlOIfDO&d+u zna-H`nr$$*HXk=XXW?YgZn4MWsKq6V+m;f`V9S2X%T}3I?N-lNn_IVAAGf|`qi0iS z(`YkpbHL_2j5u7R#nNW!A?YdUdFf^8ueRE@ZnlB8?Y8~4Yi#$~Av;4mnO&@1mEAeJ zU+vTFk2@GTcsOiz_{}lWvEK2L<4;b$PCK2hINLdQI-hs`&c(^4+vSw2wd=U+OKx6n z%iW%Hm$)ao_quO(zvQm+@bH-S*ynNC;2Z8+>pSjy!1sN*jyzmGCBNpU=U3%-*zY(0 zK>t?%HU8HEoC2x>&L}h$9*RuGpyIef6&M+~Iq-T=ZqVz&*1@&G>w?dONJDxCEZO-JE+f&nquKuQ_j3-if?Rc{lR|@;mbnm8>4n=0-zt(7#TT^}ttxu5=&hn##iTg3cv11T;@?WlONvVl zm7FQ{D(x*jU;1vDc3D-~c-gr{nv1L#tyy$!(apt9ixU^;FCJZdVDYu`{_^qiGZm7G z@``hnhLygRnU(dGt16$Y{B?=xlBy-gt5B71)l}7us$Z*ptDCDgRKHdIRZVowbj_}s zTT5k22bW&2^{8#FJ-dusmb~ona&CF)^6BN*>H_M*>*DLu>!#~oujlF=>Pzcu>)Y#x z>!<6t*6*u7UVo-D$me{0|x^cpN1TpIiuA{$a03LB~#nj88XrW!Ui>}ojD z@Jz$`hARypHQa3Yr4co1H<~s&G|C!78xtFI8_OH(8@n6F8`m{%Z#>j^qVZhgrN;Lg zZ#4eUIMXC)GHjAIEo%Ct=~mOP&7@hU*}U1Q*|#~oIk`E%xw5&jxwm<;c|-Hg=8sw; zTT)vJTdG=`Tl!n3S~j)pYB|#KOw0L}D=i#*!_ z>G11_>`3h>?AX`wL&r>~q|>ld+Ue05*cscI*;(3I+u7bZ+&SI3wR2zR@y;`y7dx+Z zUhll!`5P>U(Cf17a_RExitI}5D(tH2YVPXqn(ErrwX5q$*E3z`yRLM7)OEA#mu}Rp z-EG?K&|TTx*xlPb*}b8AXZPXmQ{6B1pdRfW(;kN&Sx;zBVoz>Qc~5=Mww?n$PxhSc zdA;Y|p3i%}>$%e_>ecVH?se-8=#B18?=9}F>22*D>|NEnxpz|c_502H?fTvN zefxv^qx+Nl^ZP6N8~c0vC;K<_@9aO&f3*Kp|JnWv{crVu(toS}*8wu1GhjZ@KF~if zHLz}A>%hK&;{(qOoEx|}aAn}5fg1z22Ywlt8RQ1F2Mq@;2OS1I1_K8p2NMUU2R99F zA3QX8V(`r1`N1oL?+@M>{9$lrNHSzNBpvb?3LJ_Z${Z>jDj%vJ>K+;&njYFZv~TG6 z(3zo&Lsy4x4E-=PGb|Z49JU;G7?ur(4kr%h4wnzt4|flb4^Izo8s0v9X!ykNnc<7W zSBI|;-yZ&DcxFU0VmKllaT)O&i5y8CDIBR9X&&hxnHt$NvTNkX$cd3NBNs=mj$9wP zJ@VTqH>x*kIqEX%HySybI$AnfKiWMyJ~}nfPep=EN_PXi|I9bkbo`HW@mZIGH6F8i$5idq zzNwd{uCJ7=^j#UfGJEBsmCILlt{h#tX63e(&#k<+imY;3C0iA`Dqj6xJ!D8Patp}; zSewd2t{Y)0Hc;4LYHy%0!7Fnb!wjar&uI+TpW+);`!F8t(O3`L@m38Moe;=0BJL7@ z9J1gxaIZbwX0MP#u{DrWIV)m&bpbT6CmZiPxc5&TA+n3i^GqHo^%jYumaoZm-r$no z5@{rQifVggLY{P!tusJU0*z2IPc$ zEwoInnJg%Hpe91=!%r3#4Q$Qut1k>9*fyeA5tJL|X<(I7JyB4)x++BDg%=m3cW%xL zS(fgFv2_?^=Rne@g`2#Le-&mD+#%~<09kxw5Kf`ix>$#@R+-GzIYQk`)++oz{LVXL zlM7=W6P}|TGnzW=Ws7eUV~~`!ES_?6^|bh`RBHp*qO)%|G@jumnpEH<%s*1;er9=cV5;V0JV225sfu>usq-cE-^i6R!Y z2N}89=uuJl(p5Q;tvOyCb&1GuAOGDmNPG8!{OldCC*{1fyl7if2;S?GnhWAo+mqwY)Zs9_4g4zA7Ti;#*8K*R8#NHs!)z1Cg;$v95CYnQ zt*MFFiwjT;>-eWF9eZT4MdR+)L_?yr02|3NLOnCuGQA9VZIV*?=A{=8uk!BCe&_wdw)}T(rUdJze z>DaDCmJNH@3p8PtNtO}foza$|enC>@n}2)p(FeTSvfuj!OU85)_8mF8dm3Kw;IS9a zzX&ODX1`0wVmbzAr${zPKK>6nzr2eP)Xx|$Ii zn1edS<{dFS9siIV})$=JTOr%*`;lw&@U?> zzB$KF<0;L&si$i4*4O$=#L?v~{;Fv5!fK-BT2j*-E-#67CB!|WDH_)t>Wm=7zjAd^ z`r6TUxvG%W%^PHC1MiK50~251i2wRpwTHN$YS}g381L!|Ybg$qi1dB4gF>p(d^MpS zV+Tu$*Dvvw@V+VKe)1%*g`7s-isMU)AFNaGCpn9tf}rSzY`Iu$9a$baO?|O6sv=5J z677hweN0&pF5A3Zfl2VP2TMY$b0SQPV)Lp3s`s>p5IDD~6bF_@I}+lYv@9}WafB^l zbJoBEoE7MarrJ`N7iAg_32|EkF)cc8@p8zi5M{p+m0pJkf&s1EF)hZz}{G(R%X+53J zXV)yXkKVbca#gNWqLDUyydk->B-~z8qNNwUXyoAK0o7~1r5RDi8k~-mEYT;SG2Kfn zTHu|_Ke+=Z3>{w<9ZP7=_@RQDXCBC;M3z<8Hy%~c^7gY2HHImhv2{R-TfAdIVRnQI zp&=Fh5dm%G;UKpiAp2>M8|bwLOkjZNbGx1r;vzz zGM9#?r%1%<1N+MIR#(VW-;2zGih?2YWXNVBE_#mBqG{CYT58TeN6f9h?cSS)(M1ibOYp-O`qa2bIM- zV^F@O}sf6MM zma+uj#HMsFk!XQu&Ndt~c(TPV$i)PcycLJ@Yfi7pp+uhFHo7V%=5f_KpA2uuUlE(Y zWVa;8!s6U$S3<+81|$4CDx+Y=R)E!UKjVE|JgmdegQ;6F(nD)$n;-}et3Jl7;k+}P z>85Sa$2!`~R-({F`V5!B`W*9OXpI<)iNCGV$()uskYVL%+_wSuzM ztHxhra^5feOrHULa)$LGh*9N#%a-70z>t~8F%&V6gQLWD0m(9lYO*YuMlsqP>gjfoLN0%RUx8n@SWWfSg|(ir>Ha2 z2#7(Lvx0B@bYNx{*o9Nvb6T@LD*%EPYVXCXuj35)x$B6+PhsH1oSSHcrgKnQWp|=$ zg2GX39vYY78I<8`E)h$#+#+&n2a>XeBPPIOhz%XBa4E*v>@>D!6%zilYS#MmvSa8bEi=;T;OksK3+O!=0fOfGXW!^ANv zzpT`y^2KAD8zTvcY~A_nrP{KyPdwZngNd6{hncOB1gDH1d*idVo^RhfIgvz2%E+-x zpItQ#jR^Cx!Ne&f!A8vCJC>NZCN5f910U|fS_19?;2klrJ_4r*@d2YBN>?kNeDyVI zvL8#IRi4A2_TYZiIDh<3Cal&t2wE5-2;4Tf&luLZz*+#g0k3v#Y)Ay%qJ??2|8sJ7 zoZSKc>lmWMFBNZZ4wmqq2_eouJYh){UKb^)-)m5w;R9_Gzfqp0o zP<_rH$Hb#_&61Gv^iX5NxT2+g^}Fl*F?m$^3$~A~j_w@i9)|HvNq9)MpD8#owGV2C zujqaU?qC4}(-Fq@Y?xzW@1>4r<^otoD%^UbW!qkDD_vI??=03bGF87AedQxIjQ-8{QiB z*3&lXKc^D5>0fxZ>xI=t3l}U{n7XDJL_yom{Btt@!Mmqwc>TK%;H=dzwiK5?x1kgQ zJ7}u<9Z$eJ*oYeVK@5v|zyaIRE6VM~1|4`$kMIr8&C1vDzmYG5S+hPhK*0iJuE(Q) z_2$I#t!-)Unpz7Ds}J0IsCIuxjO01qIj$zA^WkB7}S7m^-aJ4ToxZYCd?0UPTWK&|a9ARNS6*xrCR3S|4g zl&7n@l=bUWGsP8Wlu*@0+#ay$NRoWFliRJFR=%x%kXo12vIL#5wa2WYm`U=K^0)KP zD^C%PS59-w?{0<%tcMR~K)<_$uX#=IBNni}@DHm4W@cl$xlzPDyW+}1^)Rx zSsy&0a!hgpxg1f{5ZWO+(|Rf?(dp#|g?c1Tzj z7gZJOFwfWS5YukuUr~=hS)6(=`C=cy9Q1v;HTKhdl8QDn#q!*xURhh(BE^!bEzd2gd~!0CKf}9cwZ;T@lt9 zD@v;#s`14nqIFNz#3q6*LrWt=b3>hVEfSZmDX-m93DHhi%id);VOatUt;~W;Ku#D| ziX$FOeKr~cDKVn^Ru%Hu>CaRlmRuaKf9E@1f9I@CE(O~FQ-+nhpmDP_0?afQnJWx< z%R>vRAAYs1{%E`3fR!I(RChp`QYRb5CN1$+8%lNcz+z=RF# z?5VRDK#tFHvG}P++B73@`-{p8j}3BeD%oSLPvaMlAE7_bpaZYbkMCr1o>lF4zkr88 zP61Zs@$Rq-zD7e$V8CIpL$={ZZz^BIId7{}s^ps_Ms?~69V4DfN2NPaC|@K0AP{!W z$c?tghy0We8bh+yECGsx0HdC$qhPcs5cpt2~^Z&g9Glta7{D_iM`nKvH>>`p zT4#D1^JhfEza?%JP0jXm2Kj*M!gJ=va4h+(t@`B&yt{wzPVQNil)R^OWzQTDmQiE4 z1>VO)GsxYUNekM$MVJeR4?QzBa@KS(Cc z+KSxduc-#e*O-VM)uSV4NJ_F{A9+Gdqj#3ZcIJC=qKZu?ik{cz^}Uj0ZrO3Z8mA;h zBijDqYd;}3wh~-&iM*k^s2+pV(PA%H%>v#}rootBMxj3mYU1mzfCwQW1E=%&0 zWhaE1Wmz`o<#cCzYY@}u6$AB|kUok}85AMqOYw<>jla8xLR|{;(?Wr7%se9C9o#=L!Xjl{{@d}7Ysg}*}AjL zPK#fV`@r*^c`M8P@T2Db>3%r_1##H@{Hh-tg+?0!l)c zt;zMtk9HwW_ePeNU~+?*GkBd2g#D`x~_p>=fd3d5JyZ*+(PZ~F9{hyH|^^a)b)xHzM&t2&e_8E1c>*7 zX%AL6m@%+b^Ot&XWxzO^XDW!VH|?%+)!-%Wv1M&5(waBrm@d#(hHK~tRV9^f2(5J} zt?P=3tIG;DAUd2xN0x0!3f4VW?H;#kurA%5(6R^5ROUnsR!0$%6;J6xMKKY{_-L*vRt1M`X zHk5Rp>=J1@#szq1Cxn?zo&*!4rxLOWj;vdgt_&d;eR3nf;hD=K9cO0Xi9~I=UqD<# z;hPjBXVEpw30M;&mWFov;>4K~>v6ERsk4riRZD2YmhB>`cE&0Jh&6|FGf=EA?DDMx!4=XXEyf6d)Gv= z=I?64!{4ZMasCDT^N?y_?Jt1O&KOQ%U-e2jNm!!~*f3m5tC&5gk>qMtW+buazUY6po)px2} zq~o3xP(1Fv^5hvVqzBjx8@fe%W-lTneA((OWe|DIFF(u<+|_1`H2yl`b=KI9nwqze|_Q4TXR@NfcOUVaU0 zpEF@>1fy)Vt=yYMgdq~gsOpczT&9L+{Nj!WGF$glI%*M}qO~t}w(PES(gHismHMao zNcYPfDh|*j(xlY`%Tgf2w)ml!YfKtn+g3zr+17J4ZpHa&Ar6Elw69Mz zb}K2!2z4YhsdHl@=+=9xayp}KFL0H5E(1G*$}7}uzvp8>`m?62pg&6-f-;s4rRF^t zP;nA-`wXKVshD*!qLUofw(?Du7mmwIteetv`tp4=|8OuN(aK->Ynb)PpFIr8iBEiAMg!>rTMyqv^Tpmg z@hOgITlggTxu?d2m@kqxq~!LqT1jJ94%BCOfL6pb-f<#aDA=4&*7EKF=Jql|oxn*u z2iOwBm}IC{*G9(cYTY1L;qP(i!GV*romwT;f&wxn=iJ;&R>&q!o;hYAA1^d-F;g*J2P1hA)3_aRy)|kT-B--3-s0 z3-`fYz>u809KCl@VMmOSr2S+EFOr7)Rc!H_I(g=?y4Wy6Vw%=vkkiU&kGxn9LNha| z;oS>RWq58QP|vsUTzHA2I(V1kLwNE9<)^EzKB=T(cP}urhwFyHQ>$Pfc#g%^_LN1E zEE#YM7oAoaY;0EbZtQqG8V_&4hz8%iKz(N}bHOv$sFV6V@I@t}zrg+XVtaT1d(aQq z=@V5tmb~(m>dlYw3j(@8j^kCz>&mb2CRIIr;0H+uc)ze;l>qBP)$M1uv4~2|@vQSB zK-zdO9=WI-H;>7$i?mdj>uH&4`=p2a8bzLd9{xs=>s@RAC8?f3=%UT=xr?cHj9V|q zoCSQbjwoy6pT_{C!ffWO33*z1$&^|dZ`rbrE_~<#Ru2@Y+DMH=5%5hUe5(YJ3)4!- z4nqioSx%UxBOqT1*(yjJ<4>|W63sO%MVd~r{(8+lx|ZfwPFRE$g*$0j>C~1x$jn8Y zg_zhx!9y*Ix;Esz>5~)gMA!3!^>04+rC*0(TuDRNoAnRNE#fl@+}{jXUX}tOK1Q~x zpYV%wV+-&ZPi??D8&p4u&a(DQtJaa_q7YU;FF2(-i9hj@w(-8@o zv6?l&cDdp9gm`5vRj8COxyXExzVIc#n)^{bcR0&TFa~p0&lzHcGgJ-YMQoxlQO_vC zau>1MGT5MFj?d|h+%wA-9f{k~@QAgMmQG<}$LiLs6II0rV~;gGE;Z5C$%<}UJM+1g zZSGi6`J-cb+M3dw@j}?kZwv)b85udXZZhv^asAn>9YdQGQIJ>(*}7q4!INc6PiAf& zBCT0FhcYQmA3t22xpOds(zMaTtZ#FG&m6#pz@QkP!0?~_2cZlMp4oqpIcUW1e5U*k zyBe#et#Aim(3wEhdSl#Z#V|nikH1k}Nc_qM_V=sK;^_YU1LO*miSRG5&kxl0DF$`{ z1vG%TR%6wvRfkTEpHlrqO=iBP7s;>cYd==$a+@Jfl?7iYGi$jw^BQrVpt#u~xmv1h zr1aMnVvfLtEM8`w5rZ~>Y&rO=sE%QoUV$zmN#(|q#nq4YM8F`6RkqG) zPAN6oA_Lcum;_s=6i3HsKYNkL$RjK!9zX40kf1OMT$NtEt_0H4f%UuUaLm#~2o+5I zb3ghl*cTX<}Z$f0=YSX9iS2Mom--GdlD~f}!z~?xO z**p`y^KAZbmf@KmJI;ot91}X5`V+IkEH7ruUU)8898lDkn$@0QCDPUiE}zUxY)-MK zYxvj_MRu^AXaOg&i}dr3_qCQNy*2fGvYMuI3iqz-Ee+Gs)RSd5&K{M8^=rk|t$FlZ z?UKV&H4!G7TCsCSE8&RbC3j`Hfse0SncSYfrY;;4&#bmYoL31ex{?;jI^BzsVR4L^ zEY4#vZOf|8LYM&b&hK8kJ11@P%8mlaYkTE)t=W~c8bL=jusqm~fM6FK_AiXVGWXO<*tC&Z&V z%r_@kN@&c|fzT!m${9IZ2NvjV7X=qK1cjGJTJb&-B2k_8&T+6TvyKjO;}E!;BTkg z{YVXncT^_navbXZyN){kO6@(pcSp zhtAbj9fl*5K22TL@41Eh*7cNyYRw*j7Od|n3&Y#}S506Xyez|=Bjzpv)|L(iJQZ`4 zkX0g%7l~!Do7P%~$?bWOzH6}UG+FiNO`)_q+ce~+h{-1#pbfKE}DBVELh@CuwE6h~8qxMCqR+{0?sJ$&S z?^wWx$^~0hm3Ze?y#1~YTN77G9ws;Vvutb+Z3DYkFq;?svC<1NRb-FyIYS(3B=eB+ zVt-k5rp`7|Ku&$Q-{N=|NrM3jJiVe8<6U`uCnZ5=BQYgqoNiJ|MEzVARj zdH-BK8HNJ*g|AeXck(LLHHbgIRF6%A=jJ8U3C7t03M3uv!A(IhhIcOIcuvnD*rRk> z_Q0t#yY>Ai3PKw_i%!7T*TKqlwn>T6u=bXwrc>Ly7uur}v8|iRjlZUTcOQ7vGyD^5 zF4ERuE>q1@qFItyv#ZWWQ>%3S*?Md=LnN5Q_8hEkI^G|R?_|!(c|Tc(Cuj=O47InI z%QAV9{W#3m)XiECNBXekj^tgo-cirm)zl{fwwA8Yu8XP^3>hj|=L~;NPQ5xx4BV#< zViX6BB4Fu6#Nt+e&LYI$iRaBd{EWO5I(d;%IX*_X9&4JoO08`dis*#84WE)dq?uQ* zH-tgE7}gu&Z@1NcWQwbd;Fr9>6)mj3Fk?-Q(FX8uY;Ee(x4J)Anf|th`7p>@$vx3o|O+JWTuSG z?-Hj}7}*nt&KGj8AX+Av(eA>1Eh8FNwP8O@rKMQe`oPQiS z;}=mn*$Ufskdp+iI8V;8X288C;F>P=HSO@FzC?X(5?m|BFHsnGs;_}*EqLADrM2Bg8VqE(B*mHL%W(>^r`L+V-fDDR!w2iuDS>m>oom*{1~%-9Xd=fx4Vp6OovQsR3*P zZeAVGKse>hj@d$}xk>iIseqBK7aY7ziN^eda^vox=?6bFv(d$pnQ##=GFV8C+cxIR zO}LZ08dy(RWm^>TmnnB2w*xA_zRA_`_a>H;Bc4)y< zlEm{r9$`{IYwnWnu8=7i`G9^t@>JV zO1W$?#!+31A~eM2;bkHGan*+qj4pquqHb@40;^ty6EVt9uwz1PY-o9$GhzK;4LM3P zkrAx3W7+E2fCtu?Lr}ohD9z?1=GN)Ls4JgXhkxUDLsKi^HvnLD^STZ<&p zp!iTH%Ez^A%u0SZB1G04;+Y!1t@a&`W-Wf_(Q zUkxX=XSwpCq7?^oKiB59onw8y3KM)KPif>0J)G`UnjLMJc)WhuhC&-{ePy)9!r+?p z;vLEUPNhp~X5MwpNQt+0|C_8TH$==Edq&bVFs&10Kr}@fI^Nmv*Erl`y%!h2d|_65 zQu$bh9nSa64u?#fiBFQZL0*3*%q$ozI`!U9z4tCzmL=Je+`BB}if!CwV;jrZ;6gEAnPQn5NC<&ILI~-U5FmwAO0aJA z|7Pz_l4(hPf5L^k)85YPlsB(@?|Zr9OEQ6|h}!KN>1lbCI0Zzye*zG7X+m&XuoIU+ z6PiYne6&3!QCLGQnAc)i7-S1(mN?r(&_aPXWNZ)@%&TP7N>K%^3yV=;;Mmg}sWdO!_ULfQPS8=s{Wayssdts+FPSNSBl#2fpKPL2asw(h zHzz1$4%(Ki_=ZAlu$x?PxLdsTSXbWeP0LEdD6N=ypuP9$gLSaI6Iw3njtp+rWI3O9 zZ!6q3G&^hKW$hQ^V?$t7YwgKzEG{nt)JW((!cFUpvF@!GdTAXnuGc$ z4yhA-6fD%Gbh0BeQTYbHeg#kD4mM(uv&KjA`p-N1smkS^_tjm?*Q6P|{nXjxOcY^^FMq}R z&*U9YwZij|cMi<%m7d17%eTLFp#36u*Gicp>b z>=)TXti8m4HcN=JWxKp~uDZ#U*Ica8e|DNK4ZRdfp%tKQ{GMtt7dZQf)`sCa48OkX zey{u1UmH5=b#%)#w>0f?nm&uJ)n3-p-{NQZUA$Nz;aK30S2DfHFNp15raxzZ^9RpB zz_Km=+aj@fyvjSp%gZIkEhIJARc0evzI0=Dntbsh5F7f^?H%#dLU}@N?w?fXU&D{y z+7F1@UHl5EjR3Kb`vc@DEFEHshuzkcc5!@e+&Sakr7i37oRyo*wauF=eUiPrT{LbX zDIu=1O)`0qF0FP){Qm2Rl-*s?0nEY5V^y>IlJT}UVxc@GSNbI6`EzCo?L`m|1(~xy z#eA^!P&@Z0c{}t(4>0qY5lPQL_>@U698ek@+y=$Nc_FaOF)*cUvk}AjlY%=7HeMeI zw~2OGGWGUE@xdZ4#(?R(byvbr!Yi@evE3(z^Q@!gj_T|d3Fk=^mXzzc@a7na-tf!w zZNypu+^4>fD&+i~fQpgA_4hW3uf`2@)?}~%00-XGk7aKoW)*`BgL;!T3u6Z^mD>&& z^xAkJnNX21rQ_IEgJ(rLZzNDat#$3*r`IMfYt^{~)^`u5_aDZI;-D{4SjM&%H{6q# z7SzP1 zg-vuN^%?rnsTL0UUS)h_Wr{DMmD?X`U!S&hX&&XY@mm67y{!^|zRqDT(Ir}c`K$bu@||4?7~2Cf#xFDq~CD>UwbD#5l*2=`zZPkGV{+{?Y zxTP|VXlfj)?2oz>=pl89GaG7 z@WGii(d6(WZn=}?|5Zd911*jF9vO#mXEMhy(%*;y3`ng{4KP3I_>=DqemffQO+}=x zFN3`LmX&_{cjE#PgA@w*gRI?eh(V$!IM_M)x5gq};&Q`X6+0C%bsK9Aep_5}g7-`) zi?3T>8N$uZV67{G?RXe+4tvIcb6m94$-^%(DO%-~fH}$sjkX_%hmh?3vz(o)=EGa$NbugB|N2Gx8~y7`Hh<<6|`o zZc?K#fWpc4F>&GF<9cweDe%E53Ng8O#8Z0?k6b-LoCo;7S<_1wIa|U4po9eR?{iya zM7lNux|2T_??R&cG= zp@j)voz%iDz{NEpz=h-3J2$)&)<%@4`1vFhg+{;{_lhqJcMA5hck~T+bq@A+aPotC zLgpS8%aO~P#Iz!TxdzxHyU2`gYAtc{$Vv|3KfEoz^jO@h;^+4WbK)B$N_+#?&V4KnkodXl7}r2}7~<053dF!V zTEkliPrO01Va6Df`Yx*Ii~zsnP*?ZJv;e=92)7#Q8EEgLvg4@S&fV70$IbrV0U6OA zZs93@{^^k_m(b(@?1?Z;ht-^{z#s?=ef7|-xG83GlE!v8JWEyp4Hzqx0bDCfklSq{eH7I z7O-V(F@N#ZwM>XF{|QUKH$5jgc=dsmvJ6I-%9;I>{|omCfV!}%aeheSV7kA-0R_`$ zzO^8_=jnrc#Fx+_^D?pQHBTEFWc&!HQ&g&Km-t06%TlxPkkD;xJ2|l~*&04Gv>WrM znf#bC@UWv<=F8zPK)*%~2ed!f0{m`$!@D>2T(1Nfhwq2ZJ%Vd~i)%QB^k4zcK;&c5 z`$_zlKgHa}zRA+CPV)v`tsiINEyO=Kto$@~PpvQZ)BNfF&AA5LL!!Bgd`48?bhQ6> zNf<|tkN@A(FtGoDG2ut>jCewp@5(mPpY@mCpmP_A?0J6YE#wfx70fXkhTkELg`C+G z4ExRUlh`Ym+wUz$S0T@5Xf!Rt7hPw~n5VqtK|v7^i161jfH2W!0xFwXg^~aU% z=uMN6tT)bdiAcgXg9O3MlVY*#oR@3mzH~$9uI4x^TN!5?klvcrH#v}L zWe2~wV^m3so9O59Rz<3#on?IG;2me0>-P>6hM1e%S|wC0%X!;F44HCTdFJu@m2pE$ z+X{f8s@nZf!^)`TW6Rs}ZO)yho#PgHJUK6pfwS0w6h*Z3C)Ia$$H)bBT4jW$D8iOk zRNZm4uk=uA-SvN4HQsT-CaJq5MkYANmc}G@m&YsjJ0)fp1muj>Cn{vNktN#WD&c!H zv3Fl>LZdF#)vcs$nYQoZT41^(V#PS&k%nV~Df&aiJGC(-syZF|Oi*rX!t4uP;VNqq zUcNjlrn4-TLm49cL(I0rx8n|-5_%WIen4X4(0!VmdRG5-#dPh{j}T`r;MTvySn?mMH!lpN-5sS`hV-g)qa!!;b&cyOlIx#r}?T3f5Y z9s2h4iDd-{x)1Fwa7@^=yj&^wNUCgVhvCS^Aq4vH@AxulHs_y(IY*?2VW+gw0m@Jh z5HrSWypd6E7S&#%mC1s0s)C~0D^tv;mCbjYuP!*WGEd+_vTCBeM-4%uq*SADkT>k>qbp$Pw26ZCH<~kT-C85;@!BGG}k&vV@XmSa=e7 z0n6;+Q(eSmiGvLp=H?;AV_{Vp{$S8aDe!Nx5B78CIj4Y7yQ)3ow#uR<>r+U+{xU~|K!>L>?ZsgI(rO7JK-gcm2KwHL+*xhcpk{l{{d0$&v+rgap>2f8Wg zc*&Wg+d30Cn%=wp;L*G%OHLo!+6DzJwR`-)(LA>#byr_^8DInR#Gc zi3F9flAfVKCN~JGwR}oG#G^BPTW9--lBD#?Xh%XONkGM>#>BSb1RD=a&xpLZ z$hwjo_j;$$$apVTA4f~U+O=@mp{}ZJJq4}~iTO3r+5P2-euyAIoyT)^%zetA#~i8f zK>{u>o+PGJf(nh_eSG+9lQkr6oVq@BUd4xSQ~DKOoi(~|ww;?g!Q>5{`!%ri|Hl6C zK>X3LiX~^dS~{c`97PLQ`oAdy63cov71tg~=)8UfJRZ4iE4Jp9ud7S&;N{nNLE#cr zln_&ytqF3IYrKa`E7sP;nv*ZHwyo|f0;^7Pw*GVO9WG~Lb$5XpX)e{vH}B3N>Xx?p zTwu+75=&|tg2gxUfvnFQ+?~(*NX*K_-P~`0Vb|gVCenzd1VKAnx3|r#?Hu$x=`?ZN1nZw)CaR zW;T}KkNcQ^kWWGF7UuI6ycnX_sG@Tk!I&)1WH}SuOg-ceiGR^0S#VZO`)&-EtZm5% zGzSAy!<|pBr17&&%pt0atKN(Qhsw=k+Dh5kqvWQzhS$bi`)}^6;z&ek|Jv<2F2m0s zsv-K7MX4a_{r0lAXo8 z*GA=+s$HDzC9ECpO^yr+?&(R|){@k454od*-}NAKJ7s82)7YI=UE51s&4&Ol84Bxd zK;lqPZc|rZ#5j?GHB!7aUUYE#NEPy=iZ@I(()}3UEYVL0MBQG0=CwtXRGVNAd^f{b zQWsO$m-)IRbWkLMzc_*Zx$^QrsI}vT{dLW29IYHO21_@{BlBD1m)_GCW^O%j|JxgD zr-^^n!R1BfJZI+@R}}57R@m5d9e-iuBC%}RrThLW-R>3TcJ#*ywW)wabsWFhzV(N9 z)tHM&W3?(6++XWoTVI*x%hMo)M2K0r7%T*1Oqd@~(!7kL!TPmW>E;?Q)E{0^Xzl0{ zIIXs|v+F&h=u&ccW0M01Q<9*9*vG=Z&^Bx$cJf*iAd@730Mq(SV1a~1)1zj~6U-_Y zN2>5IOpCS<6jpvPdyA7oz3gSt*P~?ABR4CqJT=tQUa)hIcs$C{PT`{|>e^hUZ7Ym1 zSLM|$$(gEg+)Jf3`r$k#~wsS^8Xsqiv(lXSuww-XkXc0rkw zU=l21AraRwsNZ}R9N&!$dzDSe`umr59_4st3_X&W!A z7|C^0r1)j~=zniMyg7vjw_QYNTBs{eN3E=cvt5@qWE(xp)`b%5(-aFp zuu{@>p{(PrIss;-3ymNVPBE#v82>b%C@WX1&?F~up!2EThb)5pt=+7h64Jx7WBn~T zs0P9L8V_P^eH;ZOVtn<>^l#8Yy1^SPGXi(Qjd;Z5AO=j?x{zgI@B5h*VrBR{I~q2p zY4+g|ks}%nJRLm9audA{!_u477FobnxuwD*GOKB|E)nytROQz8XB6~g`dZ55R#}== z9>RU%B}>6#_NTGsw!D&8xW|Md2ri4f3$N3{2W2)s^OUjPzYntQP z)Hh)2voQ6^t!p-KitoMAKu_pro2Q#e{mmY?iq`fr4aceC^2;iaoaj@mlT4wAl8&xs ztoNz8e+Z+{HQ8QUARwE^fMGzH;{|8rA4Pdx?!Lk$msTYy&07yYJ7iI`t_9pP9yxv4 zy1NS3&%7%RdGJMoy_o3a0krz)ealu|TCSy&L|w8%m(yPW1eTklzER5bC#akEF|UWd zA)S~;0gte{iFXF@3#0%T#||kKM{lE^u}Z8Nx${z&L_YHr$Y++641@8|iAHmKH?DhYuzy9Fl zXbw3=Qo6@???#npeT4p55P_8~&r9tAB^XWfz1)X&gQnn_XSnznSM!ZV{SiA$nu^k+aovE*3y-~|AM z=qY^GACowN_H;p8}u_L)v)S~FNB(uq93US>tJ%8GN<0~ZD&Ep<0b z6t)Q+g|+urZ<%>d9P{7{u};dJ8~{rixqk?<_y>8*ilHsI*z42S0wHGE;t63GZLrw5 z6#EA^4;CWHn0c2z{@x9}SeAY>L(G8Z>o0=Cmlfg(vV_eW>SxX&@4$qa@?A7Ci$;ZC zuW!(if{v+?Bqhe=<`Vt;a4OEe)j^7L*0y4D+|%1q(8ChI{g>X|Gko8QM1qm9)&GX5 ziKzJ-ayOBO?nQ^0WS;dNqILGZ= z`Fl_5og6jAz4`RfmqdT@Zqh5Bq#T!h|BaWrXz`bSp)Yql|HS1&j$g&bdhP*u#8;sW zIMt!QLR~eamr2yU5>SCZdTMNDy+%cwh+-D#3+JxJ;ARV`;{kjx2>dP}i4~ zyu2yH;wkgaL(^@omp0@mh1jyL_$BQMSzPtd#$CA`_pQwmp5g-wds4Et4HPLAeuYcZ z9`xYiJb*pRXn{UJeDELAGufvhG`44QNqSFZx=X|Z%XJ$%3nQHgO&UDiOVYaXus(cq z`wMc~Qz2j28i9XUS|fNG=BszW6lgg9f#>x%o|`@Jf_?_MWFX?GyLB13hRYbsAI^zF zFUAsa6n0>kwsI`n%0llfB$)X!n}CF}k-L{9*(0N*RO9EY+{13dc4piIM_w;GLMa`py?g=VqmvCowYP8xuS^U+@ zw1+FXm7UrJ(MSYglJf3hiC%qts2ObIW>oL}IqX4CutPGPUGkN3lCP8{UE=i9fL~+Y zOmlECYo(^_d_w?pOODp!#C-h-)uIK!QGD{1$lC3S? z_gp{YjE|-GsN32ic+%F>udf{c)!9b!;!EuPs_|dl(*)?t>6|t9cGgag<@1DFN@tJf zt~uW!ePm;hB~A%L7=wkq%4Wltq#O3?yGI8ur{DU_xK;m-Yy~)i+3#M%{3R{ShtYCg zNdFX)^fSv_XF8W%7>KYenb9e1wH<|B&$e%3Q$kxj-3Un;y>FO&UrdDf0IP-lH0@&j*FG#-P^^_RsBPY z#gD80;%(vwYb0-OPR3-NH6$_fP0zQbF>%UaHLy)Vj@{nc?98^?+M>^b$%|`S+}u~B zojwcgF!`DQ`HFah)aJLfxbwSP`_6{gx>$*v;4gvu0UnI`yxCDJXnhwv;aL2P*OIx5 zklqr_`Q#3k7p{U!SZ$?$)q{p8IlJJz-n_~!?O9GYoO_SGFxGZtd2xus!pSP3YIyhg zj^z)m$>hn8i`Ue`s~uX@JGLQ}oJm~0qPHxHa?y<&ipcQw@qCVIJGLIXxB6h+{gYc; zkY7@;`RX7WgCgjHuR?B`II9pr(i*X2UorX7Nz)U^u1f)=mb(UvLapVm4P(Ste%~63 z%)X0VUkM{Ea8`X2mzTC>)4?+p`UxCJJ@pTqoM29?|BBFy%^xZ(v-rXzh#7hy+JjB% z4|fm5iALZgSAgKa96p>^xA>g6?x$pCwBN$K>%{ZR$Qye7b%hGKbHuGj%-`IdB~cWu zNdCc=(TmHq$VK4(k+Gy0YBNnI{)IzqobsXLRmkk%-Glv%aWHw4Ign%Hm}H;|{EOLy z9nTyQ^Gpbo?&>?z8l>PXYxdk28=mS7w%~}uA}ptM!>NvthLR+UqspxQ9c48;mR5KL zR=4z66tAg+SP z+|D;Cx@mcCpp9K-$Ck37j0m?$s%_tt>k?XDU6klYXx7l4e3y(hZ7JAm(OCC#=>M+p z(8V&GlfZJ}kisIx2^Q_QKogsB6p5Z8`yxA<%9Ff!E-<+`I5;!RiSkvO?=F2WiFk!I z6lvr#kA#9i@ejWZZLdj{%Y(A30{#x(08r9|X4WM|>5{|kEF;r(p-tw?-QTr)A81p zWwEdsV2X-#5aR5_vp`>oNNviFvaO-_o!eP;O{)*oPFGVmo8aW~1oHds;xk9IYbNe0 zC&y-6#W0dCK2Lr|t%?rp+yFP~7m`e$y8vzvYqYUQUqKc-(v(cVN^WMNa=L1bxa;ra zy-#0zZfn_eIdU#O6bp&{&&gY2D0|UlY9?lqXW2{tC;hMRe7@k;xfd9hbgU$!uHr8( z8zu~-bu>@y`xRY2uxy0rNKkGqP*#%`pg{G(-h;w*WD5+Xsfeey>V$il1r$*WPZmMk9 zQW*&JcJ1bB5|JMRVg;v&{HVzEK)6@IwkUC-Ai+S&#b3}+XqmHTJ`ftRfKE1mVxYdeba`j`qNSfbTgh~CY{^#sWoqG}MGzo2ela9kD&0Iex zp2@cI3eRlaQk&=$s4Y(nbhDLrNFA6Gf0%P{&&Jkxaz3)St+y+Lye`ct^TY|8aZkj3 z!KEN6T8t!7L(h@V{xCDWQw-ny`u=M(AAHW`;5mfZTU_|;o4DTe>c}tKiA z?(o6ACZ0WaZA!e~ojKiRTe$Pg&4&G3B6bL=@N|bm+pRG(VYsm>6I{UFE*&O8YTQGn z_KW1T065@iVaBiIkfT~d;s`wQpfJL^n6`P%mT|3f#+Frm#i4}yiZ$etCy6ZU8(FRO^KWWt z$VZZdxpMZeO5js-hj->!#cv!e;)oLQ4uv^U=QMToKsvB>B|amqL(GLyDUx>opQfkC zyXU6QZSFajIQvJe!B*~GZ17-`h2Lzz;C%{zEY=g|?`tZWhD*AxOI@4RvZo=yJa$?m zGglWSWo$_6x=wc6V*RHM9BCq{;tO$2V6LWsaj6XJTc$9qi3L5&*MXd!B3q`W&ymgN zuFrh={*0+7+`ST82a7{JBk1wFZ_>|>F8ub~Q9Q^ky6E?_ZK9em?+rDp!~R%}ceaxC zY7iaFtk?QNhBIS6NKI8@$wX_6Ojfe)WQ`aCEAHA zRAf767gNhUPP~#N_P4G$BzTuBSv{T=w)DjlO(3jay04l<)iLVu^q$RWlL@1(K@0;dU_?gZ27%@hd%peKUuBBk5U^wK=b8ne;4cj+>jgUWC-PXMRlDYb#{3 z%8hrIi(d%#p=m+HFXQuw`ob6{naKqaEVrSjS{t@hhlmfT(?dbuj9Tc#C8~hUkvDMD zjK_@W%SL|;z|pq@sFAfk@6?5uV`yp+J<_Md52H;SXJJB?)<_*%w zkZ&a|BH%-$BizI|!uTo>jUa#cPYi;(m9>f1Cw&h!cde^(QLCxO3u-ICIa)oQ{dQ zM2En{>QuG6t*n%mW+Kz1E)Nv>&QaNFoM=5r0IyhEUO!P6MmQX>`G@yxXo@2zBXyli z`a;Q%^*<610CgW*921%z>O|R|0|o(o)1hw*{=In#!j3uS-!pcLG?I4U@27iJd%UK7P&WE$@e9*Z`6^W&|Mc-IS0p(TC7v>!O~x|;%^1!E zoJ}+06B*ai#Yc=X{nkt3Dbj-xVl^~Alrc^cmd#|qimPuwq|yO5T0|f#`^7b@lC@Kv zQB9@k_Bq!^n(nCaQ(l{SOi=h|gD$2pLNWdPV}fN!VPbMic8KB{Tt~lYJ+&O*Mdz^W zh=vx9%NaRV$NS&{3s4R<6-`Db`dfwbGEh?ro(NDe}Qx{x&XAk`U z_5s?U;t~KCdUux6U+9B^N;AQl;g?n&MSrOe3Mo%V#gBk=1OWlxqu?PExtlU))7n~C z_>c%pDIlDSac$AJ#FvxxWQO#@^O+U-q4SWD6!<5QWGCmngn+##-tcInvcP*Pr(Nbvy>Nm`{w~3 zMw|`^pbfJ8*iD<1+7)}ww=d$FUph5bXisfb`hUSFTcDf2zBo$2J-3>9HL_~&J-D_W zbF<*|uio=$^Q3Aq>pZuZrrup&j|GMPh9eeuC*&0(rReWB2`Ts{=3zyK-j+P!(75Z` z@B+`NK}tQK5}TQnDqJMgmL2a1;hw8td$qsku{%l^F`h2SD!P~)wQ|RUZDKT56`gwu zc6>FuX#p+6%-|VD&=xeh*s)yg{UuM79{cUf^vnCdctUh1JDSOLv6#Ii&sh`2v4MM> z!x?oFce8*t^woQ)<@COlano_57oVg3r~dVbxS9kO3aAb*{+zv}W9d1PU($>7;?Z^Fe$;dFkV3Aa%3}EOP)b@@{N7_P<*xo^8)(j53&^9%rW-)()Ts&V6QTC`Z>A|r>L>( zhVJWkN}ZSFZ4mmO2%ku>gt*cQNTu_V#2h4ll*BwA#dIGg_^>xL64|UkM+odiETwWcM1o!8LKQQ21Anz{tb)R{EfhCNS?Mu@X7>TO8B{%67^1<|ibT7G^2 zLVuKn#8ACSf1Iv$;D}HDUf2p#`71_`br`=>MT}}832=liiQf#(-uOoP~h)EDn}E>Crmmk zzjJ&NV1i-7(MK0dyTBj*&x54u5?763C9L4mME(CTQcn%&m%#_Nk#08*mNb`;w=%}3 z7szs9kiu>1&(}vy4ZIx&P2&U#6>9G0-XxwZ!ZR<7%jGmmb;d^qam;%Y? z_bp?nIC6(^0O{OoVj=G%-vz(44r|yHX+d?hMUD%U%acfj0KjD4ea(UwNedD_LtYGd zG-E9YJ*Wheij^4JQ(m{E77S z(}ww3uXWBSYl+wOrn{4%g8uB>t_&z>$GQ6!vU8X``5|&fkI7(TiLdx$58|4$cSVlCg=Ulo2W5o2P@!Sxxw0s))M)8RV^o#l z70JHrNjGJMgtb*B%jMy^<{&(2n(0Ytzg0kXe7M%fl8_Uyp$kSTqM38eCM>BSw0Uzm z$ZLQt^IP<+#eM1ScEP!^ap}IGhdIu9Eq+wkc&1ze6{H5!yO}CGU$a1x7Lvo76%2Qbz59a(cy&2Jam$u+z&0;t-tM^_@i=sETVkdZR6I^=Myd z^sNZeoXJaoqg8SJ1VhKGYig?roPBd8e#0SR&?#fSJ<>7T#Yj$vc$;+yu z=@sG@9Pe?9g;}KgZO2)d3LBN35H3<~upt9gLNT&?l9PP+Cl0Z>wFy4)ssM9G3#UMD zH>Fs<`}!k*sV${$5%qbYR@R5Gaa4YGv)3R$a7)bb7=KF^k5QB((w>F8v$Kr7Zkz3I z$^_+>T+5jj-<-~yras>>@!y>b%0EW7{X3oPB@g_6q>tb^vgdY#f0)%tlp{`r%mVfd z(zz@tVJ6f0>)D|6@#)OzKj5XG`=42fxqPw$IXKHn@c+zC%+~En==FQ#b&W_{=} zMCI-3Jx*fge>b6+Zd3A^#pWQ#h6LS|4H7HUnPbESxfGD3>_?rpzZ?-O4b#K3YdJ70dTLjKKJ2|zpAVOI%lP|LYUru^sy1$}DM!hnV z9xx9M))f^L6a^;aDd{FodB;%d@ZgGc{hMAIbNiDvGQa3#58+{vWbl6&Hxsso zVU!s7Ps+=H+mlEm2VT=}965ez?dm*NMW{tu@BY@%%EA-}*edm_^YN8sM*pF9yM)qs zZ+R$3Wj3CXzOY+@=v`&vZ)=W^W+8Zm4Y^?Sa4GR?IzE(6CuwAHYn1pK z*QBKQ5HR8ZV;%M9KZjSqcS2)ITf<3!x?Ts!=npY+!BJ|G%m!{~#5i!feDfmONv~gu zCIkb=>d?TBl=Ijj30Q3`tqEC4AnRjpuJ5)e=>-SQ(O!JU`Mfj7|8K^nY;tgL)25I9 zFBT^2vt(mJFT1VJ|CJR?^p2c^t@yOdc^7)|e=|IVyuraOTf|TQFXks?f1kLW{{S{1 zKn{>XCW0o;#Qezs$)IomNVNJ!-te({4{Nm*=;!V@-8lU4>SXzhpvoO8$sB4a(grGn z<#s`7jj0>N?PS<-{gqdGzpOlc=js}mdIeh^8!BAOC?Er~oBKx+_0dcFS_&d4F`O5r z;x^Q2s063pd>hQ)1U)OqmG4FU~FGbsJgDE6nsc%ogn&P#y=sXOF085bp)FY zWU}mqQw5)C_-xheAFql($~!X;{ox_x!Nzu;}48p0vqemE2Edmsw*omlM=D> z%E%==5Sjgmzi;k!VHWEE`59{XVqN6=DVKAh)WUu$Nbui8J{}}*BUjZzaE1l$D8=TO zISchyEl~jC==Im?Q!`hMtxWG-E^zB99~zr7wsK8+w54!V+C5}>pPD#EgIp~La%T%` zS9B4a#NW&6rI;hUi7s-{#qnWPV5#uI=KfU8CbH$r$pvI3RHAHY*{290W+70Ua7X2La^8y@)--o`&gH7C8vcx^%H&sK6b75R$YA6## zE64-!FN{MiDo+q3#05I25n+ZMDCfjv%LjTkPgz~*-9jETCt6$a*<1T9#Fyxy{A-9`d#;f zk4v-I$0fMxf3nEOh5EA3JvV#qD;_R({z7x){|LpDGgbv-rAnb{8BD#!mDBi#R*JtK z)xYtd>ZfVj$f*vo_q(d7q22j<4jdv*G4QXW-9QGAk(ep95`)h-RdqPMQv7lyX<5wc z^q*@x$UDf^_Ct%Ao&KBp4u~aTY<>zMrNqwmH;_`JPTppYNLk(V(UfVyRfbw%S4jnv z9jqobcU@Q`$u;IyU{J0e(FLdm@=@Y-LmZf}kPxoT5q~S?in9a)UrCxn&tn(|$%n&! z%#z0|@7?;s<^(INie1lbvPQlb*v#AjJ%0*tSe8^SBAi!q^v9dmzI?cv9-?_8hsqib zFGHfbzSCrD1c>i)aK1`$J)kEH7Q8VhN^Nj>wTYfFJ-zphX)TncYfserruLP@DCBOL zJvkd{41f&r_gvok%S)P0uB);?YO5_@l9@GJ5k*B$W_S>$fe3|Y5cZLh;+_!BlBd!5fmRx1{_3^)Edj-TE!WY|f018^#B= zAAcCPH{KKVq)hk3j?fbRuvkxoU)+dQAN22(h_5<>4u+`-!Vvm@Vd=k0UU=TXfAzDU z6Y`4To-^>Z{0RLtc_3N*-N2s3-SOxMfWC1mx^ww%+WNV^lgzwD_oG{`llskcn?7C- z@GyJURe07t=-1cpLH`c4!<0CxqB*xC9uRSrXt)fJ2iyaLCVvP0u#)E9=yL>s&sYAU z{@8nq3tDn&!S&0J7FV@oeZV>sj-n4=`@OJUJT|o$s6f5hs#}a!V8726e=F}o`wW9; zToJ~VXIv5Jl0XK&ap{e(oKLjpGQV;0>AOrB_)=fRcVrC1v#71xS08))caHZxur3wL zZ}nuYe`;@Ov_j#XKal%S%{+*L-a&KLT^Ya%thPTUt-##nWf53`CUgapqa$?V@~i83kn6MG9~lYDYkMW@rh)vEzvb-RY|K$<`5J7|z`S1K}v| zT6(xJeIl=HLvxy+LN2#R?LX3GpH!ytlqm#i;h`x>Kmo2ot+ka*6`EYqo}5^d5?~Kj zFW<8vm7(IWd2~T~j-@pxSO$lBNBOzgDmg3a?&lc(3c^%q9n?1XS~D7|In;gV>2E>2d_WUs zKloPI3&!-%cor5~0+xnJa;9;@fw7P{@n>WI&oBEb+*yAfU}u^)Dt`gOLJfYgu|??;1uKk=VZF@Y(W_wx;{GmH{*qc$Zh8vz)7^eww9S zC}9t4BBy!javXT%Xm~=Na(8I+ES$UVmmy9!h5Yhk|mkw5LstQynOV=E$3P|cHjg>3> ziUzZ;8hI;U`y=hJ)h*v&)o^6A)b5ydY;k8=eqSys$(x8Q+4JOxg%Wlj$FUT5XRgf! zK1qfU1vYeclunP`0HdU~Wh)pZ!Ach68p>G7*6Vf4ZvqIfAEt-?JzF}_9#1S4Mn*~c zGyN6}6xslnB+sxGrZ$*Y`@jvmeQA9CddHFVL~) zX7{!>Ja~FXX9DGhra#%fk+bZ6X0jc*j6nyzf?O0|zDSYGJ-8~F_&1(iFYQlamWtZg zEQberh9pZ36Uy*YCN4-=;Rt|mtMvyxxGERXzj=RKs9f20_(pHriKX$fr+9ZT)@Q72 zNm1Bs+k3xCz%TWg*WBJ|f+IHqM3@BKVb>|_ToCOwiRvhD_Fh2jW z-5~ur6<6XUs+;z6nLJ%_m$7R zj(!E1eOM~}{qFtJ-+#&e4mkk(g=d%!me*iLu-F3)F)ba8GnUt=He`Jd2Dw zjMGg2d)?x7D(AiLqM5JUw%*T(8U$W`Vg9kpyohcYOgMgV{OC&W8;rD zd?YlI;r;@ef~;XK5%>bIr(wg+w@7~3d3J?XO7H6@9X&VS)1`IhhnrjT4iDSdSXh>> zzqd;iyU>X>NFb9sLHIN@57a^uL2v#50+hPW$i1>1{OGHcuFT{CN=n{|m+S@$o`A1sSi2{QVg_tJvoR*>qr z$qI-tEtqmXDV5Egkv%W<5WI$ecy}`;4xxFP zdK6}f(DjUfXCxbCQ)xg(T}NM(Q|e~MFj}2$>un2J@E|Z1_ha01F|(3srZq)6)e8Yp z$ofSO4Hu6w6P}Lqwh<+XFMDju+t3MibI*+SWbuRtDQ~-XELACsF6~K*%MMToa!!ew zDVpl67(W-8t<3geOS!dqaC*(Mi89^tLLZ*2(lqCXar6vPrT6O6o01XDMCM~m*Rdtp zOKUP+T?!le;_|(dqdY0+pH|(}65R9s9z1K_?u{tDN=Q`AnqoXl|J?6+#^H#lRv=C( zi4@4Ra+v7(+VipV9w!BJywQWaUwCF`UWn2?_>zsig=O)Ysh;Fk9Jvb4B{C!MZMQ37 zO}coQOr_NYi=R7wQM7j;RmQ2)%0kPtKF(BC{$8q-UI z69a5f4V2ghWyeNl2HUgu)W3LDO{^{@%-(ZjWx2G+u8MDQM==jE5tMqf!rYnqQC^xSj2FRQ;g)6J!zsV{D~ zN*f>R;_jB5p6+!=d}~1{)&FqlMvg9XZ{=~ech8D1aSX#7#v-o{i~BwwQO5#e1#1jF z4_egmv#J*&no8p3GF1Y`^>-?wEZVaa0~?%H9#)mEv=Wrw^f6mdX>nGH#tQQCe4oja zY)o@BQJHFcGC!szDdBd$yK1{aOTC@!LL(wwI%_I$qs@9wxNVE&ot*A-}bXKh5ie|8#<3bY}3loA>a$CXf zVQgm`wwA@Hia#)*AIIxbor5Iwqm8VDPHo_1 z9`RuXy*X;7HD`CxN@-;<#>OcfVexwb0C z!j`wYY9+U}sbQnD8lw}XZ-Al;bv7xYPHHN~N zxPfGs#RJfGv#sq$`)vcj=ErORc~skAhvQrnkZLB;bVy8H5&;T2BPCAF&k;%-*X~+!R(eoZWD(vFXvq{!6Qoh{O7ZGmEx6~P48UHgqb#~F$#nAfhLzSz%3b0)xq1H3-trY^yMtJ5aKu*%_oXFi zMp7!)gRDi6TgG*6qYVwotCN#gB~@;$4n@W5W6$=64ZJwngbF_D{XU+gU}RrjXvVG) z9G9#wCy|Tmg|*^~4+fic(LBu`om#p?)Ohgi9%9%O$M%!7UhFvAhpc5bHq|?CtdrIY zbgVP81=u~ogezKg`!ZpRlZjEZxe2=6R;-V&x4EE2K)WDsix=Fv5qI%yr*tG|cI1Xa z*x281ZO26ay**WHio9gVRyn4>7EqjyLpC15z2aOsDZi((4Z&kV66f0-fUfHWe>^)w zO$yOG5K&64WBLrkSDJW!Ok_^<<@~*)qrN>E8LvSL7+xno7SQV~`)n1qa|N!RrLih`~*4?=vh`|`+& zbN$f($cE>%tS&AZsY`QmPA_fLlx}R#4MmE7T<@_Sl7>ugco;Hz3v-$hTv00te4qEz zz5Ef*&n%zp_@!CNtC@@g^aR~2yk+=qmswvQ`);mX9OU5d!XC_;`|TWK`pjZ3WV46( z7>ar<%%9Ba9)ZRNWh|ewTUXZ;S8U^ajlT#nT%5J1Y6GqX0)o5)Of&o8{3%9$WVgDZ zCr)SM@~ALA{1h(UTR9=k>)fRHf!QC;rrGt{`Rjjax3;cZQ)FX5T|V>_&Z9k*1FU~n zaBqrx7mz-(*Uao$l8JlZS+4UjTsry}M0yo)QIcL(M+e^@<(*M$m1(|xNU4(JS2)LD z{T>m2LY>S$Lz@nZTSe}X@znjL{mO>^_+neHYv77l)vzQEZ>P&gzE`NrJ5qb)e$yK^ zHfx|mS7I+%-~*Fe*bhv0@rmNPL(>Pvjjm)O<$4O)&HQ~(>&a?y5BfmnJ_Cnf2Y!bh zgb?HJjK5_*AntK-b=LK4akDEKUoZVXyUQL|arHW~N9-VHk8|eI%}yYbjrHRUb)pg6 zyDa7ixdrd26Vt1)KF@K!iNz6Nd2sP@K3ZKwcpgd;b8cb937*6Y)r~X5i{rsA>=j=W z%El~d?w|BIv!B9du;npkX13%3X)N(QUp@c5+VDO5JI4f+%CK;^Z<#SxmR3}IwQi9Cy#L!?CXq3Pke3RrD1P9gj;_xea)_(|61L}jdYQo%oSCU zC=`>b%|>y-s=?H@~jN#xs|*OQNfW(n>S&M^+7cFm3i_-;7uv48A5i zpxif8gHX69-d6Z#pnlm`zoox7UL2bpP=)A(>0L^iC#i?HiA*?>JJ@y9Y?6F#x(;A4!V%|psd!a)n37{dlb7f|kV<=PAcC z&L^C2t7IEp5+_x%btYBL;$x1an7oynw=sbl%h~!BkWITbJ^qaaZLe?Ig+6lFKYx+2 zy0FZqhP#bzZDUMQZ8E^3NZ_|s_pa=o)|2j@$?j04dG(HK%N~5RaI`8`DYuBK&v}Wv z`R%p8X}taw#Phg}k$buaFRx5JLBV8`pSGj~V2t2zEenpdPzkQJT{zJo<%gwZwYt_}y=TyuWF?Lp@Ys-9!7jHj+n@r&(? zZ`s?M<3QG<@U1IZMLmo6kAPRp-ewAlfZ(9Az;c8-UdEO2LglU5ZD>v=N z6q~&YY*jSoIRso|EHq%ayJ`3Zb^b;!jiZ)WkmVP%FLz&C!V*g-h8gfPC>l#(uZOi3!;<)rRFM?I>yVI zbK*-j+|%G_ZB4Ecds}e9>=}ZWA+ce3Qs}@-4;|2S$M;mm^Rzu|$=K$cQ2T@!R8xy7 zD1#3PbB7+vKNeoVPH+Q?9p^C95O0_EU!Nc*f}rxl1tl-iUv{T;`VSQ8T@z)+qs4wQ zb7gAhHoVpO%ceM`Z&E~LVXT+Tf;0C?4v%Do2}S-napL>eW}hQlzW*3GwV$Ty;JrkW zWb4MlF0ie@!J=*1P)OBKMDwd6HNd5prSMm#S`2~$_19?9gX=@M%_E$8PAFw8C5!T*8$w6@ibrZ+P zKK+N}2Vx@mK_!L-_uU4c`*L7s{n<_fcNycdFvhTaP07z3+hMSKKmdHH=INfI4c*0& z_HwzVa&Ys0UD2A>oDds9&^x9?t;>(=>1YXmEu^e4*IPp^G!biBWQS=PV)j+}yh zTZhZxqKqi%TeB@IM!c>8n#kTa!kr5vU>mgen4kgw{gv(xqr$mh3oj+3uedZ5q1rkG+e{6|FUZi;2J8N$KPHwTSpH_*FY~~ z_u=*%uX!46Jt1B5eX|3`Yg~-iK)=R6)T|WtR~)!_LRfr-xkRLj$TBF`^SR?jYsX~f zFq>Z5=d`!(cpQ(az^DMDJCIKgUl=^vsj*X7C@jKrTh|_H7(UY(XwF&I?!3NAx2`b} z+nq5ar+1enhq^1w0dZ{NM5@b+9O&=VA)eyzI+;so`L;{fpQuPFK6PlkJ)Uxnhi>$^ zE_r-s$w}~6Y|e8@pBO6OXmCN>(xKR_n9>9f$kTwiFd-l72k;Alg@}edZ+`Xe#ImAj>y{RMfB zX6uV4C+UyqPj*h~F=WK-3eMWULx;!N%yt>~mQ;Q@g)J*fNl5z zUHa_oXM4t<@PLT$;twHIxAG+G3x~1)NPd@OUlu@nGfG@Flc+2Z&5l(=bcktY%nUXR zyA*T|G#0LAhNr+SImkozKRsHutvk;?Y{`Zr zjf1B^TK(?{mK7YQ)5Nsa=u#uC!mllOv*!gL) zO2ezRG{!5b^U@!lZbLd(_qKw(?R}^#7g^rFc3YOJ|K(Gy$ZPH%FU;G%B%N|yC!g&I z326Z1D1@|MN_k^TSZL~w5gkW;P-v+u%2wS_SDp%P3Ak?>TEjwu8){2a7&+;hLj{;8 zcQGH%S~uq3M_i97u`qHaH{^ngK*GRte^&qmB-Tmv%AkZ zCmtk1+}+*XAg&}K0wDwvBne4ycef%bK^j_$)u2V{)C<(Ty>-9!-pcKz&3Vr6yZf9R z0_DE%``@qkbICb#=9y=9c6N4lc6K&ke0HiUTOX5bY3FL|7G&=e?(|qx8VPcYJ9EZs6&z%RyzX({G*n`H&^X1H&a1$f4vb(-_?EU{0}SPTNFm6wPMk z7aFMSI7@gskDES*eoAHi*LsD*LV@l==}z*q{0G*>qtFxg^HmS-j)yjYZZ};-7a%Ud zbN(glW%K>)m_Ij{ZvJF**=D+kJgH>hW?N$T+%TEgNS4w{HN_1IlINYkVptvK)R>v(vaE1{ipns*G3Xd%^<<@DC!s zDTV&ZgVfwP)YB_I&`D#>ESy8VypS5BVXwBNXgp(b0xGAIdg>n;nq+>pHKEJ*qMdB8 zd%|~4!qs!pB+Tw{cg_2DBs_YK`(OWb?{Wx2S!P|3kA{@l6I*+Ir#-Q;*LT?yYx|e% zh^?Kz(~j8K>AUQRwH>LewGRtGO>QKUj&2@$xht&8zALorKK#{5b3*6X&k37zAO4az zqbifVV5XAGBfIet%RE@D2(S&?W#bhe6q#gilO7bB#>3-9Zm~fK@;C-2c=Wi%1sXq+ zGG$#rM(DW88XAfUCy7BrS4hg0xpS{5&uTr0Ti?l(eah!2ht8iQ7WQ7_{QVg#>J$H6 zO`I$KV^0xcKGw_0!O2=CM0tH^`JY4fSC^}Q_?Xs6jrzBA@0j&M?}M_?C~7E*z49-oKrdIDF|iqiL76iq1h{9l z<+}tpS!Kq?mN+|w#AHV{oYEJ|7KdewBR9h@w3qon#}PHXehqOg1${VlNhh0ym-m)T zXic%#*qTL%kID9$0Y=A$1_UMh*=xo!Y8M(9oaASxA^G{sxQm(Cv@m;f-m)gt)J?+2 zG445ue1=KP_de;7n}h=rK1umLkQXtWRz9K|SQgJo5o=To7?V!NJblxYwf9-pe@T-> z+q~u1*lz7=to1EG-UoSxBt`?-vfcM>dh!)gut(Xxbl-XTwL^!9u8vS)tKN{mz&WeE z#%Ewy#8bF$&2`WB_icRQbyoN4zxHXqRsO_7XB547=3DtFN>eO??FQ%9t*}rv-zOjj zKc-Jvl$DOIqr0eGaH?NP*XZ`OC!f)r$(x>yT_^9H)@(p$JEK>>>(6uf7*rSBSz@Zi&T#pUT?^ z4(H9Qi7HEr7;O`mR~gc@y3&u(G0Hk*+l`M6&x>%R+sT-qoao35f1HFxn+Wc+{85gU z2gQB|_bG-~w~qXh`)lqk?p*tHOvCz9ExmV4^|i7Y)v)Wi#f`gXq{t6w<}9pR*PLW& zW2TF2saiegM;1@n+ZK)J{jE>8xAk1vhl_ucX57-yvsz|ZUAL6Z$l2Ue$TZ6q3z>4+ z$d-_eHQ)Oek`e3Yu~_X7SAB;lD(9b_7j31poqgi{<=TCFnh(w^v^F!h%j&H|tJ%ce z&-P?3e`#kaVZROCK@vOmHf5G=o0ZAXKI8|Z2FW&KTohKF-;RX1W|Ur^P3v8Tetm)I zT=e%QQ<>T*oBHK#`<45-T=;XJ;W<7_qo<8ec`0VK=U$+Hy67LtAXmw+iZy?L-4$6!sgU4{dmj~1~V|wP?tGigQoSmqD5d5F5r{gD`Bfls%@;1GmGX4xdpK}V&;0w=l z`sDnT^Z17Nu;B*=sqlENvBV6o0;Fz!(@!pJwJhwurK)1%lxX>!wxuPaEH%JP-Zu1X z)w)JpFdtsKs)n>o#ZGm6F%pu8d0PQ`2!xB1_Axv>$ZxrN>U1VJn|up-`Um}sWa*1k zyI0u({yy16`t?8S*BJZ62hVB{1LQp!^F2*)(c8apwx4q-+O0W_Pd1=EmM@iE2=TF` zi1oenA$9!e%GrXM`Y+dgR-AkG1@PF*_y|2f{u-Le?$*DrEE=XEWQTtDGDQQ}EB7dc z1Lt12hg=vq%ld}4;_)qP9{0Nn4L``a==cAVZI`2MChfkwY{BtqepY6-jk_-`S#Z47 z*YbXyMeOwI`i(8g7G`Ev_}H*e~?tAU$V z+gFyGw_{!jWBK#<^Nn51Gw|1ZMf-Uk&9#W1pXu^=KjL0|?gjEt#g3UtTHVBTC+ZbF z(Z#h@B$#QP6U!r%FL+S~Zb>5Q*VawlS|7ZhjEk*Ejwz0D;fZQg$}=R$S!gehs=y8t zoB~2_3QE)tdt-l}(d00@ZEMf3e&0RSWB#4fd@apv8h2k_vhc(-U#kbqEMjNW)Nh!= zTW%TKRy_$Vx1@fz{#9{w`m@MWnR4(_M_%u%hZ?vXuFRJ6ck~tU#`l-z=53#k#^?6! zL*qr;*$~=3Mr2BJoi`fUvGzVA%qophekg?mc2(@`NYZJ-3tN+(dqS!EB4%niuJqv| z_>H^DTmr$>tLignRHWJ~K324jIK`GH#1uxM5|hwl2g8r-OZl*Sl25mUZvPC7e_B%A8!5M(N7wNa(@-q|asCdrz* zbw^674lKyW&;EH$aUqT6i6k;QC)Cw)YJBHGBd=* z!Y--0udIG)sW&AN4I3LsQf2Hof;#Df_c_p$Y{&{L1=Y48nB=c4KYi}BvfPzD1S4w2 ze%lXJjHx`tWlMp}XI=Glq&Ru28i28KDOT9)@0v2{)|oLDYaUo@J+CiqW<|WkS`3ii zTW)QKKax0OPcyR``gPtata39Zr!i#RgD%X!ykFif?g7P_a2^>*Ag}8}$qSeDi%k#*WFi@fbxAR$A(E zNu2;i^adUe?to_bLl>OL``#7fV|7~luY&zV=RI#N4+_2d|>CcS<}xU!8- z+d}raIBlTwHXO&Ayo@Yvlh;73Q)e`yz%iki1%U_&@|j{cvCPRj@oHo_I* zsXSsKEOs@ux`7k4-%Zg@Zkwj&FHWR@}7hA!3&95xNxF=a6im)%icz3=Cf4f=O!d3In_du=jB zR&HZ#M0KV=mrXauo))r!-f~ZaJ7B-)3og?O`YA4Kn(X}7SKQn&DG)lub=L=b$3=J$ zs%p|1D6*)VjMx?%-W)czh1b~=VK;o|aW8g6_D?MhDXm7C+2x1ICTwm`(a0gW^-3aWJO;@ofOK>FFnw^rX$@ zl}ph_y5dE*HMVW3aV6h-W$8L4U2HV>knep-NgY*e(HoyWK_ z+DeTJq7&{h(J^j;5jL9pk}G4mWMa#cXlgP^Ng>ug*)bkY?ub^{j`J98=M7`$?CylK zLO!aEp9LKlV)jORr-QvCiw4?17)Per)0)H$bMdnQ#)r9LdZ0~rg=Eb)1UEa@ZWV}c^%-6IiyElMZpQ}a-y z#w}@LQe;h0rpqq=uD=Yw(fNq8!x)QuCxqTag+Ek&V>x`rmWCnr;u+|Zqn&{7!OKh`_U*)=}QLzc(-MLX9b z3_@&NLOq=Q9Ie74ld2M(iBnu6hL}AxrVAm|$9cQ=?xGQ_D$;G2e)~m@5BxLo;lig%UaUeeY7zAwk zZ*&Kq_cPiwUA)-FS8W;skqH=VJbBw&tIMBH-WaExPRYzptWR^NET*a}Bd&RT7~7*s zi}y~z#;P_e)i1-HtS39x-sS3>)tHbqV?6F*a8JRE5+6<+0u#Ja^NE8UY?(W9PbOop zpWjm`Y?+qZGLt#wo^A{?8Z%YO{xsg&Y}q|w{*CdNpAV?i}vxkr3p}bg9f^4V^X5H;4r0H^rikIuambs^?}UbR6wTRXRzCpEt@Kxj6>K zyC)SwmZC;9eL&SkqYa}+l$3kOvr4HWokY**%joXauwjWLYa+= zzx}vy-*L#Ob@6i;7v|?gi@X!U{A^ttl9751eQ}DfO!iNY3b1vqib<|ZLROh`T)BeF zDV?mLLT)aB`0E}@dL4boS=qP-I^nOit!p6HDcnc!2km5DBkdPA4%ZBrPe8(0qX8Rk z;IetQhxk@SCQeKeJ=2wu-U8%G z$ZLwvm{p1sb#e85nK3hO?@S^%V@m_Q(%q86-JHXc++Cym9JsFIUJ&eojk~r7M)mrA zE_5c}17pNe&R{Oux#%575of^+|6gxC_vcL0s!RV~alj=a-Pb!Q*wHyG&BrSx)TxrX z`i=3z&F8YWx4kC}+}!gY`KVW)d-+SJE5JD#Bc9-s`zN-9?b|c>(RmVo;l$W6p@AN_Ju5K8#?q%U9|uRr1;n~q z$X`74Ac4oVhH9*x9UaD5Qqn|iypzMdBE0MnL1cyjWrCcCeaj3~v%va_=o~~G3&Ow} znL7rUU&W~gk+12`#UqZ7imVn5&y+CY@kDGcxZ#}RYw06$$WAZheATQxROw&j=Mt=8 zwor)UdFy7RYUJd`z9oxd0-Kv^v-}wIO)d=f*J`U%vQjh@UiEF&{`r1n?$Gac0d|R% z=Gw3cwLTuje^y+te6AMrp`jzYqwr zF)K3F+uCf5dsvEp2qa19p|J6>Nc3|{D2>D+;COe~;KYh3zQ1)6ez2^$fW8`gn)lsH z@)xKt_XfU0nMG{bFD7Bw8Q^?llDAt#Xt;|{giV>oH6+Q$ zH6kp+#V5)}{^HP~-@fup3UP6CLjq@r+gOj3Fc(Kx2SS1oIw6LOO0ira7l?}f1Bs$_qgY*O)r;=fQkdYrGbW29r6jf-t^d7`gP zjk5JJ)lJcj^$hnO?K|4WF;dPa;YE|9lp#v>z6vg^3-w@>(nA_E97ZW`2`9PwCz%Ub z=#n0XtDhO!tHJV;`_|vc8=zb6{N%eI9}LFIbIcJNP$&VaI-+7LoR`0rbu8MeqIF?@ z{_L_Ce%i;(FR83!RatsRRqCkn(^p2F(0?Wl{X|yfCxv<<=SDNiJv=)U2ZG{p%l0oR zt@(aP+bC+AyEt|DVr}Y|)1307{%!rwTTJN}DyLCF& zs^B*VInrU+D_EswN0ww+pDVn%6bWkp3u&rp8)n%TJUB^wt?J480uRd{K2 zSmUhcb1nGCdf`LOeaJoK8GhG7Ny0ZiwTa7l=d zc64$|Ny~6s69?Ct;rLR<^un};G-OtTF`f^unF%@bSgNsLga~C&A5>$|KXOAQhSMVo zF%a%k$?jMX8J|V8G)9fXo?Tsgo>-pSkG!}qaCLaXCGxvssg;Jdle-lQJwgELdkgVi z#7?+$Oph*FgtyK&r%(Pl^e6Rthd!#u$yxnEx=|mkcgJ)5om%WCUwfyc`p#5s!+BzR z{x~It5uMb?vyJUcR9s>z~5dHc7WXHCJ;wr6P(ix1-_orzPN&N$UIL8O-5ijQlan(=pHs8KyV9 z-Uu*G4?YRv$`=sNgS*}q8$G2cd@IXJO|7xHIA&B-1g<#tiHfqavQJD&3gvEac!INq z=1fvWG%U)v=(0qbnm`g$#w;bwa-5@sy*a5O%wnv2sE22W%P2X6&!5sWkjbr(C68Ha zEs#OslQ2f&*B{9%7rb)M#)#kxLG`5R>d+r9>>1J^pw4q7jJ%Me()$)>-dT}8}FDr^Z0^1 zvj?rVZOQ9vE=u$>ceS+5S>85j{ghN2GvzT?@&_H$^Fseb%DOLnyX@hKM|Ur&M+hdp z?`ZqF0htCAOzB>f@>tbd5an%szCf zXX?Ru72%eaX4WYU3-_I#-g)2BTpUO6FYGKXSv|WZGsps0UO0po&7M%Tc3OcWd8PZ@ za%2RiPTzd^?un_54;m{2J+kPSW**Zg?opSCoSxMpncZe%L>gOvf01A zbnP6@nQTU!qAGey!kZhad{dQ&T&eVUT4j_Svae@sIdcCb*X9d%Zf(O6+O(cKXKvXo z)9~t^)thtN($}q+TN{g+bX<@J$v*)8s2JCyp%Wwb#I(3o#7EsKR6T-RJ=wqS!>x(7 z8oLdzDL)@#&%LzxgLyvZ7#{9K~RPVhqKVHC# zqqxib8%-Vh#!Xb`=4Yo()l7MO@w)!ObzBpyQW}@`-{01FFI?2k)v5opko- zR`Ioc%WZd6)8yrgJ8Q6q9ah=BVnbF~(uyT>YtdWbmEEg0!x9T#WlcSJ9ln2Sc+X)3 z$Khh$8_xU!!-Y249XlId-C}S}a%x7+>GlW3wmk# z6DPJrUz+<1%D$z~1mjh~lg=I8I)k^Pee2-eD6hPHNf&1voUYiE6?`M(M0y1N%xE?4 zG#oE2#$7e5J*k~HJF@xobI?U(rn3LYxBqYP()~k&PSo8yCoupCInf2dY17MME$%n3 zTYs`~!un|m*vZJN2~nD9(-v~ZB_+2cJTx}~6(s!fTaroB!0cqWJBYERv^Q1wC=Xx^ z7*;8_qyEJ<{$3G^7H8B&{U|u^!@)v+M%`M!!-ds5D7h6&DtvWju~psc_g8gXY)&6P zSTpg!qB2VhkK%=88MX+aEmyj2%jfMXtKPk|CC3{HA7NYhaxt!TTW!Un3IssA(4B}2 zyrGB&`G?B&_cY9Zc6%A_T8rPBgzWXyj;&>>-F2t~kY0g) z3qcza)V?*Y$7P?P=P$BweY^|XCOiFkNRx3ZbT>meCWpyKG55iD)9|44^#QkGk&B?4 zu}+7Gx{=I|!9^3@bN1J?_fPgSwI?zne)!N!c3=r&^Ac0A5e zLv1|b%i>GtRYvNxwo!FY(vmeN>f>Myt2UmQ((%OZ8p@^|yfWw4hWl^d)Cv`L_t@&_ zO7wDL&A!mai6zNClxEM~n3K4$HB0o7Gz~snH~6-{7LU8O!>8H@al+4Nzo*(x+Vk?- zWp}lCTT$DFeXp!ude<~>tFxNX-pSQTjoYTBT3{HB@=2*qZrV0A$&%(Q{NVT$#@gvU`yJQfxN`i^ zcNf_heYy)Qj|P$xKkF~*LJ&2>gzJdr+8Mdwd}rC*JRq%R*6NZ; z`=dh+!}*z$ad`5Cxs`El8tplqd1O;*WMx6BQ-w=+O%?JzE$FzMjmu`2p$bAl>1wT{ ze=2`GC6VPb7pz3wZo}LnN}R$n{gj}R2E@4gZW+&c&%s?NU&Dt7M}DTWd!|j(;k!^^ zz)%g7d=TAG7-xOAb?x#4%kADiJ~*VlrX&f2o!ip_$Y-694?G4_-2r$WTs1Yk zNQH6s!>W|8Cd$nMGbYYiQ&P1frsJIQ`vIHG!6^k@m5J_V+H>et4_v_)UY3{QJkhPQ zG_kofHOy5drmxKvOq&Wv#h?diBiJCDnW5Th0-A zz&88#sf8F7u3FtWon>@OY2CV*hO|RftDBIlU>XuB+4_H@JmB*2MJSR|K64?)L$|qhoa^AavYK0B0uC!f=cZ=# z*NvZBmEd8k?r;@sppyD(`=X?mEOj=JY>#vnysX65z%=}+aU$meKqe2{QRtIWq zV@V)foZT ztY*u@b7$_Ycefg=PuIER%qc3}ksaz&S>F_sKf5w%EFG;ew~eeCOKNvNIXkQ!$Ez8u z*l@aKao&olsW?FsyvifQ*^0fu;_7-*u;V(tG!neTVO$1+mmt2TH}%*5XAb2q8|%!0h5}xgMAn|yX@Y7?gf*#gn^RW3q$<*a zy60?MK8F`^8(*|?h|WH@8t1n{gSPnc!q2q}3sN()!8UBm(v+0-J;jWQQTea&WjGi= zZG+Ej=8z*6GdqoWE7XB?bY>9+c0 z%hp;SGmEk{=emmL*Cu=D%sg%4E4#Mc)m^_UejFlg&JhJMMLp$VW;*N0TFtX$jNN8< zVP&h2Pn^YQ<=W$Q?T_!m#iS9XGZ(MPezWd@quV=@^u98o7IkVPhCG|9< z@cv&4p2un~A^HWUhtC=#eFsqlTFT zM&|OR=*gOmuWmq<3x_3-{&CBg=N{@jzo~w-zxB9^ZS8!~Qg_=28~(lf)BR;)&4SzF zJO6CCy)PTlW-3iLSZH`3x)@iw>N?=s@HEZr*S4AEH>@LyJBwc3GUQj}zv1zoz)=Bq z(~o|-ebdFBfKd-yT4pS5Yd_qbYm2H~8B1Dc-qw|4OD9zy*wh#L{M?^)Izrn{eY|vN z?N=u!!$Udw>2kUD_GP7v6)ZbB*-&%)%5r31Ej!f$-Xaa(vP-b7;e0*i2ryFpV5t-rlz~<=)X6hsX(G!Bu%N z=I71oR}G9WTR%D6tQHY5s)S6uH8FHa!iugkGs_0g4A0yOR6H;3EzFx!ne01?^hM@` z*pab8$V7nK9Y9D>)zTXMcL|;Gqqma6%>R(lku^E>W#}`5f#~GRtVr`Njpq+^D$=|~V8;u<%*#l zsEe$*<@J>jqpa+gKA{)}&M80DJ+$EBw))Z5)}xEJcYj<>#?XO&x`MFYM}J>GaqnN} zr&AonAQju5oI7dC!?!dtqIhtw{(rukaI44u4W9|Bj`S6Eu>sWOq{MS3uUhnVkM|+8M0#@G~vWDbEe2)v8rwyU%Dm(k} z_D8nA>hemGlHw}oxhg41pRk0X%PgUv*f&ZV3U=TUKKe?6aTi$n;sXPE{31w=Y2gsrIVD?&S5@w zTDgA=i7KCwKuY=_-a)iD*84Em6~ledjV-!Z>d$op*=51AWs?o0G!*eGrCN`kwqi;PaxShf%lRpN5Hd9_yf}OBjDyHcsuy# zbS6NFodkW%=bXOb$6+{g9RcqJN5lA^={S8Af55PO7|twooW2TgH#{id;9s*q$SqRP zA0%;HZio+lqp=Wj=1vapm(3*cCh%TrHv*mr`YQeaaUKEpF~J9kH%T3)qcxb|?W9`Z z&%k?KMZfb!JAdyq-e1y<@Luxc2sqaV6@Nhb?HXM4y9#f|b{VI`$49iFkCuaeFL_MB zV_=J)(I}vkqrO*qU)VChWs4E;UeY!UXRl}_BfeG|n1#ncpW}OJzB9oGd*xv``$OoD zO1~W^lZ^Q68EvEKy@#cru^+F}vDG#Y!%wjUF0D6 zuMl*yrMJaci~ow$$ndqJNIp6emfS4?n@&*56B zy;;x^cI>S7N5EA(*-2!Qj`wnX^Vd8GIM*w!)H&Zw&{6HGtqK1i^gltxXWwbwGvezo zgAZcXpoaUDGI&=Rki+Vll^i7NvYewG<=iSb z4akx5NgN-Lt-t^I%gpgk;;Gk>j~6k!h{P=a3~a=hFA8yu%n1xH%Z_&-vy`>sia}?3 z94upwj#0|kGw_3QQ8D4B@Akiza%Oam#DYq!Y~a%h*NE>_sJ;NWJ0GY7t z!;QJ~Cx*+~mOW?dAG6Yo37-%dT$vYb^qDHxHHMf~37;u6yrwwIIbc)#;+aKe8vD?! zzcna=H)vdhQyStoVU<1kGq%?Fk%MlURSM{tIm{TXsYkW#5SxV z8|kUYfIy%0K{v1JYS1TskO$WV1E~d^$A7*MI+ACEWB0*?Uu(i2Aew9VLI*iMbT9>f zO!zJ){6pk}YxtUH09WZBBFL0B;o~Hsk)H#w<#ogSU^idI*GdP=>ORhyXQ!uy4bZ`9*N;5peDIJT-)CfEVYr%Y$7WkNuTIEHatGvcf?T5ZVNPT*!IBGki5;y zQO^=bvqn}vrbk(P{oG_aCa%3o)k&@cXM_%@eRM$jz|==S3!ULIht71XI<$HVPe3@wv{Z^be6Y zuhADeui_sf!76=3pky)c34F4P)G7UVugcF}&=L4J`x7nkv4Hl%Z{mIyp6C1%FQH?Y z$Jo2NEWis@xKz#kO8zv9)rA4B`d@>F^&}tg(NKcVG~WQO&Xa?NSXg5fKS_)c6~EK4 zNsJL^;D4<-Z^G|1BuH8npDH@uUKRhK;Q=9k%-i&Ctks6;A2hUpFJf4xlu-hmcY(#d znZBc<3F47AvGd%D{`tt?)EbsB!9jBfw5g#>DI=e2o&#;jGUn#gu^dW>$2~nfNyh*4 zF*kdYS6rUo!)JGq&8U#k$2L zk3;AO;UA;c7tenfmQyG&xPC=oK7JBB`|~Vr^k*^oUcfD|Pi~=$0~Q~zyq}MeILy=L zN&(#`Pq?Zs6A}nE;32E3b?0|Cp!zhE>YpqyUJG_A9`^{ z7Xf_q6zKFyZ6u2G1GtTD58$Oncn8@h=$kXxs$qQ4_ft-RpF0$D@}rNe_o}JalqGa>iVG< z6=1oa&HXtd<}U8f@j0zgrLUN476|$RAN;Que0nJ6>|MDWbOb)xCH*+eKjgikjP_^Hi4y#D5fmjp{ERlnw}c!||(i2`2m_DF4dWOPv0o@Pk$SBhqJrAMEVO z4+**9#v36Y!#dE>ite_+|nQI}UzSd`@4* zACNAX@b4FT$njynxw>kT9E(cT1Q zkmKwBJrW;!^1HCpDnH34`Uj*JMSpSrKNIa$`8hCEZSM)afyYUJk4k4^oVpA8IeG(+ ze*ivFg-fdi{De|85+AGWwSxZ~rD!BRYAXIyz)$cvjL=&_A6oLdkbe%&ygZ~`06U}7 zpHAL`ZVs<+dHf=QzgHTBkHhVlx_;p6Np)Q@*ru*q#Clk)2UPq{$spDP9Dkh9XBEG* zUDaoG{mj<`D*i!&qgE#R+=t@$eEvj5TN6J#KBD3uCX2*8rml1NdR4_g41MP7RZc%# z*hv-t2>AuEystQiV@@1fKjJgDB@l#)c4Xq#JoNhw-(k4 zJp%^khxQ6R_B7m~IjCEX_pUO+gUCwAC)uz_4ifxh-V^-8V&c6IsI>*CKe>&=$rXdA zVc~y=^So_-E*AJ$aZ6fqCG8VI=T6AybFC}j2L=6X=@Xn0f&77QI|ANIW)8!F?{36L zzjPbp0l@dyB5o(>Xr;l0Sf8tO*pTK+6a9AS)Cf9@P4L5zbCB`9cG@MwaKw|YN*0hq z0q)&EEeF643qBW+c7q;pH}L2}E*bi~91dMK2pJ6ucxRcAkx_TKj8yo+Mc43u67S`3{$3a4*`t;O zWXJ1<_(He;w>W~amPp3UL@442UtV8i#vz@I$0f$h25L#A}rd!{LwVltb!!G0u43+#%=;NV^2S zEym?1V*IJ&a?lVh#s_8z`lXPy3hy+;N&cV{4EQO*j|x9%m<$~xhB~Yzd5sawYX4;= z`HBC{Wayt#6!_fvzez2!A}8KKUI13rcVeB&+sfam#hOOQhSx8V+eMpTt+}lsvS^c= zqLERD1o+1|9KPo($}ywteT3c~7j$|ZRT;Y}*y9uU9M17yR8AQ2Q6B+xRQPn#scajj za}5rDKGAa@4f+Wg^SMN|WxZsNksrqEjts-mC%(#26F%2-75{*ApXgg*vxMwb+texT z7P432T+dbbLFq9Q{!>~v6CAbd)c0b%3<-Yj5%TFJ5k`J=yq*T|1sv_YY-;b2&`l1< zxGPk3Q`Ex{bnZ3MNfLBaIM*o-ht6iG@^ny&c>N3`obSOQIE419_`JO;{()+h{v3sj zn48u9x*hmp&KCTLIa?aWS8Xo0>8i~g>=ARVTF*krO@(*PQ|*Ili@DrXTYONuO~_59 z!{=ZXei*g$Fb4}dM}<69_z~$VVK?%WKAG3cK!o9c_Jyxi(6ETF=ty&k5BI#m6;2GT z-ZnMjZ)G(K7EZ~t8ygaxH}36bz_;UjB3kJroOZ4ct?+&AwHa7r1x(}P_oN|Pz~=(~zBUW+ zU?aR-#M)pEXqz?@@DL+>qVOHJU`^vL=tS8G`kMuP!;he|Pry@DeB~uUAFYLH$@pm4J((+i8`dxcLe21W}dp=Tp7cmd)&1rdz zMEzaj_+bkE52h*Yy2K9zJn9+_a^uW5#NO`En=QG+jACclfSPur16NA_-gqY z{=AUWN%*3F;XOfE!+)$z0{mek+{^GM;J!)=`&!^XYJ{f<{B?%k(Vu=sc|$LJzY_dn zjVfD+es~V}TIrOl8smd>1@x4y` z{tUkVCcaM+zt6z?Khiv4dVl*?^*wk$`&_`)_qQ)m;o^Ow9cql|BqA5Q-2z{b9Kc@@F%#Sg ziQW?hFo$b8h$`iLhXFQVIMvNqjtB{5tlKQ2dRA=Fp1vHdu4T`K#+KuYv*bt3wysa< zZb(PT=js{Z75%-LIwP}e|@p$QB6oiPfqf@DOqGec70mVXs7(P4UN_kDYQ|IAn$1hirRMFgz0Q-MAknQ^e7EoC1Ckao}-u z)z%1lHy^7)#^QI#c(^abcQJPP?yRO$(0#{9cb16HgOC3*Ce<;0|<#8-W~Y3Va)z*jAH+o@4W&a90FhLk%{jG;yWw_PR8)K-FGVA(w!m?;l?q7 zJYmfJoK7Y1)SOu4DR4{lKj*HyQ}TWkPhG#uN=;pF8qSHW*)%1VoOF)ksp~u?7N=>O zM`o_G#%r1DsU6#^qb6n}8B%1fXKt8V2sY4fVxL`%O`$)A8^`K@%XffQur-=*(QeFQ zTtB2&xXs4B@!yL0qn5`j@g4HvdmU(Zk@y}C8~otk^BW9yN&$IG;1v%)C)bL7pYK)r z81vr^^DE-Z;1@RPV7(fzd>Tw-i8zcJ|H-DsJgy?Gggz)Dj-keXvia>YfZvGUOW(dJ zelNAZhA(WgO23^tjKJsl2rB({WB!O5U*d6pXfWiHZOp5>F|Q$8+9T+nlD)_##GSOf znicrFB#)-Yv}X7&i|;vxUl}e5mHcJQMUqaAq$(aPu6zpTKmDcg;ytAlwjOfg`!COH z{(<-3D&PkU1%~%P*La5y#`$zXSBx(qH|`wpxX^Q=U6`x2lZD*MjPRp^?tRKko(BQC zJ_3F_>dJF|W0aX4W~0*Z9T(Q^7Zf z>!zFF0n&I52VbR{g~R;bG@lHk6ZRt$?@{eXHuj{1JI~z`r8!bCimac~F3-3b@cq(LVG%o?nZ(+gXhN z2gUar<_`m`wQioU%WsKx9i*Yc-ecvbwGnpj8x>AA3A=aW^Y=k6TXa0GuIkJGm}fIQ zkBD)m;v4f3c^=Qr^25}4r)bX#!M})e3OkD)LHp23=*#~-H$vQjt9>8+m?hfPPR!s{ z7^HN(|3%1Oi<%vrF8}_i<`UY4@96J#X$SX-jq>6?hAOXi8pZXH$CDs0?(?YfYA4%; zzWL$qh;2Ho8F=27pz|NG5ATIMvxmffJMVAgInBTyyjSSCh##wZ-bu2=zPGB+M?r_{ zGmm5ab`4+nJSu)W_8s`RQ1LlGs{SKBD)!zTw;A z{eK$q)&3R!h>*v70^TWo&*fpvAA1mV8UTkpBFqFos{g|KN5yX^E^7aXe6zphl^OjV zp0A+dA0bV{_;Ry|r*rx`R8k)l^k0U3ND}h?K)~Bcu8{W<%$L85{zt#?{_McKhW6&+ z4&8k^bJ&4TZ6)}nA@W}JIcg@JgU_Wosd)guUj;ls+RWE>LXI+Jst8SO+nVwAz_?EeWlNW~Z9{~_?9j^|?o~wPb(OnnecC&_W3Zr zW`^z+6aK5xPekw!xxA<4bT~g+@@k8iCse;y$M^pP|KtteYfbd|cvJD;Xn9Sg&*dZb zl{kI?_LY!-jrNU{)3v-UaV7jdE-tTcwFiyw(~%D()a_K| zB@gJ{FyRlNn#v>OzXE{D%7ay7MpFmvGmg9@|58L|ytPhY^c|-fJO6iz?%?t=+IQ}M2S9*ak6s~_fQxxw=$DFrOm5}+WyB9N z;SWl$2z>;;JX++xa(wI~waUZvHD`6FhVh|~4-tEnzGl48M}bfFmk50{(&zq;;0O2V zJV79L!Oz!1A65KYt3Nl3&{m1cPPwLeEQ|a?@Cg|g?ys^Yt#g`pK|Ec)5PFDMm<8RcxX2O4!pm?wm z|4q?>r zepLD=WL56jO27QOe7_N&w|KtD^9Mf9n*cmPwD*Lp`t1$SC*&;vUTcJ_F+K2u^Avo3 zQt^+;L&6@Yc^rIxQt^+;Z6^LVi*?36qdYCdJPmwJfmjdst8g+!_*1;SBk{Az%A4XN zZ+`?nA8#uCW14Ydyb1c+F2Gg#&~L*KzRH&K-1DH4(PmIM}J8-I=V@D0Ff1i8%&ao&$P%x`B##t2bN~!2rSyHt#CUVF{ z?|RPp{9nIoh@}gT7#mOCca>Hzu8uO7U;it-FE0=0VJl}XSe9&$LIvXFY(@^z;aJ(w zk$}4D(iGeZ;TW9igVXn@Z!x}a7dNMnhornD`1P0IZ{hZ|E95FIfV{G#6^3c}Jy*F^ z#NGUP+>NjIWLOWtBb5Cj=ISqr_y>8334aate7`Y2FxZISCf>vG<3)e`q{0~t0q+ms zkIdtGi6U|X_!MP7?o;C90d|DHmx%Qr{K@^-`I9fPr#U|S$^F;)lP^*53py_YKS}6^ z@OQz#@E@fm!2exN0sY^M{HXB1;nS}LoxkCeuLL{??YdLY$4Zp*$>U9UZy4yW5&Yx3 zfWz|!pLZ+!b*R*X_r9gVwPKt@|MqKb1pYTFTn1mDvstOpT;%ImBJ`EKL_aq?3OH5j zzJ3TrT@O>hq=Y=oC_zv#=@6T<4tLoFbS1LTF;gfoYw`x)X_9 z-hcVB{yqJNB%p9sURrau5B>l4ULuWxKac*9tkGJWc;U@d@A06Em7)2MEkI@M*{sb~ zUspji^lp7My}O^zIm`=c69amb_t{OJEmyv(I$t&5vcHTDxGHY3Sd@LNc#)6$$us*E zbR^;TW@(n=y>|G5t8mmBXS_h0dPFpaKL4NaO|>W#zK9j`-&uqBJq6FJxxZp;I z1pbdITt33#hAV)NSnGj)zJNaqz6u1sSnGj)li@MQNZ4k`+(yV;h#Hp!AdnfumcG~U z$fUPi_9|b!_!If*6a8B|sk#0SYTnOA>HXsY#73@#k@Uk$9e|&(r5W&Oev` zw##E@&TJwFpHM6ww^U}4z5VRop%0kv5D$?1LRzoA`>S7JqZju>3=CzAbfnHDNylBlC6 zA4gh8a-?H`>!{QS{x3No+y8kg0{4L0x*~}`g`$FV0B@BG@=p)}7yrRF89x)un8*$h zP>Rof#?K6QJ%kuP%NU1g#?KnquVFe`z^54DI>{5+04g1G(BU`2@c%4PXKJ_cvlUu# z$oSbB`KqUlpKY+~`jPST7|EKLp}j;l$J6PEk*c4GWQ80B^)toi$;Qu2@+Gs3pJmCJ z>@a@TNTJBtQ1P{Zzh(TalQPLq#?R)G6^$@{wv_B>it)3RLD>R!~-F{8cDv!JVM#_TrFXk49G*)_GRuWLeI%j}L;6`ZVslCS;h zss22%t*5u6tJ5<&JTfveDKRo-1c5LWMSaw>qt~;=v#+ORTHBnKo>`t<(~WNoSKpxi z8{XPAC#Suqqqnc4rPC8nw)OP&c6Anaw6=BjwoUV#*Ey}N$Fr}!%`>aJr4@gSzl3^@ zV5GgTuRA#+V!?t1;Vl9yysKwM1lq!B^hV%HioDXQyfCnAWKHE0E=!lxiIBXfG)-#3 z-xhpo1*{ua!1qWU(hP(>`L6|lb>Z7=sSV$vanvCS2DTEgsrY{%{y#xHJsZ!oUWc80 z9ai#9pY^=%>4|tp54M{+K($l6EgbLT|4Wh*@o&n1;UMffDkFLG1g%~?#aq`0+AU~p z8`Qo9pJxHqCE?P^>$ncT?%T-LhYR`4K~Sh&NT?SSJ3xtZs=kwR--q{c?u&&y+VBa- zTJTm+X&yfFxA)+4A82rSW`(*E0kxd?J($kOU2{bampd$$C;WPEcv8NwSUe&Uh!ax5 zuvnpBAslRR#fp|e{mym!CPeKDzP`y75x0GZ^nGjYs7|#XM`RJtaXhtD+9*dyY8K4<{AYBg(b~*6k#+ zNH-HEt%241Mfw$XuwUAUY_E^tJs(D9@$c|*|BVdVoj9GoOZq|Dgs9fH(u0T!|41~_ zJ4B0U_UA+g8+ckeL(HXP#DZ8N5@C&Ximmjn^eIl$e;|D*eS#?S$A}1wCSwqHup{=^ zU3bKa&Izl27eoTxuv+#Yp2UlIOSfVA^2I3~e-c0faatjmgpg1YCLKV;ErLXnD4YO{ zA+e}e5RdyO5=j!l1q~#Xq+zznAeq=V$VO%IT#`rfNdXy8CXhl>M2blXDaBcya#BGm zNfoLN)R2j!mei4YGKn;hM#R6H$z(DGar~*I71amY$aFG;w4*M?O!zyq$sE#2y0FVI zm-LWc(nscz`D6iEi1QJP$r7@ZEJG!U6<7tYLgk1xWGz{T2*U01-q0SzH69`#k&nqIhzNd4J|mx# zFUXhVEAln@C;5haOTHuDlOIsE;V1Gl`4{;G^*nwfzmtEHKgfS@E#9BxFIN0CX4IToP)lk>ttkp=(NT0X9Ye=bJ8DlIs3RRmov1T)p{~@8x>FD8 zNxi5y^`XAhkNVR98c2g^Fb$!hG>nGR2pUPFXf%zXu{4gx(*&AGlV~zcp{X>D;uty2 zq**kZ=FnW4$1k&?KoFl(rd`QoPoWsH?dx8$6nM-n4(!QzO$uH$_?gR7%Xn?=fRlGhY4GV zTdo#KOQdDE$##XbTv~~93*So*(<)kxi=-yfT3RRJiYQu-3mh6~BToHDw23y;$#e>B zp;Kuq&K2wBdryX=AvfHoHS#&m?Lpx~~?ZzDqJ+znh(Rp+}T|gJ&2H?eX30+E; z(dBdnT}fBb)pQMAOV`o$bOYT;H_^>>3*Ab$(d~2x-HCfLZ=t*C9=ezAqy6+&x}Ofv z1N0z0L=Q`UNkjBDIw*Z1eMyhd+vy$jD7}*&qsQq9dXk=^chS4)J@j6BA3aUa(EI5F z^ejC`&r6Tc3-m$y5PcZ=kYCeB=%e&8`Z&EvpP*0Dr|8r48Tu@Jjy_K>(aZD-eF4{q zzeHcAuh3WNYxH&c27QyhMc=0H(0A#3^dIzn`T_lrendZ}pWrU!&*4A-BaAY}WTs(S zrekKzoLMkSX2q;=WXYC|Vx!p@HkR2jd*;9#ahHP=b7n5gmANr@=D|EsGr^nrFkj}! z{8<1CWI-&Lg|JW-hJx@BERsdBXw>D2WpON?C9p)6#FAMGOJ!*+on^30mc_DJ4$EbE zET0vy@oWMsWJRo)m9SD)#>!a*t7KKIn$@t0td`ZWdNzqQutwIzn%QJFg|)D$td&h; zZEQN5!P;2|o5^Oe*=!E$WL>PA&1F5Tm-VrEY(87S7P3WbF?QUxdxgEqUSqGbH`tr(E%r8hhrP?* zWB*|9vk%yZ>?8Iu`-FYUK4YJ=FW8stEA}<}C;Ntd%f4gZvme-x>?ig!ZlM2#{mOo0 zzq5a{KiGfRRrV+Qiw!Y7Q*i6IBokcU%TSD6gS((~vYBiyTj1tVE7@8`g>2MC94(JQ z)YVS5M=ak_9w$2?*T6+~mEB}_*+ce}y<~6MNA^YbpuZd-2g*TmupAFAmUH@2^>r)`=%erijP)vOsk zZEc;iTRNw8w4$8a4A#~;Lo>Upb4Ks~Ywt|ptEkTYe`d~2$eut#*cU+okz#g0ae*xC zi!3T?t6`6aVw$xYO*E^rzoHH|Ld!F+=&pGFrxie8?X3kqMH)@{VPt^M|wQo^2w*>^RA65 zoi}&h!o;a1G-n}mc6Ah6Ja=B{wAs^2ilc@U&zVykRWNOKX>rtqnbS&(qem9cnLM@F zy|ly~TM{+CWX7CgId*1=9J{b2s(AMNnZ>@zq>7rM^G#LxT1=b2umoy+i@6}xMdtpc z#lDhxls4Oxwx~odm^m+cp(-vjN(ZvExU5B)$tvel1JS5?bEeHO$b^}uoSaOXKGT+y+0S0@Z$q0eE884r+4Na9eU?q1Wz%Qb zdb4c3Sq=H~ZT6s+tQJ3>&v$FW!w6)ZGG9czHD1hwyh`I){|}P$+qR^ z*m84hc{#Sc99v$FEicEmKgX7vW6RC4<>uIOb8P!_Z27si{9Idpt}Q3mmXmAC$+hY8 zG7SBBmhL=DZ=TJcmus)vcJl5rCHy&gww-yl{5)HJo-IGmwlmMRGtag&&(_<|wv)HD z>GJy7`uf@W`q}dO+4B0?^7`5G`q}dO+4A~ZI{I5W`rGpR+w%L{^84HJ`&)YYTRQq% zI{Mr4``hyS+wuq4@(0-R2iWok*zyM0_6@N42if$4Z2Cbq{UDoukgb1^<>w&VjzP8^ zgKhf3HvM3GeQ?8d%b&rv-odusd`oY>&7W_}&$sytY*=X9S7_T;WXmfu{LalV*K@5t z=Vq94bFE(IW|(&6W*9nhGfX|X8K(T)4Aais3{x&2T+{uWn_=3Un_=3Un_>8zn_>8z zo2l!~!WE*@6YBO6>i#6u?I6_j5$bjj>UI$7b`a`z5bAai>UIzgPShTdg;VA+08E~p z_`@=c?Sg67;Dwns)zq0~%j}mEJ9lB39x@jAW|u4|j-Eelp|YKYWeeu%q?xw*%uLg) z%*?#lX?R}d6qin$8ar?9v}wvQG&7-eCPR#gFN~jFa!o@#VIdXIwHM;1%)?Iiojtc~ zPONSf&07@DcrvHBc#0abRFy@AMVeDZMMavEgat8+r!AP*mzE~YE?zK$5l+>~Xp=gn zWWkiOIn!rPTXbY-YI5$#AeA&((SIaK%O+JWV3a7G7Cor%!Z}msM-MhZz6lCUP-uc8 z6AUrIP!kL@!Eh6dFu_O@j55J!6O1vzSQA`if^jAoZ-NOXm}r8FO>l_`E;Yd<6I`Z) zSi=??9z##)Q!%C2!YIzf=^io3rq3%|U}N-*Nw=_Mkx8dJ$V7EFnS^soY=MS#M+W&8 zx}viAEp$C)^J8r_W%FZ9Eh?fbA&stsG`0$2wgwWJ3WzXkS-6l{O6-D?xifT+#ZE0= zSW-N1QAu(96daGU@yeB!Oi5{otB#*NZF*@!(-W;4B|%+RbCjqVeT!$8YR)K$Ya$no z)J&OKq7udGnT3w&DTRtfjnn%PdOu6;qjfwhS|4N?#vBo`L@iBWV()sub}UgxxS0ku9#h7Lw{&a zC{@NL6+{=%!NsM%nRKylg4&g`iyL&Lx8sVBL|Y6plh_u;CX61Wi;6BbB@UW51L>R9 zqS%D-`Hg)ZKcz9QYtFQ0IWuE0EhuJY96ePBEedTNxR}+1Il9o)F--??h0I%xEsC3V zB-*0T);!IG(S@eOX*!4>(pY!=jK;WWN0u38GP5!hhBPrd2{W1;#1C!E6+g2v9z9G; zYIKPXS`4!-$N1`&4>K( zQeDD=CI`{uOx+7iFy7=^sDt?Nja-Uf*cjIxo0Vzi0a=-59*~u3<^frmW*(54XXa;_ zdD+nuOyQ*_m}ok+%yjBROJSL%aH65GOb1aDm2O0pseR(art~G2H9cxE(RO~B3F9wm zY;F9tP2zkBzG1+O|50N+`Z7cJVjaX?c0_dI79WYW7*wdQwkV!vxHD$q?BazpO?+OH zxKVgB$`qE)G~xA)q=#V}*SU2(Wl&>t>_yEW9Zwq6uzu8s#(L;za-$*9$BFq< zrcGtYDAq^ug-t3m&DZBs3XiEQsqm-@;)gZKH>^n`haH=5*wOh$H?}!`Op`LkG$~`u zF=fP$Y0Q)~=IHV!HYsCblQJeAQ%2Inqw`H_Oq*bhs$qz+s5+it?Wwtt-)La~*wZP=kZOF>d2Q8bL zQhg?+i3v4%jqNmft>v^AniOh{roNEeXfgG1N)v;rPqb`mDNR|%LYk{h?W4WgNL#G3 zisr1biY8A}n`o~#=1H*D&s;F3PsdvwW%$fxWAAjlWm9WsuQrw%Z)}`CpVGv_=@W_L zk5ZrUjoDgGXks-@p~kG4xG`!vo?uOyz0k<*IBm`J=~hP>Gn=i6Sfn&DVESrG6U(Jf zBuzS6;*AB{0#q;ME zyQ9k7(Pa#Hx(+#R<~%t82bHZx=FcoiP>CCgPPP{sj^p$U)-=uf!}LK6HR(vKYM73t zS*KS+R(&#RmTE+cd8T?j!etN6cjuN#rpO6RiAp{udxFiQi%GB-^+BBWrs=3IFvl!) zGji-wJI5}ubL=HZ24yieINu6Vt(m7@coxvyAO}S=m%CU7N*daM5)4C2a zt?MAux;!$i%frsiao@4XpSl2|3O`mJe z=i2kR4d<5@JA+? zQ!-ag+!o@OojWyl+M+4AK@oYyt)ju!;gMNnTAyVcESZIdDniYj%tGU!Ake z`873!)&XN3DLK~Rk&|n=l54r%&mQ-)+~{Yi?`Ns+XSv$Xa$!J2XwMI_j+;T&Q8vhO ze~|6Pd|Q6LEkED(V!pjzV6R(;ZjN>6<`mdoDX?@D*xo6y?JKbDE3ow!*!C3Ib`;p& zDzJ1G*mf1zdJAnk3T-`www^*;Pob@+(AHCE=`OVO6xwo2nP7uouYY<)$xKI3l5$SE@A=UQ#ewOW>Iv@EmGIQ|HYToew{^>D1~ zA=LE{>Usz@orIcBLR~MRu9r~LNvP>0)N~T+b`WYh2{oOWg@bi}659F)+xiFF`i*0e z>$d*Ew*JAke&cB5x~+e(t$(nszd;|2!;y5h{=v3>BX607M&1Z*{l+oLv86xX)}L?d zH;ziKTl({D{rR^3d|Q9Mr9a=&pKt3o@|;;{got}bs0IP8wsttn&zNZ_WA&uet4+I9`lY~k4E>u>4kZ|N}NMLXj5qW=&f#mvbha!!`Bnl}{v%j+xND zbf<8xze1&Ve#@QhE4Yh2lRLXr@^kL3X7L`fANZE|e(c-GN61f)DvFvN^^2$nqi>16 zBYH*j#uj-k-fyulCMKp^OrMx@VhUnL$6Ok7OU%PDPsY3-^KnclHaa#T_T#t<2DDE%uZR2~ykBz@9et!Ia#NQMDWPEx23-O`&+W5aE^iCL?a81I439lqn zCdMVsPP`@YvBY>zerixvPa9YEw5>LU&|G(=C@kh>iyL8)UK&LQv0N4rS?xfKXq#A+|)&> z52QYx`bz3Yshd(GX>MAtw9#p$X%Dr&t@Y>WGt;-W8QEr4+l;o$+OBN7rtQwQpSMeB z*SFo+b_?3w*Y1UOmF?a3z1oj%U)p|g`z7sv-2Sc(ojVNda9M{%9Ukbgvcvigkq&?9 z=GE-xsxAk+rgUxJbzs*YbY0SQS=V>Et~sskX+@`%p0@0?wWrmd z_P1`GyY=ceyxW9sKj?N_w-wzscB}7xdiT-Yujqbt_eG~qK4WB$ydDF44DKQ&xreXm1jwm)-u@6Nq@^*+D%RlRTN{aEkXv(nDW zJL`(GZs{|-PyP3<`ra*l)B1MqJGAfgzW4O~?b$QW{*SYlpZy%qMvl&SFf%SQEpt<5 zC@U!|BkSU<>$C38UX;Bx`%gJ;PM@5joT)ii=alB$nDcPXTRFkpq}-*st8(ATU6Z>u zw>I~0d2{pb%6l&F{k-*gf9jXsuUEfU`fcv_m;P7upWOep{+|y>8}Q=+j}3Tbz&isz z9bIvR0Y&^H~xdYGr@wtzkdvIXFz_|lU2l~(Rop;T7_njYo{^{pG zaQ?~*dR$O&!3!5`ys+rPsTXd#@X(;?gKiu2`QWs{KOX#8etLdR{_y+>`B&$c=Kn|j zefdx3ugqVQzcGJb{-J`ng0zC(1vv#57c44xq~QI6gN1Di&o7)=cz5ATh1-i_iux8^ zT6AO4<3;O>HWzIlGJnY3L%R+=f9Tqw2Zs$D_JiR=hd(*Ie8hqg*N@mfqH4s!k!d40 zjXHf)(Wsed-Xxw@Y}mK-y7FY=Y2Mr7VlONvc{{`dyxZz|Z?9PCt>YQ6mSVN{K2I*C zie27nQRA&~&h{SVEzcM6u9EAVb2%R9ZR6i?wazfF%o)M)cyEj|!Mn>@<{fsP1kZTy zIptoB^Q>3lJV)AZ!@8+TJu)k&mqC}}^GPx9V`Bdg)WO0n1bBV2gd@p;cVZM^kP2k(72vXmND!-XpT zm;aG75=`(ubS6U4BVG_r_~AsrSd|5u`th;Mv38yUr%K4o66J4zJ4G45xn& zE$@k0^)HFVUN7>F;tT0_i=TMEf?F%ZE8dM_l{Z7Y>HUQArop{O#Ctqd`@XkOeBk|n z@_)lKp~-NxO8C8{)Kx0>c}w8#bK+0l4ZLw=iTIoMBmQZ61Khp|Za)aOw>mw&o1HU> ze~+HqW9benC$>?TkfE$BSfopqxS^#exT?@0%Ga4G@iU|3C+8Cf;N@2D=A|OWo)60EtIiE zr%EPO0;%?sDv4AdlB$|ifg}Cj7T#1 z_OSO9EvSIL525cvxbPudtb>bna4`%QgS6-%QalOzp4Yjnkf20z9U#|!a)rnh;wkDH zwAcstJCOHm!r_D?;oSsp15a76re#4&s`1LX8scn7m5#pGU}2_v>VGDtk6LL8)%iE{ z`QydnYMn}=eQ{fZ5Iq>l=G3)QIi^cUfh@1FW-)-Jm^xg<~TTIU-i&gbO zdaR3ht9~yu7K!)j4~X~c|IRx&x1ew1(6=b$>ksJLFcGY;N8eH@eJ1*rgubPsZ+yDa zOM)jYY5hR>vK)PDjlK;;-;&_b)#%$WL@)_GWsd0R-*xl=t6?l1@r(L@jBXm5N!{k?FW>$ zV{MrgU>~2w608K9phlIjS?lwY)VPascG2=0?*n9UFLJnt`rctI-^CcdQS0dl?BRGu z;0f62SW>@D>Q6}ZF{uJb=MGY?W3&&EYALDKon)#Q%KCt^c2M&HYTi$oJ1DQ(T8Et{ zH7f6-Pinliwmm`G5}+*yXp5h=tcAXfSZHQ7%u!M`T?3fi41_+u0#523q~1>I9m>x0 zACiCfs1YUFQO_|E9_b~EP;(yAJI=4{X(IUB%; zHH;n_0ZdN?PEu-4P6AzcVP>BywhL}lp;cyNJBYj;vLjI#83{8tuHlRiZ8=+yONY^q zAR5sI4J8-yQ-kJwL5XK0Sp&cXrAcbs!Tz>EavuT9;N+8p%k^AVjZ<%VPl>k~^WQ^f zgWi**-0gHgSBEnv9|=xQXUmVW2S<;~4XulazftbljIaZ=+(#IHg3KRlv_9|V>>k>@ zhn}tRUV+k2p#L+{kL3z)9Vg#NByoZ_@+4B6Xao(y%~MfF^JRSfqsht7W=?J%d*ZR@ ztGWE`pP@8r*Qs6eo!ZhGTiLLNZ@QjujK`w=wP=4W+OJlawam@mV1*fCh4~(H^v$d= zUuPx$ETi*t%rM;}R-y&5FgYURc-7{3ku;x@Vi^CP`0KZ4 z-_`i<@VI@))qe+9zihFN@0a}7&o)2L{-&fjm3H>)FUxrRzP$hDdDTwrGy67PZS>|f zA2Z&)lb`#3TT-5Q_I={3U%!n%v6Ow+o)h!u%cI9Xcjn}*Xm9HJ{?-Mv-q`Pk;S= z(D)45SM^47Pn|U18_lOUwKKcs>uWy6$w|=3J@55@XMFtTY1F^}o`3VQ^v&Z+P zXXYpNnw)$&$G0=z{`;QI%R%!g{vGSwQ)^pK-E%1alVjbtU)qkZMa@fC^C?c{$oFMW z-2a`i@ZUf3oY*g_Y`l4@_vCH!S3j3>V(V|7mTIiA@#%^a=R3I-#~YYfp0$ z-zfWyv9GIlPflk~evCQ!lwUm>ow`}*iLLMdwtBuUnfa#a*LUqX@wogQf4<|-iT`W- z9e=*#&%g3t^>3H_G&djn-+sOM8GZ99PW8O;yYi0r28WZMO@Gt*ck+}peFov%wrc;b zz5nWa5Kg>eJGFN^nzwS_`Lj>mJ2#9s>DzyArqTQTb*;A>J-#RR59)6}kH2m`Z{8Ao z^DMiQ`G9)!8}Gqr%eO8clxz4-`E$NQyz3&5w?tHcb^L#|FW}g{4?F-K^ft>O-ezAM z*IV=5%rw57*@`b`raNhTBe#o4cYiBdxsMY*Dbi(2&=qtClSC_dIru)flH*d5Ca))~ z7wI%3-RFXye9iMCk>sU|6wuwfSoEp?6JO{|<6FnuMIryLF9JirFmMqV4=&;Vv6u3u zn#;kx9N!QAi*rwt{~7QC$1id1ZNhiJyIiZF%ypoa<9hy88{=KFK>co>x6kbd`hx-B953je3kFjDd6aWL;RS>j5)LBFCl9=G zX|oHT+!0_D7z5y$3(wq%;1VziTn@euX4U`6y@~Ku`S{t`S2eg%FF zegmHHf-=FoSf+u~z5TM6w@*Tg?8Eu9iDwYcBw_OhB{75hwj3F)U zlJudx3Y3uUYSPT-Tp7pL5MBpvAbtziZspo-gtrsk$@!mxyTAkBLGTdZonUe)SO%Wp zcsc2xCjAP+X9&v)pCx>b@Oi?Oguf?zf$&Abmk3`be1-5;!q*7@K)8yKw|B`m2;U@p zi|}p2)ztAG_yBweD!?aT9oPW2fX~1-umkJ@d%#{00M%eWH~_+cw4y5WNnf*FkhLh)xF4$sjrzL??sjWDuPU zqLV>%GKfwF(a9h>8AK<8=wuL`3Zg4P^hD`MP!@|6IT=tV`k{0qh;9VYgCKekL=S@K zfRgzjG8sfBgUDnMnG7P6L1Z$BOa_t3Aaci-8o_=LhEC@!Ga~d9m-6l2<<7f&5%xw| z>bp9sAZmNeqPX+pQxc*RKT51m%1By~a$n21mX)dXX)Dv)r*CX?S(}&IE^ZrX=eFz9 z{>F~4b=={keT z5yD=CuoofhMF@Kl!d`^17kpKd(xVwAZ)23ajnU{fMx)ypjc#K!;v8BMLQ6tuNeC?o zp(P=-B!rfP(2@{Z5<*KtXh{ey385t+v?PRM|pa={F7Xw=DUIwlJH-aVL7VtbRO#z)iJ|K^r1+E2)!TsRBz<-0y zU@NEu+X3y7y8&&Heh>uvKnNU!CPlR$s{K&yhiX4m`=Qzo)qbesv4MG774x(z@hR`Bit(zLPgOCWs$xD>#eAxY`BWA2 zsVe4ERg5JYnD=lMT#6su)u?$kV*_j4KS7+k{=+gk9Z)UEPFT-NamZ8*}At%$2t> zSKfwo+J$x6#VAq9C{f8MQOPJ#$tY3DC{f8MQOPJ#$tY3DC{f8MQOPJ#$tY3DC{gJy zq8@bIy&hn_u-luk+ncc4o0t=CV@|w{Iq^2;#M_t?Z(~lp4NJI-(WO%MK*xJAYwGQ7 z!ZPk+KD-S(zlr(qHb$OGIfCmWIUYqgn&UB~p)HcWke2}Z0V}#o&Llpc^FJgk|-%0pWa2NOm*Rhq1A)6SrDj7#MVQqKGrC=HOE!Upl{A%zX_yBweD!?aT9oPW2 zknc0F4eS8Bz#gy{1h`%e_Jac)hY4$-rw$wjUw}V@zk z^jHl&wwfMWO;6R(ORMRf8hT|l++Pa!m%{y}aDOS>Ukayd;B*a~u7T4vaC$YIUJb`; z;8+bDtAS%RaI6N7)xfdUaH|Gxt%h4QaH|F`t%gIZ;m~S0v=k04g+oi>&T6=_8ZNAc z3#;M6YAC9Kq8ccwfub5Hs)3>!D5`;?)ljq=idO4+YXEr+Addm$F@QV13m|s^Ye+TIA0R0`HzXSAlfc_59-vRnNKz|36Hu7%KSa9qb=_33lYMpc` z|LnXRG+i&f#PP9frc~bi+nRSBe)ZZZfwfZtYo`R(P6@1?65!OA*G~8ku=D${^ZT&# z`>^x)Kt#NIF8C+cRoL-;*ztYXaeNpe9POZJ5TV4f< zMFMNE1lC{)a6c%^IM=WayMcJqwb%ocq1Iy$5kA7TrC=F2nf2Kg@_YuifgNBM*aP;0 zrfatY9J79to{0B3K)t6qL0ra){0dO*9dMU}6`-8e^;ob3+zlT04)_v5YtpG4wdANJ zM=d#O$x%y=T5{Bqqm~@C4#KqH2n}-dBe&#Rh@KLPCN3ovy<{_~K$}5@I1UO$! zy8VP9a1ew+1k{1U;B)Y2@K@e>D?l1=$!*PyyD#(BOpa*>^OtqZU)Evg)?nw>VCU9g z=hk57*66uwhPMvR_~DG-T||5_xE|a9?(^2;BUz7+WWAo(K0z8aw^j36Gp9YI=d?Y% zb#T!y&!q>4Fn1jamqu`I6d1$#u~=qkXAZFro9Neb->V3Vy*1dyHQ2>9%qi9}pIC># zWh318<8#?S5BQlIt6m5*FFr(nhnZ8XV@|P7{*t;L;rgS5O9_8P$UFDtul2lQ9dl^a zQ(-kPrnmfhZtM`M`7x^(#{PAT{p;}MtY^NgdNJ%vVos0(QaPW-xz?QPO1v959jN(q zCwg}ky{LLHOb>?Xy;bzyDmWj8^Q++cDmWU3qhUC>3J$JkRh7)0A zEey3`C=EkR7)ruWp~kT=@)f3~VOqF~u`CZ+;T^}wR4pnDVOzZ(4}m+y~7>I_4C1nU@+$j0G>V8w?X$}a4EP9Tmfzb zOTaDQK5r+zw3A-iNiXf7mv*q`#hZ<14errnJ7gMhyngiD4ti~eq%PLNLDs@SdT%Ga zwnO6eV_h7i_ja;24ze~5(u+IfEu6<2!#X+0IyuNXIjFVeG15KB`KQ2gumY5W=fFzv z0(c3$0$u~Fz#HH#u$eNp0wj-hc93;;kac#Db#{<-c93;;kac#Db#{<-b`S~KfrRWp zLUte_JGI6o6DqB1NqB}x@$~>b>HqH`4K+x^A!|n?^n8u@gtwNiBUH9>Gx05~&CpeP zw1(cSaYlKE>4gZ~tbv;~aI*$(M&M=y4o2Wy1esTMD}v0|!L=G~udd{{l=IgUDx0J1 z%`dtBDEJjn_Jl8+KtTiwB2W;4f*Nf*l&v_!J4~x1d>NoSZ<#RK>gTP;NyxGv`AtT4 zleNZv!a1$Agqy(@M#oCtpL&4nhmdQJH>1XYG;PVX79*oc$YV0{n2bCoBag|*V>0rX zj65bou^+ihM(&c4yX0duURiBFa+C}Q{K!x;T=2`&L=s%UYBTzi*JwZIuH;+^$EAeV zgPS;a3&*#CpAr8h=^q8Z0>Ae5%E#!}-*Ns)@Dyp5gB740JO@^S7r;y474RBZ1>OK} zfqHG7m1XuDt09t*i@m;NZ8i2H7g!F?odJ4?WVq}Xec|vP4FC0;K8>*0ty~xF0Y5t=>(mt7vtVZS{Uy&D}oU&`nxety;XB7VoCTyJ=xV z>vq#R)hgvRsye1sRkW&#R_&)HyJ<-kEvcd3|PaV8bI;XoAQD7{ZOMT2T!ptVZ%qGH&S`kL92(yMTvxYDphcF{mgwa3D z=pSZuiZI%T8I>Z8^kGK&Fe82VD39}DM*72y^oJSY4>ONCp2ztxqy1q<_`{6whZ)@u z%S*vk;AoHYVMhAHjP!>Y=?^o~A7-RK%t(Kjk^V62oI}iF9%KHS3|cZ1jAKrDm^r1Y zSN%KkF!Q&=%-;?(e^X^2X8v@T`O{%Bfz{E`z6$POYJbJOoL4>y<)3KqO*Hr=)E(xp z@Jk%m2a$@oe-lm^+>k@pJkkk#%RHfI_%i&dR%-m3KKS?{e*<98cJ|_AH0X<#4%N zsI})iga^E5Sc#X5df@Q|BJE?;>(6pl<>gK;pgdOP<*drfxp$Yy`ZJOBXCmv*MAn~) z+^>&tzdpkK`Uv;yBiyf#aKApn{rU(!RL&~CoK<`|tN3zO@#XIEe2@)m)APu40T=}G zNefM^_RCrAm$TY0XSH9>YQNmQ2tb=V5nKW$fy=@7K~sODS*Mn>PQ{t(wSMHIcPyBKOoItXIqJdbJ#nLAg}x)mu4#JGhhMpMtx9@gbHQ zA0lZQ*RADPxo70lq<;oH3!VqR2QPw`!K>g8;C1jOcpI#y%=f?t;6uQDV!ROLcp=L1 zLXxi1;h(fjmQ3Qs7 zVPHJC7u*kC0B?hLzyY3!sU)ayD_~_EkVzgpkGVmc#a<+d1sG#EsuV3rdsmkjBw+-!F!STdFzXr{dM9Ax0c?=d>gBk$Bf6j!#m`?>fOW$p5Q&< zE#oUh|Im+_Ez`M}yi@SZT$5`@5)ol#eaz3+xsPXh z)b;(|J`dg*MuQSIm#+5A~1d6~5wkyer;j@7I*6d2IQ598M~3cyAod zWA8dujrY2@roNo;hxG^WI129~&-7#JS2RK(DaoYUVy=H#X1r^>UG=YdJR8tZ0KFgr?v#b<(6E($d?7hZAp=KD+^ID_<74jqW3*@#jEx{q8}pOi{85`?a@EoH%Uz; zP077?JD}H)EPi+^?9cY0mR@vUT~pHA@JloibEV;=3h^2X+VQICV=aTam0U8d{SDGL zhcrm1cc=Fd`+FOBgg3K*g*?yxym>lDFJy)W;lJEKH_SpuhUn|atfV7G25BO+-#0BlUdn3=V89Xy1;qVc~mTPe(U^BlsZp3 zPl{`Jvhrzht@8}uXZ(?~kuNhXc6K^D#dXeZXOFnv%>J6JsJ7PtlC1-Hm85-++#-J#+ocep!TyzGu-UGa+h1NSQNjyu_%EZ%dc zx>Lpb?sRv$_`sd%&J=6hS?(>@9mcF|v>B9AY?&prXz2zSag(LCgBx#^^8rTZ#}uz8$B}G*$V9}6z$N?Ayzv(Y3=N+wX>Vn&hBXE z73iqZ&gFRCd!dUji9TrJYus0Oi>)vEw^p1j*0W`bPua4>AJNEct&w?X(lSFK0U7W z=?Se*PilR7O6${dtxr#DeOjUQ=^3q0(lF6pWe{=^rqIQx3oUJt@Y_0 ztxv19KE12;={>Da?`wVfKQ^r>8YsC8(g)}gIRhXnt=ki7-}zraJpQ^hhv98fwW z4k{f&=g=YX7o|hu@95AtM{4bf)7q1uwI@+)PmrF4M zH@&sq^woNkq4g$H>rH>HH|J=*nWFV(s@9tYT5lF=y(!gtQ>OLiI;}U?YrVNa>&=Z? zZ5KKqffKU*U5Ie@ayF?XDh z&}8IuAmdv;TPovOfoQEgPH9?m()GC32F)3(o(pGd%a}8cG-`}%ueGQhT6CG{z{qns z`gR3dN3Bt<8R?c|6;`lGtyk@|UbWGB)mrOS7p+&W)~h7+N`2*b3tKC#U9Q$HS8G=n ztzBKTcExDz>Y%l&wbrh#XxE=bS2XM|v`vkDUA2yNMY~e*f~7fW_(@wc0=7fbdWzOg zFQ=Di;hgE5DPpwN#cHjK)mj&$N5f9e3}=SutjEMo&MfqhXJFC8&RP$BS`VexL&iK; zifA{%O%Oge(M=IiZcDedaNTsby^wAPw=xeiJAwE_#^Q8r z#}8=#mF|_a?JCA)SKAR++YwjW5m(z0SKE;UZAW6Y9f{L+Bu?9rIBiGbup`$}!XkGO zrTxhL5%I3nJA)Ul1vt^0E6i+lZF3t!zh{_OiW*l^tY9;+qiteaZ4=vRo7fhcm`(XPSjHAu#(t#lFZ<&k9U#x4mUHE~{7dmXc^)k}U!G5z z3$UJ1SkJ+v%*TdGY-l017s(>wlSAYX+AvfO<(}*?IZUL=;aJ#oEbK`9v!moF(OQm{ zqxtXK7(Ddtu<3tQr_)^YKl9TXWGm~M@OosiH{8utrUL~*MYO$Ow zI$@Wmv!5Yn(2|*Qrf4ItmRD2bEIEr-G25Y?%yuZbRF>lPFOy~DWzIu8ufvzjzb^UT zWwN{h-+w!Kqr8!FZqj$1m&hfw>SlQ}XKt0ZQs(XQcJ_D3J1Fx`c_(H5RNlq@XZp_c z-STeI-!Jc{-Us9ZP|Dni{loHM==~*ku3O1RcjXlif-#lgo(z zPO3ZEkITm?=V|#gbv+}WVgIarmi_bcdG^1Tzi0oVe3AXj@@4j~%2(O{LH>dL>+*H> zZ^}2>zb)Tp|Bifz)~?1Yo-W^&?-G9x?|8a=U%pTL1H9zva*bR={6oCu>GC7_5%CJV z=IQcd`7!ZN@Sdm3wQ?=-b$HR!<$AfE_y)Y`>2jlF2Bk(d_M7EqXx}2YK=oF+mH21! zGvbx9lK3{cjrexCo%jy9gZNIlllU&Vi}-H2oA@5Nhj^8&BEDDdCC=QEJ#$N>k+~)N zdj2DuEIsadwDU29aZldiIlp#3m;cNr`y|i%wNoRgh*cw~aMcJZq8ULGxPzbQOB5X# zM_Y*&zEoeTi1DTAyZfzutvSz(RJ37aZ7;g`I`}$}hIuLFFfXMX=B4bJmomCJ!sqKP zTCkQgzs6W9BidJbzZ#P3P=_ewJaSzfE3{+$jb?m}W$a4gzl}|Q?KxLbYH0+M2-b z743?;roTAyGfcxZ^D|y7hq;OR;dwmHPnDVu6yJP$ug0T`FG#B~8Ub%JxQM5B?)mDZVxQlnI(3GUTvq`$A z6knAMivh;Y#S=f;s+pcivE`9a|4dm?aJUt6q3o5h`n)+pA1T|fer+jNak&AC+e+Wf zPlau@R5kKjm8E{lei_SUEQ-ph?g%Jr*&vH5U4zWEw%61dBQHi;R2hmsfgM(!6@z5# zt4gQJV~&emZ7B0(!-jglI@FaOk=LfO+Zb=up@!Br$f@ZW)fbI0vZ~~@>8R9J%ekUN zQPq?((}JV-hBu0KMRn7ANp0-tl_TC2PC?Pg3GhvMjCuS(kKPWoO3p-~OD(t-OTF^!xb#N|hnA?lk|Rg=GXJ@tt?flO?KeAzx2X(g zZGV}VEUp#{NTbqSWlC_<&9U3nhTV=i?re`c+OXlcA$^`bUtq%`)_uc8CBEigI*;IM zUh4eHS?2uOdCd8Z@;N(?J5S(seoFbAofY_;%bjPP=bY!AmCo<~nLIMyeZl=bc#-WT z_ht7L_f_{b_YdwW_jUIT_f7XL_igtbceVSj`=0y0`+>X0{m}i$t#ChfKXKQ(>)iGK zTrSzd-N3ey?Nhc*Y=30i!nT#|Gqy^$ZEV}wcChVa+r_qrt%_|go1ZPf7G$e-_p$9~ z3$YzwJIEGhi?G$O)w0#G9b!Ao_Bq=ZY=2_=GuvO-{>t_@_ir9Qx1P;&J&DLjhfTRN z)K5*(qu8R^TF4l-ShhGB=l-5v+zw)Z&-n#1I0CH4o3-9Kz`3=~9eUqI?|;p;wOrfm zY$5h8v8~Q$#CT>2U&?N0m$S#Iat=CSC*ssNwN9OLh^uemnF%?29lsNBf=;!w&)Lt} zxwa0MJ15fl-1)-!g0qSEe+MG3`FNk&i(A=p#O-Xk491SggP=mu9}meSah-bwcN2bw z*W!Bd5I%>Wi{HAaXzWv+Zu6s9|Fu(JJC~@8U_3d&k^+h}(?k(_uXJX&zW+x}p zU_$6tyk*3w@guXQADFR|5by4U*tHuqH9N45KRZiE&@5b!Ny{2DKKfqI1BCdm#4~5c zjGUZB?1%^2yMpUZV=|_vJ#<}gmykvkgic#JHg)9a-_jfMd+XzR^RYPLu-EQK)cc{{ zVC?wp9JlmYuc7`YA%=DtnWILIdYfHFdk4{e@c5BASxOuB4A*mTf8d0X<5PEq-8K=r zD+&GImX$dfO-ju=*6;OL+}Z`t#1f7hlwlF`J{s=Y`ZrS74krk? z_{6OV-(U0mu+eiT^QZQab}6XZ6UNWthiB|k%%5Ug^xR1uY8NNoWVt4`vVot$b_?+) z!-=l?x(mT8XeE(Qm*fRB5?6?ByAC~~0hYb=2}$G4XiX9FEn!u?NZ??c4CF8GoS8WW zJLf8Mbsth#<3K`pB=Qzp>5RB5kTCj`-;4KR&kO5L=E%R3*X2x-t^0{gkROo2bO_02 zbID4!lDJE$#7|yGy3wViFY8L0(jQ5&6h-{y{bUKAIfIgpG76<5%085>C_PX{qa;%k z*-p!Gj}OkxB%9<=GD|8XJ@q}w7`ciB%D<6wx*)Pp*N&W%^HB0ppH9~6O2|1DLB5d3 zkRH1FIG;eyDUWgOFiHxUCI5>3C^Ade0e$$G442;~QMzHISbj_b^%10{e4o4`-y%Ws z6*8RuOm<7*BnEpT^&>r`Y(m)^WT@N&eaI&H=+j8-Gvxp>gzX~ju z>5@X$$Zbh~>2)#{a7=@pR!V0{ zhW-uWCdZJW9B=Yja$Gi&Ey_iVOEJc8CFugV2g`HFF5N;>mtG+y@<383M-m_AM(XLd zlX4ETemdSWnhXOzidjL`CEX^nLY_ee>m~#DCo$GHs#bD5N?By5)PXFOMv@iu2a*ri z4}f+DOS1rrjx1(t$O%HspnUUALMo47KOTGV81tJZBokdkA4o8lYzrZ@&=9z2k<)XS{^tl`GMd-f3{Ni;K z=^GNG`w;zKje2`BK}jZilyPK-&Vhs|4EJ?G=}fYedDtg`)~8f`kNO1VGtxl0i)W@( zJ>l=s*CPj&&7kGZRsYq8k(;_-f%A_*%PmM6 zLC@#OROKlN(Y-?abUn!-IgM<^zC>{#jpP$me~NdsAceZ!;1{3?-8S-;{0dnr=aNaH ztRnTKu9zR2NO$E`l-ndz=}lsFVWbIYB1L9oqW%nNuVj%}{RiMhd1SNv3t1-D0X>$G zAe}Gfau>2*_5}BD#HFNV5B@-y192FHb9z@MPtr&~;n$^vp6^EHxYfcNq; z5@kH;%0`pH>`j#3!0{OH==r1{+f3F=y8wR>IitS@el?P0prlHhNn7yM9?~%I4Dc0Y z1vx1bp>rpjls#lNcw~mYKN+uFB4g#9WR$KwIShQiDz7Db z@p$$L&QBq8q%<-S{a!1LAa8-U86`qy%d1E)v~>piV(C}Nwgl2z zK1b%GK32eWfMg1O$mK3%DdbfLUI1$lmtU-ecnX=w<>EgSE+>VI@NeCuS33hV}C_iN4}7bfuBGR;j)eEB3vK9*p}iRzCVZke7=__%O<{cR6j2K=HxXW37$-Y*jR4RnnEb#I}euxeVe>?=qZA9Fq)|JOa& zpSTXgX+(@$wH}4zL0q4*-gBLT>ku06m)BQ46ot=0KA-=s@Hx)sw^ae|FM+wr+>N+q!7H#HuaPF6S%OMevxam1uiobzj_gf2?@UHqLjn!g-HY zZ2HIfkXAT9vMwAi8h^5eq54?xD-MswuQ<;_vAc-(VBY9R)icG3xUtocIaA3ix^`8Y zbiGLuORF-9c?Er1%nyu{rbBa@eOY(rG$MEa^kmLA#4*>Qpf`!RVbPazg$`($+l3hS zNVIbb*K;}j^1Z_KBt9RZr*ZnkocTh$uUc>CZF60yrf>W{+|TEQ=o99m;8R?u<2pU( zalCI_f9E`c&vUNxSlSc1I;TmLX8fAamoPUl2M=M)_Hlik>r4C|jgDX5YjiE_9N0fn z9(2S>q&=VCT>kQY30=RMPw7&sdMgh}d%Xv2gX+F({Sx{o^u=l&NM|>U47Tr%`3+r= z>u(xQt8O!r{tT)*STFY`ieJ_(!xK21;2o~d~+=P$sE;4gfy@f5DxLnqU8GaYnH zt_Sil;5hl)9=fT_^+)KW3fCKfcY#~jHah6BTTUG@RD;5l`uTD2>7&Z4ebqX|PWeez-0k6nD}ll!j7IH&Ka*2oBeai>{W7 zeqz^*Hn8X2z;ofz!L%uLapGu&<3@)r(U6f(UFw$9yH*^-twq;E8yohGuj{qZxqVcJQdDg;cWTwYqTzY)R+Il@e`-4 zH+%>!KR)*S?;n2+fIa>fRTq?jzhE&y9yBZ%e-xC$$s#JsSN#3s8|sHg)&7a6qd`;A z6oZI?iSn}iY919}TWYvcbD9R@XQ=@>_yq=9-6^QC=H3{v9xw zLg$o%pFOqr6>V6m*rLBaK$gI@1>?5cnj5PRIJPZ#)wWGBX)J#nqfRwH?MXliQUnNr zVv^%@RHH`XB6?%F$%ocK?_mbQ{1K%-;WeW46244A>JwRs!-;RmT%wR+#F+$<*<>d< zNDh&6Piizb0By-yBONY}jbT*ws*VA3pNT1Lu=F1XTGCRZGWAC%C*{>3n zB*|WKl|rQD(n<;Tuw;}@O6R2arEAi4=`%T0j+Q&hiE@gZDNmOd%h%-3{KBP-1}%zMoj%}30;&4uQC^H%dBylqTX8o$G= zL!nijDxX*W0q;;b%He8HQ9hpEh_V*-&V+p5?R&?&r|&+zn|Sx;@i`1PraRaJLC3< z+Z}F4-H!O`vcoml;u{gi;BGMzgHz*2i>M^&RtZ z-*)W^%|i{54hF9mYl6}i$2>boS_mENa6(x2$h z^Z|WH=Fq$JPx=>qPG8VUYR3GWM^(%W<%IeHjE8tBgks9hK*z?Y!n;KQsJdtOV+U|Y$}_^a@b5Zi{7I@&_~RkZDgC+ zX10Y*X4z~yn?d%G{p>M(%1_uY>?!9b>@W75yKB{P#FOl4KVD^n^_Vv?97!KWyb zGIC7PNs6SG?7%@BBuB{!_PmSa3Xik1)JyUr*CcQ9vE(Dwk?KnIFnd2C*QNSWZ^@7R zNAf2(qyQ<9d@2Qz&&cQGrW7ps!aooqHIPE3FezMWC^aHqlCPu)sWCX)59B`iQHmr# zk)O!}L`@!&N8ol(q$cDSDO!plPo<{hSE-rQM~Wq?6i2G0c&WLRAhnhPY7#oX@E3PN|ur!^FqN5sPr7XB^=zP5si>4B{S5CNa;7}cWIC` zSo%S_4?)pHQl%;guo&q_=_hcZW;B+@(RkWi8X^sqewH3c!=&M|oop{XlpfIp+Cq9P zJ)tdWEBcD`7i~@3NPkFwN+YC^QVMNLUzHVEPutPgWF||}FVa(4mUXl}eO=0s#!C~V zOess6NITGu(y!7pX|c3~cA}l7rP4ClL3X5Fq~)@cv_e`*N7Gc#6@h1V`*FoUeA*2BbC1E6-G$f5k1ZhknNfc>9qT%IiN}7>a5=Y`mbCN(> zkd~wsd4;qlZAe@4DrrYvBkjrSqyy*hC&_=CnLZQFdyk-`U~cx8M9Bu%+q1kDa?*JFem27oS6$VFjwZr z+%XHiFb};UGkh@r>hc*#Cy-2%LPn7>;6_u(0y3VwN#~Hsu!>iaIhfbWNfupA*N{|_ zO&8H6bTN5{t{~}TIyr`!y@bpr@FLS?WCL9ZxiyZ=pp)o#;1)k4CW-mTM~RN38Ia3k z$zr;e`Lk7YD#k0DPT^xlGvU8|la8m8!Cjt$$NUPZ_8a}3{z0E{{sIX9;+%!5WI5Rm z={SMpk$l(^(;z2zkX$2)>}Is@l~hXU>f{r&YLRiFU#Yz`d{~r`Mg|6Ue6xd*j)*d{ zNF$91iZV)(ft`#}Xs13&A<2Qu1DC%sdU;@{z_BAo8|6^3$A#48$W|(>LR-Z8l|vaNxhSdb36DN+jU6x z4GIeEXguF5$#}klZ%}e_lu@baBl`N*n{_O`)khkYh$y3-F_TrYXjO zPBvxn&0M~z;F~}Pnr(X32}i^EW)9y(JKR58ooKgH&uKS;6$hJC#LWxrtl}G zm|R`>vwZWIZvtF!-*CQJ!#5xEO%>m~>Vlgy`R1H~H)O!M9ejgow#n6i3pj^2yW?sV z-+b(j3yFLa&8yL#*u2U&bFd-cFKOTeV<8RqLwo)VJkCoULA>Nv#1nCPFL@O)K*BgG zb^gZxA`z92peG0$+^O%nM;AoRaeC| z&UK~h4TEfGZAdZ9FccWB81A~+xh;2l;@-}Ej|cO}@Ob3e+%wJdu;-s%o?eT+D!l7^ z&-cFP6Xvtk=TV)wI-~2HsLSehtvkQ&#k#lZ`PUm!Z)v@!z9W1u)NfF~L;WXy{(fct z&7h|a2~Yy+2Mh_=9&j+=Y`~qs=7A#urv{n=F9tb4?~V!T8ZsC($j(5GSj!m`57hdYIL4d2s{HC);#uu)p0dl9`N${Ra1&T3p3DMvPs92>bh zvLy0OlzUW%sO+c{Q58}5qnrnjtU)uh#) zSCm&~z4D;-kk*G=KWWph&E~dB+qrGeyh>i}@~Y|8N9|(TWwa}Q&F-}kukC5?(0*(C z2d^i+e&Y3SJH&M;>FC|DPsfsu4>~pPw6IfIr*AvwbS~@sdzU6%a=Ki7BlwN9H?DSV z(RFnpdEHqj|@P~!ex-n|z0de(bb@1Oci>RZ3>t$w}w znfg8J->QGf0Pg|!1|Cdmo%C69!{n*S2a_)+KOf{WD0p!F!7B$p8q#6Ni6Qrg))|^H z^!%`T!)6ToY5?&g7IbJ zuaAE+!EQqR32_s;Pna~plxfI}%xsa_CCeo%EURr+pRBxzY~t!k^(Sqg+3l1)n7p5<~v4|{cy(oRr*~Kjuk6pZT@lQ*)znpISKV3NX?4!(vuhfxS-a-)+SzNLuN%Ft zWW8a19sC8ZU%dXohJG8iZnWE2Z)4=fwi|nGOxrkXzo}%?sZAel`exI!&C2FFntgZ96 zZrob5^~BbzTW@WBw2f?Y-_~$jt8Lx44cnHrZT_~6+jed{xb5t=ifwncJ=?Bqud_X3 zd+Y68wh!8#v3>6L_1pJsFW-J;`&TW$0F1Jtau-x?AS-Goox91k+ zp2@wQdnfm4o}A~M7o685uU%fBys>#R@>b>*41>Y1r+d+0X z?eO0bv!nfveml~4%-XSf$Icz59T#_ew&VVe=R2Kt`tNM9v(L`4J7?@%xwBxWap%RI zU+#RmQ{83Q6}&5MSC?Ibc4h3Ey=&vHqFpC;UEOtS*P}vK=vf$6*rKp!;fTUXg$oPU z78Vwk6<#j9S@=_70ZPsN@)d!Fr8_PXzFus3FJ`@Q}4rtQtyyL#`Qy~e#4 z_TJcgfA8}mry~ENh@$32?TdOA4Jt}2np8BqXme3PQBl$1qVl4%MVE`N6@6CpP0_ug zM@7FEsl`fh{o-cD9f}7Ok1d{2yuNsQabfZPVpH*z;#B}FBNOD>jt zSaPG}Udf;P$UeJ$hJAJRMeJ*~uhqWx`?~Jyvv1J8lzr*@CheQCZ{@y?`||cZ*!OH- z<$lBd;QbN%o9*wizt{eh{n`5$@87zA|Nb-kukXLV|M>x@1O5k^A83D|=YbIiCLLIK zVDo{(1BVZsKk(s!TL&H;BnRCOHaHl0Fz#U2gCh=R9Lzbm@Zj2mc?U}l8V{a0c>dt^ zgLe-;IH(>n911(s>QMVbT@MX8G~v*~Lt76WK6LTWmxmr5CWqY*H$2?>aG%3zhbJ7K zdU)mGorlX0Up;*5@S`L0kvd139O-am(2)s8mL4fQa`?!pBNvWbJM!g`dqWOiHG2J-VxY4-Zc-DBs_){q<^(>7jZCl!}bZqJD()Fb!rDsd8mVQ=xzx27u$>eW} zGj%nMFlC#Tn+i;2rYojzOwW!gN9!DIa5Uy<>!V$c4mz4~bpFw;M-Lypc=XGoPs)_C z`en_^x|9tn%P5;&wzjOWtgP&E+0C-MWlzc~kJ%locP#Q)+he_sr5wvXw)oiAWBZSt zId3b{LXjfs>8H^4U zF-<+Bkc9YHA1TBmKK6c47b)#=P!~B>*G_#=_03K71!Z61wRrFA@cHk6Ug8UDDa-O+ zXS~Z@L++toC>eJDLSg6>pB8KHI_igSNZr02jq zA=yVR@D%LF}UW5hL*R47)l%0-U1}Vg@uQO#m6-8aVVIjeam#4Rn zx3`z4qW21k4+~33i1qZ2ZPr{`w6?tB%9Vp@N6s@TYv7j|(1>|Rhni)dr3XaT+i@Ffi~VW@<0TsVYD9Bzl`Qa8pyvrq!yu2Wkz1z2th zh&F~9N~3Bo7y}HYakW*DXPKlviG{mTjv};Jg3L(Lx*N3&6<_eBWd>Rq{QK`?- z6QR@xdQ5Tk6}}@8aeU_-7r}QfmTPX7YjrI@TKT|^daGjz#b^bqgnF=+!n4^IQ>WTrGm!Yj(> z9pagH1kb8x!JiB)$(&;e65t$5FeqDI1TxM>lwUj8e4G zIU2VbNP>@#!rZ(J?f^TCxUHn#2b6m2Zr)s1PdTJMVBP6B)-HvXKw7VyLgL$QON->{TH;H%pvA3kI;GZt=6A2m-FoH%*&aN^aMdxS}lb!hyi#9nq zGaQ-VAm%6Z6()NpeuDE%N6rsJ6LeCn6zZe%&`VM{eN!z9q}}DQcCt`qMjE^g4f6UllPMat0j2K#X#9t$c}T8Y%<|bxrTnahkjO zfcg~U{-&%IJXkw0YupK-gr}#5F>oFqAH)o55WUS>r2=KRA9JmSFyd zRP(l1EF2f|;9}!9BK_yIZ)0Gr0*?9507F z`{L#w&%XHL_Z(w!@!`^%eo@pa`LBhjYegbp=DV`FqRlB^NJBQcal)SfhXMF@a=4aUFl#BZ5uc}cEp%;1N}O{YyE}=S{p4yuni6^m4&WBqf1#WEJj6WPL35OJLbrd z0ae7A&u6GhVm`y)ALJIUm&V+^JI&mm?O0&WV17z0{WMiwOS3vim6f4VTZSZjj`w|- z8+PbR02yuR2?eUDhIbcKT=>kO2835?X0pl7h4Pl|qM_26bOCm}0xi#j>w2Z$wKp2= z45jsJt6=6rui@EJyI39`L+7z`;;^C^lZ&Sy4wvXs-`c(!Jq@M7wN>D^nYWKVOsHdC%|YxI05BQih(|CqGYcPx z3u8;Vt#297GOK6dr>##-ym+>yPZ$T?!6N3G}c0XkO1@>eDYi zSMSqEs-u~ew5@sj>`~)BdHVg{BXAW`#1)7b8z)331T>BSz)^!nqY|T|?JOmn78sNC zAqfbFfaA(`51vOj<~T-ByDux>kxuKns`t(3)MYc^{bvKI9)Vejj0WzUfjb{q6w%~O zOM6~u&r54hkSM3hD0?qH-cgu?QG5B1!k4=r7ESZ+DBv|*!jb1(kq`lWg28Z|UdJyY>X<*Ma}4lQ3(xLfKxyLjiKdAYfu znPl*t@2hF1rv+*on@6LWQc~M%lipJZalI|UIKMHd>j_Ro*H#TJ| zbfPI*!SLVao8e-k$5Eyp7jE;TXuh%M8>;9zCBW{}RT$-pvJg2|W)qEi1GiD_E6O76 zTidgVpas2`4}zZYD8U&SEUogA^a^WVU#YJ?n@wkqq%&r7p2f%}S|oig9RStp5uL;9 zrN(6j8c5kt6Oytfa%N@4FHHvCS8RrIE!xUtMT1=VL6JVMJS(;5MS3mW{30DN&muFB zWl{|@qY{Ui;XT6{2aRuT^Nl?=+=7MmO8^ME!*Gv;E143<5I?$&4Ri@W4*1JLbg??z zqnEg{2ZqR@ji(9m;j^S3l}A}lMuyaXrn-2fx@Z=4_f`A=Z%<6nE`mn=5ls-IX(PpJ zq+>l_E}D(?q9MTR@uPnh;Pu2^kcEDlN&!@Go?I;jp#;}Ra~Kb>%46wt8Zk6u)Y92g zAwrn+S<%rC7R_kuYgn;@Zd@>?f7X`lxht1VQTCp_dT_}nlj4VrP&0TY1S4bASCsp@ zm58gpj)Ny}TwH>O;P}et z4xe4?`KDWZUfP1C9zG9BhE3|oq-GAi5?1eZbXSe)X7z1#h?@sOqrH>L+6J_{He6k( zj_`1&pVDcF!!CPq!q9KTfK_ocIfc+L%KDJL4egrOPHeing7T=F<=txD;DTe?~!F51VTRChV0fu)9+-V3(evX zDAoKmwew#n6-?M7P%7-KuqInvMcfMm{UL+~(Gck)bL!?Og~y2;M94kuU0 zWkc;*K92)xt1(Su-GVFzuSGSZs0xY=t=0=>5S*jXB7q3xw`P(>+Gz#c*mLrC8;ZxEMEaQC|L;kcMx;T50QNV!@tQ|?$Cn7 z^{DNbQMPsT0F{1R2Ky)wY6Qk4iESox8x^_(gL?xc*gQer&pgye_kLABqY=N}rv?v} zRpuRx1-h;;d})&(&fcZSX#(DOUy{)mN8~)z(wU|+XgZ3?LFPUXc#2HX4j6kYtB_;Q zid%CYZAF)yN4r5~v=r%A^XpPbWtz09@(z2Oy<^^!sxzjUzpn1b2!WGoJ@y}G0#s%} z{C3b??C8+40J~^AFyll!IqqR)aZKOlBVdhnJ`C1oMoiNnAQ?6dCcay&{NuFBi_@k_t*5a9bBfMr?q^APqvQ(^ zVsG?M!t50dYt8^s(Yhqw7E62Qt1DZlr;+I!D=>{94Vh@AW&`##=6DQSmgEUL#TRX+O+pr znOrxz!SKS z{r{gIimNSLu<%`Y9QR6DGvsd^)@ASlKakJ{xM@tuy|3{=)sV<11F46u64i zxd2xl$l9y!hXIqspiz;gJDMbW1LuwgL#a>g4CPj*4VR>z4Bqijq2m1;;>M>w@2md# z%7QNcg1tTJUwt2R`^(Soe?%ereg-(K&>ex#Eku)w|A<3Dd+vbB-4>x%UI>!|5mq$t zYU_-s!7I0(d3?wV`h|#=)Z#gI8h!ZF^TjikObZO15$b;^R~<{oTq-|yTwTuAn$-}xcKES@uakJM z8*)eg&hu>eyCxQ25-DyL9|)MX#gpVFpH#p8=?C>r&aKk2J33=!=%Y&WL+Pu^&{H2= zJuQitErotTZ{mZNn#pn?#$NB8tiz;!ItmZ=;jJsE6kg9smP$9^li*hxfoI z!P1ZL5Iy*LEPXptNuY5PX1l&wI&3 zw{3d?&Vivte_sJEjHoyw7gw}xqZQlqR~rLyn;z7x=hSSk7n&9vsv=}!lsHWr72a9& z4Bg}ZVp%rLU8mNk&(^5@)dB11Gu3yU)SgW+H#7UQ`R3W|4!b7$6NLVpLVxU#S^W3@ zh*mX}Y5g$~nfppC4RX;I%QEP@E6fk4nSWWqmPm~%N1GooUkL#x%u&359NurQS${UK z)YJ%Td2PbVK+Y}oHjWUJz0T5T0)%-ycZzsDlHPjpOd14t;U}r7L*z$k1JT}Y^$LBc z%*EUZCq{iV4+r5zR*o^Q%UijL0R`kDSCZ+&>(|wC+EuCdmuH&(1l|=>wLsFL?;?i7 zEdBsZ{eo8nCTPqQHe!m-_!ri9;C_O(yNR|N0GH7S1D49Qd<3%C+M^rO6bfTdJhTMb zO+EIX|0r|+?2@Kn(FJ^}>BMG_YVw^QLVvQSwXt<|oQso+HVk!@QQGBcA6n$5B z5t+FS0TKtxG=~Q?Y9c*lJLDrW8(Quv2VkL-G?XJ$N{FTJPWgpx$HQ3TD|{@_W3R|P z!3!Fbd6pj31xeS12TycI(||=q;{qm0;gMyNb6sJXAv78743#p_ImQ{jxw~LmofTt}GJyif+>qw^)FAq zGCh>pxFd587Z>$fI$ha(l}0~`ctB&WA5iA!{`Gdm`9B4&Gts~QRO5PtrH2Be8mO~QyIHvg~t`2&W~pkFWEA3KCr4x0ju3pj=Vjtbz}8#L3;3J$I7 z+PpD265+sh1e>z;P=Wnft2por*${~?SU6QgR!fj2K*ZgQ63E0S2s4AleW3nI9nZdZ z*DPNs$SP|)BKMA-nLbrcHJcN2itW1tIl#7X%C`5 ziU79{zO=;SaGb_%@a_Q);PEmfMh}CvwFoQ5G=lp(p72c;%x~`b7+Mx>_bNBgWB7@k z{Djf&Jol3jJ35Jn^sHQWoKqsF%NxuRBNUJM&f~x}fii9#{&w`}?hQd5LR{;_2B(ar zOjV_uDFwSt4)&uI{j98llu9fwIp(r20zF^CRR&cweVeM=OWzNSBG;fxk)t? z`1Pg9B?&I6KV0i+Y#-2Wb?<^*2_;$Yex0)uv=|Y-WqLuOg%(qX9C~r%lc!-psewV| zg-iP+)8MD?{+K?L{yr>6t+eP21rQ@&Vs3dL`X?|T^rwHESvFiu7)KlfL=yH80CKVh z2>yLehEOR)FwJ7IdN(i2IdD8@#f+JI!(p_}8<}zAwmFsM8@J6HXXf0LVU-Y}4RBRv1=&k_)aJK_IljH2maNw0Q}}ylR!&jW)*nT>){I ze}GuLQhUG9k}&2rCa1f>=vLd78*htRyffOUxrqoy18q9;J>u?hX-(l*+&qZWm`*j zp0*@NCC9i!IkSozG(9%|(3zZ7vsY|&r_^E5X7;=Xy~&2|W00yliVd;u71=F7jss0mI1i3p(a`9ft84TI)t>*0I3=Uf@L zbBrsUZak5*V(#o6AvtoZw?~iv{H}RCTYqZ%q6uba-XqS(c)nmA^ojdhII*K zqwUg{tYw>IBab+Q4G2to#Ec1K9*-cyz8Ah8s6jWspo;q9=9lX8oU{9j&z&zRIm@CR z^CY9kK~LcPY5L?$70`1g=p<*jJoyzmk~%`xpqx*{ ztiY!G%Q}+o);p69G|x$OZGHecQqG=&>081Y^UgnQ=UzQ9?;X2YaDo-9_ z{xdo4!Mg&MOm&2Gtr`|<9YpKC4Z?*EqQRn3_y4;N0%;K9##P&Y&_Obbn>&r2mQXZ7 z=pb3!A{%X)tmz;_2kdwr#+oGd<2uOCsRNmN@7=Jw%2>1DSMw;ka25fWDl zdu#WFlb;+s{+W(tZkfAa!Nh&ty1H4Ms7OMqzaFtS(&w5 z!L|xfL3c1B@yU}jJy^RT7Wa(^C&LEfI*}V4^ypEKc76#B-2DeMo;2t5X~_wBk{o6V!^0vG$0}6wZ7JPR%&#=TKR7){JGzg_odpk z1V^=7h%_qBm~-Gl&XQS63j=e~ONWoS|BOvGuef}0#yE++xD32Sg15elzS#PfwB~JO zp=MPI-x96yEz#>C3O@HTOHCc2j-Ewb=gg5BzqoASlN9TziS8mQw*DpU{Wc;=_?NUR z|5yJ~Y=TFu2l~Rj3EYMkq3tD&l-PS??!_rlmu9J#(w;;sF%QP5muJ!8@4UmlGKXHi z%)WYYncY2o+FW0Blwwslk;-uFsQJNc=*Om?njfcj=){;faQnfe2=@{UZ|;LJ*^}x> zjg@N&i>gCctLy0OmFkD;hpXuvb=@j9m!2{|G=D)qQe#;-^RUd@5a`NR1@5ZzMr|0L z4Z6fYf%}=LohKT$*50|CMl^*A`lwcygg@?+FokwrtVTpEp6Aut#leNozoX{wU7&1#Z~$ajVfWtEikPrfL2 zuJRCDXtg`4+C3i6 z)p#VD!489P70GAZea_xGo;z{s)QP#r>&=-mc<9i<)8?uf2@m(*nXzo_;+c03JWfb# zbal<$35B8IyT{*Ib14FSFsVi;d&R9(^8e)o1@`lefR< zvv;($9cj}0c#A%JAS0(bDGt^mA0O`OkM+We5Z-nBIXS~djT$y(PQCKHtZCD-a*wNL zA}+1DlU3Ltq;TThweL4dOn7|Y?u;d4m(94d|6u~}!x~yF|0sFj+X&5w$=)05c)V?y z8=`DZ(VVdxYRw0}Os6iA?vbp=ogS7X$Z(6LSMBcjv2c3Qx}7!j2ly~jkGInkX^pJJxavA_y;WkACxSYj$6)XeT>Bi4dcGV8C8zbJ$%161li7F;@Pltk;uWdEo(=mqk;QN zutf$Mwlzz6j9y}`61JW-+#i*CSh!>;^{d55tye`X$zd2K_m|e}aNkOoY31XXd}CA2 z*^jQhom23EB-MIXmR)fF?_D1n{#C>mG`!BOuiQS&uko@_u@)-^@t0stcenAdYwXs> z2WnSg3R3tCHwM9(7X%qS9GkK^L2H5#B(@448J#PPL1JZ=r&xi7OjjGX1@!@OaaV9G z=r0@sOcFy~Bd3wWOPA?mn@F^>uS2I!`j0DfJNBP

d7@`p2QLizj&|rCuF{#nA?9x>vkR6mGm#}d0|}og~a^> z4z%siuGQ`VFaD&yS1wau_4~_L)bAH{O-y{FV8E{47bj$W*yq5&{ja~#?e#-RNBX>< znQ^h#o`G!U=jwIZa$PPZ;;b*r(pNV?Vtbp)0FfZ`96FS7S? za+x|Hduj&`;y< z^3ZnniOO&#Q<7T^O(;j{psBl}Xlsiv@g%I1Pk4^KPzdBG-S;)LRPIScn@ zWG_;GROirn`0kw-^sIU6&lD@{)L!Z(^&(#fg>hKI%GjTvZys04v0zHXRXA}gk(P)^ zv?-8h79(B=4Wv4x;v^y~5ToT8PP3d=I!QxK-JOt^{Blsm>7Rlsa9xJgk~)wjXp^h& zz}Ei~PGQUJ9a-qizSHIxY%cGUI3#rx)9qO@bAywMn%8N8=dlrQCbA246Y9rzoRR)! zcANe~yLGl#Qs%E&q+X6mj_ln%dP9#E?eXn3aw{En_R}$$5zR_jG*We46b)C8*T>?3#fjq}F*6OL? zSdn8|*I;ZcmH@p{dyV^hNf2^r#Mb(_Hh<-Bc^2W^Aqpe>eN|Tx=^_e}R!zll{ z>D^j1Z0}|8>K)O%U)RCCyY%nM^|^FiqQuwlNW?&lG}?l9D=f7(4{+_s17*WqkYD5#HWbqPNgAZIktpC17oznD8w-&R!5? zu&jC#31Bs14+=J5WFzTPHD`jFLJKC)-IZ@kuS;!G)i>zzR9gO`4bRU2Jx^u1?1=6? zjLQc=MJ~q{=X_coeN0o_GnuVnmvonL&xg2YyLL}QFvNzSPpq8a>sZgwFLakh%ohLE z1!sYCWX=FI{FUt>M+lGEBB&HiM9h{iy{E5lkp9ZhT~^deF^>x2zxt1`->Q8QHhxPR z+ge0&H1Cz>I~2XwycO1JpvlRV8$2d=J8oHke^mP;xXo`#f)9r{r*&6PU$(h^&KSp- zyzxoPqu>rVFZsA|TBanwxSZR6aO?KwKXhLL-afGF0zqF6_->kLQ*=$6t(x!IM2W@9 zf<6LoC0v)WZmcBzN7YQFAMY?bDt+=X)jjV8(DBY9mPKEa8dzu+v40!Bfwcy&<>s=i zGRwUwY7fd+61d_EY@&Uw$=aukb{g(W^;WbC!g8stB0ObL6hp$rv<*-A-6?To!3O=H znSIClL45WdJicd}S6W8d%@Oo6kZq$$x=Wyit5sEOn??)T>P*mrkPi~iQR9AI&~uF& zhRX+s`hrIx;TfN>8d~~4dwNA^#xkp3TKB%>$i|JvBO5juGsb6($;=u%HdCIu@$~79 z*_%$D+%#_CqV(*six-at?al|k?jiW~6hF?dr_dw;$4>ZIPJ!o!Q~cjGY%BIt@uf>U zs;3{ZBfx9*Jg9{W@8ZwAFP@nSo!U-&7SDWuFD2GIBUrVV7kFkRVht;F?}_(+E}r>F znv22KV=mRLoo}r%ms(rq5+fPvR4G+{1$lD*Jlf@Eu>-|w7H$U;H^IxfT>W2{qhd{` z&1x1!(F=tRJUYP=`xakSfNsaXD#2Q_#zV%ZESWQ9Ez4r;v%O_k7tU-`AFEkd(Sou4 zCT^KjvzlemCzIobj-Z?PS}`{uHUM+M72g;vvW&Md#9p2af)X@OkVKTFZ3$5;|n z9)J%*zA8x*Vcc4K5s~O;lOb;vyyHP#?)X4>Fe!#g#5n zXYwre+iB)Px=!kh|D+6ab|`r)UB)-U9bxg9WCs{B)S)^A#B-(~8YsRc$v+~jr*tSy zQ}-p(0d!!Zx{szMs@v6Ed`ogX9o9=N6dQFzBF*5Rdj)$zUhF~S#eN5$L?|+)sw43> z*`7j0;5um&E5MQRX=T)!{F?-Gz84VOgzq9OyT;-qxF96ENY~)@BTt+~j5)j9vPAmr9pcS}1ICtK8ug_obPQ z!xi&}*abbb{MzWK+#CJ=*ep_P+qcd8rr+)P52wDW#a2ic%{2m-uKPo3Gp{}|XFdW(lx#s9tBdYFVgqjo z`-3yM8unWwJ-LI^-i?PKtXIpM{B$C&hRpc}wPPk?l$s8K(3XYgX>nS7c{8qh37Qvm z&H3oS$`dnb)~&n&$HIdfZRqsYI(6;roF3EH$*n%Tvt!NpPkRnf@2=anJ31&eplQzV zQPg+I&@cK7nS7uCG=v@7gbzUIVceg|6RX^U#OGqDmSQ6Rviw@>reE*afAY?!RGB?%N&W<; zyM1a_X~Q<>CSAF0b~#!;Ccj;D>(a`uY3CZKmAOUprIpJMIx{vg*DEt^;Ou?t3XUZ$ zUcWfiNm+g@W6Y?mKW~oqJNM|d<^vOYjvm*R2CjZ{!X z?&B}~TVVF^$RP}7?J|NN*~Vo=z1_9wDfAIO-(gAV!nv&vN2*V#50)6?V>%qA7EM-a zotdpZ`nW>A?3Db=;|hJC0*_p$eko4&2O%=ugwazkz+ug4Kz zv6q1F6jLH|*O#%z%W2eWx(sN>=vY&!QE@PM-QPaR!V07=#u6 z&Qp2Zx^+fO;?UH=sR&*tjEd?xbkykaIh|fp=)4B~qY=Zt)~= z>*Fpzt>rOoFVCGdH>r8^=;pKy%c3N4>%BODlzfF;F&*^R#;@kE}ez1yf3-+mH zO8h+sP}8b4`C=OrHvZpo0J(SUpK}21E%EJ~=KCi7b9h^S!aR52@PCSL*M$x?7IMJ@ zw%R{^5ksiqob?)nx^FaKb(kT*0GA?M5ic!7ZYN|4|~1BIX8I&bA=mMdgJEDg*-LIod3N(vzpeNl12H_H z#3Dm|JVLhk)OSnuJ-*H=FE2-m9zA}vd3P$yYdXFu!$)*D-k_V)zd-+v_yUkXhz<4E zD5O-b)+GL=Ulm4poxy$VK{mV>30^#_z|x1#CeyU?@@dkLPUAb7-Pk*w$9HBw@wUs= zZt@SnNgaIeTC^=Bs)iGr;Du(jirZ|0*rJP=lQ#KXh*4n4EeMn67`~L*6<@RTO8#Nj znt(Vz7uU9415+w5@-U`riCt@g zTLropI@V1Zv10C9c?~cbPK+Ff>>^JNz!;swTiNXAQ`@JHseF!^0o$qSXMG@SPao*a zt1Z2^S+OjTtf5~U`dT2tIe1{f%8oF3Si+|s{~v2#0w2@a{XfrLW)dWsB(hi{8;L!L zBt>f}s@7Oa?SdwDL1`w0pq5f9wxVilRqZAtlu}DeH%b((mbQvoT18*9Mdr!>d!9RY za<8TD^8542&D>cs&vKr#e$P3G9R=gG7%SO9eKEpZF-HSb3Gp*?ns#(F1#3_kg;G*O z!^m4BepFIVG@*d>R9jThivDw3-{hxRwVQ3IlYwM`yk`lR~tP&wZ(z+7fY39 z?a+dx4)bB{%lIPGH^aTQtj$NcW%J>G|H6-5;&&nI`eH32v5!=rtpO}yF-?=KGl5!! z7Dx*~Dy+}~iH}-kp?3I{6COps1XAq`K^a%YNMX>&6_QiTplCSj3QZ*0sJD3}qXxM& zYG@Qa6^ru_pv$YS^@W67aJEsSZ*o1D;1y5Re`e2=*UvU;_I&4^K%^9BLu0Wk}ek^H@nfjA?9 z>du;ZmFh+M2Rt46V*i2y4eVU59>C6b2Hs)2mj099Xh#i_-HazPUTR#oFGF z2Th8+K5L>i86LjQW*b=F9YL)6jaLI<{=!B_kqu)32I!LpK8n2wp=cxdr)-bO{@YlfE`ncls$;;Wq=22t8UVHMVU&|S<=~{*UeBq zOehECP3cuGTPcElQk?<=&X@KcvluJOYACo>{;{N1Es zmnQ9sqAII!gsue@A%O39h9R+ z;-aviH8dtY=0kclCvDg@vDnsqN<>wk5O zT5Ch#&p*SVO5gFivQ_#Lx?=#YcZgI%T@zAB*j%pOso=@q}FWNA5Zk|-73C* zV%4fi$zsmExPz?$e+;HLYA~Qq`u7<5AWS2#7aRT^EeM>#dOhDRE-|WZczC7Ob=wWd z=<{^iQ<2F*{#}C0_2}5@wIuQPGnAWBvHAo4ek|%LSfJhrkPRvIKvluggS`P6iDIL{ zq*e~(~iTtG+Ucg`&spi?qf$jmmJh>+{ovFC6g>OluL4` zdIPcG(w2B6;>$Hec~);I%o_u9B6x@I6Tv&wqlk@{DI^vzy*gjwXGTkr)8)GvvU&rt zF)LGW6?qSmWfy;&ohe=`_5~=%aAbYztK{_6A2kiL_}YD=eCzl&_3h}J<~z!FvTvU6 zYTwep&xmgg!TiE>pCgvg7`NQj?dgUubZPWV*XL_QR;pI5Qe=$_4cfPFkkYnoO1UbP z%STkM44QKLEBkn;S_GO35q#A<3ReJ1dtvoZrkaQL+b~Jl#~S1PtCjtHt?Jg^4;Y(w zL0kby@5K8PtR zJN@GtGXG_(TUk5t5Ad#c)o?k%x*U(lw}u>ie4mzU?p?X2rE_ibY^!YBZ2N60sz@2Egc3w1|`DP1q{x+$P68(@g|Mgibb;@zdQ;hEf8jq-X<#tZTk9uTit}@Lrd(_MXak0w&FkR6Dh2^BZtJC zD5@DN3KYajZ(4c1iBjkoDKtk#`6pUe(1Hv!l|?Dz*|XBf&KG~*6ff85z(@oxRT3Fv zDhzLA%DMXCQjn|8QvupE)SSYZH0qLd>Qb^k1@&b7jFXoX4M~%Zx$AXBhWQ)m>9RdT zw(7N;sD^_Lma!PmzmHf#Ko~1>3ICi%roUzteUhcrD4|n^sJum~jlb`Q9%+xxS2tZu zw4f4yG0p}4CY%HcQYJB$gkLr$?dPF#kD@?HaTm$EimprSN9l??H=~dAmejjXhU)$l z>)iuqq#wRJ1o7i|bXpVNZ*nzx)!Lx4LahxV?Zs8Pl!zkW+{4ioWb$6X$wdAPLx~b+ z7!58l3b86nbS&!c$3_vrAvzI$(Lj=u1Od`w2#JAm81;5-$@lPL$-w|e`-n9M5XhmN z{_F2k6TkiI&ofN9!;fG2l^;KNkR|+z{NBC%$D*aTKRNKP+XoNbk_Quw=3rjFm{&Qy zdW^}&2!}x&t{+l8ZZD?p1)7GI2_khplx9o#Zlh@>9E)Ujz^hvpDr{_EoJCXJ!{B6; z?pwG2=-@wG&%VYlInHdeX0s!b@AZ$RI_|aCls#+s=tf!7^d7tN)WteY%`|9CTtKj2^2 z8JpgdJ@@rEwDs-F*YL~ZPVn75)1k*8pB=qbJ3teoeqCbFCW}L?xNd&vaB}fBJ&TZN z#^B6#`3Dl#%vC}BqLS0$rdSmS%9JG}d_puik?Nkpw1}R^S0;a*RHsZ>Kwwy%3LSg< zC2bu0@!7M7#;i~Bcjv5FIc{l<>PyG2T%|NDIy1P7qV(}A)n{wG`|3g z@NmO0GFs~}fy^EVW6?&qQb2O`$pG@iGd%?p=olqQop=2_r0?uSe}9>_yRqZ$`X%$0 zygq4Dt?eV%xVF7LPd)tYhV=Jp#eXsT^PihF<*K@K>n-<~yjMrP=bBOUS?jKw7tPs0 zJg+A2FY=a3>vdO5yD1o;zMFzUkt^3%_GIHEGK>%SYUB;ct#bHi2OpKgsw0gFM&vL2 zS+-B9P;@#MAR$klr#Pq8(c`UzZuG+`s6+oIofVN8Y0TbJL|oq$ss;7KMKM4_q5%$t zG0F+b0ee)ud7+ec;0bLe$$E}xoXF6SLgWJX4H>7Pt>*iL>zbI`%Ia%6_ zO|I3d;7wJ@trK2VxKYCs3NpiU!==#${lYWDNk1S|roln(lEVcE_Hih1XH|QCR0+}H z)=7*37(^`zzzpL~M99h;%7se>#iQbejmaD^{Nmvqf2-1n9n+R9o&VPE-K$n@T)JQv zg5dnGornKq)%w3$DJHkWf>j%4SbL2d)4g}bOX)+?#=Y9#`t~}~LtFDv@(S#6G*ARo zz1Hh1)i+t-{%Ojr5}gzyriZrLRKOHSW6hq!&_e)Gf+Ii^9{?u>rLg$uBzXlNJ8?+f z+~=mwVvBm!YCOE%3mrc?oHd(uk=-p+XKOAm|8@Mh`6CAnSRVUgxxp=-diwaXu`F@} zTcZ-t5&5K`eTr%Pr}@z2Or<&Lob12Nhu)Tzj{*XdbCy>@#NvarVP9W+a7?ND;oI36 zMSp4WJlQe>{M9aSa#U$!rbai9cX9e_E>3^wn#eCL*yg|ApL9)sXqd2O1P2C(&oJWIKs2)H?l48Gk`qaN}ojUzT z(GBUXP4B+5QF_arvH2bReoSMBmuFIEhu$P#0jmi0v>OF zgQLr_wms9?if5v_wk%cMuKGV!Hfv%W8&au#qF@nO_NMW5^qrhmi-b`k0>I>5Wnvbv9 z?;2&UW)xRSFeher)*{_b=Nn!I^6=>_DNLUdn(y7k`2FX7iEk_v$8<#J z9`MtBz4`5NQ#!QaK+nA~dZc4ezH`C0vBUcU<2`Q#wTww1tA$lxP{rSRa=Os-^M9qPNGtN9-I#KYF!BPUO* zorEzZ#@DC12A;YAA$sj3`TK*THa_KG?CwX$FF97OSowDKw_aYcMpOmp*w+2M{Fm>q zOo1`@0I1?StNHHk>AxM)Xeg7X%O^xE(6go{*)I|U^-=46n!u*v+8}0a%<8Ua0-|G0 z4M{`r+agn_goDSEW?DZ;dd7JP^^@M2vd($vqa}0M;$F3y4DXTtd+|M`!x5Kt+A_YY zy6e~Az>LBD7R9_6-oI(1My0}8_{HkiSfZ{^3cQbQ&C?HAwcvSU3@)`p#~+zN%1Hrpfwx` z3}nIYyuR*Dsd3WOx(!bJ@a1_x-`9S15GH3H3w&*2@ut6d;az5tdSVQcWi*db{V|4c zaM|vn>YY~u(7)TXM_#7^z0I45PbztsK*10m$j47)!6I?kQziit1ilrSzyU%ldTZo_ zy7R59)C;F0+oeh*+pmfvv-C?Os(^ng{L=%tSvTpM`j^i#X z?SVN|MYg?=7p8qP zB|Vq$HjtqRq2mM^g+K7-1eZo^0Ot~;2X2}qCuq?s*@!=A4gvv%HXa|3sY>eV(&xKK zZ_J;(G<(UEym?ZW=chJLJ#u)8t7^6U$)A4Np@q`$HGVViV6o-kSFAEWhZANwIFAL+ z!U?;>k4~97bqcG0XA@%+#5tP|SvUncVtM5Ack&_uOpq4u>RW^(Su`7TDM6wK5~4 zg+C-)-2;D!r@pk1kGjDiwno44Vxb@-jgjIIQk=j4E8n zWfI4CtCSoXRw|}!ozyD)ii2N@?~o7@RVpkrsZ!VR_4ie_R#v{v8SG!CuUe{MSN9_K z2C0WMv}?msYTq*cgL8PdQKQ5@JO$iz70_5H{Mhgf5EnBMmhKf6uZZ$A#M+UrZInP2 zNGoxb@*@NwH-!tYqj|(clE}BJ^bZ&tK;dIku6S>GB{Pe)y0r`}=4rkWQORX^C~1-aq#bUWRZOV4h@#b~j^8*VykaE?clB!5D;3wY`Dju)=Scf64Lxz}i2 zFFt=<*NbP;+v|NV>RT*63D_^PB1aiCW_`zWPotnsUG}<|FD2YlEEu}80jUJUYrfGX z352FGkdI^vgY}3BmLyX|%aR0V6%^OtV0u~@@yZ1@;+F?Smv{yDvEaZ1e^slpZBbyD zT#1b+*s*gvYVEK5^`nn|#b%!5ZTZr4WGLrJ3sHMN=fm04J-B(mn0+XA9R#$=WNm&X z&#%rbT$TXg-$iB=b-^phwai1tp=gHZO0^*54tWHr1jr=X^(k6cNs8N>(nDw;4dh9{ z1;Y`>d{NflFlAEKy>mqX^O-C*;_`iX#3~{rkR=z;Gn(f8-l6jrDkhKIV{@{LcDh1CFjB$I z$+ZpDQd#Cc-h0QOn|B@CclY0oLW`}$k@~S*g_GC$K(=D{>I&uDjlJh-FJC2atlnBb zLdNP8W(w+=R6Tvb#>j~iDBn^Dd+VWU_^t$!8pVk*w7pqaM1+BPGzI0oRZQgR zZioD!CKZ$u1X)NcWjfV5X%oXS*a0rdSI9!ijHP-cD+q8*;gOBS1Mik9k?t~V_?7z) zF7t}=aC*FB`}Q3m*Xuv-+50ngGRnO;f7Yv8Nhf}uuTo#b`23$RKHVI2mZUWx6blJw zz*B0W7bk!Sn1sQi1>s?BP@XC=8K;X{OGt3_2S%&8nGd!N^&8OT9ea5>_U)oo0W?57rJJbgc!3UZfB>s9WKW0a4Lns2#I2xsPcgbGZ6Nou`6}vAaxf?FhT1{8AjW- zm)2%&-~mge2=1H5j^t-;VMp?~k5p-?^ntsz__-w=K&`=r;-{(GuFVfMY?Xn~o4o#5 z;eyp?p;HP{=BpADESIn|wOqe)ndM}#`*Ij`0xm{A_dob!jUD{FC>`O=_e96wl|@4_ zD)6tgn>}Gp9zS>OD}EC7+`iki|C=vA+qUiF-3RwAKb0w2S^1;an4eO2#I_pot{I>F zaOQ}0&aU!(?r=e~yA-jDNf6MO3I-(fnVLVed4;0fC(41VanVn2{c z6Np|S*orX4f$EvmWkv+c2{0Z5z<6b73#2bp!}pSZDnPGPYWiN2=gn)XgXtPe$C(44 zBvnA|263WXaJb(H_TTh3E3Ge&V(Wb(qOD4XCaiMitRBX6;c7Ip=a4q;c6kB7uD##s^icqkTIiS&vm zMqViji^wZk&d4^GQz`%?-Vv?X{;rT+9{Txq)`9t!&yM(kF<$(G^Cw=+Ea%Is75VOa z_xT5>PqS9{@3Gc}{7BLB%;)q;=EMIyd79sscWHaQldn-nVvYUC?@t`qRMJORd`;XQ z{zTxMP^tiDotikC*}h1l0q`d<8tD^_q^!BVBOW07a({=Uw!Z%XZ^-%y8ruRITY~Qm zws`76nmE5O$MucYY1PTq(SumJUmQRzrsi-#nOJ(K#m8!rwz*a zLO&H42W!ZBNo7&L{fpJ$r~h?>UqsQVZ}#oG>V8{#>FU0H-^kajr%}gu760{j6o^^# z_c?3+Ar^P7e@4}7tm?s?(8<1q-TpcBfDm{c-hPbEXfh;pq7{ry*VbHqn)-;m+N7KUft3elP-a>5@v9pXjArzj^c$HH>g=!?PyGIheR1z)NbM+1KfTd65nbo{*&7 znzIqCpX)#`{s)rO1OB0vRf-!~lJ54Mp48Eb^i?R;N)wQtA1p^tmqL@0AP%%1Y0;S& z#Fc<$l}Ru*w023Nd>gskP1XkjWLjx4q1rPo2|F?R!W7nX9-8Z3VS63CCtJt&ez3n_ zHOr8)57wND36?rc3evA`xy^=Lh;7~l#3!#(h`KyL=A#&?s|ACDAxXKG8 zy0JVVIbBR?_YCc-JxLN+@f3KKMb-gg(C{#aK|}N8KqCk$bv)tb_s@Js!GNEaOzbNu z+wzy6M%my`2Cn~T--h-3_RIg`w@yW06S62<>W+r@EI_-vLuXTDaZQFVs{K$kQqm*19RQuG^}f zA}?OMrb@IHV~^gz=6-oTz1Pqw-|pt`v0gJ4E}n+p3A6K-FXg`~4d>@|nN+dtygmz; zv48O~g9r2+`jXVYPyar|C*H**8e{xsY^OeUT@2IFH&|oDD}{2`*!_b;S}va~s)aux z_Bn}vth5#D;kEAs=h6S7&UsAs65vuW>!D!4mE#p@B;xS3Ci@ASn?i;YsT#1O$e#-l z^J=$@(m_)0DBqDqCx`g5IlgIarEYv!`taZHvYACScpui7f6U&MI-KGcdduk;Cj%W? z)FO;CjH>&Q4kXToK1x$KP_P&M74M4BXH2$}?o)FGN&-_F2o8#h{RRC3GXnv4G%O!k zPiV_dMhg-^F-?HO%8)+jv7X{h<`dw$-{v{y@lo?-c7TtZ&j!wSEMNl{^5N{DyZ{}V z%FvH0)s%dB6?T?>+<&@HtF#{sz0YsR?+8pwe{G&s3C5z&MrW4!24|70T%gCEdb08K zc=U>HEfJXiAFL$`vdeD_=s9S}#ShotgRQi2%ABQh7ryu28@V%HA4hF+eqFb_P%fW3 zDW=lY0gK*$f4Mbn+SvZX1`Hn9r{}0wdRnJ%Tq)+Z7PNa7duXKUd!g@NvH^RRa#=s=sp7qV6dGn@;QvvY}e__ z^1s`4fk2qVrlizM4h)pfIe7A7XAP;!$bn+HPV!m&V}4;6`vI+21)pTZC)Fe|4o}}q zu_O98Oy|w(*rg*TmR6TvUZemp{NNcdM__Hy-c=!YgRpe9q-p7vm2Fz&u=0$qystHD z#d>)Gws9ycS}f9so zAk!z8TFOwn-GX^Ot9-DX21D5kIu>SweAeOK?I5ecvwam9;ZF6jnX%3K*d99^3PMXI zm@@CzL~CCmr4IIFLW|}B4S7N8^J;Kc%%s;;tl!1t~La}sJLwPk{MIFa;)9?6bPcE zvl2y^f(TR#rbO^evKpnNDulj8exC@`CPkY-shLMVOzIh%72CVP?qgr=YS5>0R+S#f zyN)VZOBSYdC|5BxY2o4`mbb88hlmR8>Mxovm8DLk0Uvaly>CTM>o_J1Y5*K3QLq@0io`XF>B;Zm6}qaOB7M{A23 z=Sh-;h=zb(>1es2#fhU?uP=XoQ4tE}guF>MQ*vat>Zv;$WnT|i`(QEid2eOLnX9xSiasPXL!t&{on*6KyerqdypVWChx(TVIa_pVdi6cET7R zwZZjKn!sJUDlfM5|CbFOr4Kht8>{pHJTsq0i%|z^qjl3lVof1y27@w2CYenm|R7`q;9`Pc3%gAFP+d$$7aFwO2F>dFI2oq*oM8ZR8 zPt6NWj1IOAF*;rQLLP2XG!Vs-I(F-DNxl8fsr&a%ZM~{W!{5(Yy+xLJC3Znlx5!st zb66K2;m3Zh{u@7bVzYJHTi3U#>FUNy*ng}i?C)UAgZdSFu;3ZBf zvKG2D1s{n)!CFB~gpBCqL`s0bk&Lm*`3~~vPGj~_0e_ zPa@X7{KgKxr*|&A5783X+lY+88}WtltO=01J*PbjDN1W1$QP2uH|6DeB%RB|^zb zXp<_n=3j}1Y^(F48=;y+%W^OF*IKjf-tAzC%1OReG-xYB6=4RbrKXIN{?t0PDJL_2 z`ib}uvy8-f`d*wT4@Ss@PSZ6-wu;Rbt4)W> zy}$;So_@5enD{ne2t@mW`2I#5Qw=o}z>!)k;G4TeI zny=4COiowk4N-i=QXY!jBZm541@9}89-aK*i4&NNP^ns3D>Q^v`YbWYatRUW(8V{4f>nn};m zIhvS{J~^Z9=>*sU2`t7MeI9*_TriB*o3C~76`FSQ;8TiOgB-+p-3+-g1ir~A6Q)m( zs0gh}zY(gxexuu0VoZ~}4f5!sg!HoxIh+4Ve$CoDvbLRe zEOO+ooUnA_gk=bQ{&w<*VMB%t`{AS#^5C~sn>Vj2`K^r~eRtK1n2dS+y3S*=S;hGE zSN{KwU%hx_?a+6s)m%I5ox@qvhL3r}F)MTAERb-E!^isd?c49zVQH_s#rzd3=9m1Y z@k_-QLDxT9%Zal&R-(*SvG^$xV2%>6`a@BOI5u~i&#Nm}VUH(Pkh7u}F{;Z&IAq$Z;3$CNu;YPsKgmHtj z-zWy7>`q|+0C%V?jw@Wvi28@wVhQRdg#ZesgTWGYxR|E1bVSwQ>bI{ld$2Sr{EJ=t zuSh}e8v+zIN(YVcdk84iieaIw|DQiucO2knu2jxQ7tk;dY%JZ~fZ|K2FAkcV1{oNy zuYs7UiSqOtp&jUJpw|L3$_E!f0VMAOAy!0f70u&n2#V4E8#Ekeq$o}bU#*b+fU!Ix z9<_3#T3Ko-o*bHqtkQ#0x4!nYUw#k$E!c5hM}B{kM~a^LL%k1OzQ+$NT=Zf-zY)^1 z;5V&DbIcW91}9Jga@L|8#1c?_eNRO@Au9C^_j)WI@ymJ{h{Y(+OxlPpu*JxAHQ#0R z@zkTt4=I5z6FphQnZngyc!Zx|?(leZVG3CvHsh(gmWcw1zD# zZ7xU#UV#_|ypFhP^Aaia(T|-Mc8N7(otZCf(L%9Z^Z6N=D21NgIw)mB*Z1t1wr}p4 z+OE<3;N?~?W8WfRcX_hL1S#oTCB(XZz;)P$n38}s;}w^$pQyZ!vOl1CuxI081}FuR zy%Oz|IgFWz9Ogu948!RT!5$Idi4ceJl!Qw8!_g}*ewWTWD#Lkd+IJTnZ*5#t%3)i# zahX&(m<@DSWjSB(lh(R>e{_;hV>$0lx4VZ*%S+E#3uj>&sj-kvVs6ytwj!jfac=tF zndWBNA+JZlr>vM8s=8oqFrtl$a2P$~j1Y4($I{3Kqq$MuP^`#M^-e8>B?d>Y{QiWM ze<;7rKRo`uW5Md?rLt^o-pOM-%ieR}|K#hB*i|0RK05KqCu^tMd1ZE?)bzEVNSzt% zGsLNZaRs;vxhK^u^R;s(PLsZ0f+6cS`q3BrWpZ}vnT_I=7|5;|+DTim;MKqu;cVIL zq?aKOYBzX4QQiSCyeRQ%oY15Vb-BUYq94Df$daNxPEOH|BdtxU92)Y-{_b3}AUml( zuZmi>WyCgPGauPxWyWgS^Yle^-8~Vz?v3r1s8+7^2==-%vO7HMVoFMh#T;YxjW_Y1 z$8Nk>7k!b?b1ar*7_c3_hP6O>B+#}V9zWS3-(ihg{Wno8!3(}c_^%#d- z&||hf$U;c6e5lb$O)No8oiqf6>wa+kTpMk0S8Vy3H0js`V>JSoHAXB&O}nvan6swc zS+CGpFQKX5xX= z*rI~{wU5`9sQOv$$l3|Do77hNIFm>w)g!pS2udrlT7Ehe#uNukGb{;5E&${xev+bB zNjrCj$#W*Yv4CIrzIm@s!<*FVy=cL_rrS;&IXrFJ!Cl*(d_P<1DWvB7a>vLm)#J9$ z{OC-xCe8YXy%@c?@9=T&&U$OnpanB>mSr%-Q)x}I^u?MEx0V%adR1FfA-r_55(KBO zsc=^k;{?~R8K?$;Y(sRxRWnuy<(dh`^>hW)5Ni+iqAhEfaS64>Jzwuuz0!S}MqBFH z>qXUjc$rJyV;|i#_|f9%j>W$9MuiC3h?q?-=@0!(nR7u(=+4ervC!M$Wb&INQy(TZc zwq8}&UnAMepifwoNzh)CWnNTiY{BXQv^So#;1uc z%~GdHnf`u#)KX2m7g6V93H8E8E0?W=1xe6zlTC}D#|uc$fP_UuY^2v1v+E?AY`TS?|A;CH3c*w=NBym=m~st02>DZwF>M$}Zi;uSnPP zvV$GjfjN2CZ{En87&u{kaCY8JtTWYdnSfpid&S&}Gpl)PcMEe8k6QAC^-)T+F2$ss_0b}-)wah)JiCLW!vdf z8?BB-a2csh=^VeD+ z^8IC1>ixkw_rdpfZeGQ{r-uE}sZVDw|F}Of0#5bc?vHB~?Nnx6;5unjwC!0%k232+qWlMY;%XK`9!Jxr z;8g$H{lIE#UJx>zp12>wt#2Rxbj^tOYSdUe{GG#xR#=BmBj;Y$8!r!=Hf`9Om8S4J z4O_Rzexx#cCXasVnb(zPB=y^){N}N5`{CcW$5`OeZ?PZmFXK1gTDM~Uojdbatb2~*RtBLQ>Up@`PqNt zU`Eb9U!ZIPF1wuGlS8P&V zP~;M&n~n?oCY-6ivj}u4{`RB&SFY^ufEJ{^?5rm%^*i}b@1M0g55s?Y6W&wObf?!F~*r$AOCdk^p-0qma=}rI_I|atuesffvm=lR0>6SI8iEP zZxP0ZgnH!CH-`Tz*y8kuVGrS~o4;T*s;vr~WK~jB@slXyUTTK0IRD|pnLqQNl30~< z{Kpg)dt}-ltV%=ZsLsv(Hu8M-#-_fT*z8Sdo7iC9b5q}qq;D0ys~ji}Q2zvdqYgEU zWx3>p;;V4b&=Ebv9XyKhk!qs}Uk=}c&*Z9M#oeqS&=YG~TxIN#poqm8K1j-t$osPU5SBdm{hcUB(rzSoYcGh^9}j!$&u>I?~Ko=6x6KKimn)&d#qZUKW*&~ z46={K)0vxLG+{RP*x8L6sOP57$*xWBdmr!1)ZZtgq%TGupAwI8pKs8Zy{^_4yw2x- z8GeYpt8Rm*nA(&!L5-h&mP|`7{ySetaK4n_91AgPSZ+|Pu`ajs1reBg!Jgl{WLl)- zy+po$T=Rz;p08Qx9BX&hr)z$W;rXWvoh|J7?Mj}Z!N!rMs>hQ<9==B=#Xr9O@caMW z{lkB+s8~`)^-CMANQ3Lvt5=)-BB`U((#9y#kUEL=YIhQM^djyO_}8XecX!iA-CZSR zbXxz>D!sXG9ex?N{lslT{knCY5qD!$X$bBTl-t(SL4#7QH5xXk$$ztU7>vg?8#JuJ zeM=s@@0C2}m#iH#GCJZt4Qi_8_0K-}{UC3P&;4r1cOHz`kYe!#E|)yQm4L0PN@d*< zt%^x-R!nflCpZ!AL1|PvXeOISuzCc)pw*&ycd#5EoQMjOYDg8Fxg?dPR0*@H%!USQ za=e@p%))|gGOtm3e7}|r%4DZKCsp!8bEtI>#`z&Lucy3RV$E7q;l)MZu?JeRxEg_r zntdww3tar{;ivui7Q{#2@dwmnH4iM4GoV!?y0ESGWi7(;i{1!a*79@dlEj{C$xjzu zl=z-jtOn+%$MOb>Sl&=gJ_*l|&TUNzzE2L{3DCJWd{^ebjo{%_{s$2}WOZg!1P_Vl z+qV~O@x<>W%H>k>AY<*=8xJl^SkC$!bZ(6P-M(4UUs-Bvc7LbpWCQT`SHVzwMqT*O z-+x5@{`21_&opIyJmdb}A;o8DIA+#^#=nPOQCfqhLM<DA*wk zK%50^g|T!7^btdp1hd08qw-!^NiS?d;j3sWYkrFPvE*OBv$A!Y+3jyni7MyrKlso5 z(nbEIBK3H%|LQe274@KX;J4*X@HT`P#%ZD5_DA`#h1c!&hFrIF0{RrBBQr$F}Y6dl(x2 zG0P6nLm`G-)`U*dPpGg3^cyd65IfbqUasI$qHeCI)t0Lt_1iL*4`xa*8CB355K5<* ztFMHD0T?R%7c~PA6I2$VHTKOV{JGv4^Ru$%XAESM5KU<6woBXj1y;%39(RLTdB~lm z81p+Aa}!LUtX{X(gm)2ReuUs2Kjwmd!I{Cp@n;6-1`~iEgD;pDyeb#~{(nCQC{dm{ zfK6f!etaF9vyyLboAFw9_G=mKSTsNzf4U3Vts6JA)_Z^a!Omm+oe&=xiZ!=eJSYuQ zl+WZuHLbZG(scPqo=BLhA5spqyn|eydB{jGL3t48GtR<~k$W42L!$;xlrmkZ$8oGY z{_`vzD)s+NdS<5NUMEeL-jKGqyMUd$2S_Vb6n2Rgxh08+Pu9V@+o4?vnJUJuFSQuA ze)I3fEm9@4B#QrO$kK&%*?g4b`%pFv%I)b54k;Z5YmGWIwgXseKg$$t%wl9ZNt@`~ z6t?%$x225mSnKs^wxMDJtl6I)TdM{~)Ue>#V6y`ioCT;6T6`jX6rOon?&OZ69+X+K zB5lsNzmr-|Vz3xD_^3*GD}FleLyTKrUK5Q!Vcgoev>@jQ+eNu5G;-vsKrJRxrwPo% z*GOZ?{r6uCJ4|XNRpu{fSu9=IFN2C|X_+iyy|?q5HtK&9PIag#cnMx%0(%L?g&dId ziZ^a;2^6juU^UEMXIevJ%rnds7yvClhE>x7D?e^9G3yOlwST$!L)<#vSpOe9+X|o+ zbO6-f_l(`-6wnW#7`x!+6sfh?MNuX(cH(mwa)7~iiXf9&zQE3Xb3Ha z9c9l?GK?01ROnr`OP+C+lWUV&6JJ~CXrXpz^+IQLlsoe@bcUz|Y&KFNOcdGhC}=Gu z1rm@p2o6gL;S4~agQ%FGR>~+uT|8u8=jT>-<5&3h2ZycF(p}8|d}6;E^H-g5xqf)n z(QsNDcjsjb$4^@_C3j)@*x0CO_Bu;A##v`oO5?vAEkr8vhqcn2xt>a5h@VmbRUr8(wwfq=YBy6| z*2LswWpbA#&!$Xn`3?GNEwc8V{K@;3TSkt|dT-Xu4PD#UN>5pp(fP%+%yjE>sbwlw zh>Bt@|7`yiE3HcXPOeBj!v8K^rv0^fLl55J4-OB`{jQzAKRYmN(U-dxjGX#eN`r&o zGqHS)bvVvzpk5Ke#2-zv$a`|ZFN`@lNX-Fk%vg*Wb_SrxqKqWu4E4+`sTcyNd#1dD zcPXhG(k4CqL4}gaA&6HYN9qR7VSwHT!^HbcVP4&#Ogzk>?NPcAJo?5l0q=)MfS>Md zC;dqq8Yv-^U(8zbQ_>-RUQeNtPp79B<&`8+F^gW$B!YU#6Z;ZDW?hz;LP%o7#2i8- zQ8g*VT*MiGA_ONitTwW#ym2Gp=R|}EV}eSjl{o2_^i;;Lj%-Jd7q@35*B_`CItlPm z{<_Ns57Ek}d!#~FwddF(AW<-9SPW5`qgUgo%5X}NSWEEaJ z1GdviuqR6Vdg4$M<Fh(xdetFqxewR>MJ9jtj{l~v*A zWt%@`g^9k($^y`zH!n?$Mqg9!88oSHR*OicN1sIlpG9GBS~YU0crZ)|QUCxl1}5`bAB799Fh%4a`U;@M{XDg|gB>lx^hS z4_)>XzxHfOj|T1JPSt;e(tP%N_!IsHAM5}=7y)FZXO1R7vv-a`77>1d;{?%9c%2OZ z2|@s4j!zDo5u*c(15cx_>Dpe<1Vc$IV1hEXB#esFORgjQcIL|&&6<@j-uT%ixAO7I zQ7fNHd}dFc=ma}{T?ngrxnAg7IUR=te|pc*4OVu0I=>Q)@8Cz3^+MMeqMb)!Q|Yv0 zig1`3&4{@Mc~lS~#`POrz;B0!jc)dstiJ)|C>WYzG!2C!C-i7(IC}dgUek?3{%KZL zz7#)8lA|Q39G49SVjI{pqoh1iPcesgU?*M{ItO@)M|=z7(@&>Rk@OoA>|D>T*j`rl z!(hwW2`OfwLZm=AnH3Bi4e0t(oiBdhc_4b}3`zR&!+q2od{dqzbqoIC$W+cN_lemt zcFTHik8q4_ucr@on5CVzzGC6@^)4wuM*11KNukzd5ih9rUeHNnuyqGBw{OsGHLdh)z&cy+sjB5G|Dup#Za0J zrxHT~s|i7U9^yEjsyw7`2G=57T^yy=NGP$Vh z-|At$gnz%DpW)Nl3oL$Iue+>%^W+{+b-4dJd-``Z={&zeeDgK*9W7E)#hCxczN1=4 z9`o=i>R^B)U^aSM;1l|eN|mYa=-qvvU6P7SjKn=-osvp@N3Zf@1}0J@>r8}M#(*!D z1`nyIueyn>g`EX4z8&TKuN$n&;%A#Y7UK&YwC(&zRu;i{Gr%U|V zi#K@jS9|y^RT{l_$(o(p^Rv~KYDORTAJWBBAOGm76S!l&)>mN+A1AQp6)k9JNK#NI z?d@ez1ii*%2Zj~<$C31v+(|T&*5BXa{OE`Lre`Dvw-1$%se}5sZ~9z1df=z;zOc^T zwSI2FhC%2RSRTB9{BCiU%`p~B96Pn5g~i5}qu(L^;q^eA#|%(%oaJg&@%lS6#Ou@O zbJmnO()MjFm^kQ1Vnv#WZhc$)OHu~wnj18FzbnK8`5~JlwawLzq0zI#pWIl8xZA8T3sCZ4XD4=dbXf|FSqf}EHU{=of=?aUg^m0_J zq7J3(I%XDMv$jX>T8t%8uNy2_gP!A~lZT*{ zf9eiT4a*Gc=?aPzb?`l{;j#7x-32F7v==F6Hh~CeM;?oap=caF)Bf7rz77-+-b0hoHOyi|sy~yN`z)x;nULP;?;VRATW} z^;7I;O}$>6&}?)$C6b0fSw^1XQY#8A2c->+o)4G|#w7_+C}qeMQ;psWf+Jjf3Bt7m zgBe1r5#-%#u^Q63g|qjs-{IQ1pD$yBZn|gZzWfp!{9@iZg~dj_5>r`H?tGZH%El(n zT%ED_%~uy>eDY!L?rN2{PDyD3<1S; zd8g|w#UZW7wUV&PSCHw5ytET?LGvcViQ=u^?M)tN_i&>&V{t zl6gy?v&N~DXDd?W$`fK@nDXP=$+_xe$4Tkf5d&A z@LyPkYxif2pP6MH5Xi5yFuy9VwwylW?etZzd@E^s>e8|&8k_2cqv04j|=iV z&_ZR)%Z7E*X+cL6lt>E@KdFYOpCNW!Te>QqrF(dahWcAB&lK^&*e6ZVOBX3#x`>bx z<$0K3{jf5xI*Qp(Z_a#eF+VD?dY^oqmX_YLTPd2MEqp*?TA!imXi+vIef8oVlcOt4 zO&d@~%!kyGjKL)eZu~Fd1k0hqa18jn?ZM znHW?#Ds)8k&;tXNV;a|riF}2a)}Q+pziV@UcIZMFg;sP=Y6y_6z*UN?KmDrLVSMCiktEu1UIk^Z21#nEV-L;CdxfEXWmBiDEF|P}=CV zGELE*`FWVMc9!MVJbmfL2CU}j3~3fi?>>D#cyiP@;z#GV&Rc0k-uH5JI{s=Hy9@v6 zQFkQfc*NCXe>%(A-0k|`m?7q~ANv!B{fV$l)#hW`A5+6jaf1JY&2m);6TR~)Bou6` zu)hL4?ER2gU65O09z9N=EbE`Vsn&*5NNT|2w~>NN(SgcZHjD%h$(_oQdUxOAwN`g2 zq;dRd+Q6JWy-CDidaQ+eAgqoq5}ZA>cW+|v%3<#!^ty54cQX{{qJW2+X8lf@BRzi>~1Eo&b(!c9M?aW!EH!JzLz_ zy%!T~k>%OmSTS{Nd)aS11U5(r`%T~3j|P?OEX{Wo^x^riL!$MFy$Ls=YewXyH{i0# zP&OPjR|QeTQFsFa(VxVN)|TKA4)Q1tLcS;xOb}Ef_-p98rd6Bgb^YS{^)J@%R9J=Z ztP17O73+@>)(3P5LBjgRSLqua%fCCz|NfDGC+&Er^Y)h}FY9>bvbIm-P%GjS_&1_~ z{}CHt3bqO_FX;e=Gv%`SiAbwCP!ACZ#Rfb9<3m%dlBy6I-drHlqz*I2$$q8B`uQtI z-#h2NeWLekHDYRyZ@G5;&W_U9K@BE6)#Bx(m1|kUi`6f%hEb9IDn#)6&g%L6o;KEK z=qnL8Kjm~ySWu3xuL!>d9hpa6ng}Hr5c#fvP)fz5V=p|Jk2wcYWw%?I>@JeDLjc8t zlrJ0t8-jZoMFAQI`(l``V`=BRdGS?c8ED=-KAqLD8J4}gU^B!;gH5c zjre)XqP0HceRWU6_&!?Kd3zr=ZdK|}ztQN3Mi+oaFMvj?qZ+E%YZDH!DuFd=uZ{Xm zc$5HTgeMs5xw_?!{F*2jNV@Id;kSDye8lIDZ98uVc`oqxsZ?4-TwRa^_lSH}0+wLbPG ziUgq@@d@iot?FkrgHBNDDCXG)ipmP#1H#qO5bw8TP z+WZfK=tze$FfMY;su(DwJ;D|g$49&~ns;>YHf*PZIpq^Y3G#^{>=iy6Q^fbb0BloT ze19;yx{LKOg}qI2dy`LCETax{^0IzfU|q*FMOa`x8JiBGouk$648lO8^?`Z@O93IJ zE^nF5Ut}BTC!6izE%B4aR;SA&2hqp}6)g~BUm#VKRQVv{;J}K?r3eFxBPsBv!h@K! zApM1|>GUJ}cSuj~&@6SpfK==^;{MW4s8$nav4;QxV6iha_|u+O26>;4*Pf@>hF z_r(W4*HOmQ0o@L_yu*s*P1qG5OF4M9!?E{BJ4<4TS6SI1{5uvuM2h1%Y(g+KUSpPY zy#KEE{Z{e*MD!_+W$8m$JpXP8D=Tl}(}UsFgj zyhd}#7J~pyNS5|e9l1Sdq7-;5D(s*;77>CjbX=2F=x(>@(v&WCx>!{qZxEs?Q?g}b zgyBfYg)W~mTAIFwh++^XgvgGkRQteqoAmC+jU#vkg`J&%l=Dn$xZJ+i#~-(oX1ZTv zze#n(xtJimF8!{4h%-IQA_{t7L?$&{98u^Lt|$~Gc5S0eWFYL|{dB>jF|JHp3VsT_ z87PgR*T=Y;(B&q*K94SVghUUz;7^Qp-J(ZK5fLy%ceUCf2K5x13>a@JfmwI;?UT&1SWk$;mZ?519yO}kl%k%D|at!u?_+uR*&)?GclPOxG2jyKs z0Z2g!2*4;Z>CyxjDwt=|Lur9cojH;E6%a)4rb{L+6w@-6c?lO~1JKjnpe|@tUnl_s zd0?o_N9k`Y47tyUWhX&@O^SzwD1O8d^y&pvFbqFz9!sn(v!X7go_mg+K4Cq4(00nT zXRj=en&p@{AMiocsAX%|&4^(iH%(6uxa^3?Seuc5^xE;Q)kD2((DF3JfjMswZlNRe{iC3n8hRxVQ@=aiZ||xRk1U27X7LHr+St1lRRSQY zz;}ZRcLu~q#wWzfeNgT$-FlzrUs+x`zDWTbdKNLfPXCDT!YM}zR9DX+Wff`>;3^nP(p$~y&f1iIKa+g?gnS9 z&!}>T#o7ag+Jmot7N3FA3JPIb)M=P|1ZLmB@{DD=#n~{y`LxECM7F1HOX#{VWqW${ zJi4)q6whD-ZvrB>yy=#zX+Q~%_L5Ikdwzo99ntpuNoJ9R z@GudD2kN4N=Ss6BW!~8Al`9Je zpTfFTfX3{Jftx@Z;yl4}01!feHqd$7ctFCa5UnY34Qatft^qru3OI#ov%>!e11E{P z)ac5JWTTY`_DmVwRgnk~BB=zRWxZt4C zWy?w||I5vJFdldG?!M|HrBuzq!{*H3t)%DOLZ8`%WQe-z$A|~ifpr;c$yQ^F-O#rK z)K`l`5#cCd2SgK<3tdswDa%ywmo#~a(j5FH08vy=KNyq8)vKmL;j}=L2^TKIVA1o4 z+QEsME5JR#KM42}+@tmqdT^E{o*9plN+bmmgYlmlh2b#-oqXTAI`KX0^L;m2w{~ys zzPz-}N;X*yWqdMNCm$n~L%rPh-B;KtUXz__DaN`O{Y~;<-&0>E&sc>3*4dvoe&jC; z$&2(VXjVan0Ri?MYPf~AYM^)We1m$a50fZD8m(1|PGKa)q66dNl;9Wl_WPb6W6i%f z&Z69wl)3HuefT2JYcsc@R5AJWzA24Z>#G-7D*y6I0^gO?;OWM4^=1wDZ>&=NXGrgy zRD9RkNOf7_*_W0$X$F43f(SHOE+^zv%+P4#V5fwQGaR2epdP?`j~3sP7KzW~dp>ij zz^5c&s>KOJ)RvazAn8XK66R?jDnBo-=oLg#PwerJI!n%_8H$nW0%cHAdP3gh49to$tQP~L_OAFIE2=QH@3 zb9ea{Ea=M{%-*-N;%2e!?tfMMX}5uMFK%Cao@UQ1TZ{dag`jyGq70<-kx&&H1{Tm% zXd7Zdp~DOl3q%{OEOfX_JLF$(Tc5f2iS=Fax0>+V%5wazGE_xC*8Y}$W?%=1Vj|G@ zp!IIIYcn;2^>o0h{%r`=w5lSNLQs?0}~w8`RoWXlBD zQorKNmIJ>{vW(Ywk>I%csTKBvkyoLr28D=9uVBrgAi89&E__f5x|9>m*?zr$ zbmyJtpTARZ?B3sB?YR4V>$^LT+{@awa_0{b<$v0-%6V_{)-~JDMaFzzuxcy2dyaqY z-nh}tYM<+HjwKYY-@y5abKCypyGB+Y!FSxr&%eW-8&iEOdls$cS@G+2O^|CJ4Z!Kj>wCEE{09?hM(vrt`JrKO??1h8P_SH3TJh@GZDKU3;-J1 zNDG9K-kUux&IXPyKk=2!gq&tAo2K_{)~soEU7tERO`mnq}7s(q8HNOtU8A z>)NzeMmB8GbbKATTZ;}Xyk6~c9iAK4vVFOl^}|_eOa7yHvQBua_GEGx>(~-!Z?R>W z{H<~bc3TIFE1(Qk&mIsJfYq}HAXOYHx!o`ka1K}>uovxRu&TI>b|MlFX$%$C2#p{& z7mUbg89YOdr>4`vIQ79{(v55U+(vfH{nz3~6ECyq4Ln&=-+o%&G?X77%5T@WFqG9D z%F5M%d|HDXyi4*OWC4+Uozc|N;4Sd~*NThWFX$day@HvRr`{0}3(_O-+4=bFkK(gY zkk2Kb{qu33RWOr|xOj9BcwK-wal+3Q0Q99e`X)2BgeeG<6U5>tCW|(sC|pJr_XI=w zI*q-}Gt&4#xdQ(N{lWS7tXixUwFBMp?rPGvQdHNj?(^=SyLBV}H@7&Q#pAmk=aaO> zqIw34@6xJ%M)HZ1D5nUThs7^70$B&+ERzrgoMD-5dBd{6 z@+PZbAwxt?$Z@`s5H8lK4gB$KAYEPaJHvjTn}^HdIk>c3gi8|{oFdQed{wBE*j>~M zC?(X%NrfnF=eiXIng?#XP9c?4=?XKf&{d2w=5#J<6gpelosA2fPurbMbk;&QV+x%k z3!Os?ozE6Jo7kN%7dkTwox=*9%?q7v?9R6OTV1Jb2?)>@f336K*}l-(*6z$GbPgzV z_APXF5bqsS=p0z+>{sYa#ZX?MJ$MD=TZoJE6}$5VJoy3}z0>l7{e`F(gs_29KvB#1)ks7Bo?As*YR*clj5NL2<^f1I9Pi_EVOUUHYMVyVt6bk zPfi~^d2&X^l;(TWGiz3@lRTt1pVqc%(>86MZPG^mu=mhTy@pt&7n18$O}Tey^dYtC zXPJMGU`dD6>nu65sQ09LNr?$+Aq#c)f`Q%}!nRb&^q2gwHIhY)-LPRSzqp}j=Y|?p<7!KCo3Y~Gy{EKqkq=d^8Xv_^7EQWe6moBp z_6tWDC%(7)wC!7;0nn8y!DfmBU58m*QI$Z7QZz0WKU_j8kek_8R#6jB>$n#4|A>1J z_^gVhfBfw3d7g(9NPrNkB=k-?RRt14uOcGd0D(k80!e_#MX;bKh}gXXp(A`kfi_XJl+9o^n>ZR|p&T7%=@-dg(df8>cjLZR9>7!fqo^t-wyJ|++(d%HN3uMT$>`wMNtQWxB zNX8jk>u#=Q_Sd@)t|OkoJnP#E(Vn&HU^ItxsUX?n)ln9iM36#QZ&04}{|uQXrd$iR z`<`o^+nf#8A!qu`^@t69zvhXWYH`YGD96YF#5aLcf-N-?G{w>md!mU)gWr*Xyiq=D z5vDK73(AJ@ZpJt2O_u1$!}nG^b9c=mrR>gMIk!6}AAC@B5LX<{hn`)DIYkua=k=jy z%?U9P8&JHl05+*_D=b;p5f+a?2uE9qm1o+7g!EfHgE0AH?5I<(o%sIS6R&+&archx zcippn`&}{%(e}qh8jfAe#eeC}i_T{W?|=8*`_9ep{`iAAiy*o7-{P0Ren^lxr?Z+4pwArxDxTKCQdajmuc)j1=8)b~xq9aOXZOKxA|J>*gfKE*nRbV6K+hX8oNKh&rVUY z@nq?>-grWTM!k}HP3uc?c&$^3bn{C9Spg+w!^KVbrso^${)IB|>KHlxiHs)Qwi|;#@KY){l!zic5(b z5H~h%W?XQ36+5-7ydwz@#>FPZro^h!>c<JhFE$GwjBA|KIHj?gevmc~uf$Dt zE%pspZvja4CG_VwJwBd@yDj*0FfK7EF(r}U6H5|T;%5Jr#JyxN*OIM#oc>$_IC458 zfhksv&T#2Fc>Ij_&-nHX#lIzo-zLAG{B1Jcl4VRiOnctEv7#|EmZmVBkUFeaV(-LW zS@N(9Zd`Tc#*mygW!8*ov!@R}`|=*0du30}?Y*W)r#^wI;MDT+slfqb$DJ+Yh*{J7 z^^6-fTZoxLoCWiTc>1AyEEEJ!ldWrrr}4~FT>g@y2Uo_ekJ}Q5Bid`pU0;X4$aBdI z9uRAnRnahEy=I-6^E8i)rS1VytZV&Bpe6A{WB9v5|A@4-mMX2k}E$T zo_G<2om{thJ5dHk`HT#1x^i_T5^znMHDgBcT(uJ+bHT}_rIUkaj~RQ`(*b15MjguR zkL6FnLs&s;Wj#zzia6aDXzD>NCy&$LkXL$CTqr3-iM^2YRUO}dDz-Kj?J+a9Bz9#i z+G8&!B5tohz!GL8)hqF5|EaiIOkxhsj4O#-8Aotv?Sr~=;pr6SHq|R>f`jQxBc9YG zx+NYwp7?&^w~3Hu{N}am!Q;)}Z~kp_yhVTDV;@58I^q8vGJ3OchdQ!wLyNF*|0I__ zb8M*;^$TB`cxJD%&TV@RoY+5gS*Nxs_Lso}2ZCR}l|A)*DbMawf6zQ3CP|suMe{}- z5AFkRnpvZWH&MEM|C%SnuPB%LaJyACbl;)HG_k!inqt!hd3=p5Hj#!<=gJ?%=rgAe z4U}JXP7X+X=%L`(p>pTZ`~#~&%sux6zn=CP_%qA?SUrRM zOH}?4TK0?uf3Qahr{1$$3usNoB?t@NkefK3oLgu~k3#^8N{UK}8W6>0X9P5FL`JBc zxUgJ=SI;Z-O4T*XWe~1&| z{ut%za~q14gzj4sy1H5?rYiRF*yFM9$9@|dSX4ceRLoeYnCeqT&m_1liN2VSl#r4z zAYp96%!EJei|sn~&cOUKaL2XlcLwE**+m8OE?@kJM0{xQ!Yfx728W$LWk~d^Iv2sM z_Ce7r*c3LzU&Y|`&Oj2;TPF?cyfiT2PU6-_+(f>SXtaZw)xEFn8VI&j`?g-^OWY; ze6_y$7QE7zQvY_b>Uwb$7)o=xzEzCU+*(Pghc=sYH} zuef2|#r2)XPT#ue?;B6s>o#nhy5@`~8}ln~mq|`;SyA3nd**_|`4_;ZSXp}tdu%GP zo;Fn1?ayr6s(8I@=5x`|vRT9v{;)R#6`KIKq z&9^=J$cD{#ibcT(j)Jz|Pd8TMebQGQE!im^jbquPsqv#zq9b#bkYsX_49sJZ z5}}~x0lDS$7piGZo*X8-JALNZ>++pKv>DOz81rMnU-Sr^*h(RiaM|cgDM{oB-P{UR_af zrFdkGbdqI5dA)32^BI`;FIhiO^J2|jv)7pV%q-9sa6PSmIEw6xSU&1NvYsK5vFBXd;t+{!L@Pg>52e18FPTVpY)9zq5&@^+yqr{USbW5V=A##8RF0h zgA*?uON7O{XFJafR#e`pKK`vt-78OzhnMB_0MOyeD29a_%IDSO0 zKO3KgJ6;TQetzSm^RuY;#v3AL>63TvKJ@sVcRns&c*{90?6>}PQUsjePKy195AXls z;Nd6l*K}QP{~dJE8J;Hh9Y!U+AcJ%2vl~aJb?m|QcyH9-5dz?^-$?mf&pmtG$1T-kARr&U|RBo5pk z4{eLS;!7)B9c{HF-4A8z%hP~NE_x<0#rE^89eOPM(z4iM|tTY7)cY`a9|@ zsc^1P7u%hGJ85^$*E(|(`p~y*G_{b6JvERy26M>aIEATk(nz;Vk2t6AyUh*y#w^UChl74h$ zoF-Gyj97`MnGV~QI07M~F&%_J%kWqN*4>Wh}CCD5BU4IO&A2((d~Vtw9j0)J~)%h>cBHt6~^!zb>v9d@slcUyVH5_Z?}+y5CS5rY1gBmmbM%}qoe0{_nC|dYwbQw9-Sv>) z?VlHSuf2WOmW}J~TPOqne(b5QFI&2HO|A9JA?F*&@RPS~seb6*wW|5%6<2M)V|DPZ z4_|+5-hu9&9$fL{yKg=bTwAs6mfLRB?cM|J-U9WnXQk#{6td0ukLVIHX&f*zmWmgr~=5W=yY2{mUEGinnTG!1#k<10kBeDK~|0vVYiH zWDK7aPV+vj0qXHC-2YTj{^YqAzPoSxm*`d-mS29;+N-v0yL|a&moB_%p$xvgt?C6e z`MkC5lCLeStiESkaNg>bg^Nq(EXtp?eA%qvHG5%ULMCaf_z8W0;^j@|n1~V3>sZp} z5m2W1ZCo-1gA{6sbVJqkVz_T`Wl3LP5gUVv8z`@uzV}{5&D~Oty`<)GaV*$U6y!UI zejK3&o_<@dmT;UziiIDm=VaCkfi$U0tsM=cB+3GLS@* z*XqXl1>y&N`%q!UMh3JsZj645IFsJJ%sR&asbgMwH7c}zu)M0~gKlYmo4)(Gr(fLt z9=Lt;@*CE!K~9L)(vs_noYD?Gl{&Vs`ju^!!O((>ZdkkG#t{?>3I47|eGYOz=wzM$ z2cxE&nUHj`@3^b#1_`W-v0Xl<0d0NsTT4~g1{rB4`NEgol~1i9+SB<&#xzALr<`Hy z`#0~qXw2G&(r%x>|L{lqt3F5ailS{Tw1ox4-bq5z*&~ zf7cwJIg`5BoCJ+c$sy%dU;6x(e~mss$U? z?!2c&27Y?wkq>UY(kYShn`!clTaHazea8bEf(K8ZJXrDb-<^Imky6$|@V^TDZwgyA z#XZfCvkd*NfA@%LLjAi3`gaeS(e+5_QO8PEEqjnu#r0rg6=tA6&j@miMV?*f>&dYD za72{0{uE1b-|J)kh__v_jN|@ zCTh9kjkRvAUAc=G-9ia`gm5UO+78iOgwP=jG(zY)&|)J^GEBX&U)WtEY>Z%PQd-be z2nPM|ihI+yO+Rq_qy5#N|M+0`x}3!Ri^nglOy2&t6R`@rJQ2UZ29{<|`OWr?pz_3xfuDIylfXttJ?v(uL)0Ztff8vz$N6wxt zgWD=rZIC1T&1jyOH*~?W#l^t^<3ztEJzad_EIXsk`2&{Ua`VO& zy8?3d+=+8$&YU=5N`jan4$u5H@eHZfFJE@ug89Kv&M<7=n9;K<__`K#`I`Geo8V8zDJaH>aY~%*RoFGL%eh$>T-JW^$V;!g z>&jL4K5@~Ql7=PcO`bnpb#K&gQheOv8FRa5TwPJR{;t(;th(D-bY^rG(B-^LJhy1EUY<;usjYe%(d$uV3JtDSOMOwtRGS<;tf-;(Tm& zrmyO^pa&Tskk{&C2&;evUk}$p;T-jrNk1ajW4SkHOb_W_B zZ^+-!Cd|ev8fe0g;Oc)l(8v>`2acSw=dv~TO&yyv=Ju5p+s-W?Ke?h}%7jHNW)B-T zuW;b{JGn%)YJE(Zsvf}Lgmd$6JHLtYP=`iS=a|UIP86)oNH#GOmGl#)=q&~R_ ze0bH!&NSax<8r~3oqblA>}qeU*-xw3h_G;noG=XSJZKw!#Du=?kP{9|i5zlnn7X9h zf&o`;yleI4dmgwty)Z4I>%;-0FH9(zFzLb>V=tUIw`=!n7ME_^edVc(D;qXEzfl9x zu}{}d)0bR0Y}5>0r|W8egr4bc)%6v+b@IF@6yFr4kvv#FeaekPBcvYs5#zywqA|!+ z%%1h@_wKp&y1fe)<>eJG%)4NrXnA#I<<(!U-m+!2m{C+T z$SsGh%kN?6sg9#RV--#G=`IC-{Np)Fhc8EdP_s$S(HjaBVr%BhQNfManHG;I1FXkj z^NpP{FzO}yJ^PehYhy7sj@D~enm?u0TWs2CN{=(~Xa87xrj6E0LRfHBc)KFPK3lje zu~qfFJG}N5Xh97HLxl9Km2HLIJ~LY!yHp*WSuu6sfXR~w44gVRqkX&d^mgqtf*XTR zy*Oy{#W zX`InS(P}VOZ^hr{-tp3zHJ461XRUpW=-b43V%<~EU(Iqo4z})jh4d z(2_*C+R5h>QQL^I#y2nWCPX+V(#(k{Lbvg8{QVE7M2(Q16cX$OEa^GX@$vFV&5qu^ zuUPodC-1(yANdjI?^?TK+xF|%-qc3ksLm*<`FC1xrE0B{?>N6ab2ND4rXvsSI68R> z^K}>M(v#;9kzWmcv?9hDdCSNf`X=>VIA;56XFjy($j3h(dB*uo zw7&DA18p9^<%Yd?1&+2&o|WAC^b41cnc;l@<{QrEqPqx)lGEbsnhh&v&wu&*Pwv?J zI_f3h)wa}qXrst6$E}qsEj;Fg+XxFP5J)K%qS+fYqP+m>zPCQ>6tgtC^S_=w{kgg^ zFv9t~<}qi@vSp%7P7*;Z^I_~c(;1<@$9^3;Lu<5kla`5Y@LP0qgV{NLoiajni?2#K zUX>ED*N9%`xZQMrTuxFBhHn4rZ^L?=Zlz(0f44?;>r~oOUfsT44oNdMV)yk`1Y37U zgdb6T(Q`?5;-CoG$M$2m)YZ@`A%LY4- zWZhT%)DN|fyy`eVyfwOVSYpl<1()sZaA4!Q`|la|?n?)!&k^-sJt2~ue>%T96Kb3< zl3M4tX(dBf&RX))+n?XD^=&jI>IBc1`jvfNjotOOKU}}6w%q)t{qpbtT7*W2UE0sDG2ctwb zQR{jhzV6Al-#)VLP->4Qc?C;qx>RmndB+(oHeJ1Wi|BP*HS&2jp_HH18%5um4{JUa zwMV}C?EbO$)H=Vt#Cwa@+Iu9<6Oln{6F;ZPe#mXK1a;4B!a{P{Z>e8MjwU1ig5P|9p`N)iS_G$)bHC5`b`6EmoUo8x-sy z?YTr}(k2FOXyXeu(#R{Ey}kBV+O*lZ^6IooV5D|v0% zeeg~~gSi^Es_S^UgN@y@6nvgy+Mec1gjSYD!ncYY z=vFrJ_sqm<+I_JqU}IMf?KjjgNghm@com1k0VZDAkuVt^%m(XSF`Zx<;F!M%Jn0_H zR_j$UkznHL!UR2-0_#3;9;D#D`T^jyj#rVD!4BLX%dXcgetERfntDIc>p1@Jy?f|_PvX+Vuai&8p&UCWu$;_`# znqSuUF28Vsf&Ny*5Wh4`nW%F4RR@OnrC~N$4{LtK+jU@w7aFF(x=!;VK0v1>#OuA8 zAg{Kz_GeHto#`UC7TU3PgQg3?k1kyZp^+&eqD#Y+S?6iG>V;vjTrYcuh%ODYp?0>W zD`+c&r}iztOb-!V8m6GOkEW|$0A<15RYmF2m@ekmsSvd}wl#pRt)iLR=3YIQV+{Q? z)CVy5h-k;&pmLInRw~-1UBhI0FlFMDC?=TXx-i2$m<`siqLg4-+jZ~^^ zlT;U`r3X`By(H$7TqOs9rz)8;7`gSMdC-H*_uhu~Gd15Esd_H$8ix3;Vamj>n(v8q zVTkV9@xXp4)C{ownXWQ%uQ-S5Szm=* zy5_+yJQny6Fgcobob=b4V7lAQBVpe4V9LY=h)M=bYF(J`4NTD5FuxT+^bBY$Y)9y_ zzVl$VUXVaADZhuIK1cKft%89~i0i2#;HgU0DbYzEF|J@IkEYGmGsqeT$Sk6%Dl5LK zzsCm+>(x=bX1#`}WAyueieUTkyb6B@(igy;=j5sv>@mPii+|Mbr*OYVo;r1$c{SAV z>VW1|vhDFx!w|1DOqnRtylP(;hImCV;MEG|Roj5Z!o1RWhz}a3U;^`@eF!jB?U5o# z(^~r!Fmw+*4>%+q+^S_&v%Di=$2Jb8v=j8^LnA*_4&=PMcxd23s`txsLxxMBQ6g3ng+b_ zVk-Jgv%m*{8Lw$a8=gTht-`cxn0GvwGO-$SH^3yW;~t$i<&E{hUjYXI;3~G>5F?28SQ>vdjPA=10!H`K z;yFfm|Kqo-12 zx-wjco)I3Njl$MrWZSy*{L7`YM+5V$cTw)SgzsZTbFmKUwhNM5u)D_+X- z(kAHBdD>8CxX)-j^*ub5;tD;E{*E5fn;K80 z7zRH&@Fe^2I2HC}mOIcx@+F|l&?l!k`_*xlJABLUf3nWRdtEN^74V>KqxFL3Ys0WT zr}^-MS1z6A!sD%ve#*7{Vu<9f3**^f{ifxmUD!S;L4SWeKyo+Sz+9^3rDs^5X*?4= zJewddJE)Ew>f$-=;n{?7WR&iKuHNU|&o72Zel1%((b%7Uv zW#wY$1j^mw^j9BpT}GStZJgKfejnr`6nq~zdos>4>nzcNa7Kscr(3{7J2VY2h!#e< zWvK5h%){{9=aAFi4sp4_!{z>s@n7cj7wx%Rd`s_Zf8_ThmmWOnNkKb5jGlD;6=)vj z8Ok5dJmc~K+cvCIIs7?Nr~2?(mEv&CZnP=(^KkySdx4A2By#IgDVobl(w7>~ zCTMxqm&sv0r}13i;n{|WjZ(6-u&E4|R+3Ix3ARCQ8DB8U!?(@)33`)Y$-a$*MSgAj zIJYUbDwF(*J9L|NMrIGAhrwHUKkF?-*szShtJ}1RjROm{o_GXpdOWZfWdaYk-2!gA zi<|*+E4L}WWf}k4c?&e^a%o)Cxn zxonqp4QMQy9{6`Ecsv3g=&+^YPM+r#IKxyW^8w%T`@yxpfe$mCPJVdw-zCnIcwgXj z^~2+RL+2>LbA8EP({ygMp40Z4uP&NS;+v*(<6P!jcR!syoGkK#0;ZQ~uL9>d@OO05 zygyIBw@x^e&%cK=-Vcv@Ax?ndN6T$tc)SlWAE06F^`TUaAMZ9=kBBLx7wd=Z zmX7d&t`4?kQ~-syHM{3d3^27ZMYRa820fsF|`6MdVWN@N6&q> zBBL&kuT9C1q2-kE@c63n6kCoSUmMrOL*uK)Q;gG8czkVQEK8K7>7nsef%ma?KaGRl%lZ5s$zFnAvW-P)Uob9bWS*ef3;)!hR1qjb71G7o{oQ8(|bIWV*!5BFmFqaw_C2plQ>80Y`ww+pA4j&1% z$!f!&QOHO~FrJ>T{U`X0J@K-mxQk%KiQ0v=i=d&a4>d((Q4->0t5fK%mLq1lZT>gk zxO?AF&Vwi?C{B$080)LmRtyRlM}Ly>hZ-OK2in!18i4I5b}`-A*3)_}7aO+yGz{uy zV8|cCb@Q!XXqaz381l!k4cQ>P4x(XBc`&568WE3t>lYg4uz?|;O=FVUc(STIkG)HG zu!Dz-bi@RL{DZX%#!2?ArXN1cU*T~`u&P_wNGb#84bmjwFE3pXPgXj^D8B;W@8rI} zR9wVk7_FHfVqV>Cc(v8#l_yUchIpl6%ESzpS9M^BR|JFcwU9X#Z={mjMdKkpXqbYt z4IhBT$A{XZz|f6p+N)`*EzmUi)-7nJ!2U@(Qv~IewddAzS1qW#+L!UmY4Y(g49zRj zbo&K8`=}N)$!-CnNtabn8-yPaJm-4LE(EE5Wo5uWe{N(1!-kR%f*K zZlPgbH87C9`R%B7Y{B|{n7jv+e6QjmL-()R2KTL5Xc&yq2Bu6rplvbVnuUgeon>G) zScmnz|93F(s~VUB%=_50%Hwb3ng!V+Edp-<7PEBLR_pUnfv~dotfJgC!dSnM|2)?IPv8XD|kMG|VPzEvy8zU57d_0phKOsT89$ zo;KmR+DfOVjhrAFhUYocoM)gLiJyJA&+aiaY|?d%_iTmQYoI4OaNpN@Vry+j-SD1iUD;utBiDxAKJXr3s&rl0IsmU48|k3>I=v}J24MElSb+ISl=BMS z--fYZ7R`S|HNK^Fp<3dy>oL)7>hz`j6&i-VwZ33K40srR&+~!y>K%7J;BL1z<8vKY z$W&HMebm$SWl(!eCA-7uS*%n3e!PJ{2)QOS4A)_?O9#FsnbSIYqxGyFJ6x%wu@F2O z7$M*9`3D$=WlqCvvbJcM`<;%4AI;#|hB3G+X;+rZst)mp&UNiks#625 z)BW5oWgKINt&5s0R%G1zJb> z=F$wqeT`s()`kl1XoOB(-1_%B&6`S1^eY#=`Y zU|^$ho5V8x!yp?+1K;TPME?c6T3p|+2lTi>W3?WCw&MI@UXN=Mp2KSx_-qVJF+34$ zA^YZk8s@YIv&nj1`(qNrJ_UvecJyF2i#G65pxs&$Oys;x!@?h9%G@S8X@ATg%*8fg z{6HQB4a<6P1@jc%y};wFUmoGM*?_eL?zt_LH%HRr+*kOP#yPZ2K@;kG^-VMY<7GmG&sS+n#dfI zuRCiI^$(gcuL+Fi_g&5V@%$chK5-y89`N1F`#i?qA3lX&`F&b~#`8DEe>3p3=J)+I zyz?5vpO12n^ZNsU2R(n+^i;u*ab}QweA>RatG0ga0~8C8K-=(Ah!qQ5yV6e23?BekPeAUr~^JMfe^3v>)PU%*FAHzjhTr z_oL_kDvpP7{fF~$T0dMC>;^t#FvB>1rzl5Rkno;%Gk3l@zxEsTNw6zmv<|pabgg|; z!+5^F%}$Vw>-iKb1_*1sMlERD@dF4ub_{EGkLcE?HzWc#jh z-0CfCtT^bkZ~Dto6%4-}d};|FNf5RN@s0ho@CgRV?~CW{&IRgK{=J-^vD%>y^D`t5 ze0>NsodrI-a#m2=3<8MWn-KEk%pEJ3Hip%-6~HAz+9?EWLE6b(muDK77odT8I$ZOD zeZ{~Ax^z8>7le!Weim#HaHDzHhl6$P;N&2|JgZ@3p@!*hcXr!`brpZq{1*sA!YeS41{eDA9tosZsm%Xv5;i=BJ!eNE&qy|v$&kMG#^%CGx_ zH$1Yby!ggGXFk7c&x>!r61?knC=~F!PJjNd`V;&%Y9IGSNDpuk&+F&{`y1vfdNtah zOl;MBZ5;M%^hG~=j@J&~Vwg?V+uFD3i~IPWbQrfE(}DIgbog}|(RGT;IH}9Pb|(|Z z;ra6b^EDPu&*K7Z7eAwSyw~tri4A%hTI0u3*EROX+oc|e!8t1@i&fVjN{_+AI za!mPmP>?@C9XE-Gk-Ep1UrKM7z%j-_4(I0+nEXjAWy;cn7s|k|x4-k<_itDK)0Xr1 zuH3V0=eVmb3f}UpNcpDg*CO?myMvc){P&|>AOD5x$UarpK~Ny5Ge!ippP#3MdBW=* z;0bi#pTv||JMi7v>?i%4c~xe8rTwJQVV%qC7R;N8jQd_d()wtStP$ux%!>chSg~5p zk)1`ET8~1mPSteL_%WI3Di9s@_z@Yc#r5QIIn)ZU=oM5?#Iv4H{EG7C zvzF!;)sy%|FjxGpp5=D7g|&4>o_KE!o431#*LGIg{lyy$V*|$Ig>+%KQ}E>m$~ku%m#dOdis0mZ-cK1C$V4$!m>c4a{qLUf4A(=gH0%`#m0; zVgG^7?TBkppkbb~MID3ubNm~n?84b?5hUz4x80Vf3DO6Tlbvj`Z+<5_f)zWnSy*Y>}sBJ~kX@%)0S^h-20I zlH^6}%WRa+{USCTi@Y3tCyI6Wex~mtCl?FuWHUX(&u4(%mqKS@KGB5vyUWhd>o*Cs z=0H|9?S(-VQ8!E%Y@`_hY@&u$$E{9e1vR5}C2UcwYVE;Jbw<`Z8+w@6;K84%wzk2R zJ0qjI!^U9V)BC_I#y!oMV9#c~_XhD(REjON2T|r6=Ulbj9*H`BW!`7i-jDaI0PlpXW^Q#|7j4M1IfxkNJT9hwr1o1*={;qml!uInao(jBwC zHTqWI?P(sbzBDk4^?21P(7?6P>f%iX58q?FkX6XMFW%DAoAWR(9t+fHxh1{%NAZ@7 zhxC-jjyns zP513Bz@__kF*2Z>ssqD#*#6ge3anaP=Z3uY8e#uyd{k$`2ig#ZiyAi!p~NZ|611@m z$n|C2h_?CjJr!(=QQL5w4RHQREH>jLJ5e;|HuY>cfoZ>2ra&9xcjoa|V!W0Iip6mw z>BHahIuyR8dW=hDNRIz@A%Sxn&P9EO$J>t#&euc{L3ZT+(b2!QzYzWHRj$Wx8s}h^ zv5w3e7ZNzxj^}pMc6>2nMY!FX20dFvkKq*SKx25&Djv#_4lV@OLC*(BRyCdiYnLml z{wQyT)%d90G`>HJ2iG`BPimaoL@ynmkVN(m#VCbkTH~bn1i~4@8F$t2zJNDLH2;i* zh0SQ+$};wj;p5Ai)@BqJO*%gu_fQObVKa}zKWaWEv5YkfQ7gKT;N!#4o8REfl#bSi z^(?EC)eXKXZg+8$#(f6w-$DFEm}c0j0qAFZ^DFvlCu@yuEoW8ev^82p9 zJAuFd#^CMD?~|RQ5q8LK8?pzy^PHm*cF1lUx(x4=S%+h7!szgw_DQVbLJ#=X#94O- zmjH(JU&z{N=fk1{jBoFc#~#QB}|Qs;mf{KY2K} zhjG%LK|fBKE82a62RxkH{}Shq9?ospYt>8BX>dl=9dsV_aBiFTa|E4U-KiZp#-<(G zw-eUCutyTS=k_GtGY|B*!);6J0MtH^PVA{-NO}Tf#NH~+)8{-|w_5)Y?Bn*L4#H~_ zy4}}!v~DfrvBYbq0e+s=i}i5cVZASwQLQ|jbV>|}AvxrBqVh?Wg5r(^eF@UTd1eGo zidjSbVIOY+&f$NBGt|Jtxn)7UzrdN`;oJ((9XB}v6tnL^HRi~g5CE0Ry6oG&3QUvPr+{cQuc>yyNLR+ zwu^S!2i$(_#UQXf&;6L@_0*3mbU*g(OVfDLJv>{jDzgW(?j8-S<@271ptZG(_vf|q z$0HG*^&!#+Ob_(IQ(7N1qFBMIMt*%j_RTr0511~%UX7e8kP6=GKx1#%z8Ma@lS8Bv zG~OMs+gK;?URcsIo=&i0A#2B3ClKDC*zq^k3A}%s2Ar2^!~i7bnLe zlVuXdNwkh+ouF}U{|lUxL!=Wl&TZEHS|@lo!#Y8?3+V)nbK5f32_BtXd$c{v1nUIg z1YX_;EJ!CnHmIljVy9V7SSJ7{>4X(pCqP;VGGY(mF>vR{5XnwAEf;F4mK|SQ&8_(5 zNRVQc*BBUg4cqJv1bt88fbZ!%)&URZRlC)6jwij%c}b*lO#DdmK9yy8x$~s`DbKe^ zIZ!=*t*rr`sm`Nt{?nX!ym@~u$J;Ik?>`OETvLy`JMAB^YZA5b#n7-_7hJ5r1#foR z*XVU#-(EqDhiqiV11misW|6#k(J!4neMR`@28&#Lkj+YDpdwgWyRX9j-Y~4j`>=<1 zhxIe!V*$&1imO`t|ScJ<;h zko%DEB%>}GPqr8h&mr)1tc!>CoN7GT?w-?*b@33dHJ+V;c){@}b@8w~YCN7i{ti!y zhi5A?l$=BKbP30(=z4wY(c|q)?c(E)b2M-|I7Q>({&bqhT;lPYHs-oi7k;n%(=O+5 zMBMLg``@(=`riiFif^!OImy6}U_86P+Xq=s^wv7SuGMQZpo^V+t$EipJv}OX&zeBF#BTLA`~JV_YFMlP?pA%ExKwS zR;#*rNM~p~6!Xdcsn&Jzkp9zncG~~c^{R`9^`FM$)$4b7XzbK@wpyR-u`|i8Q?GYC zdc1h{Her7a+9j9~?4|K=dwuS6E_uoYsjorH3a?$23_7}f3 ztvqj1i)nA- zfVK!`UWq?i7anpd11-7DvEoI(O1la7(H%~u-G$p6Ya;Ys!7fFc6Z~+7?`q)D5O{w( z;QKK=c2Y5XCcp22_x`;kmEs3}pXyYqdl~+F4KH*oOMk#0V*GlZTd5vo_;kR(#qfHb zTPaWQ`+EWZ6T@Rp&*h?g&{GWf8ixN-zn4FI@V7?5>o^C3-y8woo8cb@{!R>kkH%xI z;K|Rv&WF_!af1=A%9QB+(c-7M;@x@9)i~E0Ju4tl z|3qt*u0J=LTYo;1%6)K?XtCC1gXsw z2`W0pe>xD(7s1hbRiWe6jrlMKlWoh0CLe5;(Ny3(RN3g*(trG8DfY^pdRm^fTGs58 zSIBGSy)_f;O>_6`nd>Z(n*%j{YuaFGNWeD7`4$*U60vKSiREgzJmm_y!-~t`I(3rq zG)OdvXl+!1&${?uRzVzCQ?Yw@g&6ESvO?T&jdaF}ch%K0uI4-YhT zG^GCbXL5rYv30l+9R`HsNa%>VP7o*@3RENxuXTFt`8>E();#I-Tq{?rE~j6c8&mVO zY-!I`G+!0&dK_X7r~34PD?7ipLMYiPWz6$VB%lX3?W_N2%Id)}IO-NVZyI7=8K9(c zOqI~*Rb{BIKUMtn4`d^b= z`~->2&oI66kLVr!pV8a?MKR+V=XvM(YsHM?&pG$6Lv=b_>)d}#{NmITFE|zXNcz{j1L!Ze*ybpqnxPS?v&&G19DH`Tjb^*BCe{k=FT06 z@tnqYowbw#Hyz=X~ zT`1SGT4VP!j~2KGP3B&}N0wynB}(mP?iKd*rJH-(2NQr!9AVxE@%{pHAF`6IB6A;w zH5fYeh5i=ji(XOFr=ioJb6xDd0z7Dl7$zQ7S1auPaaxQ zGOs8u&2hX|Mr|+vLL6Rw6LtaFt0cnSn^BD z%Swtz70%8tF3X>jytsHyera-fL4NX}g?Y1aF~4+AcIim(nOaa@zOY|P%F?Avd*(4z z&yv!4DMcDbS<0y4Ik{sd|OYC05#8A4Cp*y@qgRzPrvDBux4OGc|N`> z12&>9871|^f2mw%Chq!s6l6qT>k&bLpRz(=OXj+j19KkgnvWFuMB9A4FR|w0ub;}E z5l@l75O)?}v7i876W((C&0{(>H;DFfyeHa;BePLfF`n~LYBG3I%%zv&z8pA+n}fjZ zJizIv$Zxvi_qzN@2R~A|UCQxgKcoszv6k|`p1>2v)e|(7q8(Du4t_ey@MaX!^5kH{ z=ooA;%|)oW#_4a*aBHHMOHvfjl^25eKlq;=4`n3*g#^FQEFt#1L_@R0!sewt3h@{l z8bP-tAhJFYF;(OPXn`3~E38YjhIUJauc9qhR@x)87J1S;BePIfXu9qottZIU;+6r8 zn}s;`-c}z(%=LpHoN1k9osE6;1Hr^>RA?|NGX#w{4AmO}Ykw4SL5;D-BCp7Jh{^=) z@|XyAPQuAUld&E<75lZPTQjVg(2;qFa$JQNxJTjB`5b5PT#GpGO6yLI3wZ6khaF_KXcH94iSg-4>Z()!96YCjU5$Ev$R=K|s0c1%FS|3^; z!HZfCBgH-uW$hHv@cG4x`p7sCXPvY@u->-*0nPe8;)dT7@uHzqEaLY{*;B45lE^F#r16I>|fiz2Z=6pIqE zP%MHExJ;Cb#bOEe%2$Ys#4_io^(7ICZiJFJflVx!oE8TMwe1rg8N#CEX*zWh6o7iyQ-E$&2g z`Q73k~tg97{_5Yk%_XYY$lt_7P6&m zCC`wpWs*#mZDd>7PPUgFWJlRac9vaaSJ_Q=mpx=p>mHdRQ>`y#noO4&*xCFHJg9r1 z-e=29^!n$Zs*YiQz)RRq^@8;xROYMJaqDGR2=fpHbpjbQ3lNEPAr#GgsK+9!SY|=} zEP^^BRlXR?ZV6OWg|!R=%ipYvt>xBAYlU?QvJZT1JtTYK7@j_|FY=1_w`wd$o+;0g zXJdq~6_y+*2gz)iBL~Y|IRxjt50k^?2su)YlB2C(tbfZfa;zLD$IEl%1bMEUD9@9V znX>z)pA!o`9WS*QQXXCh(d^uOnlLfL+UMT0wBDp{o%M!UzE|R6POqR>V za*13jE96CTnf#kvE-#iVcnGd7JgH+#ol~O|sJZ)cQ@RR`5kbyA&G7u8jDQ{7b$)l;RYRF$UERfft`S*n-nt@^0G zs-Nnw&Qxcqv(*4KPz_SqDn|`gxoU_Ss)niIIBs&J8l^_7F>0(Dr^c&u)C6^|nyAiG zlhpZYvYMi%s%dJvnxST@3sjz(rDm%+Dqqc2^HhN*stR?HTBiP{maB`^3bj&QqApdJsms+Wb%nZ8tyWj5tJNB{R$ZgkscY4Gb)C9i z-Jot%H>sP|E$UYFcXgZEpf;*a3O-D=MQv5v)ONK)-LCFXJJl|=TivPdQg^F+)V*qt z+N-M6K2@#mQ~T8cbx_@}9#9Xeht$LB5%s8gOdV2>t0&Zx>aaSZj;g2B)9RRdMm?*Z zQ_rgx)QjpRbzHryUQw^A6Y4efx_U#MRBx)c)Z6MG>K*m2dQZKtK2RU3kJQKN6ZNV3 zOnt7tP+zLA)Ys~t>Kk=ReXG7x->ZMAAJmWPC-t-XMg3d-s(w?aRgH2~Ew)GrECwqC z=LE3GAA*x23JX{<$RSf7i!E_>yxkBBA&n6*-^5O|ezu!hwmoLzs8PWMd9zDPiW@A< zFD)#Y1Bp*0 z|4!t;i|KD@adBa4dPeU++3bR)dHQKcM%290ye0XtqGv_r&0but@5&2{=J1_eP*O6V zK{HZ^)SFXMJ}bYdWNDzhq`0K4{+vRPQwGzUo}%)KOUm<$@(c3mSXI8E1QaJsqn;%jEAe$GtIG|zp_b&$Dco9hsLP1ATX(+qr?!IRe8{NBf0&3EY; z`Z?XeryKZm1D|f-(@nYQrrdP*`yBKAU~|niS3^&Rp(n%CBg2%JVam%e0H`CzFG;4$YztmD$^r*V~lW+u-YM@bxzMdK-Mb4Zhw6UmsJCKBgXh4E{a_e;$!zh}F@8~$XQa{cf>BE)V6<4MMSFR_nOb4z^2d+#9u1p86Ob4z^2d>%m*{M-B zy99&5tfKmh7DMrt<}ZO?C4UadWO{14!Pz@As<>=14CxQ9r6mlS zW{OWs(`2Qk^@_@eGi5#XdVVV zDjEY&>}+_Pir|l-hj{-(QU2WW823ea;p_&ph!NiKRi7W}D;nVRkKQQPcy?jw?8OV_ z7UfrXA2bTTbHDO|c|)b|org|i_dpu@cu|T`t2{qAh^rgS)|VW88LTh4`Z7dchU&{O zeHpGVBlKmYzKqhB(fTq*U&iXoczroXUnc0wx%x6uU(VB)NqmXs)@9BIC+i=k@I^Nb zwHG%H-;^&c@qa|`qUM$?F4Z59Xz*RVvcd{|LmyDA;d?GQ z&8V%k)ND|Y2P-l-hcBUAQwF@MWLySwbs715iOz+Mr#o^$E?%&_oRF$LlK;BfAk!9u=-h8xPEoS5?An({); zo#BSYLVb-M?vXEtkC25I#*7Ffj=3;=A3M@VNh~P}SB1fBC5ssLCS77j`F@Hm@;wAc zX?7Ix#U6!%?IQdMj?v#2>+i?-K8Y>%Jp{+-?~64%i}Mzil$Dp3EG)#r~(zMAP_-^)+TvnA(`7zWd3(`-{T&!6~}l%lHyK#S@+A zW!`OQP%i%(%FEZ>8CzDAS5~0!OMLgb!)x7_TV9~G1oeEriy6d2gt_Oh`96M7m>lyX zGl=gS407jM{HV1D-^PU%2|w4*nVmleV`Uyc#pL=5)8zB}_}n^$HOP%9AZEDlyWu_} zhu8gXc;t6u!ZgQ>_2C%n!!foFj+n9Gj~a}P#5d80W1LTUiR*y4SP zRR1`Xdx8FnX-H4yhlYMt%5UO*DpY@~b*KK;XioEk52;a_{6kz=WAbynPhs+lhJH<{ zacK>yfA#A}^J}3glz_&(OCH1k84+tIAe_;sTQWoAC} ziAB6mf$^{LKF!518cdFqc&)+sr?{~G;^&wt;cCRetX=@8(X65}{w;bC`Cr(B6Pv3Y zC;U(^7bYwFb%vAiN_S|ELK=7V!$co&^jLDQ@cV}3p>ZkWHvule&c?JOWJ<87;6b4T zn~(=a<}F;9Cr2-qV-{n;<1*Aa1tscSICD%fDyN_@mVjNJ=1)jX{PU)20qKY z&ob|`-1o+PkY%R#S!PAWw?@MxZc}5_cq+wgN!q2km3Fy z(~3C;e~!VQV_GrC{65(HZk(Q(#_5?k*tE)EQ;)%>bp{*y1{?YYoAL*n@&}t%8f@w} z*w8cBl$UGD&o%gS4gOq%KiA;THTZK)eREBHb4_`D+{k5Fq+0Sn~%bXQFdx|R98uYvDtp0#-4 zd((}z7^Y_SG2ffHWM*GxGw3vQ^<}o;*?iZ>)T587hZZl;Vcu(T!n65Kizl94`i*+j z-3s&?IPJDf&C+W;h)>Hx5D%8t5vN1BH{&?6FB(xcgDp9D$f$EII4sMH5usyKun!;v zF5!E8IX}O&*lM8vGA_brbDWU0qO;z&gqlWQh&xkXPklXD9jcdBk$MS23)-jG3pL1U zo7FabVdjZcTyfVvbxriJ=x5V!N?(}zkJPG+Rat{mXT)TteVLY!-a2MU?AG)VX$h(0 z>fe&Sr2Y>XpQbNq&>$_L!MMyuX%*@1(<&M~8@E4xd&5f_wN78ssC}cJ3Ew6@+jM_g zLbE;1_P5y6;^S6JTJ1igW5(ARUnlj+YMb<8^5Yq++B#HnT2K1h?il^nVMfQ~j(a-A zcKS49S?8jRPkY|e`IauH(-OKb>%PC|nx1RY5_-Jb^8&iVeMS0+)PJNe>3L6D0ur?? z%RG^JBE5CSGODZo*YowBpQkiPX_nGDB{gMA%EFY(Qf^9lDCO~#*Hhk44W_mNAKIti zlvWY(Po~$?|A;F6kKqWmefmQEFKaOP;`^80+WZ@l?*3bnz65x`^!`Ig2mJ$%dVsC- zpIZ`Lb(^HNrGH-eBk&#nmpYFAp_S;Lp@y!hRat}6mr$G0Kk%j=<7y8|(dOy(QfJU} z<_Y~abxrzBS%cBWZSmEJ^dSIocDo*0rS8Ns~-h+l*BipX%TEcdCDDddKww#6P=j@EtF_0~Lec^PpXL0r^4BtE7uAzo3PGd?BhqHD(2nT<3Dvk)0C?nK{;Lfme{ zh?u!Qj+m<(FGo>w6d^a7W8%(5Je(U1H{H4lkxTa=_Gb^`da5WE3K38T5zqD@@~BYc z)8mMQI)aF(rx6SE45EQv{D1A;d7NEEnLqwI_jGqUou#uc7!Y@MFd$$65l{&ri-2Jf zL6F5^5fuf2VG|Hh7z_xwj3chYFbaH?K|x5^nkCSf1u~N9kcH0e+sRGe+v&70I^_J` zRh=dsU~p!B^ZoC8@9T4`&beo)<*BDW^_;5nq&Ywf%>{}xfEIgi(I3rZTVhVzi(#2r zZ7ah|alTBP`C?XGx4Cg^%#w>U>DGsr&EENQoK+KN`DB@O`@=WReA{Z{ytW<9XFI?g zwK&UcV2;@>W_;aYu2-DnH88(xaCTRm+x23aTUGvFnO8M9t7_9+syEJ|dY}1I+nYOO z-c)Q}rCm$Al|Ha>F4KNyEPd2$rGv~=I?Vi}Bh5{kWnR+p<|LiC*=(fGnTd3^IY$?o zZ*+;dMpu-sG`r{;Gm8f26@A;BqM@^L{@RS3QRd)`OLK4DZ060tyqlr3ZsMGq!5KGk zp3Oey*bL6FiF0cPX4V{GPEDLmbHba>p^5Wn24>I188a8ZZl+9}A@jdKH|Do*IWOi} zvtSl&Hru7kJeM_Tj?3WOmN=(ngSjjX4b5hz?rDDN2hCI6D@^i+x(TIHm{htpj4ORh zcs;BSlkyyzV6QMP-v{=E{cO()6LMZr@@23BUJ9I9nCqH_vBlQf$>?HI7z6L}X5Ae& zykZvXgm6IdV)$sWCVUJIgoD8Q0>e>obWsk+6syCrMa8>@D`B>MH^Z&={mM1&0`EBv zzw_Ut!pGoo|2^xv3!%?;QLM>^7j4-D;iRIHZ6VwWb`BG=-GzGy4-mR-LM+gKo!1O-r%>6I-Yty2$F_m(US z;myKZgtrR6EBv1D`@$ax|6ce*;Xep}B)m=dW8qJPKNbE=_zU;A9qxc%!kyr~>G`kW z9=IPKfI09GJObn~e;l5KdGHK83-e*2@_G&y!yjP@bij+ST%J}!C#)gITZi3?=fj>w zr#GTi!(PSG@T~2H#q-(3qBGlBxCh)GMwd#(($WRR^Q8;nVz{=bmcC`*^{~EJn&;32 z+ZNB~dwJ8}KCmzBXWy)%Ge1$d3|7EPu%>vvq1pYmkb=9VV6D5)clW#9{cd+(>+W~E z``zw5-<|Jv=eyncZg-vUuJhe>zPrwM*ZJ;xw>!;ur?u`h-<{^W(|mWD?@o8S(|oh! zcPM(o9z{>K0g9rh6d;4c;1akDu7E4yYPiN*0Jnezu*kUw;{{_dgE8jbPcScj9Q{(E zUn=xVB^(4t!AWM~&lcVc_rjy_81zAr^hAZ8sL&A=`k_KUROp8a{ZPry2xGiubxg+B zpH)3$va`b&?YyF$SG4nrc3#oWE81v98?9)g6>YSljaIbLiZ)u&Ml0HAMH{VXqZMtm zqK#Ix(TX-!(RM1@O>8rj{D3ef{|L;4BW=@%+Db*csAv}zZ6daT3K^}C(Fz%@kkJYm zt&q_Q8Lg1f3OTHh!wNa9kim*|10N+%AA#AH=<+>`@Rk^Opbycpba$S|{ zs$5s)x+>RID=$7F#S`2qVj@g}$uI>@fm7jhN6Q7>R;9zLbWfGuscPp{?Yyd;SGDu1 zc3#!atJ-;0+pb#qF}k=)FLzb;H*gMo5xx}nk?bnTu9EC3$*z*@D#@;r>?+BwlI$wU zu9EC3$*z*@D#@;r>?+BwS|!p@tP8{8*rHF5*r(^~3+syhY*Nveol&ggr(|7rCY%Ll z7whyQeR`2T8oZCT?xThKXy85?xGz7TSeJhUX2LPHPlC(f3b+!M!%FCMj~U@Tezyfz z2)lx#!nff&a3{>Q%H0WS#Ha6TbA3h z+?M6GEVpI3Ez50LZp(68mfN!2mgTlAw`I94%WYY1%W_+`is)T>l^MlCdVLX2)rnJe zhPhTOFD@41O`TZ=wd5vaVxoOm%DbkYY&fT8^eos?Q<*bb1Ut0EA4YDIc=BI zb~$aA({?#+m(zARZI{b-xonrqcDZYpvv#>@my33(ZUODam+E$@ zZkOtIscx6*cByWc>UOMnu61Fh(56?VqvAT+qJuW>pp83dQ7jHe3Xihy z7`^ea#R{!|1x?*SQ+MFQOKIy4+F(VvPY-y%ntj0W58}Ubitg|b&(RMTU9@=zZQkLI zFNMdQ^F;A%c&d0V%q#vaR2*N0wV;iLI`l%Hj+Bj3$7T}JD!pmkT|2a6wRKV3-cuF$J>=+!!C-xYec z4n12(exCon0vEX6g|;siUgrNR;7Yj0f8VtK7jQe=0l$Ph;coaf+ynPJ?*W(t55Xhw z7(5P7`hOlg1JBx?FI*@u&%t8&BP@XqcoCMn?@H(dvXZX`a?wBr8gghP6X)xn__KkJ zlDLn-fp8EU1;==wvfPr~4w73Zxpk6TBe`{w+d*2ZT0|>JT}@K!B(+XbJ4kAcq;`?S zI;pFZwhq!(CvA0-Rwre35>_W+brM$B4=&LUF3}Gz(GM=s4=y2fby8O+b#+o#Cv|nw zRU=(B(p4i}HPY2Vx_Dgk-!`xv>;OB#E-)Q-1NS6db<$NQU3Jn`CtYz8W zH4;=KK{XQ8L4xX}r$%x*NKTE^)JRR8q|`}D2T7@ukPZ^kksnYj(JwF2FE1e}byCtn zO6sJfPD(mRNu89`Nk*MibdZV;Qqe&o>Lj90BI+cfP9o|gqD~^}B%)3t>T12N*6V7$ zuEy(Xyr#x$YP_b#Yihiv#%pT4rp7zec!wJA(Em3Sx2f6N!c6+)n4(urwyDWBHQ1~6 z+SFc8>J=YWi*3amwbmP+RQi*Qk~)d7F0$7}_IT)kZD2dt0d|62U^?su zu0zJU$XFK{>mp-aWUPxEb&;Dca??d-y2wWt+2|r0UF4#RTy&9(F0#-?7P`nn7g^{c z3teQPi!5}Jg)XwtMHafqLKj)+A`4ymqc$U^OO2jJ8a<6v4x2_zGi}F_(uf|S4MdEJLdtI0}sI?@EEX)sqamrzh`Y50p`nHcO`VH zvr*xAwRb{dBP+t{Vr}ULm<=}>uTO_l;9R&Cdf-ovJ(awSATJ}x%O)${OxpvNyl(Qc zhMWvo?xMABfT64-BLfz@C!(g%rsmP}gBH69MK?Jau+&8>-RmuMXON@M!I^LtoUKk< zShL<}Y3n8f-DIGf40Mx$Zgu}Zvz(pc+*9H7qFcSMQSaUAyjz_|D_6HVU!%U)sOJ&t zd4zf%p`O>M;{nUoCM#CA`i)ksZgsjwJN;{xrEYcFtxmhuX}3DuhO^7)3?kE zyBmk>iI2Kk8jl>#d-V};Bpi#=9#29(CH!6Dw+q6vj$a6i9lwMuF2#RWI=|xh)sC$S z*Fp{I&e$YN3W}F2FSxcBW{J^8EQkPC3g1vun_G;VtjNtmO?V{O;ec1=ysQPXqO?o(=T znVMRwmTGE=CBK-XmX@iZIoaOyMy!=t#d0NHQ{puxJVy!7QNnYSZscG!B{)Z^)s$3C zDbr!m1U_clY=fY&_xEi$Uv9z z^ExunrS5yAysYkHTkciIUFxz+J$9+X*tUDsVQk;M>aIt<^{BHR^;J<xTVTOw52+}H5?B^k;Mqnh zY$Fv%T22olQk$67F)KI ziV|C%O%_gtw}B@iN^m)wN<|4SPpxo*z`wvVB^Dz>{} zHLQUutOfVY72shMVAKxD~z!KY$;? zkKo7fQ@GDHeh&}ATzD98H};|mdr^hGsKQ=UVK1uW>XY;=BR$JV&oa`pJhkS!Ft+G* z#qx%xFs5M`G?R_#VX8Km;K$%rE*$MQ_sEFNiPEX64$!;szZ6&*{uhS^8S1FUl zRwY&@hpkGjoHuwsVUrLqCX1~D+Qq*8?DKYXr5Ae%J%oLy+CCl3dCD(!{N?a9xT;u1 z25A`kzXjJh=6bjRX2VTzGu#T_gCD>T;YaXe_$e%Nj}`C|B(3B+HP@}XZm)2iu-`it zS=Y%|t6C|WskJ*h)(j=Q7n|j?;`7B93ZGB*%T?h8+e?gBdyG5+?5t1U0}j{Ef0B)| z1Q!%9k*Sx+)JtTlQz=E;Wwcv%lBrcnr;|)|E18$b)G8$tpOSTwr&Z)>6?y6=Pu=9H zn>?)|Ppk6lu8t1OHzrR>TrdBl!D^|-vC#l+9N@t|huax>usb4AeE3}MG zsqajwXML4}HF6O9x|MRUQVwFuS4#OxDPJk2gQ;98l`(bEn%eog)OAW-r_`;HqLotA zDMg)9)G0-4JQu;Vm1Uo@Tq7m%Zk~^0%O#A@vsZUp<8Et|Q=fA3ZWL{Z?ME5KHn&FE z^eLM@dGC|=K6&qRr#150=UM;Z`tc*+NH|`rdO%o#ZoTGe+g0(kP=h-3!aD!07h(z6 zS`AyPVQaN4gGSndts16P!=P#yQw?LP={@V% zQVmqGc^w(FQGOgVwWwxde5iur>KN{r}f2XK(#{f0I>h;Q4+%{K&X?lyUJW zGhFIQyoXJxhfS%+tg}(!AYruXA0^ymOX&$W+rAf~E#*<+W6)jPq5a=wY}~`v)I$&4 zHDGl&?wz8ZJ^Rk4v6E~i+#L=8*Jpp~$v*Cw!{BJ~GuTQ#2WP@ra5nr`Y%6+Kvs>z= zM$p5Slyph2SQ-v3p1+TPkuVBI!<$+12kkCfJLjG7Zg{U_w}I`zGk-R)9yYKZHn1Kx zu%42g976fN@Gt4-G<0gFjM&qg~;&k#Gz zDC6@{#^#~PAk+CYpe?$7nxf)*xLg~dVkq%3O~JzmeI| zFiVfy;@zerU?hx!(ePf_2DXD8U?U${Dbl z)am^7$zsy2H;6r1k7r()B!Yq*=ws z)3ta`OubaUYxTQUziaioR_uxTU8~=<`n~w-4!z2qbo@p=ABJbQ6o0gLoxSVqT}S(` z%kDR8?)Pl94-`*ibBnoN+;@wsJwS_P^v=R`oz41-(Bgz>f)3VrtWxL$8&E{46UUGWxM_v?Yo#Ik2q+QU*THSxH)?mhg!qVrM;Yw0de zY|K|(TIw+^^5L0Vv_8jtCms6G>r2GHt!&d{*rvzCtC04A9BsNvEQ9B1`QwV8N%d^U zjCV|*T=#A)!I+c16`1{w&KY&PV>Y^ ztC;8hKVnn(gezUlel*Y3ma;3XGyeLD@z*@%cewOjrk#osW=A7uO^fGC@TWkKceNl>^ zx4lx%J_)xweoi`Spww0?m)|*WwR_b!vfniuEnd|mwQHm$GK^Ty@kxv)0G{j6*2R;` zuh-n(ql@L2n#x9q-U#qoC!e7K+EiP1Zmq_hp?*3gV zUZMuCP=nu9gO@0&->Ajgl>Of-`|m6Jvz2{WZJs4pH!8tjsnv_sYO9i*o$NZXjo*#~ z-BH}9KJHT=_mQ>xJQI3Ay+m!W)~t$d_Sh*(eTqCiCr@=xDA#VR|K;g<@>66&KS~zH z$wRkv|Eu);tF$bVmc`Q2CM{jOgpK0OFZNf9)BQJZ58X;Vmg{hJ_NZ(8!8M*GPhGCD zj0`OxLsfNooAVbKvmRZXqx7!}XT3T%T(semaM^|jl>YWg{}3rXSxRqE`mJHkhKkaE zdw68SDy9Fi@Wh5VOXRrl)P`5XybUiX{Ueorqm)0W^bZQ%8#XBY@lxTU?KUNy|R{FnG`V*D@-b#P8l%A>d50c}NQoC=q&xT$(ekhx{p{DfTuk=q+`YlSo zQR;V*`)J=du6S5V+ob9qcmG#+yw4qe?G6jw;YnAG^%={q(^Z~vm1ms&w6kmKtfJ1! z>TE!lG%Njyn8ZXS*6FNO($T5ZUQ%i+m0D+bcW92WJJMyda9GQC)-R><`I(%(%Eo=&>xDRUO) zY13a&_hy%ouYZ=-c4>WDTAwCgPm`@avQ-PEVc(?JLd&t^wlntIGKAvh;v2=YMO#rV z9yK%ezws$%{WlKY?9k#HgPU|~DEbSQ>*Ak^-xog-e^z@Rs}+wUOMmsF6|hLcQ=1=3 zBmI>R-uGYr=ud`x(mnYYB2VeV;<52le7{(&US9XnazljAgu%b$w>%jCPr`9S_YbC) zObvX-ij9pa@fka?Yw(xk{QvkAv`Nb0Yq^s8ZW6okQ~dO`*h8N7r*w$n?{QB)w$YwlNyVDoz$zI*k{871sj{KJqIsS{GZ~6;)lgeaGlcd z26Jc)V~QUazbhWoHbQY}@wa~88_y`F6l02d@tYL?mtrBk8t}Ny?ps7##E=gS=3{=@ zYo9{@7VCRsosS;;V`KdeZieFO7}d9K_DSg{OL$29q_c}P=~}T4$I`JIKQU#4AFblI zJX8G<9w!H5X^L^`d|dH@HoJ20C|BK)o(RP=g|XU3DU93kei1|DtzggFblw|dwDN!Y z(ObO5XHZVx>=5;w&Sh_U-6!tfyyRbZz*}y<@p_vMe-o+N^k>ko{trJG-+%fkdIzri z#;Yei66G}MgEzUx=50R7(2(22_7G<^`W>=&v#1`;r?`2uof|je{odrBZ+7VG_QjmM zF*mO}=nb32hl(AFj}*JY`$*I<2Mp8a4=WBSzEpg@xY0FRi;-IPMe)=Pr`TSAr3F3U zW}gk(B-R^n>hvK;sr@9Weys)vdVu2R#q8oidiX&tJU+7+_-qV4r4M=;8hXPy@sHx# zjsI^9-nxV~>A<096&DWO+B|NS>c-E24jbHZ=YA~j0zI+582cKIPmlI3(O_eYl-_0b zZv+1c)BUr%XSd^$tB0wq8V4F59PGO#p9n{qQ-8GYJ6Yk5bVb@Dpn>KN@~+J?4So7uIAR6#mh=%tONM)@B|S{;70C>4mxV{IRcZdmR`1^ z@Q>c1K0KIFm5&PD)^D~3Ys>O+VNG1e8LHl){*KV&o$2ohuXtnn4&g7}l)hV*#rL9T z%~ovgleJj2xoL&JXJlK%x1DG2wO;ew zY@6JA&1`!sHZRV0v}*IpY^V4>^XvoGYyL~NhqsUaHv5cqmXBvAd$;(r*|}C#F37%M zW#yvmi&j^5W?%9K@viKv)>d|B7g}GrCc7xEvCJ;^2Jt^-mw0#hzh_s(w})q6^Y-u! z*;UqCma?m@xopV3?%m{Gr|wV@OE zHHocgyjJu}?d?~-B`d1$l&ZUYOQ~H=P3>w@YFFb^yV^3ft6`~KMc*JV$jcJnty1e6 zmRi@a)Vj7zt!vBFy562z*A}UDjZdv>Ypv_g>?D8j9iQ6R)~Stco!VGQ8=DX&^Dr{e z*lv>cHdTAu#*y1*+lFbpiEJ0%p4#5<)b@s_wl^`gy|?rA@i!XnIa*+rT40u1U}I{5 zBdxpcQIoZ-#`aXt`a%;=7O#Y1yjZ+y6t$t0g=YRMXemA{hFe$L!Uj5l|BBIJqINsp z3fl=<@8syMB24A4;_actXT{cze1|8yCB7@(DgG``cuRa(yj%P|C9=Vn#d}@neI;6t zPm68Dw=Hcez8yO%pHaL$W@({Wj(3Gml|JQaCzMVQ|8(io;wP3)6z8`>{N&Qf(tJwk6eaW7 z(r3j_EuAWUTIn?L)9I$kNjFVNx@k(%O;eI?8kuy{$fTP_Cf(GWbW?NEP0dL+H7DKF zoODxj(oLi3CUYwIw75|*ur`#p7;%74Z5umv9$yE)iA6^QGZ} z`~vyaTll>szeKJtH6vmxUNJ6n$IJ7}#jo&;XetjGUlYI5{N1T~lyA7swfVKKbG;c7 zC4Msg&K++sQ=-IQ#<#_1n=w)1H{(X}oAR5)zmtDQ{AM#KO8jWtB7Uox6ea#NzAOGc zGb&2_YJ6Y(2WD23_}BP*@gJIDQQ~LgAH;uTrbUUr4PzcYH-0Ssll&**KQ;5B#Q(<6 z#DAXuT&{oNdB{Y*IQ~)mcF#p7^2zZ};&*sHGLdhNe-{6x=Oh#P==hcRot~FW*O{P*GyUYUgJmHjTu zmyvggxxe_QpJk+DwF|Gv}yO}&0dy?(Pke;fO^^=(eQen`Fk7W({M?2kQtbL!~> z4!W!OZoYw!un*{iW8XhK_5CfW?;nx+{*kHgpPc&sQK|2rf{*U+tjGZJ!~lZ+|3GP< z=^H!;JV^ZDaG3bvJc%_X9?+C{K%*ywNBKAM=)kwwC-vF0d;=e2$H-@7)~%iy9A{5t z3DXiwXiY3(4Bumy+kb^`GapmYUiEF?W=|YvyXK92js?D>zGKhLz70H+@i)%{*{!bp zUECrJ;TFvsxy9W)Rt3*0?{)ldeM4d!t?3OeA#sjIKF%Jo|4~me8`#I@z^?X52D z;?MdH=jZ7U?mORiEY82ce)Em(U&Lw|5=WVw-u4pklouQmnaafE%`EU|wiK6o(K}y4 z;wX)*oYAfo#{tv40fs#xRJ{kL(KFN@Jjr|)@pZl-@t6j0hgok=zwZS8)m|3o>B+y5 z*)%3*6TCO(Kg4;9vcK?cz;yy1tHqHJmvn|E9@{G5EPqv-xiDQ)E*)G}p z#iwV}-JSn6@egDlaOCcu0ypr)wufW(%sy=Ye%XGG**_z7iCs1D#`ZDsIKFA*k&VCY^;%beF ztA)hX8WUG*PF$@iakb{e)tVAlYffCPsdPr^Y}YxbbPmq+`O@dHpL0v+ihrT>1@SMI zz9{~s(wD@~E1f6)<*8^o+QPS)S&fMij^yL) zo30so;i$w5TN5uFm3ZNl#0$qHUN|N3!ZC>#PD#9QO!S53+*?YwDAij_J>r8*QF~7u zu{m+XQPJC&J%db9drus33XWLt_8oa)GhSE{kBo3sVuX_uBMgZVj^c}K7$(%5Yww92 zHu6i>B0eG?foYA**^3fiY~rVEw0In6M}K8w#K-1i9TUggO?;P)7oUJThQu9{_cHOw z9VfoV9p7zFWQxtvinTrzsKdr$uG}p{*4^8IdRa2#6d?T4%(W3CjX3oBL|(FM-DnIanLY?gXZ}r4w~nm z!$Cvhpbh!ixt5ZcXhUM6lk><#r{!PBzhwV;`FYaz<^0RyU&+5B9vNzL9vNyApKV_i zztF6ghWw)ZBJs#sn{qzf93MIB#Kc)!6K9>6IBRR-tP>MwZROqVD(vv;{A#TF>-pE6 zbxnSayF@NKIdR!(yuNuJ#`D{^!dTwluET~mvD1Eqz3-&o)VvDK2ifecTbBylRqQgp0|rf2HeE&9mc}< z-F*8a8*bqPZ=qHkIdKbLc+ZJHpJOk4;+dz;FCJ?*-*|r%e<6QCd`Z4U{NHj<`}b>LTTwRmLM!}-^% z+7o&9d@ok+uv|zUL!q9hpz84qt@vhHdf|9K! z{I7-eY}5XX3O4%20^^Fw(I;~f6J`zkp8YpxoE%Qv_{*D2I5ql|38#J`{+>DT8~x*i zFKqlhZNmd4+v^gB%Y#_18SYnapUVq;6= z{*ALz-dLH8KFXn;7k!L((Z~50eS(M4=wmc`8I68M2Rx0o^ELV`Z==!Q zX!JN5eU3)2ql@?*eU9hR=lLFu-bbVV(ddCR`XG&7NTVOp=!rD?B8}ciqd(H+Jd#GA zq$^7=`F1AHq|rBNnRn9YpEP^ay_7~jrE5#yB@N@1@Y_hkyNu*ojNfLm7$0nO zwH=SmR~pw{?faoL8rqjH;afdzcqn^3>=z{=%uKe+gR?S=;m5Jfy~7Q--yz}0rNc@m zvHG8kgFS?IeU*j&VivB&TK6hrl>w=24q0g-d5g04tL)!~NZ!Iw{=Xu5zj}jz*?%BuD!vIl4N@(XC02ewO6u-Xup)COLX0$&vY) zNsEyqSC4Y!{mI#lWcm=Xj3h@ro#cz&Xi0vspWws#Uk5x+M{m=Pjps)B-|W~o(>spM fQws>G1!SoO#Cs0hgHCntc;ACI+qZ4nckllP8pbT8 literal 0 HcmV?d00001 diff --git a/src/kivymd/fonts/Roboto-LightItalic.ttf b/src/kivymd/fonts/Roboto-LightItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a85444f2ecec38a4df2efd9f09b8055169909a8a GIT binary patch literal 133172 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⪼!+`pB8ILOqDAf+mbV8|B%!V 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 literal 0 HcmV?d00001 diff --git a/src/kivymd/fonts/Roboto-MediumItalic.ttf b/src/kivymd/fonts/Roboto-MediumItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b82820554134a817749ff81922c5a4c0082abf35 GIT binary patch literal 134312 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

VTi)^qwc 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 literal 0 HcmV?d00001 diff --git a/src/kivymd/fonts/Roboto-ThinItalic.ttf b/src/kivymd/fonts/Roboto-ThinItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b79cb26da0377370ab3e41bb7a5a62943187124f GIT binary patch literal 132860 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 literal 0 HcmV?d00001 diff --git a/src/kivymd/grid.py b/src/kivymd/grid.py new file mode 100644 index 00000000..db310193 --- /dev/null +++ b/src/kivymd/grid.py @@ -0,0 +1,168 @@ +# coding=utf-8 +from kivy.lang import Builder +from kivy.properties import StringProperty, BooleanProperty, ObjectProperty, \ + NumericProperty, ListProperty, OptionProperty +from kivy.uix.behaviors import ButtonBehavior +from kivy.uix.boxlayout import BoxLayout +from kivy.uix.floatlayout import FloatLayout +from kivymd.ripplebehavior import RectangularRippleBehavior +from kivymd.theming import ThemableBehavior + +Builder.load_string(""" + + _img_widget: img + _img_overlay: img_overlay + _box_overlay: box + AsyncImage: + id: img + allow_stretch: root.allow_stretch + anim_delay: root.anim_delay + anim_loop: root.anim_loop + color: root.img_color + keep_ratio: root.keep_ratio + mipmap: root.mipmap + source: root.source + size_hint_y: 1 if root.overlap else None + x: root.x + y: root.y if root.overlap or root.box_position == 'header' else box.top + BoxLayout: + id: img_overlay + size_hint: img.size_hint + size: img.size + pos: img.pos + BoxLayout: + canvas: + Color: + rgba: root.box_color + Rectangle: + pos: self.pos + size: self.size + id: box + size_hint_y: None + height: dp(68) if root.lines == 2 else dp(48) + x: root.x + y: root.y if root.box_position == 'footer' else root.y + root.height - self.height + + + _img_widget: img + _img_overlay: img_overlay + _box_overlay: box + _box_label: boxlabel + AsyncImage: + id: img + allow_stretch: root.allow_stretch + anim_delay: root.anim_delay + anim_loop: root.anim_loop + color: root.img_color + keep_ratio: root.keep_ratio + mipmap: root.mipmap + source: root.source + size_hint_y: 1 if root.overlap else None + x: root.x + y: root.y if root.overlap or root.box_position == 'header' else box.top + BoxLayout: + id: img_overlay + size_hint: img.size_hint + size: img.size + pos: img.pos + BoxLayout: + canvas: + Color: + rgba: root.box_color + Rectangle: + pos: self.pos + size: self.size + id: box + size_hint_y: None + height: dp(68) if root.lines == 2 else dp(48) + x: root.x + y: root.y if root.box_position == 'footer' else root.y + root.height - self.height + MDLabel: + id: boxlabel + font_style: "Caption" + halign: "center" + text: root.text +""") + + +class Tile(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, + BoxLayout): + """A simple tile. It does nothing special, just inherits the right behaviors + to work as a building block. + """ + pass + + +class SmartTile(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, + FloatLayout): + """A tile for more complex needs. + + Includes an image, a container to place overlays and a box that can act + as a header or a footer, as described in the Material Design specs. + """ + + box_color = ListProperty([0, 0, 0, 0.5]) + """Sets the color and opacity for the information box.""" + + box_position = OptionProperty('footer', options=['footer', 'header']) + """Determines wether the information box acts as a header or footer to the + image. + """ + + lines = OptionProperty(1, options=[1, 2]) + """Number of lines in the header/footer. + + As per Material Design specs, only 1 and 2 are valid values. + """ + + overlap = BooleanProperty(True) + """Determines if the header/footer overlaps on top of the image or not""" + + # Img properties + allow_stretch = BooleanProperty(True) + anim_delay = NumericProperty(0.25) + anim_loop = NumericProperty(0) + img_color = ListProperty([1, 1, 1, 1]) + keep_ratio = BooleanProperty(False) + mipmap = BooleanProperty(False) + source = StringProperty() + + _img_widget = ObjectProperty() + _img_overlay = ObjectProperty() + _box_overlay = ObjectProperty() + _box_label = ObjectProperty() + + def reload(self): + self._img_widget.reload() + + def add_widget(self, widget, index=0): + if issubclass(widget.__class__, IOverlay): + self._img_overlay.add_widget(widget, index) + elif issubclass(widget.__class__, IBoxOverlay): + self._box_overlay.add_widget(widget, index) + else: + super(SmartTile, self).add_widget(widget, index) + + +class SmartTileWithLabel(SmartTile): + _box_label = ObjectProperty() + + # MDLabel properties + font_style = StringProperty("Caption") + theme_text_color = StringProperty("") + text = StringProperty("") + """Determines the text for the box footer/header""" + + +class IBoxOverlay(): + """An interface to specify widgets that belong to to the image overlay + in the :class:`SmartTile` widget when added as a child. + """ + pass + + +class IOverlay(): + """An interface to specify widgets that belong to to the image overlay + in the :class:`SmartTile` widget when added as a child. + """ + pass diff --git a/src/kivymd/icon_definitions.py b/src/kivymd/icon_definitions.py new file mode 100644 index 00000000..5b717356 --- /dev/null +++ b/src/kivymd/icon_definitions.py @@ -0,0 +1,1569 @@ +# -*- coding: utf-8 -*- + +# Thanks to Sergey Kupletsky (github.com/zavoloklom) for its Material Design +# Iconic Font, which provides KivyMD's icons. + +# GALLERY HERE: +# https://zavoloklom.github.io/material-design-iconic-font/icons.html + +# LAST UPDATED: version 2.2.0 of Material Design Iconic Font + +md_icons = { + '3d-rotation': u'', + + 'airplane-off': u'', + + 'address': u'', + + 'airplane': u'', + + 'album': u'', + + 'archive': u'', + + 'assignment-account': u'', + + 'assignment-alert': u'', + + 'assignment-check': u'', + + 'assignment-o': u'', + + 'assignment-return': u'', + + 'assignment-returned': u'', + + 'assignment': u'', + + 'attachment-alt': u'', + + 'attachment': u'', + + 'audio': u'', + + 'badge-check': u'', + + 'balance-wallet': u'', + + 'balance': u'', + + 'battery-alert': u'', + + 'battery-flash': u'', + + 'battery-unknown': u'', + + 'battery': u'', + + 'bike': u'', + + 'block-alt': u'', + + 'block': u'', + + 'boat': u'', + + 'book-image': u'', + + 'book': u'', + + 'bookmark-outline': u'', + + 'bookmark': u'', + + 'brush': u'', + + 'bug': u'', + + 'bus': u'', + + 'cake': u'', + + 'car-taxi': u'', + + 'car-wash': u'', + + 'car': u'', + + 'card-giftcard': u'', + + 'card-membership': u'', + + 'card-travel': u'', + + 'card': u'', + + 'case-check': u'', + + 'case-download': u'', + + 'case-play': u'', + + 'case': u'', + + 'cast-connected': u'', + + 'cast': u'', + + 'chart-donut': u'', + + 'chart': u'', + + 'city-alt': u'', + + 'city': u'', + + 'close-circle-o': u'', + + 'close-circle': u'', + + 'close': u'', + + 'cocktail': u'', + + 'code-setting': u'', + + 'code-smartphone': u'', + + 'code': u'', + + 'coffee': u'', + + 'collection-bookmark': u'', + + 'collection-case-play': u'', + + 'collection-folder-image': u'', + + 'collection-image-o': u'', + + 'collection-image': u'', + + 'collection-item-1': u'', + + 'collection-item-2': u'', + + 'collection-item-3': u'', + + 'collection-item-4': u'', + + 'collection-item-5': u'', + + 'collection-item-6': u'', + + 'collection-item-7': u'', + + 'collection-item-8': u'', + + 'collection-item-9-plus': u'', + + 'collection-item-9': u'', + + 'collection-item': u'', + + 'collection-music': u'', + + 'collection-pdf': u'', + + 'collection-plus': u'', + + 'collection-speaker': u'', + + 'collection-text': u'', + + 'collection-video': u'', + + 'compass': u'', + + 'cutlery': u'', + + 'delete': u'', + + 'dialpad': u'', + + 'dns': u'', + + 'drink': u'', + + 'edit': u'', + + 'email-open': u'', + + 'email': u'', + + 'eye-off': u'', + + 'eye': u'', + + 'eyedropper': u'', + + 'favorite-outline': u'', + + 'favorite': u'', + + 'filter-list': u'', + + 'fire': u'', + + 'flag': u'', + + 'flare': u'', + + 'flash-auto': u'', + + 'flash-off': u'', + + 'flash': u'', + + 'flip': u'', + + 'flower-alt': u'', + + 'flower': u'', + + 'font': u'', + + 'fullscreen-alt': u'', + + 'fullscreen-exit': u'', + + 'fullscreen': u'', + + 'functions': u'', + + 'gas-station': u'', + + 'gesture': u'', + + 'globe-alt': u'', + + 'globe-lock': u'', + + 'globe': u'', + + 'graduation-cap': u'', + + 'group': u'', + + 'home': u'', + + 'hospital-alt': u'', + + 'hospital': u'', + + 'hotel': u'', + + 'hourglass-alt': u'', + + 'hourglass-outline': u'', + + 'hourglass': u'', + + 'http': u'', + + 'image-alt': u'', + + 'image-o': u'', + + 'image': u'', + + 'inbox': u'', + + 'invert-colors-off': u'', + + 'invert-colors': u'', + + 'key': u'', + + 'label-alt-outline': u'', + + 'label-alt': u'', + + 'label-heart': u'', + + 'label': u'', + + 'labels': u'', + + 'lamp': u'', + + 'landscape': u'', + + 'layers-off': u'', + + 'layers': u'', + + 'library': u'', + + 'link': u'', + + 'lock-open': u'', + + 'lock-outline': u'', + + 'lock': u'', + + 'mail-reply-all': u'', + + 'mail-reply': u'', + + 'mail-send': u'', + + 'mall': u'', + + 'map': u'', + + 'menu': u'', + + 'money-box': u'', + + 'money-off': u'', + + 'money': u'', + + 'more-vert': u'', + + 'more': u'', + + 'movie-alt': u'', + + 'movie': u'', + + 'nature-people': u'', + + 'nature': u'', + + 'navigation': u'', + + 'open-in-browser': u'', + + 'open-in-new': u'', + + 'palette': u'', + + 'parking': u'', + + 'pin-account': u'', + + 'pin-assistant': u'', + + 'pin-drop': u'', + + 'pin-help': u'', + + 'pin-off': u'', + + 'pin': u'', + + 'pizza': u'', + + 'plaster': u'', + + 'power-setting': u'', + + 'power': u'', + + 'print': u'', + + 'puzzle-piece': u'', + + 'quote': u'', + + 'railway': u'', + + 'receipt': u'', + + 'refresh-alt': u'', + + 'refresh-sync-alert': u'', + + 'refresh-sync-off': u'', + + 'refresh-sync': u'', + + 'refresh': u'', + + 'roller': u'', + + 'ruler': u'', + + 'scissors': u'', + + 'screen-rotation-lock': u'', + + 'screen-rotation': u'', + + 'search-for': u'', + + 'search-in-file': u'', + + 'search-in-page': u'', + + 'search-replace': u'', + + 'search': u'', + + 'seat': u'', + + 'settings-square': u'', + + 'settings': u'', + + 'shape': u'', + + 'shield-check': u'', + + 'shield-security': u'', + + 'shopping-basket': u'', + + 'shopping-cart-plus': u'', + + 'shopping-cart': u'', + + 'sign-in': u'', + + 'sort-amount-asc': u'', + + 'sort-amount-desc': u'', + + 'sort-asc': u'', + + 'sort-desc': u'', + + 'spellcheck': u'', + + 'spinner': u'', + + 'storage': u'', + + 'store-24': u'', + + 'store': u'', + + 'subway': u'', + + 'sun': u'', + + 'tab-unselected': u'', + + 'tab': u'', + + 'tag-close': u'', + + 'tag-more': u'', + + 'tag': u'', + + 'thumb-down': u'', + + 'thumb-up-down': u'', + + 'thumb-up': u'', + + 'ticket-star': u'', + + 'toll': u'', + + 'toys': u'', + + 'traffic': u'', + + 'translate': u'', + + 'triangle-down': u'', + + 'triangle-up': u'', + + 'truck': u'', + + 'turning-sign': u'', + + ' ungroup': u'', + + 'wallpaper': u'', + + 'washing-machine': u'', + + 'window-maximize': u'', + + 'window-minimize': u'', + + 'window-restore': u'', + + 'wrench': u'', + + 'zoom-in': u'', + + 'zoom-out': u'', + + 'alert-circle-o': u'', + + 'alert-circle': u'', + + 'alert-octagon': u'', + + 'alert-polygon': u'', + + 'alert-triangle': u'', + + 'help-outline': u'', + + 'help': u'', + + 'info-outline': u'', + + 'info': u'', + + 'notifications-active': u'', + + 'notifications-add': u'', + + 'notifications-none': u'', + + 'notifications-off': u'', + + 'notifications-paused': u'', + + 'notifications': u'', + + 'account-add': u'', + + 'account-box-mail': u'', + + 'account-box-o': u'', + + 'account-box-phone': u'', + + 'account-box': u'', + + 'account-calendar': u'', + + 'account-circle': u'', + + 'account-o': u'', + + 'account': u'', + + 'accounts-add': u'', + + 'accounts-alt': u'', + + 'accounts-list-alt': u'', + + 'accounts-list': u'', + + 'accounts-outline': u'', + + 'accounts': u'', + + 'face': u'', + + 'female': u'', + + 'male-alt': u'', + + 'male-female': u'', + + 'male': u'', + + 'mood-bad': u'', + + 'mood': u'', + + 'run': u'', + + 'walk': u'', + + 'cloud-box': u'', + + 'cloud-circle': u'', + + 'cloud-done': u'', + + 'cloud-download': u'', + + 'cloud-off': u'', + + 'cloud-outline-alt': u'', + + 'cloud-outline': u'', + + 'cloud-upload': u'', + + 'cloud': u'', + + 'download': u'', + + 'file-plus': u'', + + 'file-text': u'', + + 'file': u'', + + 'folder-outline': u'', + + 'folder-person': u'', + + 'folder-star-alt': u'', + + 'folder-star': u'', + + 'folder': u'', + + 'gif': u'', + + 'upload': u'', + + 'border-all': u'', + + 'border-bottom': u'', + + 'border-clear': u'', + + 'border-color': u'', + + 'border-horizontal': u'', + + 'border-inner': u'', + + 'border-left': u'', + + 'border-outer': u'', + + 'border-right': u'', + + 'border-style': u'', + + 'border-top': u'', + + 'border-vertical': u'', + + 'copy': u'', + + 'crop': u'', + + 'format-align-center': u'', + + 'format-align-justify': u'', + + 'format-align-left': u'', + + 'format-align-right': u'', + + 'format-bold': u'', + + 'format-clear-all': u'', + + 'format-clear': u'', + + 'format-color-fill': u'', + + 'format-color-reset': u'', + + 'format-color-text': u'', + + 'format-indent-decrease': u'', + + 'format-indent-increase': u'', + + 'format-italic': u'', + + 'format-line-spacing': u'', + + 'format-list-bulleted': u'', + + 'format-list-numbered': u'', + + 'format-ltr': u'', + + 'format-rtl': u'', + + 'format-size': u'', + + 'format-strikethrough-s': u'', + + 'format-strikethrough': u'', + + 'format-subject': u'', + + 'format-underlined': u'', + + 'format-valign-bottom': u'', + + 'format-valign-center': u'', + + 'format-valign-top': u'', + + 'redo': u'', + + 'select-all': u'', + + 'space-bar': u'', + + 'text-format': u'', + + 'transform': u'', + + 'undo': u'', + + 'wrap-text': u'', + + 'comment-alert': u'', + + 'comment-alt-text': u'', + + 'comment-alt': u'', + + 'comment-edit': u'', + + 'comment-image': u'', + + 'comment-list': u'', + + 'comment-more': u'', + + 'comment-outline': u'', + + 'comment-text-alt': u'', + + 'comment-text': u'', + + 'comment-video': u'', + + 'comment': u'', + + 'comments': u'', + + 'rm': u'F', + + 'check-all': u'', + + 'check-circle-u': u'', + + 'check-circle': u'', + + 'check-square': u'', + + 'check': u'', + + 'circle-o': u'', + + 'circle': u'', + + 'dot-circle-alt': u'', + + 'dot-circle': u'', + + 'minus-circle-outline': u'', + + 'minus-circle': u'', + + 'minus-square': u'', + + 'minus': u'', + + 'plus-circle-o-duplicate': u'', + + 'plus-circle-o': u'', + + 'plus-circle': u'', + + 'plus-square': u'', + + 'plus': u'', + + 'square-o': u'', + + 'star-circle': u'', + + 'star-half': u'', + + 'star-outline': u'', + + 'star': u'', + + 'bluetooth-connected': u'', + + 'bluetooth-off': u'', + + 'bluetooth-search': u'', + + 'bluetooth-setting': u'', + + 'bluetooth': u'', + + 'camera-add': u'', + + 'camera-alt': u'', + + 'camera-bw': u'', + + 'camera-front': u'', + + 'camera-mic': u'', + + 'camera-party-mode': u'', + + 'camera-rear': u'', + + 'camera-roll': u'', + + 'camera-switch': u'', + + 'camera': u'', + + 'card-alert': u'', + + 'card-off': u'', + + 'card-sd': u'', + + 'card-sim': u'', + + 'desktop-mac': u'', + + 'desktop-windows': u'', + + 'device-hub': u'', + + 'devices-off': u'', + + 'devices': u'', + + 'dock': u'', + + 'floppy': u'', + + 'gamepad': u'', + + 'gps-dot': u'', + + 'gps-off': u'', + + 'gps': u'', + + 'headset-mic': u'', + + 'headset': u'', + + 'input-antenna': u'', + + 'input-composite': u'', + + 'input-hdmi': u'', + + 'input-power': u'', + + 'input-svideo': u'', + + 'keyboard-hide': u'', + + 'keyboard': u'', + + 'laptop-chromebook': u'', + + 'laptop-mac': u'', + + 'laptop': u'', + + 'mic-off': u'', + + 'mic-outline': u'', + + 'mic-setting': u'', + + 'mic': u'', + + 'mouse': u'', + + 'network-alert': u'', + + 'network-locked': u'', + + 'network-off': u'', + + 'network-outline': u'', + + 'network-setting': u'', + + 'network': u'', + + 'phone-bluetooth': u'', + + 'phone-end': u'', + + 'phone-forwarded': u'', + + 'phone-in-talk': u'', + + 'phone-locked': u'', + + 'phone-missed': u'', + + 'phone-msg': u'', + + 'phone-paused': u'', + + 'phone-ring': u'', + + 'phone-setting': u'', + + 'phone-sip': u'', + + 'phone': u'', + + 'portable-wifi-changes': u'', + + 'portable-wifi-off': u'', + + 'portable-wifi': u'', + + 'radio': u'', + + 'reader': u'', + + 'remote-control-alt': u'', + + 'remote-control': u'', + + 'router': u'', + + 'scanner': u'', + + 'smartphone-android': u'', + + 'smartphone-download': u'', + + 'smartphone-erase': u'', + + 'smartphone-info': u'', + + 'smartphone-iphone': u'', + + 'smartphone-landscape-lock': u'', + + 'smartphone-landscape': u'', + + 'smartphone-lock': u'', + + 'smartphone-portrait-lock': u'', + + 'smartphone-ring': u'', + + 'smartphone-setting': u'', + + 'smartphone-setup': u'', + + 'smartphone': u'', + + 'speaker': u'', + + 'tablet-android': u'', + + 'tablet-mac': u'', + + 'tablet': u'', + + 'tv-alt-play': u'', + + 'tv-list': u'', + + 'tv-play': u'', + + 'tv': u'', + + 'usb': u'', + + 'videocam-off': u'', + + 'videocam-switch': u'', + + 'videocam': u'', + + 'watch': u'', + + 'wifi-alt-2': u'', + + 'wifi-alt': u'', + + 'wifi-info': u'', + + 'wifi-lock': u'', + + 'wifi-off': u'', + + 'wifi-outline': u'', + + 'wifi': u'', + + 'arrow-left-bottom': u'', + + 'arrow-left': u'', + + 'arrow-merge': u'', + + 'arrow-missed': u'', + + 'arrow-right-top': u'', + + 'arrow-right': u'', + + 'arrow-split': u'', + + 'arrows': u'', + + 'caret-down-circle': u'', + + 'caret-down': u'', + + 'caret-left-circle': u'', + + 'caret-left': u'', + + 'caret-right-circle': u'', + + 'caret-right': u'', + + 'caret-up-circle': u'', + + 'caret-up': u'', + + 'chevron-down': u'', + + 'chevron-left': u'', + + 'chevron-right': u'', + + 'chevron-up': u'', + + 'forward': u'', + + 'long-arrow-down': u'', + + 'long-arrow-left': u'', + + 'long-arrow-return': u'', + + 'long-arrow-right': u'', + + 'long-arrow-tab': u'', + + 'long-arrow-up': u'', + + 'rotate-ccw': u'', + + 'rotate-cw': u'', + + 'rotate-left': u'', + + 'rotate-right': u'', + + 'square-down': u'', + + 'square-right': u'', + + 'swap-alt': u'', + + 'swap-vertical-circle': u'', + + 'swap-vertical': u'', + + 'swap': u'', + + 'trending-down': u'', + + 'trending-flat': u'', + + 'trending-up': u'', + + 'unfold-less': u'', + + 'unfold-more': u'', + + 'apps': u'', + + 'grid-off': u'', + + 'grid': u'', + + 'view-agenda': u'', + + 'view-array': u'', + + 'view-carousel': u'', + + 'view-column': u'', + + 'view-comfy': u'', + + 'view-compact': u'', + + 'view-dashboard': u'', + + 'view-day': u'', + + 'view-headline': u'', + + 'view-list-alt': u'', + + 'view-list': u'', + + 'view-module': u'', + + 'view-quilt': u'', + + 'view-stream': u'', + + 'view-subtitles': u'', + + 'view-toc': u'', + + 'view-web': u'', + + 'view-week': u'', + + 'widgets': u'', + + 'alarm-check': u'', + + 'alarm-off': u'', + + 'alarm-plus': u'', + + 'alarm-snooze': u'', + + 'alarm': u'', + + 'calendar-alt': u'', + + 'calendar-check': u'', + + 'calendar-close': u'', + + 'calendar-note': u'', + + 'calendar': u'', + + 'time-countdown': u'', + + 'time-interval': u'', + + 'time-restore-setting': u'', + + 'time-restore': u'', + + 'time': u'', + + 'timer-off': u'', + + 'timer': u'', + + 'android-alt': u'', + + 'android': u'', + + 'apple': u'', + + 'behance': u'', + + 'codepen': u'', + + 'dribbble': u'', + + 'dropbox': u'', + + 'evernote': u'', + + 'facebook-box': u'', + + 'facebook': u'', + + 'github-box': u'', + + 'github': u'', + + 'google-drive': u'', + + 'google-earth': u'', + + 'google-glass': u'', + + 'google-maps': u'', + + 'google-pages': u'', + + 'google-play': u'', + + 'google-plus-box': u'', + + 'google-plus': u'', + + 'google': u'', + + 'instagram': u'', + + 'language-css3': u'', + + 'language-html5': u'', + + 'language-javascript': u'', + + 'language-python-alt': u'', + + 'language-python': u'', + + 'lastfm': u'', + + 'linkedin-box': u'', + + 'paypal': u'', + + 'pinterest-box': u'', + + 'pocket': u'', + + 'polymer': u'', + + 'rss': u'', + + 'share': u'', + + 'stackoverflow': u'', + + 'steam-square': u'', + + 'steam': u'', + + 'twitter-box': u'', + + 'twitter': u'', + + 'vk': u'', + + 'wikipedia': u'', + + 'windows': u'', + + '500px': u'', + + '8tracks': u'', + + 'amazon': u'', + + 'blogger': u'', + + 'delicious': u'', + + 'disqus': u'', + + 'flattr': u'', + + 'flickr': u'', + + 'github-alt': u'', + + 'google-old': u'', + + 'linkedin': u'', + + 'odnoklassniki': u'', + + 'outlook': u'', + + 'paypal-alt': u'', + + 'pinterest': u'', + + 'playstation': u'', + + 'reddit': u'', + + 'skype': u'', + + 'slideshare': u'', + + 'soundcloud': u'', + + 'tumblr': u'', + + 'twitch': u'', + + 'vimeo': u'', + + 'whatsapp': u'', + + 'xbox': u'', + + 'yahoo': u'', + + 'youtube-play': u'', + + 'youtube': u'', + + 'aspect-ratio-alt': u'', + + 'aspect-ratio': u'', + + 'blur-circular': u'', + + 'blur-linear': u'', + + 'blur-off': u'', + + 'blur': u'', + + 'brightness-2': u'', + + 'brightness-3': u'', + + 'brightness-4': u'', + + 'brightness-5': u'', + + 'brightness-6': u'', + + 'brightness-7': u'', + + 'brightness-auto': u'', + + 'brightness-setting': u'', + + 'broken-image': u'', + + 'center-focus-strong': u'', + + 'center-focus-weak': u'', + + 'compare': u'', + + 'crop-16-9': u'', + + 'crop-3-2': u'', + + 'crop-5-4': u'', + + 'crop-7-5': u'', + + 'crop-din': u'', + + 'crop-free': u'', + + 'crop-landscape': u'', + + 'crop-portrait': u'', + + 'crop-square': u'', + + 'exposure-alt': u'', + + 'exposure': u'', + + 'filter-b-and-w': u'', + + 'filter-center-focus': u'', + + 'filter-frames': u'', + + 'filter-tilt-shift': u'', + + 'gradient': u'', + + 'grain': u'', + + 'graphic-eq': u'', + + 'hdr-off': u'', + + 'hdr-strong': u'', + + 'hdr-weak': u'', + + 'hdr': u'', + + 'iridescent': u'', + + 'leak-off': u'', + + 'leak': u'', + + 'looks': u'', + + 'loupe': u'', + + 'panorama-horizontal': u'', + + 'panorama-vertical': u'', + + 'panorama-wide-angle': u'', + + 'photo-size-select-large': u'', + + 'photo-size-select-small': u'', + + 'picture-in-picture': u'', + + 'slideshow': u'', + + 'texture': u'', + + 'tonality': u'', + + 'vignette': u'', + + 'wb-auto': u'', + + 'eject-alt': u'', + + 'eject': u'', + + 'equalizer': u'', + + 'fast-forward': u'', + + 'fast-rewind': u'', + + 'forward-10': u'', + + 'forward-30': u'', + + 'forward-5': u'', + + 'hearing': u'', + + 'pause-circle-outline': u'', + + 'pause-circle': u'', + + 'pause': u'', + + 'play-circle-outline': u'', + + 'play-circle': u'', + + 'play': u'', + + 'playlist-audio': u'', + + 'playlist-plus': u'', + + 'repeat-one': u'', + + 'repeat': u'', + + 'replay-10': u'', + + 'replay-30': u'', + + 'replay-5': u'', + + 'replay': u'', + + 'shuffle': u'', + + 'skip-next': u'', + + 'skip-previous': u'', + + 'stop': u'', + + 'surround-sound': u'', + + 'tune': u'', + + 'volume-down': u'', + + 'volume-mute': u'', + + 'volume-off': u'', + + 'volume-up': u'', + + 'n-1-square': u'', + + 'n-2-square': u'', + + 'n-3-square': u'', + + 'n-4-square': u'', + + 'n-5-square': u'', + + 'n-6-square': u'', + + 'neg-1': u'', + + 'neg-2': u'', + + 'plus-1': u'', + + 'plus-2': u'', + + 'sec-10': u'', + + 'sec-3': u'', + + 'zero': u'', + + 'airline-seat-flat-angled': u'', + + 'airline-seat-flat': u'', + + 'airline-seat-individual-suite': u'', + + 'airline-seat-legroom-extra': u'', + + 'airline-seat-legroom-normal': u'', + + 'airline-seat-legroom-reduced': u'', + + 'airline-seat-recline-extra': u'', + + 'airline-seat-recline-normal': u'', + + 'airplay': u'', + + 'closed-caption': u'', + + 'confirmation-number': u'', + + 'developer-board': u'', + + 'disc-full': u'', + + 'explicit': u'', + + 'flight-land': u'', + + 'flight-takeoff': u'', + + 'flip-to-back': u'', + + 'flip-to-front': u'', + + 'group-work': u'', + + 'hd': u'', + + 'hq': u'', + + 'markunread-mailbox': u'', + + 'memory': u'', + + 'nfc': u'', + + 'play-for-work': u'', + + 'power-input': u'', + + 'present-to-all': u'', + + 'satellite': u'', + + 'tap-and-play': u'', + + 'vibration': u'', + + 'voicemail': u'', +} diff --git a/src/kivymd/images/kivymd_512.png b/src/kivymd/images/kivymd_512.png new file mode 100644 index 0000000000000000000000000000000000000000..7dbae604b08b210b328811e55eaa07a4ac208161 GIT binary patch literal 30694 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�Yr6^*!j4`?xt=1o7 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

{o3)qC%_NL=ZyH!i#uU@H7YaP~Sij5YY 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 literal 0 HcmV?d00001 diff --git a/src/kivymd/images/quad_shadow-0.png b/src/kivymd/images/quad_shadow-0.png new file mode 100644 index 0000000000000000000000000000000000000000..5d64fde5abd43c793c2fe2dd0bbdf9ddcfd923d7 GIT binary patch literal 29962 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 B=*s{A literal 0 HcmV?d00001 diff --git a/src/kivymd/images/quad_shadow-1.png b/src/kivymd/images/quad_shadow-1.png new file mode 100644 index 0000000000000000000000000000000000000000..c0f1e22642060aec1971849ac7fc73c3c4a1f6ed GIT binary patch literal 30186 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 l{J(65`hR_|Q9i1{Yp%_~=~Fq;?y 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�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 Vs`!V~6-HfPW?}VP6KRr*>ly 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 literal 0 HcmV?d00001 diff --git a/src/kivymd/images/rec_st_shadow-1.png b/src/kivymd/images/rec_st_shadow-1.png new file mode 100644 index 0000000000000000000000000000000000000000..759ee65285764c0619509c5b8cb27f972b2ab3fa GIT binary patch literal 32265 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 G;{P8x^pl$a literal 0 HcmV?d00001 diff --git a/src/kivymd/images/rec_st_shadow.atlas b/src/kivymd/images/rec_st_shadow.atlas new file mode 100644 index 00000000..d4c24abe --- /dev/null +++ b/src/kivymd/images/rec_st_shadow.atlas @@ -0,0 +1 @@ +{"rec_st_shadow-0.png": {"11": [262, 138, 128, 256], "10": [132, 138, 128, 256], "13": [522, 138, 128, 256], "12": [392, 138, 128, 256], "15": [782, 138, 128, 256], "14": [652, 138, 128, 256], "16": [912, 138, 128, 256], "0": [2, 138, 128, 256]}, "rec_st_shadow-1.png": {"20": [522, 138, 128, 256], "21": [652, 138, 128, 256], "17": [2, 138, 128, 256], "23": [912, 138, 128, 256], "19": [262, 138, 128, 256], "18": [132, 138, 128, 256], "22": [782, 138, 128, 256], "1": [392, 138, 128, 256]}, "rec_st_shadow-2.png": {"3": [132, 138, 128, 256], "2": [2, 138, 128, 256], "5": [392, 138, 128, 256], "4": [262, 138, 128, 256], "7": [652, 138, 128, 256], "6": [522, 138, 128, 256], "9": [912, 138, 128, 256], "8": [782, 138, 128, 256]}} \ No newline at end of file diff --git a/src/kivymd/images/round_shadow-0.png b/src/kivymd/images/round_shadow-0.png new file mode 100644 index 0000000000000000000000000000000000000000..26d984051562b2baf7d39cb92639aae94d222bda GIT binary patch literal 39635 zcmb??^;a8Rv^ErX57HnF?pg?L2`;6$6}M7~ySqb?;zdG>7I!G_Qmhnr*Wxbu^4|L= z-0z31l{IT-&Yp9&KKt3x@6_b+u&J<-kdW{c6(H}CkdWj4`(dIZt_%x*RYF3_%2I?# zYkB3IwA-fx2a_4BSMWmUu#)M#PsffEzW+6Z!*7p2zBRD(kaP9sM*e~-CDwZVW>m1^ z=dw7c{3uBqQ<7O-f{mS@ucv2hg`T#n+N?JM@3r8k`TzSL9b2J2F2oCMYW=I>PG|3N z4a{wWcfuhTq6UdedoT?cZuNT0?vOE#Stt$+p?Qs2%%EKFn3Kl;A4R)uExm(vF z=(_Qt%>T2tZ-(dYj}KO-@bvF*_(EE+8u3Kq8Wx>PO@Xezj@X=dKyha2mdaQ?g^7`- zdH%-*7Q#!Ni;jAE4T~+eO`i;{v<({GNP4#xTSWO74WJCBF2@#Gj7_h(Kqew_H_KDyd<%-_rHrT{*2sq zOn!!)JbIvXh&;y!3ZCx{+9tI13>9vgMEGrx~p^gsAz@F70F?R!MUu#W8~3d`i7!+ z)?9nUG@87nulFb9J1F)8Z2#b@m3vNC5x`u#Y725DEW1u4+1M+FCPB+jXg`%LYK8YU zRbXQvPNbr{ETJt7)1Z&&gv4E^i6+>|eEsxx{@>lgy^$r~#AQ~6kk8BxN9}&MyxaI# znrWBwB#Faai%xW?jy$E{@w|@vvJ#z7fMHhJx{qU}0kpeGUh`^=#k@4F>aW2`AbV#y zSW719d3W&U(zTt;N+)DW^o?G^ZigS>HPJw|s{ug&N{)kDRGD1OBsNG)S@T4hAR-l;2pqyFy`zKzxnnbU?K zJw$=%VQD8@8akHFiH+VOo5z;U4CP^B2IGtOjTW^1ID}jI#PO>)o&6qcd_AESQcI#s z0Up3Bj|}@-OyDA&$nB0L2H_!2-EpDJ2z2i5>maWr(i#U@v-anb=A`GyfCL3X2&-05woz2^gF*#X*n zx;1(rI{lfA*)8a+Hm?G5FOpA}TdmAxd$aI6-l~4sgCkbp%uPqd13}0dsNgW3ZT_XN zui}#?u2f?K2>-44xW2PfMM!~EE1DCzin^dHWA@|kE3B@;-^<0mnU$qmG)rj^fJRm+ zDC)I}!-6cwUuRny=rZ$YUbQM|rUHxf+1>IUKscdNTfm3`Bws)rqd?c}NB*=6|IJg7 z()d*rH6eW8Q&o9o)R~OgC&%y;4#sV8MV_`mr6Lb0sV7p$yox%qUrT20=OS*)7u2PY zbD}N`q*JRGnl9Sx=p{*00O2iu)-YLme&?=Rd>MT|SUune6fY z)u+QJCHZP=>z|8@F-J#nXeQCkfI5NXhqj*m`^t|W?o(%swjKLBFu0V6m6$ZD327DS zj=IY+`~Ech$HaZ)^X|ar7YNf!dXdce6q7rHgz20& z9T6eHq5j9R-aTba;&fY~ZXZSpWoXE&{Ddu%Pp&96XQWFMUZBDJr1?zecVb?Tfn6Rt zo2yLiTmHjU;HQ#~G%ys3cm*c&~28;tQpD&lzUuILdHH(r(-D zE1k3hBNjWPrEe?IA+EoDb$f`szos+L=tBxdD{gMDMUSz=8*ss<_ktC7su)6XrACS9l zGf+drq`%m*V1J5CBTeu`e1$Gj71GnIb(_qW)`c6Nx;4>H^1!@0YEW&7n4&7{7djSV z6AKTzj((usg(ovM_249C=r@!85F+NnaiQ!3PLJ?VNC8pAhw@kjc2)Q2ElLf`f>CjE zjSVSH)xKbBstgCyqK)j|j-+vH(=+GFF0cAGIjw;_M_ti9(!ga?LxEbKX)SHiuRV?5 zNHNlxD1LtO`C?*09GZvpMA;?zsi?D;0U&8kob1R`3=?~rLB9%SkH}L|eNIrMc!^Nt zc){!H{9M#&N}Q;hF%()_Ht|;VI%5c=#NQ&X81jxg8FXHuvgT0a$m^R)Wo(NbYBeqG zpsHw_bs;pCv{(K+XNd)PN<;$P)_>JvTR%-~4~Q>$cK0sT^U^Ai=^jb~odfH7r8vX} z<3bfUatL7O>>>mzx^*XkD=MUfax|wkzAGOvy8boK;(63`xt!moB-j`wn^s?Rbj{4K znGuHtBAuNgKhXyTHtEB$G^t|NCu^{8nF`+}x>E0(vnbViMJv+1kacw;-Ps_)-RoY2 zRC+G(UBPX$`2K9Mzf?}aP5rfv-+Yoy%x~ye@g+?^!%vA)!Ytmn0QqoP@B?}oD7blx zSxwAtz={+qnhh$$Ay&e|yufaQgx=&KnL=f<7@G{}rl^Voy#1#u@RHK{shI?3^%vRB z6GUmp)B1$xiioTnnqpC*hM$T#*#GQS!3?xk>Dsn@PN7} z&kRV|0W&s~RMj$G>e7&|vu`Gfp@=-=j|t7x6MxbE79&&F7ap#Plv8_s>LxKIvPcCM zHy*?AO+%HwGkT_)JLEc{d!VaUft`Z5jn?dtvlI8FsLIKsIFr~@ZDz*+2TiBrc;S?s zn?wUZ|K}!P6#vrxtPx}L=2TId7$c4)BjAa~l`0E7DL~o}YL(?uB5$$fxnRK0wE*B_ z&nS=SnO+UMHOwIwPK=2if{(lg7%|bMFBppk?n#OiHW5}p%ZoK2X|AN`pNK`FB5tQP zEuNERhf)pfy7{KZP)?o^eTc^NB_N*l;*K)q_8dcE4f#CxDl`S{8>+gvQ}z3!T$ytc z>)JDcZSrpK`cDQrrgLUzSEy*Qkp3AA$DixJ$w*o8lW)OnB1LKOc0W~t27n}I_S&=H zPw{N~0z7DnQ!mc^?On?R;;mz0u#c}3!NTIbqz-=Z-Z^0w)_vXlDxeG0OFTa1vAiSj z66dTvIqs`4))GmJ7^W9yBsf3Q)ZH!O2!ua+Oy=6cm}ma@(^ji~_;(;;H<^8pvr9_m zv;sr84Us(;D4_M9d3WmzG70Y!R?53~9D27g;cR95jM!?P+4tlbVk+1a{h=h{26BQ` zf_vVPi*D7LiXojf%l3(UX^_mX{2N3?qMx{{PdIp}spIvb8sX`~qqM^KY(SBrO7J_e zeN_P4d)l9$pFHfje1%uk1dAH1yXmAldbY)%#EWb<1Ch@<&11M;sF|iGOL{cbKZ++o z>+^7;1aU`8Hwz|wOLQ->Q;M;Sif!xrKp<4pw%=mUkQ&pKfY@k?7Y-6}rI_&IyxJNf zPS4rh#d8H>qmEuu=lyljyz@8u=YY?g^43(wXFxV!j_wwfJz;#=N;ym2*NFGU!BdQm zUgx49_hUY)nepj&Nh$lN0kmV!_?%>f>d`mrL9X$FWH<}(gqY9#iuB{u_({p z=P+;6Kc{}@Q9sz^trxw$fgYC0&628>1kv{^dVjs2jB;`?YxydtY9FkPU)3lyZ{>r% z5*F<4M90)nP9rWwH%Lu_|kF31(`&Zpcy`ryIXj<*u z*@qg`IhY#qAc^#Jn$f?Bwp%Z|`B-$@rTcEZ#fp6|BmWzIPFRAd3M+MUtB&2^9}A;vPR?E zM>|D?4k2rDoc&Xf%Lq(F2uehPe^p=<_$*Im%+Vi=9p02^p(h-4x$l*PQo47cP{_77 zdsFGs%6F<@XS)bc;8g-B(%zWpS zl}N*=xJk?NgU*P<&q;uofsc%SNRpkhxW06+b&iN270S z-ID~(%u1e#bc5s9=|PhEInB?+O$z6+tlr7&)COk^^NAi6Zfy zt7GL)*q10-4AC5TJ5!3gsy9Ag>sflvg7*~s+>GIaEGbp-bm(PNPJ4e~QB|0ag|3#av9%3@;CAZrmY-b58V8vV& zyk}NnNQ#CEn*Iyfupk$wxG3pqI%<5~M__JeqYFE`#j{%7sd!pL8yPltpor-cCdQ{5 zhm&BenFYK{vjFr-lj>`QBnjhD;)_A|r^1WB7H-`IUVr893+Xtx(Yg8SuBvKxuRi_H zo)}jZ`b^JMa7Qo?z@e?vOVOJ&64+;j2Vs%=-Qt?O&L_C4sHnTu`wQSal_188=K^=# z(|ah&^qVUpO0=jUi#dl}b)9ZHXGjqdx?=Dt{d80Ip;XyyY_9BR?vMPkwFC$Kyf_Ff zMqpp+!aMe~=9x55nWL8XCk@bYF4Y^pdea^vUGolT+jn5TVdV%V!WitPLJg&xYJNCq_wHDxJy z31e+tZz~AsfdC(J&?Y}Gzs(4VU7Z%ns5&QC;b#4A`)lwf|9~;GQ5iC}Ajph=&DJ>x z)PD*(+2gosiDY@sHxD*l82(-L<1G^*(E#;@a}-94;BM8mA^U^1rmDJks)l#E54C+9 zm)inDl|AG6DD}bkeq%73V^FVjcqGQsKaC$a!J>HTJPilmjtBiSUH;B}C&9?d`nW=v z1nv7UAivat7K%5tzd4aHlzJNR@cDA-M>N`RXm8b}jY<`scQlqj`i=FHjv)j>E9cl_ zAHK01888S4>B$i$reQt26!I%r$N41LO)b8c{G*_ZrLLb{t!uf+q1>*wr1F{)*xx;u zv6$^B5fHC00G{o?Xqwin@Q}d7ALpdV-GXDNSO5Yeu^52c9SliB$LN=IhyY!AzGmh_ z{V-|FCGTNjy?FnlNQTNt6d_(!d4!#_ag@?ejOe zIwMYJ&(_m5szof0Ctykd>%ht4J`b8F29blEWb$%aBT3^mJ9S|MGMWd zj_O#eOPr*hLF|@i#u{YwROu1!oV$@(_+q1xH7y94166 z*JSREn8x$~%J95@UCG6})DQu6YX#>4SO9C8MO<*lE$`Tj>PdQUQ z0^V*?pdVXZ6J;OS*p#4heJ4FM!gvOaB{>~<9=PH~FFMhR3<-X!Z6-(59-}L4r&Gtv zAq517=fOGTQKvDj=oW?if%mVL=KK{|o70L%y<@``yl2WSqsH4{wd7bLr4P>SxEc$D z$4#kHpn{l@y}qH;umIUNtshVa%PY~kPX}v%;zy#3hPVIgkdxRGqmY8WVNtYz9gdVP#p6=)w7 zJ^qlFj@Nzj)_}?BgL(qWb@TOTCL#%sY7hx*Z2t&9l+-U93v>nYz+8fl+iAFuq|coz zr5%&Q0$i>!#!w7V2OF|{X8d-#aXzid_}QrkG>N>gSB;jDOxRxIKf~7{k}21;qfGy> zBwGtS$ullrJ%LqqOeUV(-SU6dSTiWyGe#uFt%-eq(L%QmP*#!@?#}r_uKB!$4d;kf zMvlQl3QN4}8UyLsN3)5J4XB01#~2N+I1wGe?==b2B__XRzEY{mL&=-Eu9|{HW(2j4 zX%w4dOjqZ;5f)Ves9t#)wwot?T^gRl0ujd_0`!*s$icIjMM3SD@!U6^hg^8KybX+At_qi~2#mYox@_VQK zNcD_f6Mi#^SucOo;imb3mF`8fUd~sw@PCgjHp7Oj_g`E0k1U&p&uhm?zwxvAx*IPv z9yhnk3@EmLd=|+jfgTyu9_hVKfVDa!YjfOj)<241cdQx){_R+}H$3WVzeR4h|EQ=` zHi#b*>WUfRL3;fYJlTug>Y zbM^D%)MmCXI%LaC@xxTA$lj4A5K^2X^-Lz)hyj zx(B(}2BJL{W8E?vmg0B4G4^#jEe5F6?o1wl)zB*U$%~(SGKa#Q>GXysEh7Fb$x$E<)24Bsks7%{b`tL$H0;RaAE$=YqqiuF?q?K04!cAJu{+T!q1eh=*KcDQ zda_|P>ih1T14oSdA6GAkkIb+#zA`9~zKGz$;oagzD0*QFX?q87?I}7lIZMiKqWpp9 z8&n+SIOMqgVD-SYNP+aI0f{sypndPs|Lx-EjrDCm?|;&c#6NU!Z(BUJ-X1!*9~yrM z^}2EUL>AB3q;Nynm%QfVFw9$9+bH&lIocl--XKTuS)-m%Jc|6es%$OSRbn75r|>Vq zRjY5MN!9cB@h)L{+?WU-(!BCg8+SbO?u(|bpVSh>xGQ_SR>EnV;vVda^S5dxZ!LZ_ zec}RWupQ1@fzz!*s#8f41HR?)D-wuyKvxU10@=+SSW{*7Pu;~CMwO4X#^uz%rxOJ* zQJ(E1oO$&gA~i9LzA&x_J` z3u^G((;u^;#ox=WQj>edFUF^roD)_G(uloh5|Z*C+__tJl?B^%2BmcZrHmvMW((mG zvox}2peSV@A3 zgW<)ag~P#l;ZY*!v)sxf_BxfOA7zcGFfjoqazz5QgQT4Jaj4?jM3rQZl$IwmZMLv( zShv!B(1B*y6L8}P@lHok65uE}q-NI9S2s85l;mU&zTxh}e4da@t=YtREnxV_adM|G z?B}~JeX+RWJ#y$vE6SAXGx~L-pE@#*qt0h$EqG_{0ikWq2?j~1&Rvc^+$R_s3;47D z?4x)TQcr8LWAy0}&Ifp$$79@vGmur~Z?{*53hCdZZxmJ9HnaZznz~b@GrbB_z&Lnr zVI4+J)GxnnsS)kcP_ftK@1RHt;=L7dIyD%)V%vmV7>38nuIGPD#4TR%Xb)%%9Q9tr zAV}=#Zb91;5Bd)^^@_~okR&g(?da9QaIE3XN&nQ|SN<)`PM9pNtk7!EXp`vX(?mcy zq!fhvtctZMzI&7?cC6$#Yx~vo;naYf*7CxqgbCHv$DoH@nG@XTQ^URe_FJa`5 z;pes8QA*(l$AA-`XP=Y25IAJ-loei6QT*9(oAO7gKEZ;Qoc7v>1YDfQ&3qAg#^e{1 zM2>j^mJD$r+4>QKleQs*vwI4TW-&pzBTFfM7RC*@e2_42-8JF;+kH9@h*Pcs6f}sC zx0gxsK=mckwmc^q#2OECG#1K_Mj9J1OQ2tJQW@6FM8zLV&*49R+Mh`3uiSqN>FX9f zE-GsY)X8hVt`B>czS+|7?-d~yx^tK9QsNYGY2iE->Xr}^H}bDV4pFm8qPxee4=Equ z>?-br#&AacSh~U!202xAzGhUxOs7ZlmwZNE`%3G(j%ywmTx@=7e`~>_UG5GmvEJ*|}VCC0G*TfmTz~9X5)EVgl1WXXOzCXBRMtA3Efuh&^6QOUVVwGW z#TF)cyXXA%tmDyx50HwSNLBHLYfd$C7}1K-fL`Mpu8xl1bCqJK(0Rp1bHHmeKbXH7 z{z14$tXbd}x^ff{>y5kjo`b#I(a{}bzM-qaDiRY>%s@l9_OT_=wjR@rwFV+XePnJt$7{5Nar-BB9ttN$&uS1toEb{VsbhRqC?$^vD>nuNe!n5iW}b>pv*28vPQ z_DpaYd&fZbvuq)*T=p7@SAqj@c?kZuW@c+;RPf(X^YBQvu`UjZ#?00fWfv%F(&{ z|qY$OGhK#Lesdb%J*zXw9ElW3oJM6*nJp9+b%gLO#0YXc@cKVe5+q zUE~IKliE#}Z+rcowl(L}kk`rM4ABI78N?7#(8m==q0#fhnQ(ZCu%L-&b}hm4W|Ima zV*D78<3+yfcko?MK*5=d^-f^@H$$GFg*v}b*0+}vNCABe6cfl|y-)3@%1Wv&dORyV z_D_L=m!0OmU*K6P;olj7S6m0~Nh}@Rjiz3yNkpkJ{o*c;wc$VfVX;v>S7{m&zE`>` zA?L*Bm*fFsQPs2irnZ@4wYD2wu8*X%RlJCLg-(gr+feT0)B#Sn#C|H4)dW&WBSW8ia84_0Cs!oybp! z(;eC0OvY&Q#S*$;SxAy}*!8)cR8~1ruZ{XOI@G)}EW=D5Kl@g0jtEN5fOX4qk9vBV zAvWA;{^)VI57>-*XZYO-pI77Jngt&b=a4G{`(`{0OiT(1FbFcds-64RqJ)kANL@3UCh0kZb?FTE92~JI|4AMe6Ro2)-4i_L zF5t0&FUtT>k%dk{uc|+)yE(fVrkE1ab(&KVzEE9K^RZC~&7+TIL3;Z`LYGNn5q6!& z3nhm~92itx4}Wf;shv~^J%|!j**;^mu6n;DA(E(0_0<|egk=mNHS##EjNvlk2pACf ze9ga$pv+$&X8J4)y zP#` zO-tnO(OoUi$;T#MUweHOk>~T|8?D@$mjha=8Ob$waV1?^M;NL=l)K*nSpc;c&9==b z$Q&ebxEKrbXeJutp5g5Sr1~#$!Xr;)uBit^9~l4!xn;j>kL%`V87R8koU^igVkjBZ zNF^G(Pl^HY3LF{ly`vE>rW5H&9tqAI1Sg;S8uPyVP%@UU)<_T<+Vo~^cqWF2ML>-- z$uk>lE0kenTcHx?j?a zI2InZqBSF)u-s)+?>_{h`r;S4!0r|@nQ(=h656dG+rRlCAt_q!NThaX6M2bREQUi1 z(d-<3uc3WaU9=CI`*kdlMkb7}qH6bA?qtK^(vrWpxx`6pOTT?*+-V(wr*^OLG<1sM z{dFbRPxZdof2EgaisagVS;>kP72!q8D_P#ni*G8_;AFdTCTF@eMIR7)!W#>3&V0d| zbJo?ezFMqhp}!b6kgLtN-49e8|5X@9{aX`|X|o^;ND?}LeEm^yH$vc(N*dc~e)~Kz?^KV`#_2^!Mha%>vko?U{jh3%@3e9SS@+h=BY*gtSbM4 z=E|nzOb7)egzKa_YZ(?IwJzn;iI$z zAjPM^?0fEcf0(F})s@_9`*<$Cz3!!NCxxT8^A4}Eha=a;`htny(q23g*V!(QdUx#8)o&j2y?3Q7Wt_EuKec&+GR0QSvoo$^jh^rY*Ti>D zv!Z{YH>BBQI_T!_r?g301dMM=T2Qs!1@cJ#R;}4TujHQci3)LL##zMsxUv57(^u_D ziPEwEh1j+J9E+a`hCH!vB%b?Y4Xa-$p`(uj;KQtPLoBW?dldy?0NB4xD$Q0~+>b}CpMh@&)o&iG6QZ;8wC7B6YHBJS#@rIC{r%&{_RKb_{u3P)m z7=F}ejz}+Y2WFD-f&!kD-b5AH38{vzsZ=f(?zC_;O}Fzvix`1`ft&QJN^K6?B(NoG zi~`sPhI4&<@OvuQ3wd2s1-#xIvDQ=-M$~SjFtLMLus3UicD3?O(t;_*r23I*ajY)-^>7J*>%C;@MIeK9~creNv`g+p^c_$&h}Kw6A4rMfF&somZ0=rUBvF_U#c2 z`X}C#$*!3uh}_qE^T}Q1_DjslW0~)JthrBL zy=>dBd@?ndZ)zA~1`s$||JdBTswS(M)JRz=1{qV4cq#)6g-YT>Q^`v9v7$6IEa`85 z);U>2pw@>*$v}9RnDM?^L}N~g6PTEJ(6Lgf7#}UY3R>frjsdejUYgRqIooytMtTk z9Dw>CFd{5DWhploW*KHx`E$>}6Wk@pAB`;kceo`A$0Yh?QuUzNIw&QA%O!x8?nAC# z!%3(_p$52O!9qeqLxU*F^bRW@{VJ~CPuoqiy~32cqSKM1lCWbNaSVIc{jO)y?T2G5 zW|txzebk2^@y#{OU;!f&m47S$hNivBpQR^@>KtKA?M1s%J;-Is{9CMu zERqhERO{wGHD9jL_nJAkMWt-#XAWfDkj_$X8y!9;^AcDDfE9uoY)TC# zQ3THWz*J2Vr!}X1n1K2p*?aL+2jxK_i8R&rKQeBJVzi^soDeO)BV?0Z4NE*MBacY& zVooBw&#pB?zkVM#eSBqIaMqD;*?s-f!p3`V_C{x9W3eyfMsLa~>C_p>ree95uvqjF z&XF|+W{l<2Wd(Fy;~+3ZePm|~BUudNl$=>CBn7kslt;c4!n5`4iV@VzI!};1GOw{`^ZsG8V6!!h>t{S6dv9n2c?- zd_8we3zw({L}76V46VVMy%qD6H3egnxo2QqkVWr_wy zkZO-}bfVGsDD{#2LCMt2B94}v@7D$`faWz0;;+TJvT@>I&u!bKrbrfL}= zE@IiwM?`qz?6oB~!wDqcbbpH;yuUbAeQViQjhzfmYFNy@d0;8oA$u|0U|9bfDdPldUU5RAH0W z&@jPYyuMjD`k!zgA2Bh~4J}Ei>#QoqS3uE+6jKk?!#89JKOV0Ppf~L@Nhhx>szxGA zaSiLPi;@g-w>oHk7!urbtMdQMqSGZh|n)ts3iBe8V<)ldS7281c#D|Dy9ftjuAHN z72^SMQPA;~9)YM^lXGAsw@g7N9$X5rSE_NLY0g8I1bdg!m;b#7|0BYiRoH{K-`)gm zlp)udAKC56nwhPewhKBrLE5ysherH4&P%BL*VZD$SIcgeZ<|KY@n`K&FqmtVN#aU= zwJ-Su#B$hg+dd}yN1iw;FZ!A6^*F4X`Zs=eaHQ%ywICQqpt_44K5eAk^B72vn8Owd z1r50luV)>_9Tp8H8n5TOxp00` zMlwsHzSq)#D8S&#>&<-f*9*MtM-G9NCS>@tY!u2vk_HlQrF;~&V8Jd-qNMmY(Q?5a z+1`%?K;WPcKW@d%=V--5ZP*uQC=Tu4M(u?~R14aw8VrudkndMuxi4N27q zSe*+mc7VNb(S7LSauZG|D8Ta*2H+v5sh%DQ3!|@F^Yr+Sn1gK2)#%;(l2k#+_kbNH|Ko00)Kf6YK`QLYi5bpgo;a$ zy(K~j+By{)zGyIpz$Iwk(1b`V*8{JY^Z4-%^r9XD6Kz=nV3%!H;AYj?=*ZW7cec*GY|c(f-9vrBqmN$6 z_;HLdBILK1cPkd_E)b-4(B>{I*z}(2rwcK-DkpqQx*4xgm)wyxk)w1<~+dQ3-3`0WwF=3!+4yE5CfDNP}>Q}cc-{?R+XYiwY z30ug$#Oy)a0(3Eps%?vb z&5X)zkJ$nGZ4WMuG#mMwC|ump94v%Q2)JYi#q_mMl58e4$A&CkGttbFAqm+EOR-)o z5nwiHfHW+I%^34&z8WJ4;=WGC0@Y$;5TV!Jcuv$Z0>9D|Wybo<{39|GGc{!RZ24_( z=9yn}y4eE=(HjB{mBH5-m&#MEw!yZ>HbmB`0b0Ry_+9}QK`tQ|(tsM707-WA1Wt-1 z^V{Sw6h;(9Wv~xw`0NFZ1lkgi0Y71=4yiGCQzv?WF?m1&Y?~wtAyuwf_sWN&5=G0* zy!=x=4Duv(KfL!dc{V;eU36L>6`z7I;I=+<%{TR9aM5HcT-A3LfBP5e3IR`&YA4#} zkYWsy#tp_m(Gzf4h@8NIprd7vNaG+&q&tQ`{?*3?#i8_vPn;Vi3LD8on}p^Yut{0s z)!Ei#z2*iNR?6yc)Hof>S^IV(l*nz~$B(9+B?yihhH@Y5aBrd2HQ1tuciUmx?~GNi z(#eVBNpcHa)j~Q=m!4{nI8HVSx})DHb#BS;kGy_h{Sy9ZPvVK2^Hn!95-qadmxIDF z_G&PglnxsoE!yB~ax-eJUQ8%k?I$7#!>bsSZ!^(epuIvnNa@L_;M@(I@ObZgkNpF~ z-sH`VEhJoaloU#y9vAB04`Vt;@q#}A3D2=pO+XJ|p(yk_glD&Tj_J%#F7TS4aM$eL|+Cu?Q{ z5u57({(#Tb%77&1^1bmx9{VHZzHSNg0zEHcjx{q~22zZiT(i08IG_UdfV|2HY`n)e z^QB7=pHwskt@GbdL36JlH&Tsl4&$ZMNb1b{nn{6BZuuls>GQwV4^&-3eE!k;Jj>w#+{hQRgH-UBfd*3xmaO8K*tPyIf-k{tUT!iG?2m9#jPVtRIi*5)jCk3aY ztMSh}XjYaT9scSFL_Yb|g~rREg(#q&CP?4XHpzDXL9u0hGGxP&Tsx|=O|OK<@=Z}O zRjzq9MegX;iS-MaHH=Q`>Q~ufZaI?_W`Yn>0LEFiN~Z-=f~4T!b5sVyFRq!gE7H+D zB>h4!h(pCFVyB}R-1Ie7m2mrdgfh-|++t#-VX(g7+PCz)?V~ zEK$M=(IPG^j8+=6H!&Y7BRV14x-^HJk*6i>4`~ zdVTIl10x=G9^@b~`8=Ks6Z>uorl{SCwBTG9_b#ZL_T`VMe$9(^G+h3SqR{9y=xd2!y&dJ72*}q z^1Cy|YTTIP3TS|Dddt;*-MxMIpR6E!(uD6lHDvMku5JT&VVfGBbEVhys7nMOlO ziE({MrT%FFd(G|1CbI#4%q2oGf&nQ_LzMk|co%b-Rdk0z3%p~UCI;A=G; zah8&}1EknaMnAdNecO95oij1(?(Yd7n@jv0NgOxmLy{@KvAUg}A$`snM4o*hKgLkg zmmN1!VcDHi;7g85Cr&BOEq#y1w9(v;%97iQ49kz}BElLoaBPS_tRvHI#FS}QD$30@ zFSDP0Zpz4sAfHd*N?Y$bT0o=k>5lv@ylOu13hj_x<@-76rI$Q=>)2uy)tbRpMI$9X zcmho4LX|tT{70QeW72N@`$^IU0!z{gj6tS7LNF|6$p7SRhZJXoZQ-ZXWtt_(aSe@Z zY*8kmc#{Hw_PF$AQE9eb;4Ovn~mrpPO&f{lY}Uk3yoV&NYajH#y7OhAcg|rkF@1Oz|4KFR7{lH zc>s4m^5~%GrQ6ugaM7$Ln_Z1cYK;1y9fniTw+M_YDX9-%ISjO&r3GWBri;u}=@3p#M(uMrgiSTF|}jt_z4tN(_NctRPd zCf$&%yGq2A$FYdX@fqm)kBJZKl?f%^(7T;(#6JnEg{ADcv=&SlB=2C&TXZq zrno?Mkuql8i$|y^{WX z5hjpWf&IH|{rC9MyY|8-n--A)_)NEvGi0WhGMtMux#a6T)i3ONf4o&=ud&5KuP*<0 zJVa%@kL1n}qNMgOQ_FOt1$4@Xa<%yLBYdpxswKJaHUk*Ws3uEh$K?*JH_qXywf|$! zz*Kj`M0sF@)yqr%)t3`&D~!(>iI{@Y;-D~_w#(OpsL7_~dZ@2ai#B1R2-!4 z{{uVGw2O{GLqdzE9tZiR5WQ4c?7abL?X@IZNU0+ApykJ`kn>kSuiRgTS$ zBBZN?O%#N4%hJB_)clkvFR#4Nt>zCJWaFPi9kRL|kC< z$MV(1p%liHR4gy|CSpDTmI!R*<|g0`cXU17?G7l1EL-c1Ri^bKStzZqFqnVq+Pg_7 zze}7}gnbQ}7gCij1~z|HTjup=z!dQcKyx8KO#Lrk0w!S4nch!Ze-IR`iBz~Jpr-vy{8WMkdQ zQN}UzPc=V^9EA9vK1eU&_)UgA3JcG#8d!uTY&~U@i$Wqu=PzyIk?HpR#E!9!RYKS% z`Vw{4$%tqn3q_n@UGQ&A9OY?^_Jq)sh}Z}@$|+v4=@}s!QM2mhtOu9cp^?sk{hlT9 z5mc|R4e%Y!<;pt=>kY7%`QRuJ!_-g;WWOOb`1Q(1d;S@o5PIy26%%SGie4R`R45u3 z*{aO8NJ9j{p+g4?WF;lSb|c8WA~!E4!f@A(hw}$_^&?8# zc<2qDWL}C!Sh(vteQ&V&8)7_1$;Q$Sy;PZkgP|e2s1J|MHhXSBuLa{XcA!(BaV2UF z#U1)m72sTGxs{~Uj+AIrM70)tpd{QLMLD(@+LF=gtmh_@R zQXoF6;5=vJ>w*gvEuLJ9S7;^%gSv&CgSg4Kz;?*SoD0YFQ02m{oiKquRR}Al+JDg< z|FMXX9w=tYynVmaKDoh)D^0Q27Mw)Xf4^tv~_Bs?jGF^3b|;5{MPzAPetf@Nmvh5 z_B3vDJx%`qv3Ay9P5yt}mz;#7Lmc4%fsta32H9wVDUEbWj_&SG2_=VgNq2*wv>+{A z(%o@ipYy%{f%}~M*PUHEyXqaU=kxh^QENswvh57CZ}*GOJ=|K7m}t;jHz;x`2)MlZ zq1{TZEfT?nJBVP0-4}8fZ*SId{Z@f&S~6ZV#!$;5G)CNrKq$w@OAn^@zC&CNYU>lc zWXP`=xV-xRJsF4#rbs7oc5kYa*-D&XW{SqyAEqSsl8J#Ya;if`LopFtzjw%p{;ty= zB#!Lv>D_-V?3*)svT@^xt*2W6KX@MX5a;s>8ZEs988(1xOpUm+b)QcSshi=PPCxn5D0saYI+F>C(Q$RGIB|5 z)D#13`f+hO>>auH3I)K9Prh>#UorM{P$*az4O1RO^|BBxGyO6!JFO3{PF&IFAVI+O z^_CKDM$Z*g*fE=xArzP+=}DTf;JT(Sh7YFJaTrH7x(wFx&E-q8Lm{yWIkRRuT$txXY#3sqmdVcBk1R|Z`n_uQi^3F-SiAKAmkmzV7964R zz)-mQmyb+;T2N@DN4>b+;^_*Bx#^qcYFuX6%6nqO_Gf+c^jPZEx`{4Z6}TGO0%&${+2*hwi2)b(Zmsf2+c<};H%(-))SKXx@zNs}Ine=s?kUrN<%PDKAK*scGq#Sr24i{yE|3sb+g zI1@|SpI;BhxkYq-UDT@H6Rxt0XFnz#HZY#`Xd!HU5stfcKFv$;JXwmSbd3QhG7guk zkJ&=X4e|jcbhlQ%XaD2nRv*8AAG+Pd>sB%_fa|up`_sV@axKqo)-uHS>-Bxjt(RiF zGOt$et_(FK|I+ub`>!;7C&+|E_QHA(zva{Cg(3^2D`U|u2@siFG;ziCzk!g zL5^G>dfwX7t3k|JsJv!gtzh@n<}5Cz7|}L<#0v7y&U|kiRM;EqSK@-b{3~ieq@P*? z!bE3)n8zzmUG0O2e6VdxYQT#fr9i@#j*!psQ+FG#~@i(ptP__g1LTwcN~k>Q`O zeB;2QdL&2^9q{mc>*tw!e15ltYA@>kv{ofVuBY>o$$=6IQ8BCtB+>H6^x`{bW{%bt zqq7)24Zk!tKFh=uT<8yVKVM*7%L;qo5F&u=Qp^F04IIo7tQjUM6FW2RA5_6V*tv7{ zv(1(mb?nPKTarp{@|l8ilL*qBcM8VL&C8%$-$qt68OH2F5zO|Gn^Z!L{!R4dZ&W<)NP`HI&P>TK4b*B$nhRw9&zfv`H!uD}i&TTsUv?_Ss;4F%-@~C5?_};|7%Gkn_tjZ5u2dQkA%-J`u<308kRiZit8ZI%jC2m$=9@q6b=+i;eOgqz*KVv9 zJa3LziWHMy>8tt4!?QhvKfsC?bwvQWNFs4NIa z#Pnr(l1Ev2<1@YTnT0V9O8I!indW3DZq+uN20RDzkJyq<@7o;1Yt&nHlAf|S>=1<) z)IYOyX;aKp;i}?&RqMLH>D>1`vSXYY7dwAbvJs%nHYDk_g|-yYjG6*EUpqNb@xKsCL9#hyx5I$?eP z=1;dgtOeUY+4kqzgl(%HQoptALALatUpi(RA9J{$+P9>?w@n{_7H2r|N~-wy zFXNa2^hGwJyJYwfv zPU^Wvn6g^lgm>!cVxcX_c9@Lihy1de*FwcS!XZ0GT7 z*K-rjqvE0(YbbhQ#w@e3H2QOm`UEP+@(|KWE?+DR_%Lpfr<-r^5W7B>_c+UEWm|uT z7cAw6vuBGOu20QSrm7h^v(ND)K|Y_zP;i54Iu=3j#ve(mn3`T+&JVX1f+~-PKB>Cp zSlS4Hy$7fXN;@#G^DpT|MC&u@x8GaoZ4@=WFb_-iQndV>Z6B!hM(9D4hF}=IBwtbR zKnCKE+|kO8!`>?`R&3R)rT5m1mF5JdF-RqG#(uEd4mB#R2oh4wx^L2tyQHxp6moj9 z{mXAptkS~rHmgxVVMIgS3F z5+%2t!tH;21dM0J(qjB&3uXZ?ANJ1(GK=d!0nL!i^`ES5HfyFv zo1hwsD%I-M;;jxl-jfMP>-CkjEyLFWt{2~k==Bh(HtksVGMtn>$oZV}0iRq`kAKFz$NK5lPThPZgJCAC$?>+D=!jqe?pPiDAMj=E z45-`1OXagvg)1+GNO-gUu4MBk^+}hHHS@R z7_=71rvDl?rGMs2=Mpuzevw=nO^|9SU=zRFGMNX6?%ByKQ#3FLQwncG^oJA&th&or zuD_7!(o{;N#X>t1{UXk`uMf}iE^EE)l;fOiXRp60CWHsY{Bw0voH&aCCcaKn8Y-tG zk_UI~CnDQoBl|j6mpRt0Eij|vo6(A@1x{b{4JO$;zlH!64i2#m&5kj<`3yy%*abvq zzIy1W1Z1PUC;Mx8J52Aj-%_Hcb-3=^Uuz=nZNsF3Qa@-bJ#OJ)r}oh=BU!_V`OOJA zIqGShq@WkFJf{ZtfxQ2=d@A%RGphh*!f><)Y^1JGzZvHMf9#DF2b~t`F<%k*i(d|? z`Oaf|rqUjn<&17l*mjO760A)k`&nys`+TBPLW%zJv|#0cdUhzlT~i)kocX8#@V#3G z9jk%LewAMM#AvdI;hgi_HlqYEN9x-#6%!T7%i}j|f=)fM? znVs&ho2ciqhGI&&KB6lDeMf~Dcs2L%fcZ(PkhD}N#2T=5%)iw((VyK;iwjz53xDbH z&}MLA8OI5dM&hZ!9P!%yy_?AHLO@7S6cl`*QoOuCzd;Nt-4^ zzW>0xOT}QH&nGBapxWSF*O3m{!b%1oFsbU~2fs zbKmA&?X*L7q1CK6-{qM~hk6txJ1(4Fct!kUKDheBvB%ib@|-z*zYOQ4doPi zp3)IV@FQNv;$7ZqwspcE&2{)qunq($Cq5@7`IwI!3fRw4i%aLNn*k(=Qy2$zcmO-= z>=7oXvaF}svsAYCl%2K>%QgD4>D+VIB^YnbFOnuL|7&UDcSZLf)CulU|AJ9L;ESkv^fX|^&rRCVq6XcP^5V^oO{pOx=GWJ+oKAdla zVl`a4Lk@(YnJ>tRn99WVg|*%+U|rxJo5}zE1fW(R1Q52Mwm@MX>d9pqnD+Glq1|1S8A;$cvvq#WM} zr3bk%j8{1tqMLV)U(bdgINtqC(uQXRbU*A0gEHgU9P^v3i2}8-Mf)H;m$F2eFdX{H zli_4+C%qUnDN=H}=HHP~gRfV*OTeha@|4cY#odiQNN>*aBB>FrZVELDK~?P5ulHX} zt4gKgpd5`{GQ(wXPbR6fE|kuG^Z`keDqU!BR-O{LOk?Fi83#uVy?ySp-~Yo zSQ81jW`b*EfTvWYk7}Rsc}sD+KO?2 zdr=J?VDA^_0)!k_?(|@Gda9@(MDyarwgOkBTJp;AW5G#^@K92po@DplJSJ~IuYpQD~#QM*WOaS~C3_Jw0AL0BREfozy;JTEn zVG0GOwYrHb+Th73`v7~1ZUS*JaI>wHfA&z0G<9@JiAShmW{MYbVxLYd4(+8@4%7-a(0>u(;OUe(+-3^<(6 zVHo4A$9X;KnZo(*gQwkC!1J^B%nBz5?W1UPEwbKOVr*4i*SpFZ1}SS`Qd zHP;hiC?-@`KC`&~QvXxzaw-pJfbL?SX^>k`uA_eF{t_0<@Vnizp4Sw|p_sLN7$MOj*i*Kg7derslz zgE>DHVq*-}I6U-fgF15a%b! zoJJNEkm ziiHVVOyY-QNonQC@1j#8nY47fwOZt~IDajQk}-%*-(`|Mx!+$BV?1+&jJSoOl?kMf z)HAwry`Vx4SJ3w%GKGT`W}4$ zMAp^AJi~VLC2}TZA3TSjd`va_ml4>yzC>jj6Au(i{xJp=+E286VyEoSucZddP|p2u z9!4)NA2KxUW-o}|;Q+izJr(K7#V860jV8IZDQ&2X+=8$?w@w%~L^mWs%Qw(@zT ze2<^a*lu^A5UD%_v>S6ph9OB=a4Z?#FF*tJ)ikq@;`x3X&%o@|ZTg+<#e=WCSxQ)` zQ7Um^K$H%EFJ<@gnS)7fR)oV}lHN$)7e}qhDc0OkA8T{xXxkTi9OgJ+HL>iKUjgu= zM3#r7KD7BR=rNJd62%D{GSudrUAxx{|B)3q_+&fidQrS*-~(Bl2BHuo_=wl!_vUZ0 zj;;AmG2+J2Q(w4YMm->uJM79QD8MD<1qnCA+`W>O_KV;UItxg{9S6AG5ne}9K!uG_ zc}a&rx$D2t6*`;jaLV<9?C?Ie`gGp3HDFCh!8rRVhadUhCLOHqCvu?5@rW#q=I%4E zKanuZM<*&(uBTBouAi%QA;$g^#SqZYXZD*Mp*ABZQLo>8UTGj%`U`tH&jGm)%2#h? zmnFn-k>%=)JCWUnnKH-k(XqLCb43L)y{mJ~#JAyV4g*6t3(`M8_rl0O;e1-2S#Jc` zsZVnKHDUIjeq^&zIROp>&Q9fiVJJ2$PSlcrota zdc^^KhWEqL%7d)5qlEo*1iOc>PhYRUy#$bIz3laD8I>Mwy-{uLh{O?PErIu89-N{$OmQ^4sWTq^us8ywWKk(}0)DMX>QYL@?A`LjB zIqba{w)973c7Djo!yt!_=^fgD`No|GOSX+^WP!zb6nIaRKxzMWeFApXjie0m`YGS1*jQkQV7`Bm~LRYY``s8K3gPe+B=XwfWlap&(HT0-*IS?->mRcn*4 z8$uqp#7M;y7xIdVFkYHY=G_VvMSn4?tc9sIfkU|3ey1%k?kHIgOzsYz;S$7nm z7w0WsX8m$te~w-j1%z%b=ckcr!N6>}^0X7XNAmnoL2^~x!Xn)3Gj{e6vmI$z@QV1X zGBZ&|*K=_mG(;seIGhF}il&A@Ua+cSA-I_%3lfC&uf0%o(SkA$ANsEqT6y^I3g`KM z3D9EkW+P08(DG2Gil0bPbE7|opSq@qGve3p(DnsN&g%5M?X3;PdA01jTLf3;LdUAM z^yy|#(GcmrNjB{ElTK+Yqg5X56Ta8hHuJK4d4XpN*-WDVD)!>Dh#VrCN73(Gou7K} zs!*G#!Tb10fUEQzH|Gde&wWM07Z4=AX#et1AR?5D9ioSu5RRla*gS-=;2I{{Y*K}X z=r)<(U6Pp;>Lm+4iF46qM(@Ax}(2!2`HL3P=la$m}GCY5%;>f7&l> z?BxDZsK>fyPe&?aU1VLtJO&Pfw$zxg5@WCNq@1L`9MCB?^yz#pgOMfZ6!K;z1&6ZE zfAg5LtRnqx?~ z|2Mk;ok+y_(lG>;zw7kSy-w)0s5E2*HmVFcxZi`D(&~R34ZvzkpOl@M9V5_ldpoIP z1)J9>)p*bgtgWD-^LCG@i1C8e3htzQU00-sbv7%iuJ`|rMbcGl-ITiFg<3u(&;m@a zej`(7^RH(nqJuoTc~cySFG>^0sGG|gbZf53*`W4PWjb8u*Wtkl^+p{6?Lj%o6mzms zSFFQbl{GVh6iI|n9^(&12Ye6?kpLDT?XTSqXyquueCeEUUkGrcJJtreLMJ#S`Vbfp zWwH$M=LXm6vY69c>q2NYT$$K--iQS;tsx)m$FS7*5YyS-l1|id^QDB94u#)txA>Nf zptp61c{qCm`${0I_fx^a2zf+;_5>>0EyG;EQaHUbc>ff_-x11XS&(F2?X68n2>nhB^}JdVpFCf~T2RZ)@VIDaCe}G~-ii|D zv{Gr#`d1Icaa8=5HZ0$xKH&2z9rS&LjVukop!v+!Y! zwqW?Y@}*S$rK5HaUK}4lf?W;_8FXfp-`u@NQKll3R9PwrApkn!=0*g&5`n<1?aalQ z=;Cc~wZ<)n7T)GtpZxPUYc=y*LH*V6nwyW=E$v3h(-#QQV6`AMM zSTlw^ojnuKAOX9l_nA-EnQTM?*K~lRAT21O^FQKaZFm2weN2{0uO$Gg;e8qyaR42% zx&};U_(_7`c6(xCi13hm&ZFDXprEa`mWdVNYVYHP+d6YEs@i8A4`#Y`o$fLgDpyRC zUTqq68=UHP6PD0`8b7)v{;_x5%k}SA^9$(GqOwLe&=8IKcnpC~Oc?5$c@>L}OMgr} zqpfDhQt21bwJ0~y|M%2C0`G_1jxtFrT!1_T|JStCfcT|_UfRu?U6_G|I#&zrpYi`3z11Q zam@1bYht1Q`*HMtp&Oh0*1TfuZmQ|_4nF_<#T9ww(})LvU`E8!>Ge9Uo^ca311wNiD*4lpv97 z9V#%7DqoTP0!x2Lb%=4pjP2ACkRYP{KHDk}3Gn(}VcVo94CZ;q=kAMUS4K=6F^Tr` zof11ggmCpBiqk=0MO%?wx3No)@|v02{N4ZV2b5NIWB-tcVcS|wzppv8m_%t<|9VlM z1BLb|cS)%^m+bWk-ZfM8nNOxk(t7qF1kI&pX-N~Q>mS-)5%>}6F}0KIbYt#;8~hX! zQC((~_IFE!e>ZOJgk zOOl`ssbGa~b|AM?Y*fFVKJ01lFt7?!Mhq>#`>r=!@rkOzQfR*mhlUkmNfF85-xrEO z(v2P_yC#wGd3w|`3>G_h?E!Hl#O{JU6U^!)9%0!MqEHFolWUa_qY+^i+NSbX_mYQA zjLd@Tu-%^xL`)Ma0-Ltr@P{lhSfHp!dkxlq_n7Jl?r7-M`)jmf)27_*VryJ11q7vH zY7kGm#E0!_KH`89Y7nAb9Y)Vd4KSZg8|xMzG$M-rNBtId--91AA3v-5F&Mb~db;in zHyJ>G;_oz%3$q;_x)jjl1w*;!oNZ=lh*T4mYtFsCmr|u)2#CGupULY*_2DviiN|OF z6ns+OyR-8JPQ^ZGr0UY*oPWi*#{=h}rPovCY%l+;vHSa$*7=gg1(u)Zv8mz3Q~Wn3 z3IDWsi!L$O;id>R*A5Evl3~_rb1rW7{<}UTUi_CiIyCx8x{yV}fWYRbb8|7Vq)d-j zaCpAHO4jBf)FXdu3Z)5kit$~1I|7YLLVK10iBIsyiL<5}uL}=eYF}CsaeAs+grD`U z!##c9*kj#j%eoRh)3>9`IKBS&V)n0L{WEl-vrQp1P~v~Wv(B%DlJ&XBA|}4E#FGUx z^1=eXz8(>A?!d4t_LI4t_^vuIM^J;chB`~RnWq?Tbp=Q)T1EpYf_S7;%mv6YIl=rD zebC@=l1eYwXu-g2E-U!FZ+8Cta7B6)^c@?LCdmie=V88%eBka!PA|ks5lewvhs4DC zJ;j!0fqLum_Sa0mhp4NUfU`=nxsGz!#gLAthe6 zaS1_0QmZBwZv21=;~Vb+^AA}mYVV!lN1#*<71Uc+N-App4spI1be4vBjqUik*wY{H z0>czudR`hk7XgJJ#eY#0uf8QnzI4e_F-G|XQoFf{yv;g(VujNl)3f`gQfvdIS-+o~ zfFuG@p-%LHS!m5b$|MK5LPCXaQ^8F~r#U}$)n)3FF6}%B?}G#<$y5hIXW8tfPMTAZ z{<;K#ie!w4`o^xv>^{^;tr!tl@hPo*52iPwpgAn`rDs}K|I$P_4|HFm!;Z6`hmfRp z!0S|OE@We}u}P(JlPn^aCGH)!*;_VVqCxtQ`OwavZ|$-jrk+EaOd<8=K-TDD5o`^) z5WQ+kq9|PJuYADp3eJfBYQ(g)uqS@9ytE33p9XlOY8VG*N0mjD&%QW7_*W#dr*Q!b ztUPUnEW6nHkU|DzjQPg^ZZaZUrP_0Pi%#=gcFb|{r&$NDLYd7If~J&ulA#sg^d4OG zKrNMeC2AQC{UVUT0Sa7jGvmeE%-ucsNNx0cR9&stD_VH1zKSmH_gTMUzA+>eM}~8` zKzJ}jzeq-+&Ws_59B);){q=Wq?$LV0er501xe%5_;tZx<306pB3H6eAOK+00XQfFL zmoV$U4adX!*AN6)`v(pxGX@i;z>c}Esc+u~I=8Sq6E$eM)q&fP9^<|n&YlC%Isa{7 z@K!1e-mF&ly2yfhbJ^-9XL0@}2cT?=efqy6NXIY z8C~oB&;P%?(42}j5H6s>4>EnX?w51k@ z#ZO}G#huw)?4+5_ABf_t%w-8~jkke~}2f2W^xVs}S~K2QP}(w}aC z=+xzv{ngSy=Pzx-;XSlcF=mg$ko{kk4VA?`!!%i1@elr(F7MC1IpSjOQ08l%Rj>t8 zD@}tpz;aGbqCWrM(?a)J?ooXK-k);@Bi7s%=3xN|IQhI4QFuLm@j)30)c-+!t?!1C zIG9|%dfk3WWYGY{q0K#n7}Q=oXl&<~=2*tE*|wu(9@TFu$^qKUR1Mk(2j~J^qs?#N zAi+4siYNycDCP>QR^Vxb%w=0d1RqQvjzR!FH+B`4O_6xo)_H{mt30!m7DB>EPEk&6 z(93_^e3chCfVMb2;FD~EH$ZQyZ!#}AejyI=-)cveTXPC~|0&7Dd&_IemIRI}o{o$)Dj{V~X# zk_<_{vj8L2GqmwA^iNwNlOh3c3iEY-!ztXocXqG}50Rpa)8D$1782`kudIO%0TNiO z|L76aH;vsLN)+>K6ZxJ6F#rCjOA(hCy|AdtbZ6Xq=ekjh2=H~qS$v~_IovkAePmkx zf~fAr@Y`X=AdJ?JR|!Z;fq(W&gs@Ja*?>n}Bn#9`0;s&8^Ci+B>+dCsPRT;dt1s~> z@Zp87a|UNGTW*t6NCGVgu{GX+p~Nbl%BMcIKJ+=`=Kj`YuCBqfAa_M>J;#v5W2_wF zHQe+*JO-01r!i5RUni(qkty#lg$FNHs&}*g8=|ZDR5(##!W4w(46U6ALZEv~q%Gi} zR}bx2dYbJrZ~k50VJs3#Yj9I5uwkjtDY49?c~NuS!2cl*U78c8kvem#2|f$dWD+cptHXP&^@8Dztg`HF49%WazUl$Z#&LGRS{B87M-7->+7m z5{4|yVaV{(rI(kVOiTB^fr^fZHg@}sQ>woFKJ?S>0Nf-@S(6hXy(*mc@)tZ%AE9f) zLYZoA9FPj5#s!{f#4>0Ag(rcTH%|2b)jkR(#QQ~|@W4)~*WsUN0Z`~&NOPgGq>i+@eU0k{H3=3^3X;{yg5q(%i)3WuWbGXaQYRL`{ECK3JIQkM zPJD#V=+If)kKZ7Sv;^BrKe3l;=cSE*T5JT{UzeVgS^+m^2o#Pbn4pvpHkoC_>J83Z zFi57U-mPhl!?8m{AnqgDoSm}#(1)x9c!X@uf9Xn-=*CkXH@Jjeknu+TO(Hzum6G;s6!e~=<4Ow3P_ z0lF699#TB(aP=c#8Wjhu?*Pf>2|Fsp!Ixcg?$;bME9mx}9bh4ibz-aYxPCN+*CWsj z41HL_u%>Aza4bS@1ofGZ#6 zBX8$@#vYD6&;CgH*WN=J0IVovNALblA^POo@ ziABu6cl7cuVfQz1qmP~AWhTPi-l#12+mPm#+&IXrKm$a{x|gK~bb*&Jj}fzp2@2@@ zgg%-Wk{#x6dM(DbT3`Aw;XWdbh{;>Z=n=ecM(k^)%m;dWDk8A?z3;9=>Fh>IaVw-8fG17wG8eDIMEb51ZgQUoX?@8I2-!{-{uTZ zGqQtq^{I(s_(W#2K2jV?aCV0BkrGG;KHsmZR;qj#le6(Nuq#Kgbfch!BsjomK~39@ z;;{i= zDp({0-lBrZBHjqW!5IKgERH~G+-BZ;Z_t5ZiAku8acsZL4kFy~ngh93o>%qu_!T^>~PXj@i__{ zJ*$jOk1EdIIN!tx@nEF__9^Pz%+}|89xW7J3At_m)MVf0%fWrEec^CL35cq6grH$C z);acPmQB_7>~K>F$mU;VMann!3L?D5^JC6moI@c&3XV4#Fv@1uH}*_WjPm>6ucK$~ z)8Hegy1mck);1rJY{6rRPKIQnxK#LFYVA5f_#>b#T)#hdf}#mT*3$=1n}3m{_7&3O zf@%aMq8{!PUvhR1*-sU5S;OVHD#Odhg@uCe?>PqmC9h)=x%ou#Z<7id z;q(~!*z$!7H59VhNP<54E4J{f`y_w@Hzyv}I0XWwnge+K^OH3FiwWOIE=;9#bpMx% zSR{4aF)8xP-FKeMI$$>eYcwa23JT!b8ittR_A19Iiz-VW5!kcEJ8a<8g8ca zJg_+B@?mD2cakGHC2(gV(c$e(_RVMjbS*)=+%YFN2bL(9_ zTO9InwL_d#u`aXW;_9g10$C1;#TIvhs0~$EkRS;e%6KieqO}1cK>T@S@gH%xUu$!8 zf*?sM8iA5B-T-VS>{sqm^P5yi zeQxE+q-CPHuah0LnCk61X_I$Qelr@Z2uj@Wg$ggZBT z-Wtc5rMe~S@{-Atg06UAUfi{L9OG{2QRStPGqKbq$O9QY< z;Pth6v$p!NzvN8c!HJg9SfrT3NwD5KCT#2^-PjYA?QIl-!cUj&5vMdUj{cUkjRLZ8 z4z#H37qJC(OQV2d>}u=u%GA!RH(XfG9}~h-2__kM)Uzhk{lLgAk^N;4#NEZf{DXv9NM9FAsgPIctyD>pCo zQB!Bg(F3G7va78sCl0^-XD@%{;TVIoy{*s>>zZoz)d*ptQkrQGxdXM1}Ld z><>H#heY0G?F)n7-r8CAQ!y|dGq90QIYXw;i|=EJ>Pz0d_-=g(9otBm0SMr(%A#4y za9+gezm$@R^U7TRxH!pG*-d*~FeuF9vtVDkTYTKcVkg#)KXX&k<_vV{fitI=mb%iY z!?EZ7BfWsZeKzAPWz2}BfV5T-D|wok;nG{XfD3B5HfC7U6W9^UzP|&H6J5PtpkLBT z)=&U>4^2w%^OHx#H%YJwMaItI1Q|PpZ8wrkTUp zepX-(BXXkybd!Z*$m(1Pe^mh;dD=YWkSKakc(AVYI(+k$>$g;$E?wuo4Zdb9SUFTq z($nwKh|TkzV^Z+@2WV{;1#W#~Cbx%YV{)cOe}CPbJevvylVc+nBEIqVUt=F9&uGmD zCO2XC6>>2f=|%rWi1rmaQG_AK_cY5IK}1yGldEQLDv%t*mL@sKyXo6J&(;uGc`4gW zAXnxK?w`k|{iBHjF#wgIoc;Xy06QiW2;Y7KFTqDpXh=a}yZNtaASu#2ocPtdqM`>R zGI?MwWGn~6mS0u9=-IBK8Bo9aYDT5}rgmp>r82WEndL&exXaC=eGC^@cKqp06GNNL zR(nhM?Bc~}b!}qe9d%9HN_#KwNfY)>tBe%>bfR08R@s&yrukL!D~vKo_I_KpfY3J{ zh3eUj1RO?EoM-_}Kzc>%ld)={gn!Er5=SSL2)s}$57oF)r+O3PC1=ZR;7TEu z3OVkBvGp95-%fq0j{GS0C(Debv(((hyAa9zr((|^mB&bx0H-PFhunOZe@ zhA*sIsuvQ;57TwoYX)+S3yeWQM#A;#)-lZrK5*%_j=^6oac;%T*@xPyiuZqeL35ZU z7I=etM?*r+x@lYc&7(zz4(%!=Vu@ZW?Cmy-`>njCz7Tni0+)Lz^y)9N9m!15#XjS> z|6c5DrF+xMlwb)+X0$$zYanMItGzqz%#hgCtqASrsiY=B08GK)Bj0%}WZa4ERzXgp z!IRK(WbZWCR36uefSr>n2KY&Fk8dR+^Tv3QURcXZ^zVLleIWgU`P~2>zocm_(tfL% zvH3---L=}xpx5G7mn`)zZ?d2cr3Tjk3Md-F!R-8_2M$Ft#&x}o%3EyS>BKF2%{#&_ ze};gpS+$RvH_iJqqT7e6uccH4!0tD4T<$@2J%@nCTPmDpoBIPb#}@aSfjE`D zaPL_nP~EQ17itb2R`Pad$?ffk+kO?T!c?}$>AbV+Yh`5|TDJ5H`QdZp3ClI=9EHT} zpOfui{W5UQVh?XXX=W7v)!Y-wqE+vEo1~-eoUYm=P1|>n6>vLBE9IO{WspWeB;3X$ z?L>8IMl-r&WK6|~Q0zA9fzIUrSs!hl$s=Psj5Ww&jnrKaFj%TEqWx1_vZ#wihB|Sb z6iM$DsVex$eT;=ThqYLt63MV;kdi_Cwheh9w!_$J&W*>`8G%=hJ@h>%8+)MYi_2dd8VZtER zDJgaHn9&%Vuq@QbW7BVQ?~_Om?L=$;w!5j-8vJ+aoHWsx{OG5x{MjHKhjxs3hEsIY zqQ)PANpq3YeR}DzF(G**n86L%uPWePmb(FONjbj-*!%$Z2;8!4$JM{pH{0=o_q)B6soi^Jd2u5Z~)p@T`+AKX?htS7Y#Z#n6+(AsS5q`*8IZn!6zUX z!uaOP^}ffnsDGTQJBfkxhjEmrPf|_()0^hr??rK#N)r>87??cLWMlAGB?$*l4Pgp5 z_Tbjj#$)6?k(E&`4N-n2wJ4`;N}TgJ&5hV}gV!Y`{DA+&@O7uJQAZegt&fVB>a>=L z*o4ompa?h7nYKnA z#fY0ppGjGo;HuNmG z-xfeZckVyGu;Y#n_&WKH1YGI;JrSW46tGEGb*pt#M?wwuuIj45Z}GdC##<;q!pGcB zT3o+We3mw;FJImTk{DKvc7S~KV(stIYvgW7vT8m`G=Xnaq?05;?l)5eq~&0hIdj;~ zSnIZ;I#-VCGcs$>M;BY2&_CCm;&jeuX57MRpx91)0_Wa`0vdt$Nn@qXp%0rs^^!&c zNvqj%b*>3;h8LameS%kFer3%cS*2O&*>n~#!HLnts8P)BX^;9(xMo>tda?%M=1&cM zzuU(bU|;KjCi9b|?4pf;sprhZK96;A$-UO9T#{I+oCzy5?W3tRO(!#Tu4`PiQS_Hi z>Q2h^w*M~AYrN94CQcD?>!RIu9JQ20s^dT%T*)sW^tkf%a2_>p+8mgJR{qI*&TiQc z=bx;%Z@D>*`e7smN4Pna#`+`sZsqt8P_>+Riy}V=d#Y4^VdAP(HRBfyqOx&h{rLGN zLil8SHdn)mJI!o&ctP81C?+}XB)f$C*5aPQ=Af})D0Le4{ynPqWTEJmo_L4p@h3G4 z?N=kug+B0N*|%+d(VE=vwfVfJV)%i~r21n`?xf_OyL0Cq2ClSUF#EAeX)piDd$Ly( z9tZQxhP~gZv&}w|)*Q0Uu5Y0Et(RI=K_ZB@eII%p)oU1a(V6X^W7Ji5g>CVmV655@ z+tr?5CQ~t6+t!}D6F^0Y$5R{{hnJ>0Ryzh4ESg%btEZ?CBx0u(J>@CC&R?bT@XKobP zYKo$7TsClG8gm*ZQGszKHc2+NxA|Xub&g!P;3V!A{DP)L+n^e+1+{D6Gj6}fz-A4g zdNo%WXH1Jct7uwC?Ba|wS@G7IpO+gf%l}Mnr!2iTsdy-n7t?Xy!cbIMQ%gSsv?9E& zez*{n;Izb`CWQ+)%`P7;3&L^1mC>_utia3)9t$yUQ-cA?_V{hjNVm3a)>pUWxr%YF zY8;lk8}1oTzK%hyP8O&7^>p&@b&*M_T`I^l)my1GcqlL!_YrQ>3tAYnhMlLheM%=o zD$!wP{x>=83z*3ZpL}us3rlKQH1|7AREtxKfHw?n-{UxVAs9?ml2z%SPVKFglyNo< zZG9wrj+g{iEIUH7rn~7n!wsdXW|~cI-+H{4JQuwRiuM`&1}~mA<`wL{0Qw{VIS!1% zMnHz8X83N4m2BXl?-~qfopAna9>=vV6~dy)x=m3rx1qLfv!x19rMZ1ovhAyt@BvO& zLI7^)Hm}xxOLVVRAkN#>D!Y${~kKZ!H>myR6>T=AaPbt}RqN zgt?+*OR;}4AjD{eNk|Dfp(|Z_Rq$*r0JLKtFe@rds-yJhS!!R+#bS$9j4LZlT6KMX zK~Cu8O^e^%FQ@%2`dZ}5N}eZOt)M1a1Y6b^9P5Rp$I+^*UAqIllqwTA%8*f(M=U2& z|1rYfl2Lg42?ictnUGL!O;MEXe7@+U5+Xv*#X zQ`wn@L-oh~p9Uk#*q1cM9x--mFk_vekbRjXAzRr-WX(>E5z|y?L5%EcV+q-Y7-e6w zWlff{WT!~~^ZVb=?q~OTe9mzHd_Uj!>-Ao#DMKo7J07Z)f15`Y5Lp65qIhlu z=&}{<()9vG08CYH7A;&F??w<@fwdC+qDcL2&i=}hwyX{^n9U%`9+g_AFMML0?N4`- z+Az{Y+k15@?ql;6#>9{#HUPyj#>UKaVOgH6Uf$r1_Nmwp@!@gfz3vV(wHaeZ(^NWR z$2`$fwtpM&Kq?d9f}%D;zT1|B6c->YhAhl&DmyCs#vA0hlgl<#rS-4IjjwaniRiS) zR(emGFF2wFi?SX3Nb(ZbSY(d7R82)PO2pY+>Fog29HDsRuX(t(%9s3@6^KwulwOf( zB4T`n119p;mAMSZJ~gS>?$1czcHVj+!CQRGm4g_k&cZ$o|8+->?${yO*3;!4E?rr2 z(MNqPhEK|@&82~uw(T8}ui`6u(Sd9T4GRXWVi}K_F)tTHg*v!lEI8Doth$m5U`~K> z*;pX?il};{U#)s{&*uk_5zUm(5y>+>VNZ@n5YP1WYu36>g#G_qK?yHX1xS1$9gcemSS)}jhGK1QJ zXTs|A3T4)EAa46qc@J0<^3R_W@cOsh436-6d4i1UJ7?LShkbiY>Jaj!Lkhi7J5|}r zDpOI6HJBXoLUSO{)NSGS8WI0VT=o%nqLCo%p~raP_?b~jt}spoein!!Ktqw(gEYKq z%A97cUyON62?=fQ&(E`8fImn{g7bo3;@Z;x@?@LwPtUfitjLqQr*2)pjdL3r1vC9czFKgK;nkV?;6dmV^yh^3Qd_foV9Eyk#D~)Gn)dkLnWodsxcEsx3 z1}cizx*oB`lki@@IpPv&1#dIqF`-+kJ2Gl-M`J54(>b}E0iy^6nd!XHw%~B%SYSFk zL`k1JFC+fJXXnBGFFGgxf?LWwm}T3a8qJPvu`yd$de9v`f?VraediMYrk(`}xvYBn zNW|4sO%YBl-PLHN@qb6ay@8qL21>_#;HBk-=FemDZ&MSyzalTgYX0WUQC9V7MQZY$ z;lTK-H6lAQ6u#DTPFfUU#vxKuFM1D#`fE(1X3^lC*EQIUI@-14EW>W2E++MA9R@Lc z(%(%lR~){>c;|YFxwa-?U(?JFnZiqoI|Btt>KF9()X-{!KV}Uip-!`9+7RD!kZG5C z+9lYY(0zE^eZyZ*$=gzOVB}17LYl!qq^JAO&RCI0yDS|qu?W4vi{z25^UGRGWHoex z)~)^~lh*XxSm4VHJL_Pg=Jzhby3N~E5C^6E;Ct1YMrF*C)?fNZzHO75ckh*<;AgN9 zrnL*|QZ!Q4So2*>oK3XCtsE8Z4Y&`1f-Yp1;NpT8Lw(?HdkFO^B{XuL;jbv zbQ0!yX)tj(pshR3EdHDBJDY_ZO5l837UPDsga663ZJ=o&Ajj!Qz-v*rhurfqM$r?| zU7@&m=I}J{9ZR&*08RM^vc(AM;$~*dApm7#eH4WoNXp}elsjLV5MEZ=V>O*Wx@T?1 zc*X6HZaT<*PQFHxkLrH7Ucx!r88@FJ4d83xX+skj2IiZGI~7BjlHqxeZ}^^2@Gz&*dk~Z{BzD0rI{C8 z`R+Bjg24c=YD^Qk9%nN@yJ$y?)no@Clb&8HOB7d^r7{km!C{!47;@>FiB0x}5i5qz z0xy0M>J4V9Om&a|Z(ms%H*)4|Qa{T0P~nCvwfkGXsnAV?uB>_7QrMNcEQc#VnkC!g z%YkNge#r9~m-b=;M$U5sQEwzKRPNo2|3<%GpH?99qA)7)EJ#-HwC0W}h@^Hdx3M@#e_?=ZTbh>~*5w ze74WB<;+%(hqx{!$maXi@E{VYqd`6pRw5J6Rbcq){fnO#&8EUzV-U#tSn?R(ArWaZ z5Nk9(5)XQV2bmjK!hxEv1wH@bgDchTABFOgKa;-K@e5SlbX1c8HqnN*V}04SE(o3u zDCEu;9(HZz$UH2@mH?(VqaJ4A)iNjwzK{OqOI(N5k5_Wc(-OQw}K-~VMBjdhi6 zKE!LPVmhq39A;r;x?rjvak#@%iY1)8sr6JUrWGjpu?O}v!DzcLm3QZ1fZ6fQ{BWid%VTvsSA>yv|Lo(DIg2r3hh zsZ+}m3(Utb-FNxVTy-TLM`#&ds`xQJpULSG^C0I(k&HaBL3_CceH+WwGM!YG(B2cx zsnzvtwq-LbWEIL0W3{sqUp}I!>mB7& zk}Ep`H_${-X>w9;A9RmCH5N9X2x!X6?tXVssQ)ZrGJAz=-#V~Y*g7v9wEj~n*!rpF z;KqAbqw!IKg2Nfgd*K}owi%|63z;n4(!Ys334X~)e79;eVe;8v)fW^Y(#mSei%VCW zxFhB9^oWs1mt2Ubrmt9?_D)vV%RC3c{@X;>gSar~0lLq4e7}AcR%Xy@ufy}0Im97q zBa|Dqe||J4DP^R-$AMCtwWHtc{Zzq9jZGB`3IzaS@^ zRxKV7sNFqG3coyR;xi`&ghoDsWubih6pBbMBrM~3M1~L4FEDN%X>5)W9b&cjUzb=e zY!8!WPm~ZRq7VoSdF@BU0S`Y#82td3Jo88gB~_cifo!)~8S>A)z#r=Qyd~{Yvchx#zN^Lz$Ok;) zVgsb#Paxd=677Ra{Fb4sG~<6vBWs|O1(;N_6fE&kPOli{wh{5r8VS&_ZVXnbtBTi)$3ZC6s2ccFPZJfG&ByBNi}VaV91+zL~d+3r*1guG>Bv zIke0TZeRO3x@`F{1JjAlW9y77D5NlVWHI@&UfYdqc)2_FAVnd(OWARC+H#v&m4}rj zaaOF@H5XCjmynbxC;(ABrmhQ$SdcMq1Bf@Pa3cFE_bX^4UBmPq5Lp!M#Lgr#sskf& z1`pB@KO0VA02`Ris{H2OuI7&dqn|&t5Wk1}>9}^l4d1<#23J$(a-k9nH@?mO6`6>- zvta$bGGn{OCRpLV;Aq}xfL!x^yEhHF9XW_@r@t1M7n3!1fq(^`c!>{O(;L z835!9go0puFDtTZYUPW(#O&5D_!X55k&TGSqc99SSgzmKRR`~(_4YuDYtU->kBL06fR zl=#Z%9BKS}T(0>e9@fW*AIQ)eE==Z7*i7kTE7DK3BI&D-VnYmU&Ei)&RH0=WjXCa? zhH0;?dc^yRAel}3Ch7jlS{xsB<&NiAzZ%~bJD^+UzanT7FmIVy(7LMpRCMB$bh#KrP6bT9>SP}cPVY-0 zqR6i~9Cn7m@f-BG_cEBG%Woc}YvRAkagI1?W{Xqf zDXKqSQDho|THTnRS4o-8?~h0=OCyFH#b~DnBB%Aj-o|)BldXx4t0pO%rE%pO)&|aX73Yfc9_Mm+2r@A_lwlCD{JK z8Vbeod<;zB(?b=A1uq1m>%-e{ChgdpL)}(q91ps7Eo?rWTvr;Z?$#wQkuz4}y%=)2 z<2l?)4sjxI`!HiZxnG>#W_tDRh`}J<_qF6}sE4;>I6RB12l8wLPMgAQgFLtI|3Jb8&n=YDMPnCGVuln&-Tj1p@-->(B zxtA=qDYK&rjRcVuhUcQYDW{w7BY!0`3M3O`#(YSig;pcSCmW@ebis|3(>}cR`=Rl5&wQxwxT~RrLOt|I%kZ+8ARTqsBl!ZFzWJb3? z_$t{vd^q73m?FyyI&C~F&Ejjm&z}X&q$5AKuIUR{A1}BcP>jG0byL_$pvil%<~eR~ z$OI4$D;;^!{C6xM2f}b1&8vro=+|s!4sx>s9b!V~!L_$Bf?SB82I*mo0c*MMcFUW# z(=M--c$pm!wDOrbIg--wWWx${&dO!RP$~X2T*ZtmwCK+9A(AKHd~Xt{KPi?t;TKK& z*n;S0$l=pF@=wF=g+9wjhzGiqFjh{|QHL|laPR1UF_}Dj!N*=~5_b#Pz#>|Q$w#?H zaB?GN=PPw%BIK(3;<;w>0$*n&GcV%{oyosvKj?<`Mvm{PKoKuRZJxnOjo`BF*blY{ z3u~ketbir4#cMe0(T$hYebrz@sot;0N}2N!nF%Z$sM+u8^KFS_Zg#(()I!0*4A$W= z8#o#Xd5;HY>qoh~{J={5*~5 zm-vR)H4y7=qV*;}sM@`wq3}}D%LLt_RTfU-A{h$eoe;%l3Gbtci-U5aCIzN4yr6M> zyc6Ka-4Z=zKCN;g;z|%L&MJ!M-ozSU% z{eqD3s)O|5gm4ewJM4@zd~qF3+K$ccIrbgxvV85C>J|il6O-mV&l{IJD>WXARU3WH z;4!~?s=%)R1w_qp3q20n3K4}&-wgeIlT*{^L3sLm!EMNP2Lv8|4`!n#4p@k}9f}`) zuKtenZUulVLc+lQbd_($-Jd7)8wahmk^XUW;z*nZL1`vHS806b-mHX>_CH>q(ye(Q z!irJ+`l(lL<@pN124#HyUHl=Z9-560(FC`=?I!wz-poYQAuc!glVt7~@c#S9hmDOj zmM^KTD(^RuFfb<~4go9q3x)(|NWepH7-79qEYVHewb38Jj+KAzFUz2hycX!|)|WJZ zIQT`uA&qKY5(tw~y4UWzBcc;LaQ}Tb*+`IF^!5?7AM%(7s|Zn%CX2_hNRZ;KUe-N} zh;Ghmz0CewV^Nfw-TC!|s&p025)b9nv0p;qoUWC3=XQ#qTm$U>OXrh!4O7O%Q+fk^ zNCwN3MHu0bPv7l{ak5_4&{mQcr^zz0}~k)w$SS;JE>Eb){amlDS|tY+y@qt z>07!Smqd5hPwt`~aJuBSCvKL~0F~E?XLaCN!=O!LwU|t`aJ-m!l2o=7=L&!Is@Rm` zACy+czo@=3IU&mrc6Uno{QycV&azg1P?3|g$XPCdZM6fIso~5au$FNHOx>_r+=Q1jD&NLd(Elldq^L z8j&w6d5rr22HkUYn|G#^$v5?p)oi~USl(^ayyekM9%@hc^~f2eIXAg69Y_Dsy-4%^ zvizQc{mT8dZG|Ur&sMPsSk`VJ0A#^C0aDKmi`T?`S#F%J_OHp#Iu3kSG`Dt-$TO52 zOZ%4dr6nzIkjECiqFq|9r{vW<#FUW*e=xTmJ=CD$t$z1{WZPyrX;L{aQrq(ex9?GS zWd}}XfSVeg7#kZO<((8^f}qSf(8lLf#VQ$EX<_(fFP~e9~k8{lryHTPo(Xic{`;u1@seL`pONhX`)G)fy!xN^Y`TX)POo5dA`(DopQXC zrlXb8b$#t&*2XqQQ6s-sNil@J7qK0a1L%WXpfhqo($tqTsR5KplHe`InW_ z$ne8x=JYR+FQ)=hyfw9~OywC$4#ys?_G8A^(8nHh^@7f2qX$%~6{*{2-WfF}!7$|C zxS>2fzQ(Y=dt9<%#SlL>@|%P7@Uzb?I!CCIo!_H2DljvtU2LQN@V&Z+tqlRTq$Upp zlH*Ny*c|*9MS#}vUvBkSXGeS%D;RaLN2--0B6Gjs)!~fDgkpX@uXO2q6F#=uY;Od5 zvvH~==nYVfWxbH|J`xP+zfJt41Qgd~|E*vF|1Vr^9(Nn-_r`r{TZpk^W8w$iCBx-^ zfH0%U6;VO?UCpC1I;Hj2|4+7^2ZKNz|7X<9=l|BJmHPLez|EzRx87CDbii>HV}`EK HcaHmiYza5P literal 0 HcmV?d00001 diff --git a/src/kivymd/images/round_shadow-1.png b/src/kivymd/images/round_shadow-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d0f4c0fd4a6f9ac07d583e28e27e20a2495c392f GIT binary patch literal 40767 zcmce-g;QM36D|xv7I#@}AqxQli`xPVBzSOw6CjHPLLj&;?hYXkBsjddyUXGMg1f^8 z_u#=UzpuXk;8xwKI#s9UOilIF>FVxz`gtNW)D#HuXz|d{&Kb0{}-z^b?(%B4Y0HeY%<@8qgg)DyRo4PB#xe_tIPfUnws~yI{2^7g; z8gZmg{nI*f&jH8lx@_^(2+N!qB{bD@)6V{H%A2Lgu0S$U~_un9`DA$i}N9b`TbZ*uk=9WyTS1Jmr zqV3uS^=DCr39Tl|y!<>hRxjE%#?Q6qe7K7iUwx6H1jOddq`2oF!YDbw2#wuq%26Ub;#QjHd}pDdk%~YC95J=)b#YG!V_ja7L8;W%8_$ z-#~BP@HYsBd}PUKcoU~@A-y3BM)gc8GFMF-Sl2(vIH|cytlyqyQ;DXKr4Q#GBv=wB4i}^2N)zGB*MQ(jKs!z)w~UNl)es z3t+Q*;uJf^OC!Pv5+ylMj{&snlZiqo<1!zJma+9>juuU9tPGdN@CG7z)Ag;xj$*(Z z7&-l$cwI5+0_Pk8Jtnvz0#tEm#|cN}yBPY{P|u3tQf(7oY zD?-6b$@#3yy$&WOugG94aDIYom#@O0YTtUpxCoR{GZodrj2W!J+;z9Fg|uL0a(%WAd@;Nz?AjoF!1Xj-;fo|q>=vizYz zoE^7o{y+wO7*%wVNHL)<4XzbII()b0TzjTxdNg&bSRgJw86{Tz07|>2!nAN{;O2xk2{VEy!EaeyeqiX2bl6vbsNIU)&T^!w_ zTUaW_5P;gQR~X)IoRwyMs0^9z#}qLsD@aB&nfUwL=JADqlz(%UU-m5k?L_a~z3zzU zfaq1#f{A896lIJIZfIo4(kfY$3d=klTn34~F*}mMx1m;=Qz%bjieu&*q?(7s4rHSw z4nd@F(8g+8$>hFJgSfOSKQ}7$#PB-`$cS4ZkE=d zS29+&S%rB1&ua%7*e;T+x=5D!@D~>=>WMZ%@gBR&3Qh8(Y8LtpMS^uOysf*%2Yp+T z!R!n@0eT8sqAOUZ}L zmWa<|i6`0XE7G5{$HYeEo}xv1Vu`oWgd9PqjDsxV1Y66}XbbuetE!6~a!~PE<=g-h zfZjywoM<0k+#rN}0t|R1`zb7|>>OUdb^|hZ-{972c;m0zm)^Rk1heGExw{Z$GuWlO zemMTX%Wv;QSFOSGUSg1!EIr}R>A8@wjM~+Efs?g-CVk#jGa@O^)IJn;t$&l(SZ=I> zm~c3`W+-UD)%z>UuvkMHNA+N^G@C1x**~1x9uk;FVE`fYTinOsiSRuJ)$~~S8641E z@6(SF16^_avC&LX*PB~Ue@RB~5%c;dPQZ?&R)m2&VgPUh`eL05 zuuj|%CBW}pg&r*H9~oFpZz*fndp*5md+PVzEqP`I#(ScV!mF$nP^u-=#X)+ErlXpn zifsi)m4A$Ei<-**-K3Mf%8leDA@!9fN+28%V*RfDB0gYBb6@qvPR38CeqLvKL?4(u z;*?!95^fd15E{oTPUv0E4oEik%pS#1_-P6=!}Dz$C_rUnzgCuD2gQpMaql-_UdU2? z6`wPX)@<))q4Sc(mlkq5RN!j3oyx1zD=!u9m8>6xi%a@eB=mBqp$Lk^m_ z!^&?Dc<~s`$)e^`+G0q)kq{;O?o!6_l4(*219y%Mbo-g2gbkql)o`L^vsjLv*Ek?d z>fDDQ&QyJiiOk4Q6jFQy7QTnYO0-+w-BY%hB|1pTCWYpxD{p~+5iYmw-w(sClj^4s z@{W1O^f+MikNH#e4I%5-VDk;|@Q53_b6Q*1NLU=N4y7{PPK`8Z<1lJTC0aaS5~H9x>EuyMz7 zy_B0%-J$byo0h&mZ!9(wadp=F4*`GA2-aa9RTRp-V2{6eT7FM>U5se=>S#|@Kc7go zX!o5}gaftIMO-?{K3Z;}1RZe{WueISaF-6F-+2U;d~%F)DNUs6T37=Oq%nCYlGm?| z#|T0tu~1+FVT$yxI5{`6Neg+?0TY}*o$+$<-mW;`@bKaT=(s^Lju_U;Z9^#+zcNO8 zVEFvy<0zQ5n3C4_RDA~q1wc#@e^Srq^|xPr|Glcfx&bi0hz0xusj1L!IYdS?0NT|c zt!{I#uUcy|If?l%Xm^w#-3IrxT7qYBXpgwh{?1TPH*J+N6>mUSS3w8Q8y)Bs202&( zwzWnkRG~i_Q~E`~a$DFvwQexa&b2VO1$JPvP`5_j#w3X;doH;R^L^;7=tGyhw1oc7 zo=#|BADE#3w~cYu;08{3UkRmYm1a1b?YzFVQebj(npW<7vBDtuQm z|8+2UGQM)R@n>ksWUx)RaWLr=*LLAYK|CVKrUO0AToVyzP(?M!$3!VHUi3%HbLtr5 zl_Pn==#s*?`IsV$ic0~H zr|bhdFI|YMW6{}2{6!`uP`YZ6>CZSh;c7J4X}5pgf47yr*#O8VWk%m}ZCeW{=bcG3 zRBV9pC1V+|cb?1aO`|Gh3sP^~>Klmy>rFq58>y7u%@f}I0JE}9DrcXwTZEkQobi9u z2lStL8&|Z_k+|b0Yskji1yPJvJbAenUu`cBr}a<&yWJ;=8YJ|Mz2uDp2pY4^9Mr^H zdp^)w%DRxozkxj#ZT?rx^A*lUQZ9&@RrrdikV#uN&Oo*pWndr{nH6YOePb&W0zbtd z`ll8e#l0*8B;wc|39x>007(l9&J4Y-0*F<9IXL_|gzoBwn55ppW+V9O=kSNJpy7#u zHQ?sSlq|}xn}zBl-1kK!^E_06RaSX;_;ScDXVe5I2_?Mr^6Prd6;yI^vBqT3pm#H8dLhJ}3Q?$#;wfF^d1iu~dV+sJc)TW#ok z?H{MCNkxkZxqe(qC*kAgB=af93<+~E+nD^$-Mt$lC^{7FHpIFGnj`-hq-CTANx>Mw z71mBBv#iSwg)Q#AVzt_6OqtYp!q;*+8+(5F2nSV;Q&g4Sy^@~bC@d(S=aP_ z8CVNE*8Hb+ee@*dMjE}koBN6){@gikw0}xH%iI`Z22aTH*Nl5Fhf>;}@qt!{dxp!p zY^wk%i3R7*O8}+)0q=foNrtiKv9*L>+Kfo|1rA_JLpI5YAyofZw5g1tpr)($L1}Wp zdm3Wj1aShnSJE~ti5PKxzA?PqFNekvMQuLy3_QG-*F5O=60GshKGC_eQiGQ+22GIU%RNhqGgNVze@dXBS*FG^Th)Bx_Bt>Pa!;A|Kh)w z^rX%Df~5u6-LT_-~iVn z={edpBd=(@gqbGpEccdM_Zic$W&ufuwSo^RbQRN2pDXKC17$QQ4qg9x*JZ&o%O`HRaDX92Jz7k(cIP z^aibsxlxd@O4883OqrpZd{K~=L620QPK&5ImW^v z{tlhY-RcSRvW#=8D<)9ZLsm*Zr-%QY`5&{5(S`la}Ttp7P+MMQ3KS>o0e-H zW8C;zx}@mD*<7tkqd6y^*#!cAwbHQSZk)u`Vs z|DvEDpVnIrLYXFx(IhyB(YkD@0_S*maeJl83KV6|&_o(vXZ0BKa4M)9U>FXJIt(~+ z(DLXlb@o~SHmAV$ytoQD{RUSjKGCKY8ESnp65_(Zdws5*vfB`ds!Xx9b=_tz{#=gn zf+$yCX1lV?E?bH5XlhKbFRL+DP#yt;w!1kEf^k5Y{)fm8bUhbOWd7kr0ie zbLBYBiu^jD4__v)Cfo=>O}n|Y>$BDPpxtfcE@bZa_!Y+Xzc^P{ri<&ZoA#Q0*F~#S z!c>Fv-k8!p6vs=tK|ZoJv%`~CWA&?Fddf7ldi*aVd4(E1^)fV6jOcz9%kP-k%SD(x zM%VED@Q_0{W4Q1*fS7{2W<5-7vnM3JGj?qB6hBw&>vk~nkRNw^h)iWpNB{k3-&_i2 zP$wZ})?AV7lyT+tza@{8QTZZk%-k4{H&5;0o}Q?h1l_rBkdl=cL501YH^ma>7?o6t4 zfb{ftFsis|XWDxusUp|Wyq=TljR#e9IRDKC(Id|fYJGL}exo}wso5iN%%O=IVYxs> z>zA@lcT)KaP8CvspQ46eTD@GUPjW8V2B_zEdSvxabzVQ$>#@>3aTOvvu$&BlOGa>0l3AgWaR}9UrOiyY z^^2A3j&EaMI4ym!_Pi?#Z|6y{7`uUi*d<%snVthwROk`ndbS<@&95*JX|yw)cn9f- z`lb&p@pY?lkqZC;xE47d3HFp#Fjha7&!W`F`7^nikAY`>doX^z5!;L)Mc9fBOZT@DeG70rjXoQ#4kA~qKSQhX2QHZB zd|mR1Ih!_$BR|)~sZ^DSa7Xaesq9PSw-cV+s2g7(-DEUiM)_x|evwQ(E`20QfEx

(Ig{HG6T4&}_d3cF!08sm%T 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 literal 0 HcmV?d00001 diff --git a/src/kivymd/images/round_shadow-2.png b/src/kivymd/images/round_shadow-2.png new file mode 100644 index 0000000000000000000000000000000000000000..d5feef2c8a5a7bedd94cfce29af5cea57fab701f GIT binary patch literal 26510 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 literal 0 HcmV?d00001 diff --git a/src/kivymd/images/round_shadow.atlas b/src/kivymd/images/round_shadow.atlas new file mode 100644 index 00000000..f25016dc --- /dev/null +++ b/src/kivymd/images/round_shadow.atlas @@ -0,0 +1 @@ +{"round_shadow-1.png": {"20": [2, 136, 128, 128], "21": [132, 136, 128, 128], "22": [262, 136, 128, 128], "23": [2, 6, 128, 128], "19": [132, 266, 128, 128], "18": [2, 266, 128, 128], "1": [262, 266, 128, 128], "3": [262, 6, 128, 128], "2": [132, 6, 128, 128]}, "round_shadow-0.png": {"11": [262, 266, 128, 128], "10": [132, 266, 128, 128], "13": [132, 136, 128, 128], "12": [2, 136, 128, 128], "15": [2, 6, 128, 128], "14": [262, 136, 128, 128], "17": [262, 6, 128, 128], "16": [132, 6, 128, 128], "0": [2, 266, 128, 128]}, "round_shadow-2.png": {"5": [132, 266, 128, 128], "4": [2, 266, 128, 128], "7": [2, 136, 128, 128], "6": [262, 266, 128, 128], "9": [262, 136, 128, 128], "8": [132, 136, 128, 128]}} \ No newline at end of file diff --git a/src/kivymd/label.py b/src/kivymd/label.py new file mode 100644 index 00000000..844f2a07 --- /dev/null +++ b/src/kivymd/label.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +from kivy.lang import Builder +from kivy.metrics import sp +from kivy.properties import OptionProperty, DictProperty, ListProperty +from kivy.uix.label import Label +from kivymd.material_resources import DEVICE_TYPE +from kivymd.theming import ThemableBehavior + +Builder.load_string(''' + + disabled_color: self.theme_cls.disabled_hint_text_color + text_size: (self.width, None) +''') + + +class MDLabel(ThemableBehavior, Label): + font_style = OptionProperty( + 'Body1', options=['Body1', 'Body2', 'Caption', 'Subhead', 'Title', + 'Headline', 'Display1', 'Display2', 'Display3', + 'Display4', 'Button', 'Icon']) + + # Font, Bold, Mobile size, Desktop size (None if same as Mobile) + _font_styles = DictProperty({'Body1': ['Roboto', False, 14, 13], + 'Body2': ['Roboto', True, 14, 13], + 'Caption': ['Roboto', False, 12, None], + 'Subhead': ['Roboto', False, 16, 15], + 'Title': ['Roboto', True, 20, None], + 'Headline': ['Roboto', False, 24, None], + 'Display1': ['Roboto', False, 34, None], + 'Display2': ['Roboto', False, 45, None], + 'Display3': ['Roboto', False, 56, None], + 'Display4': ['RobotoLight', False, 112, None], + 'Button': ['Roboto', True, 14, None], + 'Icon': ['Icons', False, 24, None]}) + + theme_text_color = OptionProperty(None, allownone=True, + options=['Primary', 'Secondary', 'Hint', + 'Error', 'Custom']) + + text_color = ListProperty(None, allownone=True) + + _currently_bound_property = {} + + def __init__(self, **kwargs): + super(MDLabel, self).__init__(**kwargs) + self.on_theme_text_color(None, self.theme_text_color) + self.on_font_style(None, self.font_style) + self.on_opposite_colors(None, self.opposite_colors) + + def on_font_style(self, instance, style): + info = self._font_styles[style] + self.font_name = info[0] + self.bold = info[1] + if DEVICE_TYPE == 'desktop' and info[3] is not None: + self.font_size = sp(info[3]) + else: + self.font_size = sp(info[2]) + + def on_theme_text_color(self, instance, value): + t = self.theme_cls + op = self.opposite_colors + setter = self.setter('color') + t.unbind(**self._currently_bound_property) + c = {} + if value == 'Primary': + c = {'text_color' if not op else 'opposite_text_color': setter} + t.bind(**c) + self.color = t.text_color if not op else t.opposite_text_color + elif value == 'Secondary': + c = {'secondary_text_color' if not op else + 'opposite_secondary_text_color': setter} + t.bind(**c) + self.color = t.secondary_text_color if not op else \ + t.opposite_secondary_text_color + elif value == 'Hint': + c = {'disabled_hint_text_color' if not op else + 'opposite_disabled_hint_text_color': setter} + t.bind(**c) + self.color = t.disabled_hint_text_color if not op else \ + t.opposite_disabled_hint_text_color + elif value == 'Error': + c = {'error_color': setter} + t.bind(**c) + self.color = t.error_color + elif value == 'Custom': + self.color = self.text_color if self.text_color else (0, 0, 0, 1) + self._currently_bound_property = c + + def on_text_color(self, *args): + if self.theme_text_color == 'Custom': + self.color = self.text_color + + def on_opposite_colors(self, instance, value): + self.on_theme_text_color(self, self.theme_text_color) diff --git a/src/kivymd/list.py b/src/kivymd/list.py new file mode 100644 index 00000000..36162329 --- /dev/null +++ b/src/kivymd/list.py @@ -0,0 +1,531 @@ +# -*- coding: utf-8 -*- +''' +Lists +===== + +`Material Design spec, Lists page `_ + +`Material Design spec, Lists: Controls page `_ + +The class :class:`MDList` in combination with a ListItem like +:class:`OneLineListItem` will create a list that expands as items are added to +it, working nicely with Kivy's :class:`~kivy.uix.scrollview.ScrollView`. + + +Simple examples +--------------- + +Kv Lang: + +.. code-block:: python + + ScrollView: + do_scroll_x: False # Important for MD compliance + MDList: + OneLineListItem: + text: "Single-line item" + TwoLineListItem: + text: "Two-line item" + secondary_text: "Secondary text here" + ThreeLineListItem: + text: "Three-line item" + secondary_text: "This is a multi-line label where you can fit more text than usual" + + +Python: + +.. code-block:: python + + # Sets up ScrollView with MDList, as normally used in Android: + sv = ScrollView() + ml = MDList() + sv.add_widget(ml) + + contacts = ["Paula", "John", "Kate", "Vlad"] + for c in contacts: + ml.add_widget( + OneLineListItem( + text=c + ) + ) + +Advanced usage +-------------- + +Due to the variety in sizes and controls in the MD spec, this module suffers +from a certain level of complexity to keep the widgets compliant, flexible +and performant. + +For this KivyMD provides ListItems that try to cover the most common usecases, +when those are insufficient, there's a base class called :class:`ListItem` +which you can use to create your own ListItems. This documentation will only +cover the provided ones, for custom implementations please refer to this +module's source code. + +Text only ListItems +------------------- + +- :class:`~OneLineListItem` +- :class:`~TwoLineListItem` +- :class:`~ThreeLineListItem` + +These are the simplest ones. The :attr:`~ListItem.text` attribute changes the +text in the most prominent line, while :attr:`~ListItem.secondary_text` +changes the second and third line. + +If there are only two lines, :attr:`~ListItem.secondary_text` will shorten +the text to fit in case it is too long; if a third line is available, it will +instead wrap the text to make use of it. + +ListItems with widget containers +-------------------------------- + +- :class:`~OneLineAvatarListItem` +- :class:`~TwoLineAvatarListItem` +- :class:`~ThreeLineAvatarListItem` +- :class:`~OneLineIconListItem` +- :class:`~TwoLineIconListItem` +- :class:`~ThreeLineIconListItem` +- :class:`~OneLineAvatarIconListItem` +- :class:`~TwoLineAvatarIconListItem` +- :class:`~ThreeLineAvatarIconListItem` + +These widgets will take other widgets that inherit from :class:`~ILeftBody`, +:class:`ILeftBodyTouch`, :class:`~IRightBody` or :class:`~IRightBodyTouch` and +put them in their corresponding container. + +As the name implies, :class:`~ILeftBody` and :class:`~IRightBody` will signal +that the widget goes into the left or right container, respectively. + +:class:`~ILeftBodyTouch` and :class:`~IRightBodyTouch` do the same thing, +except these widgets will also receive touch events that occur within their +surfaces. + +Python example: + +.. code-block:: python + + class ContactPhoto(ILeftBody, AsyncImage): + pass + + class MessageButton(IRightBodyTouch, MDIconButton): + phone_number = StringProperty() + + def on_release(self): + # sample code: + Dialer.send_sms(phone_number, "Hey! What's up?") + pass + + # Sets up ScrollView with MDList, as normally used in Android: + sv = ScrollView() + ml = MDList() + sv.add_widget(ml) + + contacts = [ + ["Annie", "555-24235", "http://myphotos.com/annie.png"], + ["Bob", "555-15423", "http://myphotos.com/bob.png"], + ["Claire", "555-66098", "http://myphotos.com/claire.png"] + ] + + for c in contacts: + item = TwoLineAvatarIconListItem( + text=c[0], + secondary_text=c[1] + ) + item.add_widget(ContactPhoto(source=c[2])) + item.add_widget(MessageButton(phone_number=c[1]) + ml.add_widget(item) + +API +--- +''' + +from kivy.lang import Builder +from kivy.metrics import dp +from kivy.properties import ObjectProperty, StringProperty, NumericProperty, \ + ListProperty, OptionProperty +from kivy.uix.behaviors import ButtonBehavior +from kivy.uix.floatlayout import FloatLayout +from kivy.uix.gridlayout import GridLayout +import kivymd.material_resources as m_res +from kivymd.ripplebehavior import RectangularRippleBehavior +from kivymd.theming import ThemableBehavior + +Builder.load_string(''' +#:import m_res kivymd.material_resources + + cols: 1 + size_hint_y: None + height: self._min_list_height + padding: 0, self._list_vertical_padding + + + size_hint_y: None + canvas: + Color: + rgba: self.theme_cls.divider_color + Line: + points: root.x,root.y, root.x+self.width,root.y + BoxLayout: + id: _text_container + orientation: 'vertical' + pos: root.pos + padding: root._txt_left_pad, root._txt_top_pad, root._txt_right_pad, root._txt_bot_pad + MDLabel: + id: _lbl_primary + text: root.text + font_style: root.font_style + theme_text_color: root.theme_text_color + text_color: root.text_color + size_hint_y: None + height: self.texture_size[1] + MDLabel: + id: _lbl_secondary + text: '' if root._num_lines == 1 else root.secondary_text + font_style: root.secondary_font_style + theme_text_color: root.secondary_theme_text_color + text_color: root.secondary_text_color + size_hint_y: None + height: 0 if root._num_lines == 1 else self.texture_size[1] + shorten: True if root._num_lines == 2 else False + + + BoxLayout: + id: _left_container + size_hint: None, None + x: root.x + dp(16) + y: root.y + root.height/2 - self.height/2 + size: dp(40), dp(40) + + + BoxLayout: + id: _left_container + size_hint: None, None + x: root.x + dp(16) + y: root.y + root.height - root._txt_top_pad - self.height - dp(5) + size: dp(40), dp(40) + + + BoxLayout: + id: _left_container + size_hint: None, None + x: root.x + dp(16) + y: root.y + root.height/2 - self.height/2 + size: dp(48), dp(48) + + + BoxLayout: + id: _left_container + size_hint: None, None + x: root.x + dp(16) + y: root.y + root.height - root._txt_top_pad - self.height - dp(5) + size: dp(48), dp(48) + + + BoxLayout: + id: _right_container + size_hint: None, None + x: root.x + root.width - m_res.HORIZ_MARGINS - self.width + y: root.y + root.height/2 - self.height/2 + size: dp(48), dp(48) + + + BoxLayout: + id: _right_container + size_hint: None, None + x: root.x + root.width - m_res.HORIZ_MARGINS - self.width + y: root.y + root.height/2 - self.height/2 + size: dp(48), dp(48) + + + BoxLayout: + id: _right_container + size_hint: None, None + x: root.x + root.width - m_res.HORIZ_MARGINS - self.width + y: root.y + root.height/2 - self.height/2 + size: dp(48), dp(48) + + + BoxLayout: + id: _right_container + size_hint: None, None + x: root.x + root.width - m_res.HORIZ_MARGINS - self.width + y: root.y + root.height/2 - self.height/2 + size: dp(48), dp(48) + + + BoxLayout: + id: _right_container + size_hint: None, None + x: root.x + root.width - m_res.HORIZ_MARGINS - self.width + y: root.y + root.height - root._txt_top_pad - self.height - dp(5) + size: dp(48), dp(48) +''') + + +class MDList(GridLayout): + '''ListItem container. Best used in conjunction with a + :class:`kivy.uix.ScrollView`. + + When adding (or removing) a widget, it will resize itself to fit its + children, plus top and bottom paddings as described by the MD spec. + ''' + selected = ObjectProperty() + _min_list_height = dp(16) + _list_vertical_padding = dp(8) + + icon = StringProperty() + + def add_widget(self, widget, index=0): + super(MDList, self).add_widget(widget, index) + self.height += widget.height + + def remove_widget(self, widget): + super(MDList, self).remove_widget(widget) + self.height -= widget.height + + +class BaseListItem(ThemableBehavior, RectangularRippleBehavior, + ButtonBehavior, FloatLayout): + '''Base class to all ListItems. Not supposed to be instantiated on its own. + ''' + + text = StringProperty() + '''Text shown in the first line. + + :attr:`text` is a :class:`~kivy.properties.StringProperty` and defaults + to "". + ''' + + text_color = ListProperty(None) + ''' Text color used if theme_text_color is set to 'Custom' ''' + + font_style = OptionProperty( + 'Subhead', options=['Body1', 'Body2', 'Caption', 'Subhead', 'Title', + 'Headline', 'Display1', 'Display2', 'Display3', + 'Display4', 'Button', 'Icon']) + + theme_text_color = StringProperty('Primary',allownone=True) + ''' Theme text color for primary text ''' + + secondary_text = StringProperty() + '''Text shown in the second and potentially third line. + + The text will wrap into the third line if the ListItem's type is set to + \'one-line\'. It can be forced into the third line by adding a \\n + escape sequence. + + :attr:`secondary_text` is a :class:`~kivy.properties.StringProperty` and + defaults to "". + ''' + + secondary_text_color = ListProperty(None) + ''' Text color used for secondary text if secondary_theme_text_color + is set to 'Custom' ''' + + secondary_theme_text_color = StringProperty('Secondary',allownone=True) + ''' Theme text color for secondary primary text ''' + + secondary_font_style = OptionProperty( + 'Body1', options=['Body1', 'Body2', 'Caption', 'Subhead', 'Title', + 'Headline', 'Display1', 'Display2', 'Display3', + 'Display4', 'Button', 'Icon']) + + _txt_left_pad = NumericProperty(dp(16)) + _txt_top_pad = NumericProperty() + _txt_bot_pad = NumericProperty() + _txt_right_pad = NumericProperty(m_res.HORIZ_MARGINS) + _num_lines = 2 + + +class ILeftBody: + '''Pseudo-interface for widgets that go in the left container for + ListItems that support it. + + Implements nothing and requires no implementation, for annotation only. + ''' + pass + + +class ILeftBodyTouch: + '''Same as :class:`~ILeftBody`, but allows the widget to receive touch + events instead of triggering the ListItem's ripple effect + ''' + pass + + +class IRightBody: + '''Pseudo-interface for widgets that go in the right container for + ListItems that support it. + + Implements nothing and requires no implementation, for annotation only. + ''' + pass + + +class IRightBodyTouch: + '''Same as :class:`~IRightBody`, but allows the widget to receive touch + events instead of triggering the ListItem's ripple effect + ''' + pass + + +class ContainerSupport: + '''Overrides add_widget in a ListItem to include support for I*Body + widgets when the appropiate containers are present. + ''' + _touchable_widgets = ListProperty() + + def add_widget(self, widget, index=0): + if issubclass(widget.__class__, ILeftBody): + self.ids['_left_container'].add_widget(widget) + elif issubclass(widget.__class__, ILeftBodyTouch): + self.ids['_left_container'].add_widget(widget) + self._touchable_widgets.append(widget) + elif issubclass(widget.__class__, IRightBody): + self.ids['_right_container'].add_widget(widget) + elif issubclass(widget.__class__, IRightBodyTouch): + self.ids['_right_container'].add_widget(widget) + self._touchable_widgets.append(widget) + else: + return super(BaseListItem, self).add_widget(widget,index) + + def remove_widget(self, widget): + super(BaseListItem, self).remove_widget(widget) + if widget in self._touchable_widgets: + self._touchable_widgets.remove(widget) + + def on_touch_down(self, touch): + if self.propagate_touch_to_touchable_widgets(touch, 'down'): + return + super(BaseListItem, self).on_touch_down(touch) + + def on_touch_move(self, touch, *args): + if self.propagate_touch_to_touchable_widgets(touch, 'move', *args): + return + super(BaseListItem, self).on_touch_move(touch, *args) + + def on_touch_up(self, touch): + if self.propagate_touch_to_touchable_widgets(touch, 'up'): + return + super(BaseListItem, self).on_touch_up(touch) + + def propagate_touch_to_touchable_widgets(self, touch, touch_event, *args): + triggered = False + for i in self._touchable_widgets: + if i.collide_point(touch.x, touch.y): + triggered = True + if touch_event == 'down': + i.on_touch_down(touch) + elif touch_event == 'move': + i.on_touch_move(touch, *args) + elif touch_event == 'up': + i.on_touch_up(touch) + return triggered + + +class OneLineListItem(BaseListItem): + _txt_top_pad = NumericProperty(dp(16)) + _txt_bot_pad = NumericProperty(dp(15)) # dp(20) - dp(5) + _num_lines = 1 + + def __init__(self, **kwargs): + super(OneLineListItem, self).__init__(**kwargs) + self.height = dp(48) + + +class TwoLineListItem(BaseListItem): + _txt_top_pad = NumericProperty(dp(20)) + _txt_bot_pad = NumericProperty(dp(15)) # dp(20) - dp(5) + + def __init__(self, **kwargs): + super(TwoLineListItem, self).__init__(**kwargs) + self.height = dp(72) + + +class ThreeLineListItem(BaseListItem): + _txt_top_pad = NumericProperty(dp(16)) + _txt_bot_pad = NumericProperty(dp(15)) # dp(20) - dp(5) + _num_lines = 3 + + def __init__(self, **kwargs): + super(ThreeLineListItem, self).__init__(**kwargs) + self.height = dp(88) + + +class OneLineAvatarListItem(ContainerSupport, BaseListItem): + _txt_left_pad = NumericProperty(dp(72)) + _txt_top_pad = NumericProperty(dp(20)) + _txt_bot_pad = NumericProperty(dp(19)) # dp(24) - dp(5) + _num_lines = 1 + + def __init__(self, **kwargs): + super(OneLineAvatarListItem, self).__init__(**kwargs) + self.height = dp(56) + + +class TwoLineAvatarListItem(OneLineAvatarListItem): + _txt_top_pad = NumericProperty(dp(20)) + _txt_bot_pad = NumericProperty(dp(15)) # dp(20) - dp(5) + _num_lines = 2 + + def __init__(self, **kwargs): + super(BaseListItem, self).__init__(**kwargs) + self.height = dp(72) + + +class ThreeLineAvatarListItem(ContainerSupport, ThreeLineListItem): + _txt_left_pad = NumericProperty(dp(72)) + + +class OneLineIconListItem(ContainerSupport, OneLineListItem): + _txt_left_pad = NumericProperty(dp(72)) + + +class TwoLineIconListItem(OneLineIconListItem): + _txt_top_pad = NumericProperty(dp(20)) + _txt_bot_pad = NumericProperty(dp(15)) # dp(20) - dp(5) + _num_lines = 2 + + def __init__(self, **kwargs): + super(BaseListItem, self).__init__(**kwargs) + self.height = dp(72) + + +class ThreeLineIconListItem(ContainerSupport, ThreeLineListItem): + _txt_left_pad = NumericProperty(dp(72)) + + +class OneLineRightIconListItem(ContainerSupport, OneLineListItem): + # dp(40) = dp(16) + dp(24): + _txt_right_pad = NumericProperty(dp(40) + m_res.HORIZ_MARGINS) + + +class TwoLineRightIconListItem(OneLineRightIconListItem): + _txt_top_pad = NumericProperty(dp(20)) + _txt_bot_pad = NumericProperty(dp(15)) # dp(20) - dp(5) + _num_lines = 2 + + def __init__(self, **kwargs): + super(BaseListItem, self).__init__(**kwargs) + self.height = dp(72) + + +class ThreeLineRightIconListitem(ContainerSupport, ThreeLineListItem): + # dp(40) = dp(16) + dp(24): + _txt_right_pad = NumericProperty(dp(40) + m_res.HORIZ_MARGINS) + + +class OneLineAvatarIconListItem(OneLineAvatarListItem): + # dp(40) = dp(16) + dp(24): + _txt_right_pad = NumericProperty(dp(40) + m_res.HORIZ_MARGINS) + + +class TwoLineAvatarIconListItem(TwoLineAvatarListItem): + # dp(40) = dp(16) + dp(24): + _txt_right_pad = NumericProperty(dp(40) + m_res.HORIZ_MARGINS) + + +class ThreeLineAvatarIconListItem(ThreeLineAvatarListItem): + # dp(40) = dp(16) + dp(24): + _txt_right_pad = NumericProperty(dp(40) + m_res.HORIZ_MARGINS) diff --git a/src/kivymd/material_resources.py b/src/kivymd/material_resources.py new file mode 100644 index 00000000..46270e5c --- /dev/null +++ b/src/kivymd/material_resources.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +from kivy import platform +from kivy.core.window import Window +from kivy.metrics import dp +from kivymd import fonts_path + +# Feel free to override this const if you're designing for a device such as +# a GNU/Linux tablet. +if platform != "android" and platform != "ios": + DEVICE_TYPE = "desktop" +elif Window.width >= dp(600) and Window.height >= dp(600): + DEVICE_TYPE = "tablet" +else: + DEVICE_TYPE = "mobile" + +if DEVICE_TYPE == "mobile": + MAX_NAV_DRAWER_WIDTH = dp(300) + HORIZ_MARGINS = dp(16) + STANDARD_INCREMENT = dp(56) + PORTRAIT_TOOLBAR_HEIGHT = STANDARD_INCREMENT + LANDSCAPE_TOOLBAR_HEIGHT = STANDARD_INCREMENT - dp(8) +else: + MAX_NAV_DRAWER_WIDTH = dp(400) + HORIZ_MARGINS = dp(24) + STANDARD_INCREMENT = dp(64) + PORTRAIT_TOOLBAR_HEIGHT = STANDARD_INCREMENT + LANDSCAPE_TOOLBAR_HEIGHT = STANDARD_INCREMENT + +TOUCH_TARGET_HEIGHT = dp(48) + +FONTS = [ + { + "name": "Roboto", + "fn_regular": fonts_path + 'Roboto-Regular.ttf', + "fn_bold": fonts_path + 'Roboto-Medium.ttf', + "fn_italic": fonts_path + 'Roboto-Italic.ttf', + "fn_bolditalic": fonts_path + 'Roboto-MediumItalic.ttf' + }, + { + "name": "RobotoLight", + "fn_regular": fonts_path + 'Roboto-Thin.ttf', + "fn_bold": fonts_path + 'Roboto-Light.ttf', + "fn_italic": fonts_path + 'Roboto-ThinItalic.ttf', + "fn_bolditalic": fonts_path + 'Roboto-LightItalic.ttf' + }, + { + "name": "Icons", + "fn_regular": fonts_path + 'Material-Design-Iconic-Font.ttf' + } +] diff --git a/src/kivymd/menu.py b/src/kivymd/menu.py new file mode 100644 index 00000000..f4c96ac8 --- /dev/null +++ b/src/kivymd/menu.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +from kivy.animation import Animation +from kivy.clock import Clock +from kivy.core.window import Window +from kivy.lang import Builder +from kivy.garden.recycleview import RecycleView +from kivy.metrics import dp +from kivy.properties import NumericProperty, ListProperty, OptionProperty, \ + StringProperty +from kivy.uix.behaviors import ButtonBehavior +from kivy.uix.boxlayout import BoxLayout +import kivymd.material_resources as m_res +from kivymd.theming import ThemableBehavior + +Builder.load_string(''' +#:import STD_INC kivymd.material_resources.STANDARD_INCREMENT + + size_hint_y: None + height: dp(48) + padding: dp(16), 0 + on_release: root.parent.parent.parent.parent.dismiss() # Horrible, but hey it works + MDLabel: + text: root.text + theme_text_color: 'Primary' + + + size_hint: None, None + width: root.width_mult * STD_INC + key_viewclass: 'viewclass' + key_size: 'height' + + + FloatLayout: + id: fl + MDMenu: + id: md_menu + data: root.items + width_mult: root.width_mult + size_hint: None, None + size: 0,0 + canvas.before: + Color: + rgba: root.theme_cls.bg_light + Rectangle: + size: self.size + pos: self.pos +''') + + +class MDMenuItem(ButtonBehavior, BoxLayout): + text = StringProperty() + + +class MDMenu(RecycleView): + width_mult = NumericProperty(1) + + +class MDDropdownMenu(ThemableBehavior, BoxLayout): + items = ListProperty() + '''See :attr:`~kivy.garden.recycleview.RecycleView.data` + ''' + + width_mult = NumericProperty(1) + '''This number multiplied by the standard increment (56dp on mobile, + 64dp on desktop, determines the width of the menu items. + + If the resulting number were to be too big for the application Window, + the multiplier will be adjusted for the biggest possible one. + ''' + + max_height = NumericProperty() + '''The menu will grow no bigger than this number. + + Set to 0 for no limit. Defaults to 0. + ''' + + border_margin = NumericProperty(dp(4)) + '''Margin between Window border and menu + ''' + + ver_growth = OptionProperty(None, allownone=True, + options=['up', 'down']) + '''Where the menu will grow vertically to when opening + + Set to None to let the widget pick for you. Defaults to None. + ''' + + hor_growth = OptionProperty(None, allownone=True, + options=['left', 'right']) + '''Where the menu will grow horizontally to when opening + + Set to None to let the widget pick for you. Defaults to None. + ''' + + def open(self, *largs): + Window.add_widget(self) + Clock.schedule_once(lambda x: self.display_menu(largs[0]), -1) + + def display_menu(self, caller): + # We need to pick a starting point, see how big we need to be, + # and where to grow to. + + c = caller.to_window(caller.center_x, + caller.center_y) # Starting coords + + # ---ESTABLISH INITIAL TARGET SIZE ESTIMATE--- + target_width = self.width_mult * m_res.STANDARD_INCREMENT + # If we're wider than the Window... + if target_width > Window.width: + # ...reduce our multiplier to max allowed. + target_width = int( + Window.width / m_res.STANDARD_INCREMENT) * m_res.STANDARD_INCREMENT + + target_height = sum([dp(48) for i in self.items]) + # If we're over max_height... + if 0 < self.max_height < target_height: + target_height = self.max_height + + # ---ESTABLISH VERTICAL GROWTH DIRECTION--- + if self.ver_growth is not None: + ver_growth = self.ver_growth + else: + # If there's enough space below us: + if target_height <= c[1] - self.border_margin: + ver_growth = 'down' + # if there's enough space above us: + elif target_height < Window.height - c[1] - self.border_margin: + ver_growth = 'up' + # otherwise, let's pick the one with more space and adjust ourselves + else: + # if there's more space below us: + if c[1] >= Window.height - c[1]: + ver_growth = 'down' + target_height = c[1] - self.border_margin + # if there's more space above us: + else: + ver_growth = 'up' + target_height = Window.height - c[1] - self.border_margin + + if self.hor_growth is not None: + hor_growth = self.hor_growth + else: + # If there's enough space to the right: + if target_width <= Window.width - c[0] - self.border_margin: + hor_growth = 'right' + # if there's enough space to the left: + elif target_width < c[0] - self.border_margin: + hor_growth = 'left' + # otherwise, let's pick the one with more space and adjust ourselves + else: + # if there's more space to the right: + if Window.width - c[0] >= c[0]: + hor_growth = 'right' + target_width = Window.width - c[0] - self.border_margin + # if there's more space to the left: + else: + hor_growth = 'left' + target_width = c[0] - self.border_margin + + if ver_growth == 'down': + tar_y = c[1] - target_height + else: # should always be 'up' + tar_y = c[1] + + if hor_growth == 'right': + tar_x = c[0] + else: # should always be 'left' + tar_x = c[0] - target_width + anim = Animation(x=tar_x, y=tar_y, + width=target_width, height=target_height, + duration=.3, transition='out_quint') + menu = self.ids['md_menu'] + menu.pos = c + anim.start(menu) + + def on_touch_down(self, touch): + if not self.ids['md_menu'].collide_point(*touch.pos): + self.dismiss() + return True + super(MDDropdownMenu, self).on_touch_down(touch) + return True + + def on_touch_move(self, touch): + super(MDDropdownMenu, self).on_touch_move(touch) + return True + + def on_touch_up(self, touch): + super(MDDropdownMenu, self).on_touch_up(touch) + return True + + def dismiss(self): + Window.remove_widget(self) diff --git a/src/kivymd/navigationdrawer.py b/src/kivymd/navigationdrawer.py new file mode 100644 index 00000000..42aa9a62 --- /dev/null +++ b/src/kivymd/navigationdrawer.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +from kivy.animation import Animation +from kivy.lang import Builder +from kivy.properties import StringProperty, ObjectProperty +from kivymd.elevationbehavior import ElevationBehavior +from kivymd.icon_definitions import md_icons +from kivymd.label import MDLabel +from kivymd.list import OneLineIconListItem, ILeftBody, BaseListItem +from kivymd.slidingpanel import SlidingPanel +from kivymd.theming import ThemableBehavior + +Builder.load_string(''' + + canvas: + Color: + rgba: root.theme_cls.divider_color + Line: + points: self.x, self.y, self.x+self.width,self.y + + + _list: list + elevation: 0 + canvas: + Color: + rgba: root.theme_cls.bg_light + Rectangle: + size: root.size + pos: root.pos + NavDrawerToolbar: + title: root.title + opposite_colors: False + title_theme_color: 'Secondary' + background_color: root.theme_cls.bg_light + elevation: 0 + ScrollView: + do_scroll_x: False + MDList: + id: ml + id: list + + + NDIconLabel: + id: _icon + font_style: 'Icon' + theme_text_color: 'Secondary' +''') + + +class NavigationDrawer(SlidingPanel, ThemableBehavior, ElevationBehavior): + title = StringProperty() + + _list = ObjectProperty() + + def add_widget(self, widget, index=0): + if issubclass(widget.__class__, BaseListItem): + self._list.add_widget(widget, index) + widget.bind(on_release=lambda x: self.toggle()) + else: + super(NavigationDrawer, self).add_widget(widget, index) + + def _get_main_animation(self, duration, t, x, is_closing): + a = super(NavigationDrawer, self)._get_main_animation(duration, t, x, + is_closing) + a &= Animation(elevation=0 if is_closing else 5, t=t, duration=duration) + return a + + +class NDIconLabel(ILeftBody, MDLabel): + pass + + +class NavigationDrawerIconButton(OneLineIconListItem): + icon = StringProperty() + + def on_icon(self, instance, value): + self.ids['_icon'].text = u"{}".format(md_icons[value]) diff --git a/src/kivymd/progressbar.py b/src/kivymd/progressbar.py new file mode 100644 index 00000000..6d3a2ca8 --- /dev/null +++ b/src/kivymd/progressbar.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- + +from kivy.lang import Builder +from kivy.properties import ListProperty, OptionProperty, BooleanProperty +from kivy.utils import get_color_from_hex +from kivymd.color_definitions import colors +from kivymd.theming import ThemableBehavior +from kivy.uix.progressbar import ProgressBar + + +Builder.load_string(''' +: + canvas: + Clear + Color: + rgba: self.theme_cls.divider_color + Rectangle: + size: (self.width , dp(4)) if self.orientation == 'horizontal' else (dp(4),self.height) + pos: (self.x, self.center_y - dp(4)) if self.orientation == 'horizontal' \ + else (self.center_x - dp(4),self.y) + + + Color: + rgba: self.theme_cls.primary_color + Rectangle: + size: (self.width*self.value_normalized, sp(4)) if self.orientation == 'horizontal' else (sp(4), \ + self.height*self.value_normalized) + pos: (self.width*(1-self.value_normalized)+self.x if self.reversed else self.x, self.center_y - dp(4)) \ + if self.orientation == 'horizontal' else \ + (self.center_x - dp(4),self.height*(1-self.value_normalized)+self.y if self.reversed else self.y) + +''') + + +class MDProgressBar(ThemableBehavior, ProgressBar): + reversed = BooleanProperty(False) + ''' Reverse the direction the progressbar moves. ''' + + orientation = OptionProperty('horizontal', options=['horizontal', 'vertical']) + ''' Orientation of progressbar''' + + +if __name__ == '__main__': + from kivy.app import App + from kivymd.theming import ThemeManager + + class ProgressBarApp(App): + theme_cls = ThemeManager() + + def build(self): + return Builder.load_string("""#:import MDSlider kivymd.slider.MDSlider +BoxLayout: + orientation:'vertical' + padding: '8dp' + MDSlider: + id:slider + min:0 + max:100 + value: 40 + + MDProgressBar: + value: slider.value + MDProgressBar: + reversed: True + value: slider.value + BoxLayout: + MDProgressBar: + orientation:"vertical" + reversed: True + value: slider.value + + MDProgressBar: + orientation:"vertical" + value: slider.value + +""") + + + ProgressBarApp().run() diff --git a/src/kivymd/ripplebehavior.py b/src/kivymd/ripplebehavior.py new file mode 100644 index 00000000..21dd3463 --- /dev/null +++ b/src/kivymd/ripplebehavior.py @@ -0,0 +1,169 @@ +# -*- coding: utf-8 -*- +from kivy.properties import ListProperty, NumericProperty, StringProperty, \ + BooleanProperty +from kivy.animation import Animation +from kivy.graphics import Color, Ellipse, StencilPush, StencilPop, \ + StencilUse, StencilUnUse, Rectangle + + +class CommonRipple(object): + ripple_rad = NumericProperty() + ripple_rad_default = NumericProperty(1) + ripple_post = ListProperty() + ripple_color = ListProperty() + ripple_alpha = NumericProperty(.5) + ripple_scale = NumericProperty(None) + ripple_duration_in_fast = NumericProperty(.3) + # FIXME: These speeds should be calculated based on widget size in dp + ripple_duration_in_slow = NumericProperty(2) + ripple_duration_out = NumericProperty(.3) + ripple_func_in = StringProperty('out_quad') + ripple_func_out = StringProperty('out_quad') + + doing_ripple = BooleanProperty(False) + finishing_ripple = BooleanProperty(False) + fading_out = BooleanProperty(False) + + def on_touch_down(self, touch): + if touch.is_mouse_scrolling: + return False + if not self.collide_point(touch.x, touch.y): + return False + + if not self.disabled: + if self.doing_ripple: + Animation.cancel_all(self, 'ripple_rad', 'ripple_color', + 'rect_color') + self.anim_complete() + self.ripple_rad = self.ripple_rad_default + self.ripple_pos = (touch.x, touch.y) + + if self.ripple_color != []: + pass + elif hasattr(self, 'theme_cls'): + self.ripple_color = self.theme_cls.ripple_color + else: + # If no theme, set Grey 300 + self.ripple_color = [0.8784313725490196, 0.8784313725490196, + 0.8784313725490196, self.ripple_alpha] + self.ripple_color[3] = self.ripple_alpha + + self.lay_canvas_instructions() + self.finish_rad = max(self.width, self.height) * self.ripple_scale + self.start_ripple() + return super(CommonRipple, self).on_touch_down(touch) + + def lay_canvas_instructions(self): + raise NotImplementedError + + def on_touch_move(self, touch, *args): + if not self.collide_point(touch.x, touch.y): + if not self.finishing_ripple and self.doing_ripple: + self.finish_ripple() + return super(CommonRipple, self).on_touch_move(touch, *args) + + def on_touch_up(self, touch): + if self.collide_point(touch.x, touch.y) and self.doing_ripple: + self.finish_ripple() + return super(CommonRipple, self).on_touch_up(touch) + + def start_ripple(self): + if not self.doing_ripple: + anim = Animation( + ripple_rad=self.finish_rad, + t='linear', + duration=self.ripple_duration_in_slow) + anim.bind(on_complete=self.fade_out) + self.doing_ripple = True + anim.start(self) + + def _set_ellipse(self, instance, value): + self.ellipse.size = (self.ripple_rad, self.ripple_rad) + + # Adjust ellipse pos here + + def _set_color(self, instance, value): + self.col_instruction.a = value[3] + + def finish_ripple(self): + if self.doing_ripple and not self.finishing_ripple: + Animation.cancel_all(self, 'ripple_rad') + anim = Animation(ripple_rad=self.finish_rad, + t=self.ripple_func_in, + duration=self.ripple_duration_in_fast) + anim.bind(on_complete=self.fade_out) + self.finishing_ripple = True + anim.start(self) + + def fade_out(self, *args): + rc = self.ripple_color + if not self.fading_out: + Animation.cancel_all(self, 'ripple_color') + anim = Animation(ripple_color=[rc[0], rc[1], rc[2], 0.], + t=self.ripple_func_out, + duration=self.ripple_duration_out) + anim.bind(on_complete=self.anim_complete) + self.fading_out = True + anim.start(self) + + def anim_complete(self, *args): + self.doing_ripple = False + self.finishing_ripple = False + self.fading_out = False + self.canvas.after.clear() + + +class RectangularRippleBehavior(CommonRipple): + ripple_scale = NumericProperty(2.75) + + def lay_canvas_instructions(self): + with self.canvas.after: + StencilPush() + Rectangle(pos=self.pos, size=self.size) + StencilUse() + self.col_instruction = Color(rgba=self.ripple_color) + self.ellipse = \ + Ellipse(size=(self.ripple_rad, self.ripple_rad), + pos=(self.ripple_pos[0] - self.ripple_rad / 2., + self.ripple_pos[1] - self.ripple_rad / 2.)) + StencilUnUse() + Rectangle(pos=self.pos, size=self.size) + StencilPop() + self.bind(ripple_color=self._set_color, + ripple_rad=self._set_ellipse) + + def _set_ellipse(self, instance, value): + super(RectangularRippleBehavior, self)._set_ellipse(instance, value) + self.ellipse.pos = (self.ripple_pos[0] - self.ripple_rad / 2., + self.ripple_pos[1] - self.ripple_rad / 2.) + + +class CircularRippleBehavior(CommonRipple): + ripple_scale = NumericProperty(1) + + def lay_canvas_instructions(self): + with self.canvas.after: + StencilPush() + self.stencil = Ellipse(size=(self.width * self.ripple_scale, + self.height * self.ripple_scale), + pos=(self.center_x - ( + self.width * self.ripple_scale) / 2, + self.center_y - ( + self.height * self.ripple_scale) / 2)) + StencilUse() + self.col_instruction = Color(rgba=self.ripple_color) + self.ellipse = Ellipse(size=(self.ripple_rad, self.ripple_rad), + pos=(self.center_x - self.ripple_rad / 2., + self.center_y - self.ripple_rad / 2.)) + StencilUnUse() + Ellipse(pos=self.pos, size=self.size) + StencilPop() + self.bind(ripple_color=self._set_color, + ripple_rad=self._set_ellipse) + + def _set_ellipse(self, instance, value): + super(CircularRippleBehavior, self)._set_ellipse(instance, value) + if self.ellipse.size[0] > self.width * .6 and not self.fading_out: + self.fade_out() + self.ellipse.pos = (self.center_x - self.ripple_rad / 2., + self.center_y - self.ripple_rad / 2.) diff --git a/src/kivymd/selectioncontrols.py b/src/kivymd/selectioncontrols.py new file mode 100644 index 00000000..b918428a --- /dev/null +++ b/src/kivymd/selectioncontrols.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- + +from kivy.lang import Builder +from kivy.properties import StringProperty, ListProperty, NumericProperty +from kivy.uix.behaviors import ToggleButtonBehavior +from kivy.uix.label import Label +from kivy.uix.floatlayout import FloatLayout +from kivy.properties import AliasProperty, BooleanProperty +from kivy.metrics import dp, sp +from kivy.animation import Animation +from kivy.utils import get_color_from_hex +from kivymd.color_definitions import colors +from kivymd.icon_definitions import md_icons +from kivymd.theming import ThemableBehavior +from kivymd.elevationbehavior import RoundElevationBehavior +from kivymd.ripplebehavior import CircularRippleBehavior +from kivy.uix.behaviors import ButtonBehavior +from kivy.uix.widget import Widget + +Builder.load_string(''' +: + canvas: + Clear + Color: + rgba: self.color + Rectangle: + texture: self.texture + size: self.texture_size + pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.) + + text: self._radio_icon if self.group else self._checkbox_icon + font_name: 'Icons' + font_size: sp(24) + color: self.theme_cls.primary_color if self.active else self.theme_cls.secondary_text_color + halign: 'center' + valign: 'middle' + +: + color: 1, 1, 1, 1 + canvas: + Color: + rgba: self.color + Ellipse: + size: self.size + pos: self.pos + +: + canvas.before: + Color: + rgba: self._track_color_disabled if self.disabled else \ + (self._track_color_active if self.active else self._track_color_normal) + Ellipse: + size: dp(16), dp(16) + pos: self.x, self.center_y - dp(8) + angle_start: 180 + angle_end: 360 + Rectangle: + size: self.width - dp(16), dp(16) + pos: self.x + dp(8), self.center_y - dp(8) + Ellipse: + size: dp(16), dp(16) + pos: self.right - dp(16), self.center_y - dp(8) + angle_start: 0 + angle_end: 180 + on_release: thumb.trigger_action() + + Thumb: + id: thumb + size_hint: None, None + size: dp(24), dp(24) + pos: root._thumb_pos + color: root.thumb_color_disabled if root.disabled else \ + (root.thumb_color_down if root.active else root.thumb_color) + elevation: 4 if root.active else 2 + on_release: setattr(root, 'active', not root.active) +''') + + +class MDCheckbox(ThemableBehavior, CircularRippleBehavior, + ToggleButtonBehavior, Label): + active = BooleanProperty(False) + + _checkbox_icon = StringProperty( + u"{}".format(md_icons['square-o'])) + _radio_icon = StringProperty(u"{}".format(md_icons['circle-o'])) + _icon_active = StringProperty(u"{}".format(md_icons['check-square'])) + + def __init__(self, **kwargs): + super(MDCheckbox, self).__init__(**kwargs) + self.register_event_type('on_active') + self.check_anim_out = Animation(font_size=0, duration=.1, t='out_quad') + self.check_anim_in = Animation(font_size=sp(24), duration=.1, + t='out_quad') + self.check_anim_out.bind( + on_complete=lambda *x: self.check_anim_in.start(self)) + + def on_state(self, *args): + if self.state == 'down': + self.check_anim_in.cancel(self) + self.check_anim_out.start(self) + self._radio_icon = u"{}".format(md_icons['dot-circle']) + self._checkbox_icon = u"{}".format(md_icons['check-square']) + self.active = True + else: + self.check_anim_in.cancel(self) + self.check_anim_out.start(self) + self._radio_icon = u"{}".format(md_icons['circle-o']) + self._checkbox_icon = u"{}".format( + md_icons['square-o']) + self.active = False + + def on_active(self, instance, value): + self.state = 'down' if value else 'normal' + + +class Thumb(RoundElevationBehavior, CircularRippleBehavior, ButtonBehavior, + Widget): + ripple_scale = NumericProperty(2) + + def _set_ellipse(self, instance, value): + self.ellipse.size = (self.ripple_rad, self.ripple_rad) + if self.ellipse.size[0] > self.width * 1.5 and not self.fading_out: + self.fade_out() + self.ellipse.pos = (self.center_x - self.ripple_rad / 2., + self.center_y - self.ripple_rad / 2.) + self.stencil.pos = ( + self.center_x - (self.width * self.ripple_scale) / 2, + self.center_y - (self.height * self.ripple_scale) / 2) + + +class MDSwitch(ThemableBehavior, ButtonBehavior, FloatLayout): + active = BooleanProperty(False) + + _thumb_color = ListProperty(get_color_from_hex(colors['Grey']['50'])) + + def _get_thumb_color(self): + return self._thumb_color + + def _set_thumb_color(self, color, alpha=None): + if len(color) == 2: + self._thumb_color = get_color_from_hex(colors[color[0]][color[1]]) + if alpha: + self._thumb_color[3] = alpha + elif len(color) == 4: + self._thumb_color = color + + thumb_color = AliasProperty(_get_thumb_color, _set_thumb_color, + bind=['_thumb_color']) + + _thumb_color_down = ListProperty([1, 1, 1, 1]) + + def _get_thumb_color_down(self): + return self._thumb_color_down + + def _set_thumb_color_down(self, color, alpha=None): + if len(color) == 2: + self._thumb_color_down = get_color_from_hex( + colors[color[0]][color[1]]) + if alpha: + self._thumb_color_down[3] = alpha + else: + self._thumb_color_down[3] = 1 + elif len(color) == 4: + self._thumb_color_down = color + + thumb_color_down = AliasProperty(_get_thumb_color_down, + _set_thumb_color_down, + bind=['_thumb_color_down']) + + _thumb_color_disabled = ListProperty( + get_color_from_hex(colors['Grey']['400'])) + + def _get_thumb_color_disabled(self): + return self._thumb_color_disabled + + def _set_thumb_color_disabled(self, color, alpha=None): + if len(color) == 2: + self._thumb_color_disabled = get_color_from_hex( + colors[color[0]][color[1]]) + if alpha: + self._thumb_color_disabled[3] = alpha + elif len(color) == 4: + self._thumb_color_disabled = color + + thumb_color_down = AliasProperty(_get_thumb_color_disabled, + _set_thumb_color_disabled, + bind=['_thumb_color_disabled']) + + _track_color_active = ListProperty() + _track_color_normal = ListProperty() + _track_color_disabled = ListProperty() + _thumb_pos = ListProperty([0, 0]) + + def __init__(self, **kwargs): + super(MDSwitch, self).__init__(**kwargs) + self.theme_cls.bind(theme_style=self._set_colors, + primary_color=self._set_colors, + primary_palette=self._set_colors) + self._set_colors() + + def _set_colors(self, *args): + self._track_color_normal = self.theme_cls.disabled_hint_text_color + if self.theme_cls.theme_style == 'Dark': + self._track_color_active = self.theme_cls.primary_color + self._track_color_active[3] = .5 + self._track_color_disabled = get_color_from_hex('FFFFFF') + self._track_color_disabled[3] = .1 + self.thumb_color = get_color_from_hex(colors['Grey']['400']) + self.thumb_color_down = get_color_from_hex( + colors[self.theme_cls.primary_palette]['200']) + self.thumb_color_disabled = get_color_from_hex( + colors['Grey']['800']) + else: + self._track_color_active = get_color_from_hex( + colors[self.theme_cls.primary_palette]['200']) + self._track_color_active[3] = .5 + self._track_color_disabled = self.theme_cls.disabled_hint_text_color + self.thumb_color_down = self.theme_cls.primary_color + + def on_pos(self, *args): + if self.active: + self._thumb_pos = (self.right - dp(12), self.center_y - dp(12)) + else: + self._thumb_pos = (self.x - dp(12), self.center_y - dp(12)) + self.bind(active=self._update_thumb) + + def _update_thumb(self, *args): + if self.active: + Animation.cancel_all(self, '_thumb_pos') + anim = Animation( + _thumb_pos=(self.right - dp(12), self.center_y - dp(12)), + duration=.2, + t='out_quad') + else: + Animation.cancel_all(self, '_thumb_pos') + anim = Animation( + _thumb_pos=(self.x - dp(12), self.center_y - dp(12)), + duration=.2, + t='out_quad') + anim.start(self) diff --git a/src/kivymd/slider.py b/src/kivymd/slider.py new file mode 100644 index 00000000..1166bea7 --- /dev/null +++ b/src/kivymd/slider.py @@ -0,0 +1,247 @@ +# -*- coding: utf-8 -*- + +from kivy.lang import Builder +from kivy.properties import StringProperty, ListProperty, NumericProperty,AliasProperty, BooleanProperty +from kivy.utils import get_color_from_hex +from kivy.metrics import dp, sp +from kivymd.color_definitions import colors +from kivymd.theming import ThemableBehavior +from kivy.uix.slider import Slider + + +Builder.load_string(''' +#:import Thumb kivymd.selectioncontrols.Thumb + +: + id: slider + canvas: + Clear + Color: + rgba: self._track_color_disabled if self.disabled else (self._track_color_active if self.active \ + else self._track_color_normal) + Rectangle: + size: (self.width - self.padding*2 - self._offset[0], dp(4)) if self.orientation == 'horizontal' \ + else (dp(4),self.height - self.padding*2 - self._offset[1]) + pos: (self.x + self.padding + self._offset[0], self.center_y - dp(4)) \ + if self.orientation == 'horizontal' else (self.center_x - dp(4),self.y + self.padding + self._offset[1]) + + # If 0 draw circle + Color: + rgba: [0,0,0,0] if not self._is_off else (self._track_color_disabled if self.disabled \ + else (self._track_color_active if self.active else self._track_color_normal)) + Line: + width: 2 + circle: (self.x+self.padding+dp(3),self.center_y-dp(2),8 if self.active else 6 ) \ + if self.orientation == 'horizontal' else (self.center_x-dp(2),self.y+self.padding+dp(3),8 \ + if self.active else 6) + + Color: + rgba: [0,0,0,0] if self._is_off \ + else (self.thumb_color_down if not self.disabled else self._track_color_disabled) + Rectangle: + size: ((self.width-self.padding*2)*self.value_normalized, sp(4)) \ + if slider.orientation == 'horizontal' else (sp(4), (self.height-self.padding*2)*self.value_normalized) + pos: (self.x + self.padding, self.center_y - dp(4)) if self.orientation == 'horizontal' \ + else (self.center_x - dp(4),self.y + self.padding) + Thumb: + id: thumb + size_hint: None, None + size: (dp(12), dp(12)) if root.disabled else ((dp(24), dp(24)) if root.active else (dp(16),dp(16))) + pos: (slider.value_pos[0] - dp(8), slider.center_y - thumb.height/2 - dp(2)) \ + if slider.orientation == 'horizontal' \ + else (slider.center_x - thumb.width/2 - dp(2), slider.value_pos[1]-dp(8)) + color: [0,0,0,0] if slider._is_off else (root._track_color_disabled if root.disabled \ + else root.thumb_color_down) + elevation: 0 if slider._is_off else (4 if root.active else 2) + +''') + + +class MDSlider(ThemableBehavior, Slider): + # If the slider is clicked + active = BooleanProperty(False) + + # Show the "off" ring when set to minimum value + show_off = BooleanProperty(True) + + # Internal state of ring + _is_off = BooleanProperty(False) + + # Internal adjustment to reposition sliders for ring + _offset = ListProperty((0, 0)) + + _thumb_color = ListProperty(get_color_from_hex(colors['Grey']['50'])) + + def _get_thumb_color(self): + return self._thumb_color + + def _set_thumb_color(self, color, alpha=None): + if len(color) == 2: + self._thumb_color = get_color_from_hex(colors[color[0]][color[1]]) + if alpha: + self._thumb_color[3] = alpha + elif len(color) == 4: + self._thumb_color = color + + thumb_color = AliasProperty(_get_thumb_color, _set_thumb_color, + bind=['_thumb_color']) + + _thumb_color_down = ListProperty([1, 1, 1, 1]) + + def _get_thumb_color_down(self): + return self._thumb_color_down + + def _set_thumb_color_down(self, color, alpha=None): + if len(color) == 2: + self._thumb_color_down = get_color_from_hex( + colors[color[0]][color[1]]) + if alpha: + self._thumb_color_down[3] = alpha + else: + self._thumb_color_down[3] = 1 + elif len(color) == 4: + self._thumb_color_down = color + + thumb_color_down = AliasProperty(_get_thumb_color_down, + _set_thumb_color_down, + bind=['_thumb_color_down']) + + _thumb_color_disabled = ListProperty( + get_color_from_hex(colors['Grey']['400'])) + + def _get_thumb_color_disabled(self): + return self._thumb_color_disabled + + def _set_thumb_color_disabled(self, color, alpha=None): + if len(color) == 2: + self._thumb_color_disabled = get_color_from_hex( + colors[color[0]][color[1]]) + if alpha: + self._thumb_color_disabled[3] = alpha + elif len(color) == 4: + self._thumb_color_disabled = color + + thumb_color_down = AliasProperty(_get_thumb_color_disabled, + _set_thumb_color_disabled, + bind=['_thumb_color_disabled']) + + _track_color_active = ListProperty() + _track_color_normal = ListProperty() + _track_color_disabled = ListProperty() + _thumb_pos = ListProperty([0, 0]) + + def __init__(self, **kwargs): + super(MDSlider, self).__init__(**kwargs) + self.theme_cls.bind(theme_style=self._set_colors, + primary_color=self._set_colors, + primary_palette=self._set_colors) + self._set_colors() + + def _set_colors(self, *args): + if self.theme_cls.theme_style == 'Dark': + self._track_color_normal = get_color_from_hex('FFFFFF') + self._track_color_normal[3] = .3 + self._track_color_active = self._track_color_normal + self._track_color_disabled = self._track_color_normal + self.thumb_color = get_color_from_hex(colors['Grey']['400']) + self.thumb_color_down = get_color_from_hex( + colors[self.theme_cls.primary_palette]['200']) + self.thumb_color_disabled = get_color_from_hex( + colors['Grey']['800']) + else: + self._track_color_normal = get_color_from_hex('000000') + self._track_color_normal[3] = 0.26 + self._track_color_active = get_color_from_hex('000000') + self._track_color_active[3] = 0.38 + self._track_color_disabled = get_color_from_hex('000000') + self._track_color_disabled[3] = 0.26 + self.thumb_color_down = self.theme_cls.primary_color + + def on_value_normalized(self, *args): + """ When the value == min set it to "off" state and make slider a ring """ + self._update_is_off() + + def on_show_off(self, *args): + self._update_is_off() + + def _update_is_off(self): + self._is_off = self.show_off and (self.value_normalized == 0) + + def on__is_off(self, *args): + self._update_offset() + + def on_active(self, *args): + self._update_offset() + + def _update_offset(self): + """ Offset is used to shift the sliders so the background color + shows through the off circle. + """ + d = 2 if self.active else 0 + self._offset = (dp(11+d), dp(11+d)) if self._is_off else (0, 0) + + def on_touch_down(self, touch): + if super(MDSlider, self).on_touch_down(touch): + self.active = True + + def on_touch_up(self,touch): + if super(MDSlider, self).on_touch_up(touch): + self.active = False +# thumb = self.ids['thumb'] +# if thumb.collide_point(*touch.pos): +# thumb.on_touch_down(touch) +# thumb.on_touch_up(touch) + +if __name__ == '__main__': + from kivy.app import App + from kivymd.theming import ThemeManager + + class SliderApp(App): + theme_cls = ThemeManager() + + def build(self): + return Builder.load_string(""" +BoxLayout: + orientation:'vertical' + BoxLayout: + size_hint_y:None + height: '48dp' + Label: + text:"Toggle disabled" + color: [0,0,0,1] + CheckBox: + on_press: slider.disabled = not slider.disabled + BoxLayout: + size_hint_y:None + height: '48dp' + Label: + text:"Toggle active" + color: [0,0,0,1] + CheckBox: + on_press: slider.active = not slider.active + BoxLayout: + size_hint_y:None + height: '48dp' + Label: + text:"Toggle show off" + color: [0,0,0,1] + CheckBox: + on_press: slider.show_off = not slider.show_off + + MDSlider: + id:slider + min:0 + max:100 + value: 40 + + MDSlider: + id:slider2 + orientation:"vertical" + min:0 + max:100 + value: 40 + +""") + + + SliderApp().run() diff --git a/src/kivymd/slidingpanel.py b/src/kivymd/slidingpanel.py new file mode 100644 index 00000000..b818505a --- /dev/null +++ b/src/kivymd/slidingpanel.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +from kivy.animation import Animation +from kivy.clock import Clock +from kivy.core.window import Window +from kivy.lang import Builder +from kivy.metrics import dp +from kivy.properties import OptionProperty, NumericProperty, StringProperty, \ + BooleanProperty, ListProperty +from kivy.uix.boxlayout import BoxLayout +from kivy.uix.relativelayout import RelativeLayout + +Builder.load_string(""" +#: import Window kivy.core.window.Window + + orientation: 'vertical' + size_hint_x: None + width: dp(320) + x: -1 * self.width if self.side == 'left' else Window.width + + + canvas: + Color: + rgba: root.color + Rectangle: + size: root.size +""") + + +class PanelShadow(BoxLayout): + color = ListProperty([0, 0, 0, 0]) + + +class SlidingPanel(BoxLayout): + anim_length_close = NumericProperty(0.3) + anim_length_open = NumericProperty(0.3) + animation_t_open = StringProperty('out_sine') + animation_t_close = StringProperty('out_sine') + side = OptionProperty('left', options=['left', 'right']) + + _open = False + + def __init__(self, **kwargs): + super(SlidingPanel, self).__init__(**kwargs) + self.shadow = PanelShadow() + Clock.schedule_once(lambda x: Window.add_widget(self.shadow,89), 0) + Clock.schedule_once(lambda x: Window.add_widget(self,90), 0) + + def toggle(self): + Animation.stop_all(self, 'x') + Animation.stop_all(self.shadow, 'color') + if self._open: + if self.side == 'left': + target_x = -1 * self.width + else: + target_x = Window.width + + sh_anim = Animation(duration=self.anim_length_open, + t=self.animation_t_open, + color=[0, 0, 0, 0]) + sh_anim.start(self.shadow) + self._get_main_animation(duration=self.anim_length_close, + t=self.animation_t_close, + x=target_x, + is_closing=True).start(self) + self._open = False + else: + if self.side == 'left': + target_x = 0 + else: + target_x = Window.width - self.width + Animation(duration=self.anim_length_open, t=self.animation_t_open, + color=[0, 0, 0, 0.5]).start(self.shadow) + self._get_main_animation(duration=self.anim_length_open, + t=self.animation_t_open, + x=target_x, + is_closing=False).start(self) + self._open = True + + def _get_main_animation(self, duration, t, x, is_closing): + return Animation(duration=duration, t=t, x=x) + + def on_touch_down(self, touch): + # Prevents touch events from propagating to anything below the widget. + super(SlidingPanel, self).on_touch_down(touch) + if self.collide_point(*touch.pos) or self._open: + return True + + def on_touch_up(self, touch): + if not self.collide_point(touch.x, touch.y) and self._open: + self.toggle() + return True + super(SlidingPanel, self).on_touch_up(touch) diff --git a/src/kivymd/snackbar.py b/src/kivymd/snackbar.py new file mode 100644 index 00000000..e0ac70e8 --- /dev/null +++ b/src/kivymd/snackbar.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +from collections import deque +from kivy.animation import Animation +from kivy.clock import Clock +from kivy.core.window import Window +from kivy.lang import Builder +from kivy.metrics import dp +from kivy.properties import ObjectProperty, StringProperty, NumericProperty +from kivy.uix.relativelayout import RelativeLayout +from kivymd.material_resources import DEVICE_TYPE + +Builder.load_string(''' +#:import Window kivy.core.window.Window +#:import get_color_from_hex kivy.utils.get_color_from_hex +#:import MDFlatButton kivymd.button.MDFlatButton +#:import MDLabel kivymd.label.MDLabel +#:import DEVICE_TYPE kivymd.material_resources.DEVICE_TYPE +<_SnackbarWidget> + canvas: + Color: + rgb: get_color_from_hex('323232') + Rectangle: + size: self.size + size_hint_y: None + size_hint_x: 1 if DEVICE_TYPE == 'mobile' else None + height: dp(48) if _label.texture_size[1] < dp(30) else dp(80) + width: dp(24) + _label.width + _spacer.width + root.padding_right if root.button_text == '' else dp(24) + \ + _label.width + _spacer.width + _button.width + root.padding_right + top: 0 + x: 0 if DEVICE_TYPE == 'mobile' else Window.width/2 - self.width/2 + BoxLayout: + width: Window.width - root.padding_right - _spacer.width - dp(24) if DEVICE_TYPE == 'mobile' and \ + root.button_text == '' else Window.width - root.padding_right - _button.width - _spacer.width - dp(24) \ + if DEVICE_TYPE == 'mobile' else _label.texture_size[0] if (dp(568) - root.padding_right - _button.width - \ + _spacer.width - _label.texture_size[0] - dp(24)) >= 0 else (dp(568) - root.padding_right - _button.width - \ + _spacer.width - dp(24)) + size_hint_x: None + x: dp(24) + MDLabel: + id: _label + text: root.text + size: self.texture_size + BoxLayout: + id: _spacer + size_hint_x: None + x: _label.right + width: 0 + MDFlatButton: + id: _button + text: root.button_text + size_hint_x: None + x: _spacer.right if root.button_text != '' else root.right + center_y: root.height/2 + on_release: root.button_callback() +''') + + +class _SnackbarWidget(RelativeLayout): + text = StringProperty() + button_text = StringProperty() + button_callback = ObjectProperty() + duration = NumericProperty() + padding_right = NumericProperty(dp(24)) + + def __init__(self, text, duration, button_text='', button_callback=None, + **kwargs): + super(_SnackbarWidget, self).__init__(**kwargs) + self.text = text + self.button_text = button_text + self.button_callback = button_callback + self.duration = duration + self.ids['_label'].text_size = (None, None) + + def begin(self): + if self.button_text == '': + self.remove_widget(self.ids['_button']) + else: + self.ids['_spacer'].width = dp(16) if \ + DEVICE_TYPE == "mobile" else dp(40) + self.padding_right = dp(16) + Window.add_widget(self) + anim = Animation(y=0, duration=.3, t='out_quad') + anim.start(self) + Clock.schedule_once(lambda dt: self.die(), self.duration) + + def die(self): + anim = Animation(top=0, duration=.3, t='out_quad') + anim.bind(on_complete=lambda *args: _play_next(self)) + anim.bind(on_complete=lambda *args: Window.remove_widget(self)) + anim.start(self) + + +queue = deque() +playing = False + + +def make(text, button_text=None, button_callback=None, duration=3): + if button_text is not None and button_callback is not None: + queue.append(_SnackbarWidget(text=text, + button_text=button_text, + button_callback=button_callback, + duration=duration)) + else: + queue.append(_SnackbarWidget(text=text, + duration=duration)) + _play_next() + + +def _play_next(dying_widget=None): + global playing + if (dying_widget or not playing) and len(queue) > 0: + playing = True + queue.popleft().begin() + elif len(queue) == 0: + playing = False diff --git a/src/kivymd/spinner.py b/src/kivymd/spinner.py new file mode 100644 index 00000000..238062db --- /dev/null +++ b/src/kivymd/spinner.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- + +from kivy.lang import Builder +from kivy.uix.widget import Widget +from kivy.properties import NumericProperty, ListProperty, BooleanProperty +from kivy.animation import Animation +from kivymd.theming import ThemableBehavior +from kivy.clock import Clock + +Builder.load_string(''' +: + canvas.before: + PushMatrix + Rotate: + angle: self._rotation_angle + origin: self.center + canvas: + Color: + rgba: self.color + a: self._alpha + Line: + circle: self.center_x, self.center_y, self.width / 2, \ + self._angle_start, self._angle_end + cap: 'square' + width: dp(2) + canvas.after: + PopMatrix + +''') + + +class MDSpinner(ThemableBehavior, Widget): + """:class:`MDSpinner` is an implementation of the circular progress + indicator in Google's Material Design. + + It can be used either as an indeterminate indicator that loops while + the user waits for something to happen, or as a determinate indicator. + + Set :attr:`determinate` to **True** to activate determinate mode, and + :attr:`determinate_time` to set the duration of the animation. + """ + + determinate = BooleanProperty(False) + """:attr:`determinate` is a :class:`~kivy.properties.BooleanProperty` and + defaults to False + """ + + determinate_time = NumericProperty(2) + """:attr:`determinate_time` is a :class:`~kivy.properties.NumericProperty` + and defaults to 2 + """ + + active = BooleanProperty(True) + """Use :attr:`active` to start or stop the spinner. + + :attr:`active` is a :class:`~kivy.properties.BooleanProperty` and + defaults to True + """ + + color = ListProperty([]) + """:attr:`color` is a :class:`~kivy.properties.ListProperty` and + defaults to 'self.theme_cls.primary_color' + """ + + _alpha = NumericProperty(0) + _rotation_angle = NumericProperty(360) + _angle_start = NumericProperty(0) + _angle_end = NumericProperty(8) + + def __init__(self, **kwargs): + super(MDSpinner, self).__init__(**kwargs) + Clock.schedule_interval(self._update_color, 5) + self.color = self.theme_cls.primary_color + self._alpha_anim_in = Animation(_alpha=1, duration=.8, t='out_quad') + self._alpha_anim_out = Animation(_alpha=0, duration=.3, t='out_quad') + self._alpha_anim_out.bind(on_complete=self._reset) + + if self.determinate: + self._start_determinate() + else: + self._start_loop() + + def _update_color(self, *args): + self.color = self.theme_cls.primary_color + + def _start_determinate(self, *args): + self._alpha_anim_in.start(self) + + _rot_anim = Animation(_rotation_angle=0, + duration=self.determinate_time * .7, + t='out_quad') + _rot_anim.start(self) + + _angle_start_anim = Animation(_angle_end=360, + duration=self.determinate_time, + t='in_out_quad') + _angle_start_anim.bind(on_complete=lambda *x: \ + self._alpha_anim_out.start(self)) + + _angle_start_anim.start(self) + + def _start_loop(self, *args): + if self._alpha == 0: + _rot_anim = Animation(_rotation_angle=0, + duration=2, + t='linear') + _rot_anim.start(self) + + self._alpha = 1 + self._alpha_anim_in.start(self) + _angle_start_anim = Animation(_angle_end=self._angle_end + 270, + duration=.6, + t='in_out_cubic') + _angle_start_anim.bind(on_complete=self._anim_back) + _angle_start_anim.start(self) + + def _anim_back(self, *args): + _angle_back_anim = Animation(_angle_start=self._angle_end - 8, + duration=.6, + t='in_out_cubic') + _angle_back_anim.bind(on_complete=self._start_loop) + + _angle_back_anim.start(self) + + def on__rotation_angle(self, *args): + if self._rotation_angle == 0: + self._rotation_angle = 360 + if not self.determinate: + _rot_anim = Animation(_rotation_angle=0, + duration=2) + _rot_anim.start(self) + + def _reset(self, *args): + Animation.cancel_all(self, '_angle_start', '_rotation_angle', + '_angle_end', '_alpha') + self._angle_start = 0 + self._angle_end = 8 + self._rotation_angle = 360 + self._alpha = 0 + self.active = False + + def on_active(self, *args): + if not self.active: + self._reset() + else: + if self.determinate: + self._start_determinate() + else: + self._start_loop() diff --git a/src/kivymd/tabs.py b/src/kivymd/tabs.py new file mode 100644 index 00000000..c09f21c2 --- /dev/null +++ b/src/kivymd/tabs.py @@ -0,0 +1,303 @@ +# Created on Jul 8, 2016 +# +# The default kivy tab implementation seems like a stupid design to me. The +# ScreenManager is much better. +# +# @author: jrm + +from kivy.properties import StringProperty, DictProperty, ListProperty, \ + ObjectProperty, OptionProperty, BoundedNumericProperty +from kivy.uix.screenmanager import Screen +from kivy.lang import Builder +from kivy.metrics import dp +from kivy.uix.boxlayout import BoxLayout +from kivymd.theming import ThemableBehavior +from kivymd.backgroundcolorbehavior import BackgroundColorBehavior +from kivymd.button import MDFlatButton + +Builder.load_string(""" +: + id: panel + orientation: 'vertical' if panel.tab_orientation in ['top','bottom'] else 'horizontal' + ScrollView: + id: scroll_view + size_hint_y: None + height: panel._tab_display_height[panel.tab_display_mode] + MDTabBar: + id: tab_bar + size_hint_y: None + height: panel._tab_display_height[panel.tab_display_mode] + background_color: panel.tab_color or panel.theme_cls.primary_color + canvas: + # Draw bottom border + Color: + rgba: (panel.tab_border_color or panel.tab_color or panel.theme_cls.primary_dark) + Rectangle: + size: (self.width,dp(2)) + ScreenManager: + id: tab_manager + current: root.current + screens: root.tabs + + +: + canvas: + Color: + rgba: self.panel.tab_color or self.panel.theme_cls.primary_color + Rectangle: + size: self.size + pos: self.pos + + # Draw indicator + Color: + rgba: (self.panel.tab_indicator_color or self.panel.theme_cls.accent_color) if self.tab \ + and self.tab.manager and self.tab.manager.current==self.tab.name else (self.panel.tab_border_color \ + or self.panel.tab_color or self.panel.theme_cls.primary_dark) + Rectangle: + size: (self.width,dp(2)) + pos: self.pos + + size_hint: (None,None) #(1, None) if self.panel.tab_width_mode=='fixed' else (None,None) + width: (_label.texture_size[0] + dp(16)) + padding: (dp(12), 0) + theme_text_color: 'Custom' + text_color: (self.panel.tab_text_color_active or app.theme_cls.bg_light if app.theme_cls.theme_style == "Light" \ + else app.theme_cls.opposite_bg_light) if self.tab and self.tab.manager \ + and self.tab.manager.current==self.tab.name else (self.panel.tab_text_color \ + or self.panel.theme_cls.primary_light) + on_press: + self.tab.dispatch('on_tab_press') + # self.tab.manager.current = self.tab.name + on_release: self.tab.dispatch('on_tab_release') + on_touch_down: self.tab.dispatch('on_tab_touch_down',*args) + on_touch_move: self.tab.dispatch('on_tab_touch_move',*args) + on_touch_up: self.tab.dispatch('on_tab_touch_up',*args) + + + MDLabel: + id: _label + text: root.tab.text if root.panel.tab_display_mode == 'text' else u"{}".format(md_icons[root.tab.icon]) + font_style: 'Button' if root.panel.tab_display_mode == 'text' else 'Icon' + size_hint_x: None# if root.panel.tab_width_mode=='fixed' else 1 + text_size: (None, root.height) + height: self.texture_size[1] + theme_text_color: root.theme_text_color + text_color: root.text_color + valign: 'middle' + halign: 'center' + opposite_colors: root.opposite_colors +""") + + +class MDTabBar(ThemableBehavior, BackgroundColorBehavior, BoxLayout): + pass + + +class MDTabHeader(MDFlatButton): + """ Internal widget for headers based on MDFlatButton""" + + width = BoundedNumericProperty(dp(None), min=dp(72), max=dp(264), errorhandler=lambda x: dp(72)) + tab = ObjectProperty(None) + panel = ObjectProperty(None) + + +class MDTab(Screen): + """ A tab is simply a screen with meta information + that defines the content that goes in the tab header. + """ + __events__ = ('on_tab_touch_down', 'on_tab_touch_move', 'on_tab_touch_up', 'on_tab_press', 'on_tab_release') + + # Tab header text + text = StringProperty("") + + # Tab header icon + icon = StringProperty("circle") + + # Tab dropdown menu items + menu_items = ListProperty() + + # Tab dropdown menu (if you want to customize it) + menu = ObjectProperty(None) + + def __init__(self, **kwargs): + super(MDTab, self).__init__(**kwargs) + self.index = 0 + self.parent_widget = None + self.register_event_type('on_tab_touch_down') + self.register_event_type('on_tab_touch_move') + self.register_event_type('on_tab_touch_up') + self.register_event_type('on_tab_press') + self.register_event_type('on_tab_release') + + def on_leave(self, *args): + self.parent_widget.ids.tab_manager.transition.direction = self.parent_widget.prev_dir + + def on_tab_touch_down(self, *args): + pass + + def on_tab_touch_move(self, *args): + pass + + def on_tab_touch_up(self, *args): + pass + + def on_tab_press(self, *args): + par = self.parent_widget + if par.previous_tab is not self: + par.prev_dir = str(par.ids.tab_manager.transition.direction) + if par.previous_tab.index > self.index: + par.ids.tab_manager.transition.direction = "right" + elif par.previous_tab.index < self.index: + par.ids.tab_manager.transition.direction = "left" + par.ids.tab_manager.current = self.name + par.previous_tab = self + + def on_tab_release(self, *args): + pass + + def __repr__(self): + return "".format(self.name, self.text) + + +class MDTabbedPanel(ThemableBehavior, BackgroundColorBehavior, BoxLayout): + """ A tab panel that is implemented by delegating all tabs + to a ScreenManager. + """ + # If tabs should fill space + tab_width_mode = OptionProperty('stacked', options=['stacked', 'fixed']) + + # Where the tabs go + tab_orientation = OptionProperty('top', options=['top']) # ,'left','bottom','right']) + + # How tabs are displayed + tab_display_mode = OptionProperty('text', options=['text', 'icons']) # ,'both']) + _tab_display_height = DictProperty({'text': dp(46), 'icons': dp(46), 'both': dp(72)}) + + # Tab background color (leave empty for theme color) + tab_color = ListProperty([]) + + # Tab text color in normal state (leave empty for theme color) + tab_text_color = ListProperty([]) + + # Tab text color in active state (leave empty for theme color) + tab_text_color_active = ListProperty([]) + + # Tab indicator color (leave empty for theme color) + tab_indicator_color = ListProperty([]) + + # Tab bar bottom border color (leave empty for theme color) + tab_border_color = ListProperty([]) + + # List of all the tabs so you can dynamically change them + tabs = ListProperty([]) + + # Current tab name + current = StringProperty(None) + + def __init__(self, **kwargs): + super(MDTabbedPanel, self).__init__(**kwargs) + self.previous_tab = None + self.prev_dir = None + self.index = 0 + self._refresh_tabs() + + def on_tab_width_mode(self, *args): + self._refresh_tabs() + + def on_tab_display_mode(self, *args): + self._refresh_tabs() + + def _refresh_tabs(self): + """ Refresh all tabs """ + # if fixed width, use a box layout + if not self.ids: + return + tab_bar = self.ids.tab_bar + tab_bar.clear_widgets() + tab_manager = self.ids.tab_manager + for tab in tab_manager.screens: + tab_header = MDTabHeader(tab=tab, + panel=self, + height=tab_bar.height, + ) + tab_bar.add_widget(tab_header) + + def add_widget(self, widget, **kwargs): + """ Add tabs to the screen or the layout. + :param widget: The widget to add. + """ + d = {} + if isinstance(widget, MDTab): + self.index += 1 + if self.index == 1: + self.previous_tab = widget + widget.index = self.index + widget.parent_widget = self + self.ids.tab_manager.add_widget(widget) + self._refresh_tabs() + else: + super(MDTabbedPanel, self).add_widget(widget) + + def remove_widget(self, widget): + """ Remove tabs from the screen or the layout. + :param widget: The widget to remove. + """ + self.index -= 1 + if isinstance(widget, MDTab): + self.ids.tab_manager.remove_widget(widget) + self._refresh_tabs() + else: + super(MDTabbedPanel, self).remove_widget(widget) + + +if __name__ == '__main__': + from kivy.app import App + from kivymd.theming import ThemeManager + + class TabsApp(App): + theme_cls = ThemeManager() + + def build(self): + from kivy.core.window import Window + Window.size = (540, 720) + # self.theme_cls.theme_style = 'Dark' + + return Builder.load_string(""" +#:import Toolbar kivymd.toolbar.Toolbar +BoxLayout: + orientation:'vertical' + Toolbar: + id: toolbar + title: 'Page title' + background_color: app.theme_cls.primary_color + left_action_items: [['menu', lambda x: '']] + right_action_items: [['search', lambda x: ''],['more-vert',lambda x:'']] + MDTabbedPanel: + id: tab_mgr + tab_display_mode:'icons' + + MDTab: + name: 'music' + text: "Music" # Why are these not set!!! + icon: "playlist-audio" + MDLabel: + font_style: 'Body1' + theme_text_color: 'Primary' + text: "Here is my music list :)" + halign: 'center' + MDTab: + name: 'movies' + text: 'Movies' + icon: "movie" + + MDLabel: + font_style: 'Body1' + theme_text_color: 'Primary' + text: "Show movies here :)" + halign: 'center' + + +""") + + + TabsApp().run() diff --git a/src/kivymd/textfields.py b/src/kivymd/textfields.py new file mode 100644 index 00000000..18de10e6 --- /dev/null +++ b/src/kivymd/textfields.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- + +from kivy.lang import Builder +from kivy.uix.textinput import TextInput +from kivy.properties import ObjectProperty, NumericProperty, StringProperty, \ + ListProperty, BooleanProperty +from kivy.metrics import sp, dp +from kivy.animation import Animation +from kivymd.label import MDLabel +from kivymd.theming import ThemableBehavior +from kivy.clock import Clock + +Builder.load_string(''' +: + canvas.before: + Clear + Color: + rgba: self.line_color_normal + Line: + id: "the_line" + points: self.x, self.y + dp(8), self.x + self.width, self.y + dp(8) + width: 1 + dash_length: dp(3) + dash_offset: 2 if self.disabled else 0 + Color: + rgba: self._current_line_color + Rectangle: + size: self._line_width, dp(2) + pos: self.center_x - (self._line_width / 2), self.y + dp(8) + Color: + rgba: self._current_error_color + Rectangle: + texture: self._msg_lbl.texture + size: self._msg_lbl.texture_size + pos: self.x, self.y - dp(8) + Color: + rgba: (self._current_line_color if self.focus and not self.cursor_blink \ + else (0, 0, 0, 0)) + Rectangle: + pos: [int(x) for x in self.cursor_pos] + size: 1, -self.line_height + Color: + #rgba: self._hint_txt_color if not self.text and not self.focus\ + #else (self.line_color_focus if not self.text or self.focus\ + #else self.line_color_normal) + rgba: self._current_hint_text_color + Rectangle: + texture: self._hint_lbl.texture + size: self._hint_lbl.texture_size + pos: self.x, self.y + self._hint_y + Color: + rgba: self.disabled_foreground_color if self.disabled else \ + (self.hint_text_color if not self.text and not self.focus else \ + self.foreground_color) + + font_name: 'Roboto' + foreground_color: app.theme_cls.text_color + font_size: sp(16) + bold: False + padding: 0, dp(16), 0, dp(10) + multiline: False + size_hint_y: None + height: dp(48) +''') + + +class SingleLineTextField(ThemableBehavior, TextInput): + line_color_normal = ListProperty() + line_color_focus = ListProperty() + error_color = ListProperty() + error = BooleanProperty(False) + message = StringProperty("") + message_mode = StringProperty("none") + mode = message_mode + + _hint_txt_color = ListProperty() + _hint_lbl = ObjectProperty() + _hint_lbl_font_size = NumericProperty(sp(16)) + _hint_y = NumericProperty(dp(10)) + _error_label = ObjectProperty() + _line_width = NumericProperty(0) + _hint_txt = StringProperty('') + _current_line_color = line_color_focus + _current_error_color = ListProperty([0.0, 0.0, 0.0, 0.0]) + _current_hint_text_color = _hint_txt_color + + def __init__(self, **kwargs): + Clock.schedule_interval(self._update_color, 5) + self._msg_lbl = MDLabel(font_style='Caption', + theme_text_color='Error', + halign='left', + valign='middle', + text=self.message) + + self._hint_lbl = MDLabel(font_style='Subhead', + halign='left', + valign='middle') + super(SingleLineTextField, self).__init__(**kwargs) + self.line_color_normal = self.theme_cls.divider_color + self.line_color_focus = list(self.theme_cls.primary_color) + self.base_line_color_focus = list(self.theme_cls.primary_color) + self.error_color = self.theme_cls.error_color + + self._hint_txt_color = self.theme_cls.disabled_hint_text_color + self.hint_text_color = (1, 1, 1, 0) + self.cursor_color = self.theme_cls.primary_color + self.bind(message=self._set_msg, + hint_text=self._set_hint, + _hint_lbl_font_size=self._hint_lbl.setter('font_size'), + message_mode=self._set_mode) + self.hint_anim_in = Animation(_hint_y=dp(34), + _hint_lbl_font_size=sp(12), duration=.2, + t='out_quad') + + self.hint_anim_out = Animation(_hint_y=dp(10), + _hint_lbl_font_size=sp(16), duration=.2, + t='out_quad') + + def _update_color(self, *args): + self.line_color_normal = self.theme_cls.divider_color + self.base_line_color_focus = list(self.theme_cls.primary_color) + if not self.focus and not self.error: + self.line_color_focus = self.theme_cls.primary_color + Animation(duration=.2, _current_hint_text_color=self.theme_cls.disabled_hint_text_color).start(self) + if self.mode == "persistent": + Animation(duration=.1, _current_error_color=self.theme_cls.disabled_hint_text_color).start(self) + if self.focus and not self.error: + self.cursor_color = self.theme_cls.primary_color + + def on_hint_text_color(self, instance, color): + self._hint_txt_color = self.theme_cls.disabled_hint_text_color + self.hint_text_color = (1, 1, 1, 0) + + def on_width(self, instance, width): + if self.focus and instance is not None or self.error and instance is not None: + self._line_width = width + self.anim = Animation(_line_width=width, duration=.2, t='out_quad') + self._msg_lbl.width = self.width + self._hint_lbl.width = self.width + + def on_pos(self, *args): + self.hint_anim_in = Animation(_hint_y=dp(34), + _hint_lbl_font_size=sp(12), duration=.2, + t='out_quad') + self.hint_anim_out = Animation(_hint_y=dp(10), + _hint_lbl_font_size=sp(16), duration=.2, + t='out_quad') + + def on_focus(self, *args): + if self.focus: + Animation.cancel_all(self, '_line_width', '_hint_y', + '_hint_lbl_font_size') + if len(self.text) == 0: + self.hint_anim_in.start(self) + if self.error: + Animation(duration=.2, _current_hint_text_color=self.error_color).start(self) + if self.mode == "on_error": + Animation(duration=.2, _current_error_color=self.error_color).start(self) + elif self.mode == "persistent": + Animation(duration=.2, _current_error_color=self.theme_cls.disabled_hint_text_color).start(self) + elif self.mode == "on_focus": + Animation(duration=.2, _current_error_color=self.theme_cls.disabled_hint_text_color).start(self) + else: + pass + elif not self.error: + self.on_width(None, self.width) + self.anim.start(self) + Animation(duration=.2, _current_hint_text_color=self.line_color_focus).start(self) + if self.mode == "on_error": + Animation(duration=.2, _current_error_color=(0, 0, 0, 0)).start(self) + if self.mode == "persistent": + Animation(duration=.2, _current_error_color=self.theme_cls.disabled_hint_text_color).start(self) + elif self.mode == "on_focus": + Animation(duration=.2, _current_error_color=self.theme_cls.disabled_hint_text_color).start(self) + else: + pass + else: + Animation.cancel_all(self, '_line_width', '_hint_y', + '_hint_lbl_font_size') + if len(self.text) == 0: + self.hint_anim_out.start(self) + if not self.error: + self.line_color_focus = self.base_line_color_focus + Animation(duration=.2, _current_line_color=self.line_color_focus, + _current_hint_text_color=self.theme_cls.disabled_hint_text_color).start(self) + if self.mode == "on_error": + Animation(duration=.2, _current_error_color=(0, 0, 0, 0)).start(self) + elif self.mode == "persistent": + Animation(duration=.2, _current_error_color=self.theme_cls.disabled_hint_text_color).start(self) + elif self.mode == "on_focus": + Animation(duration=.2, _current_error_color=(0, 0, 0, 0)).start(self) + + self.on_width(None, 0) + self.anim.start(self) + elif self.error: + Animation(duration=.2, _current_line_color=self.error_color, + _current_hint_text_color=self.error_color).start(self) + if self.mode == "on_error": + Animation(duration=.2, _current_error_color=self.error_color).start(self) + elif self.mode == "persistent": + Animation(duration=.2, _current_error_color=self.theme_cls.disabled_hint_text_color).start(self) + elif self.mode == "on_focus": + Animation(duration=.2, _current_error_color=(0, 0, 0, 0)).start(self) + + def _set_hint(self, instance, text): + self._hint_lbl.text = text + + def _set_msg(self, instance, text): + self._msg_lbl.text = text + self.message = text + + def _set_mode(self, instance, text): + self.mode = text + if self.mode == "persistent": + Animation(duration=.1, _current_error_color=self.theme_cls.disabled_hint_text_color).start(self) diff --git a/src/kivymd/theme_picker.py b/src/kivymd/theme_picker.py new file mode 100644 index 00000000..e5104ce6 --- /dev/null +++ b/src/kivymd/theme_picker.py @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- + +from kivy.lang import Builder +from kivy.uix.modalview import ModalView +from kivy.uix.floatlayout import FloatLayout +from kivy.uix.boxlayout import BoxLayout +from kivymd.button import MDFlatButton, MDIconButton +from kivymd.theming import ThemableBehavior +from kivymd.elevationbehavior import ElevationBehavior +from kivy.properties import ObjectProperty, ListProperty +from kivymd.label import MDLabel +from kivy.metrics import dp +from kivy.utils import get_color_from_hex +from kivymd.color_definitions import colors + +Builder.load_string(""" +#:import SingleLineTextField kivymd.textfields.SingleLineTextField +#:import MDTabbedPanel kivymd.tabs.MDTabbedPanel +#:import MDTab kivymd.tabs.MDTab +: + size_hint: (None, None) + size: dp(260), dp(120)+dp(290) + pos_hint: {'center_x': .5, 'center_y': .5} + canvas: + Color: + rgb: app.theme_cls.primary_color + Rectangle: + size: dp(260), dp(120) + pos: root.pos[0], root.pos[1] + root.height-dp(120) + Color: + rgb: app.theme_cls.bg_normal + Rectangle: + size: dp(260), dp(290) + pos: root.pos[0], root.pos[1] + root.height-(dp(120)+dp(290)) + + MDFlatButton: + pos: root.pos[0]+root.size[0]-dp(72), root.pos[1] + dp(10) + text: "Close" + on_release: root.dismiss() + MDLabel: + font_style: "Headline" + text: "Change theme" + size_hint: (None, None) + size: dp(160), dp(50) + pos_hint: {'center_x': 0.5, 'center_y': 0.9} + MDTabbedPanel: + size_hint: (None, None) + size: dp(260), root.height-dp(135) + pos_hint: {'center_x': 0.5, 'center_y': 0.475} + id: tab_panel + tab_display_mode:'text' + + MDTab: + name: 'color' + text: "Theme Color" + BoxLayout: + spacing: dp(4) + size_hint: (None, None) + size: dp(270), root.height # -dp(120) + pos_hint: {'center_x': 0.532, 'center_y': 0.89} + orientation: 'vertical' + BoxLayout: + size_hint: (None, None) + pos_hint: {'center_x': 0.5, 'center_y': 0.5} + size: dp(230), dp(40) + pos: self.pos + halign: 'center' + orientation: 'horizontal' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Red') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Red' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Pink') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Pink' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Purple') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Purple' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('DeepPurple') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'DeepPurple' + BoxLayout: + size_hint: (None, None) + pos_hint: {'center_x': .5, 'center_y': 0.5} + size: dp(230), dp(40) + pos: self.pos + halign: 'center' + orientation: 'horizontal' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Indigo') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Indigo' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Blue') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Blue' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('LightBlue') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'LightBlue' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Cyan') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Cyan' + BoxLayout: + size_hint: (None, None) + pos_hint: {'center_x': .5, 'center_y': 0.5} + size: dp(230), dp(40) + pos: self.pos + halign: 'center' + orientation: 'horizontal' + padding: 0, 0, 0, dp(1) + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Teal') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Teal' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Green') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Green' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('LightGreen') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'LightGreen' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Lime') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Lime' + BoxLayout: + size_hint: (None, None) + pos_hint: {'center_x': .5, 'center_y': 0.5} + size: dp(230), dp(40) + pos: self.pos + orientation: 'horizontal' + halign: 'center' + padding: 0, 0, 0, dp(1) + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Yellow') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Yellow' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Amber') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Amber' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Orange') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Orange' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('DeepOrange') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'DeepOrange' + BoxLayout: + size_hint: (None, None) + pos_hint: {'center_x': .5, 'center_y': 0.5} + size: dp(230), dp(40) + #pos: self.pos + orientation: 'horizontal' + padding: 0, 0, 0, dp(1) + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Brown') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Brown' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('Grey') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'Grey' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + #pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: root.rgb_hex('BlueGrey') + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.primary_palette = 'BlueGrey' + BoxLayout: + MDIconButton: + size: dp(40), dp(40) + size_hint: (None, None) + canvas: + Color: + rgba: app.theme_cls.bg_normal + Ellipse: + size: self.size + pos: self.pos + disabled: True + + MDTab: + name: 'style' + text: "Theme Style" + BoxLayout: + size_hint: (None, None) + pos_hint: {'center_x': .3, 'center_y': 0.5} + size: self.size + pos: self.pos + halign: 'center' + spacing: dp(10) + BoxLayout: + halign: 'center' + size_hint: (None, None) + size: dp(100), dp(100) + pos: self.pos + pos_hint: {'center_x': .3, 'center_y': 0.5} + MDIconButton: + size: dp(100), dp(100) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: 1, 1, 1, 1 + Ellipse: + size: self.size + pos: self.pos + Color: + rgba: 0, 0, 0, 1 + Line: + width: 1. + circle: (self.center_x, self.center_y, 50) + on_release: app.theme_cls.theme_style = 'Light' + BoxLayout: + halign: 'center' + size_hint: (None, None) + size: dp(100), dp(100) + MDIconButton: + size: dp(100), dp(100) + pos: self.pos + size_hint: (None, None) + canvas: + Color: + rgba: 0, 0, 0, 1 + Ellipse: + size: self.size + pos: self.pos + on_release: app.theme_cls.theme_style = 'Dark' +""") + + +class MDThemePicker(ThemableBehavior, FloatLayout, ModalView, ElevationBehavior): + # background_color = ListProperty([0, 0, 0, 0]) + time = ObjectProperty() + + def __init__(self, **kwargs): + super(MDThemePicker, self).__init__(**kwargs) + + def rgb_hex(self, col): + return get_color_from_hex(colors[col][self.theme_cls.accent_hue]) + + +if __name__ == "__main__": + from kivy.app import App + from kivymd.theming import ThemeManager + + class ThemePickerApp(App): + theme_cls = ThemeManager() + + def build(self): + main_widget = Builder.load_string(""" +#:import MDRaisedButton kivymd.button.MDRaisedButton +#:import MDThemePicker kivymd.theme_picker.MDThemePicker +FloatLayout: + MDRaisedButton: + size_hint: None, None + pos_hint: {'center_x': .5, 'center_y': .5} + size: 3 * dp(48), dp(48) + center_x: self.parent.center_x + text: 'Open theme picker' + on_release: MDThemePicker().open() + opposite_colors: True +""") + return main_widget + + ThemePickerApp().run() diff --git a/src/kivymd/theming.py b/src/kivymd/theming.py new file mode 100644 index 00000000..3172ee58 --- /dev/null +++ b/src/kivymd/theming.py @@ -0,0 +1,350 @@ +# -*- coding: utf-8 -*- +from kivy.app import App +from kivy.core.text import LabelBase +from kivy.core.window import Window +from kivy.clock import Clock +from kivy.metrics import dp +from kivy.properties import OptionProperty, AliasProperty, ObjectProperty, \ + StringProperty, ListProperty, BooleanProperty +from kivy.uix.widget import Widget +from kivy.utils import get_color_from_hex +from kivy.atlas import Atlas +from kivymd.color_definitions import colors +from kivymd.material_resources import FONTS, DEVICE_TYPE +from kivymd import images_path + +for font in FONTS: + LabelBase.register(**font) + + +class ThemeManager(Widget): + primary_palette = OptionProperty( + 'Blue', + options=['Pink', 'Blue', 'Indigo', 'BlueGrey', 'Brown', + 'LightBlue', + 'Purple', 'Grey', 'Yellow', 'LightGreen', 'DeepOrange', + 'Green', 'Red', 'Teal', 'Orange', 'Cyan', 'Amber', + 'DeepPurple', 'Lime']) + + primary_hue = OptionProperty( + '500', + options=['50', '100', '200', '300', '400', '500', '600', '700', + '800', + '900', 'A100', 'A200', 'A400', 'A700']) + + primary_light_hue = OptionProperty( + '200', + options=['50', '100', '200', '300', '400', '500', '600', '700', + '800', + '900', 'A100', 'A200', 'A400', 'A700']) + + primary_dark_hue = OptionProperty( + '700', + options=['50', '100', '200', '300', '400', '500', '600', '700', + '800', + '900', 'A100', 'A200', 'A400', 'A700']) + + def _get_primary_color(self): + return get_color_from_hex( + colors[self.primary_palette][self.primary_hue]) + + primary_color = AliasProperty(_get_primary_color, + bind=('primary_palette', 'primary_hue')) + + def _get_primary_light(self): + return get_color_from_hex( + colors[self.primary_palette][self.primary_light_hue]) + + primary_light = AliasProperty( + _get_primary_light, bind=('primary_palette', 'primary_light_hue')) + + def _get_primary_dark(self): + return get_color_from_hex( + colors[self.primary_palette][self.primary_dark_hue]) + + primary_dark = AliasProperty(_get_primary_dark, + bind=('primary_palette', 'primary_dark_hue')) + + accent_palette = OptionProperty( + 'Amber', + options=['Pink', 'Blue', 'Indigo', 'BlueGrey', 'Brown', + 'LightBlue', + 'Purple', 'Grey', 'Yellow', 'LightGreen', 'DeepOrange', + 'Green', 'Red', 'Teal', 'Orange', 'Cyan', 'Amber', + 'DeepPurple', 'Lime']) + + accent_hue = OptionProperty( + '500', + options=['50', '100', '200', '300', '400', '500', '600', '700', + '800', + '900', 'A100', 'A200', 'A400', 'A700']) + + accent_light_hue = OptionProperty( + '200', + options=['50', '100', '200', '300', '400', '500', '600', '700', + '800', + '900', 'A100', 'A200', 'A400', 'A700']) + + accent_dark_hue = OptionProperty( + '700', + options=['50', '100', '200', '300', '400', '500', '600', '700', + '800', + '900', 'A100', 'A200', 'A400', 'A700']) + + def _get_accent_color(self): + return get_color_from_hex( + colors[self.accent_palette][self.accent_hue]) + + accent_color = AliasProperty(_get_accent_color, + bind=['accent_palette', 'accent_hue']) + + def _get_accent_light(self): + return get_color_from_hex( + colors[self.accent_palette][self.accent_light_hue]) + + accent_light = AliasProperty(_get_accent_light, + bind=['accent_palette', 'accent_light_hue']) + + def _get_accent_dark(self): + return get_color_from_hex( + colors[self.accent_palette][self.accent_dark_hue]) + + accent_dark = AliasProperty(_get_accent_dark, + bind=['accent_palette', 'accent_dark_hue']) + + theme_style = OptionProperty('Light', options=['Light', 'Dark']) + + def _get_theme_style(self, opposite): + if opposite: + return 'Light' if self.theme_style == 'Dark' else 'Dark' + else: + return self.theme_style + + def _get_bg_darkest(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + return get_color_from_hex(colors['Light']['StatusBar']) + elif theme_style == 'Dark': + return get_color_from_hex(colors['Dark']['StatusBar']) + + bg_darkest = AliasProperty(_get_bg_darkest, bind=['theme_style']) + + def _get_op_bg_darkest(self): + return self._get_bg_darkest(True) + + opposite_bg_darkest = AliasProperty(_get_op_bg_darkest, + bind=['theme_style']) + + def _get_bg_dark(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + return get_color_from_hex(colors['Light']['AppBar']) + elif theme_style == 'Dark': + return get_color_from_hex(colors['Dark']['AppBar']) + + bg_dark = AliasProperty(_get_bg_dark, bind=['theme_style']) + + def _get_op_bg_dark(self): + return self._get_bg_dark(True) + + opposite_bg_dark = AliasProperty(_get_op_bg_dark, bind=['theme_style']) + + def _get_bg_normal(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + return get_color_from_hex(colors['Light']['Background']) + elif theme_style == 'Dark': + return get_color_from_hex(colors['Dark']['Background']) + + bg_normal = AliasProperty(_get_bg_normal, bind=['theme_style']) + + def _get_op_bg_normal(self): + return self._get_bg_normal(True) + + opposite_bg_normal = AliasProperty(_get_op_bg_normal, bind=['theme_style']) + + def _get_bg_light(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + return get_color_from_hex(colors['Light']['CardsDialogs']) + elif theme_style == 'Dark': + return get_color_from_hex(colors['Dark']['CardsDialogs']) + + bg_light = AliasProperty(_get_bg_light, bind=['theme_style']) + + def _get_op_bg_light(self): + return self._get_bg_light(True) + + opposite_bg_light = AliasProperty(_get_op_bg_light, bind=['theme_style']) + + def _get_divider_color(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + color = get_color_from_hex('000000') + elif theme_style == 'Dark': + color = get_color_from_hex('FFFFFF') + color[3] = .12 + return color + + divider_color = AliasProperty(_get_divider_color, bind=['theme_style']) + + def _get_op_divider_color(self): + return self._get_divider_color(True) + + opposite_divider_color = AliasProperty(_get_op_divider_color, + bind=['theme_style']) + + def _get_text_color(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + color = get_color_from_hex('000000') + color[3] = .87 + elif theme_style == 'Dark': + color = get_color_from_hex('FFFFFF') + return color + + text_color = AliasProperty(_get_text_color, bind=['theme_style']) + + def _get_op_text_color(self): + return self._get_text_color(True) + + opposite_text_color = AliasProperty(_get_op_text_color, + bind=['theme_style']) + + def _get_secondary_text_color(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + color = get_color_from_hex('000000') + color[3] = .54 + elif theme_style == 'Dark': + color = get_color_from_hex('FFFFFF') + color[3] = .70 + return color + + secondary_text_color = AliasProperty(_get_secondary_text_color, + bind=['theme_style']) + + def _get_op_secondary_text_color(self): + return self._get_secondary_text_color(True) + + opposite_secondary_text_color = AliasProperty(_get_op_secondary_text_color, + bind=['theme_style']) + + def _get_icon_color(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + color = get_color_from_hex('000000') + color[3] = .54 + elif theme_style == 'Dark': + color = get_color_from_hex('FFFFFF') + return color + + icon_color = AliasProperty(_get_icon_color, + bind=['theme_style']) + + def _get_op_icon_color(self): + return self._get_icon_color(True) + + opposite_icon_color = AliasProperty(_get_op_icon_color, + bind=['theme_style']) + + def _get_disabled_hint_text_color(self, opposite=False): + theme_style = self._get_theme_style(opposite) + if theme_style == 'Light': + color = get_color_from_hex('000000') + color[3] = .26 + elif theme_style == 'Dark': + color = get_color_from_hex('FFFFFF') + color[3] = .30 + return color + + disabled_hint_text_color = AliasProperty(_get_disabled_hint_text_color, + bind=['theme_style']) + + def _get_op_disabled_hint_text_color(self): + return self._get_disabled_hint_text_color(True) + + opposite_disabled_hint_text_color = AliasProperty( + _get_op_disabled_hint_text_color, bind=['theme_style']) + + # Hardcoded because muh standard + def _get_error_color(self): + return get_color_from_hex(colors['Red']['A700']) + + error_color = AliasProperty(_get_error_color) + + def _get_ripple_color(self): + return self._ripple_color + + def _set_ripple_color(self, value): + self._ripple_color = value + + _ripple_color = ListProperty(get_color_from_hex(colors['Grey']['400'])) + ripple_color = AliasProperty(_get_ripple_color, + _set_ripple_color, + bind=['_ripple_color']) + + def _determine_device_orientation(self, _, window_size): + if window_size[0] > window_size[1]: + self.device_orientation = 'landscape' + elif window_size[1] >= window_size[0]: + self.device_orientation = 'portrait' + + device_orientation = StringProperty('') + + def _get_standard_increment(self): + if DEVICE_TYPE == 'mobile': + if self.device_orientation == 'landscape': + return dp(48) + else: + return dp(56) + else: + return dp(64) + + standard_increment = AliasProperty(_get_standard_increment, + bind=['device_orientation']) + + def _get_horizontal_margins(self): + if DEVICE_TYPE == 'mobile': + return dp(16) + else: + return dp(24) + + horizontal_margins = AliasProperty(_get_horizontal_margins) + + def on_theme_style(self, instance, value): + if hasattr(App.get_running_app(), 'theme_cls') and \ + App.get_running_app().theme_cls == self: + self.set_clearcolor_by_theme_style(value) + + def set_clearcolor_by_theme_style(self, theme_style): + if theme_style == 'Light': + Window.clearcolor = get_color_from_hex( + colors['Light']['Background']) + elif theme_style == 'Dark': + Window.clearcolor = get_color_from_hex( + colors['Dark']['Background']) + + def __init__(self, **kwargs): + super(ThemeManager, self).__init__(**kwargs) + self.rec_shadow = Atlas('{}rec_shadow.atlas'.format(images_path)) + self.rec_st_shadow = Atlas('{}rec_st_shadow.atlas'.format(images_path)) + self.quad_shadow = Atlas('{}quad_shadow.atlas'.format(images_path)) + self.round_shadow = Atlas('{}round_shadow.atlas'.format(images_path)) + Clock.schedule_once(lambda x: self.on_theme_style(0, self.theme_style)) + self._determine_device_orientation(None, Window.size) + Window.bind(size=self._determine_device_orientation) + + +class ThemableBehavior(object): + theme_cls = ObjectProperty(None) + opposite_colors = BooleanProperty(False) + + def __init__(self, **kwargs): + if self.theme_cls is not None: + pass + elif hasattr(App.get_running_app(), 'theme_cls'): + self.theme_cls = App.get_running_app().theme_cls + else: + self.theme_cls = ThemeManager() + super(ThemableBehavior, self).__init__(**kwargs) diff --git a/src/kivymd/time_picker.py b/src/kivymd/time_picker.py new file mode 100644 index 00000000..6de6fc20 --- /dev/null +++ b/src/kivymd/time_picker.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +from kivy.lang import Builder +from kivy.uix.modalview import ModalView +from kivy.uix.floatlayout import FloatLayout +from kivymd.theming import ThemableBehavior +from kivymd.elevationbehavior import ElevationBehavior +from kivy.properties import ObjectProperty, ListProperty + +Builder.load_string(""" +#:import MDFlatButton kivymd.button.MDFlatButton +#:import CircularTimePicker kivymd.vendor.circularTimePicker.CircularTimePicker +#:import dp kivy.metrics.dp +: + size_hint: (None, None) + size: [dp(270), dp(335)+dp(95)] + #if root.theme_cls.device_orientation == 'portrait' else [dp(520), dp(325)] + pos_hint: {'center_x': .5, 'center_y': .5} + canvas: + Color: + rgba: self.theme_cls.bg_light + Rectangle: + size: [dp(270), dp(335)] + #if root.theme_cls.device_orientation == 'portrait' else [dp(250), root.height] + pos: [root.pos[0], root.pos[1] + root.height - dp(335) - dp(95)] + #if root.theme_cls.device_orientation == 'portrait' else [root.pos[0]+dp(270), root.pos[1]] + Color: + rgba: self.theme_cls.primary_color + Rectangle: + size: [dp(270), dp(95)] + #if root.theme_cls.device_orientation == 'portrait' else [dp(270), root.height] + pos: [root.pos[0], root.pos[1] + root.height - dp(95)] + #if root.theme_cls.device_orientation == 'portrait' else [root.pos[0], root.pos[1]] + Color: + rgba: self.theme_cls.bg_dark + Ellipse: + size: [dp(220), dp(220)] + #if root.theme_cls.device_orientation == 'portrait' else [dp(195), dp(195)] + pos: root.pos[0]+dp(270)/2-dp(220)/2, root.pos[1] + root.height - (dp(335)/2+dp(95)) - dp(220)/2 + dp(35) + #Color: + #rgba: (1, 0, 0, 1) + #Line: + #width: 4 + #points: dp(270)/2, root.height, dp(270)/2, 0 + CircularTimePicker: + id: time_picker + pos: (dp(270)/2)-(self.width/2), root.height-self.height + size_hint: [.8, .8] + #if root.theme_cls.device_orientation == 'portrait' else [0.35, 0.9] + pos_hint: {'center_x': 0.5, 'center_y': 0.585} + #if root.theme_cls.device_orientation == 'portrait' else {'center_x': 0.75, 'center_y': 0.7} + MDFlatButton: + pos: root.pos[0]+root.size[0]-dp(72)*2, root.pos[1] + dp(10) + text: "Cancel" + on_release: root.close_cancel() + MDFlatButton: + pos: root.pos[0]+root.size[0]-dp(72), root.pos[1] + dp(10) + text: "OK" + on_release: root.close_ok() +""") + + +class MDTimePicker(ThemableBehavior, FloatLayout, ModalView, ElevationBehavior): + # background_color = ListProperty((0, 0, 0, 0)) + time = ObjectProperty() + + def __init__(self, **kwargs): + super(MDTimePicker, self).__init__(**kwargs) + self.current_time = self.ids.time_picker.time + + def set_time(self, time): + try: + self.ids.time_picker.set_time(time) + except AttributeError: + raise TypeError("MDTimePicker._set_time must receive a datetime object, not a \"" + + type(time).__name__ + "\"") + + def close_cancel(self): + self.dismiss() + + def close_ok(self): + self.current_time = self.ids.time_picker.time + self.time = self.current_time + self.dismiss() diff --git a/src/kivymd/toolbar.py b/src/kivymd/toolbar.py new file mode 100644 index 00000000..fc7b146c --- /dev/null +++ b/src/kivymd/toolbar.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +from kivy.clock import Clock +from kivy.lang import Builder +from kivy.metrics import dp +from kivy.properties import ListProperty, StringProperty, OptionProperty +from kivy.uix.boxlayout import BoxLayout +from kivymd.backgroundcolorbehavior import BackgroundColorBehavior +from kivymd.button import MDIconButton +from kivymd.theming import ThemableBehavior +from kivymd.elevationbehavior import ElevationBehavior + +Builder.load_string(''' +#:import m_res kivymd.material_resources + + size_hint_y: None + height: root.theme_cls.standard_increment + background_color: root.background_color + padding: [root.theme_cls.horizontal_margins - dp(12), 0] + opposite_colors: True + elevation: 6 + BoxLayout: + id: left_actions + orientation: 'horizontal' + size_hint_x: None + padding: [0, (self.height - dp(48))/2] + BoxLayout: + padding: dp(12), 0 + MDLabel: + font_style: 'Title' + opposite_colors: root.opposite_colors + theme_text_color: root.title_theme_color + text_color: root.title_color + text: root.title + shorten: True + shorten_from: 'right' + BoxLayout: + id: right_actions + orientation: 'horizontal' + size_hint_x: None + padding: [0, (self.height - dp(48))/2] +''') + + +class Toolbar(ThemableBehavior, ElevationBehavior, BackgroundColorBehavior, + BoxLayout): + left_action_items = ListProperty() + """The icons on the left of the Toolbar. + + To add one, append a list like the following: + + ['icon_name', callback] + + where 'icon_name' is a string that corresponds to an icon definition and + callback is the function called on a touch release event. + """ + + right_action_items = ListProperty() + """The icons on the left of the Toolbar. + + Works the same way as :attr:`left_action_items` + """ + + title = StringProperty() + """The text displayed on the Toolbar.""" + + title_theme_color = OptionProperty(None, allownone=True, + options=['Primary', 'Secondary', 'Hint', + 'Error', 'Custom']) + + title_color = ListProperty(None, allownone=True) + + background_color = ListProperty([0, 0, 0, 1]) + + def __init__(self, **kwargs): + super(Toolbar, self).__init__(**kwargs) + Clock.schedule_once( + lambda x: self.on_left_action_items(0, self.left_action_items)) + Clock.schedule_once( + lambda x: self.on_right_action_items(0, + self.right_action_items)) + + def on_left_action_items(self, instance, value): + self.update_action_bar(self.ids['left_actions'], value) + + def on_right_action_items(self, instance, value): + self.update_action_bar(self.ids['right_actions'], value) + + def update_action_bar(self, action_bar, action_bar_items): + action_bar.clear_widgets() + new_width = 0 + for item in action_bar_items: + new_width += dp(48) + action_bar.add_widget(MDIconButton(icon=item[0], + on_release=item[1], + opposite_colors=True, + text_color=self.title_color, + theme_text_color=self.title_theme_color)) + action_bar.width = new_width diff --git a/src/kivymd/vendor/__init__.py b/src/kivymd/vendor/__init__.py new file mode 100644 index 00000000..9bad5790 --- /dev/null +++ b/src/kivymd/vendor/__init__.py @@ -0,0 +1 @@ +# coding=utf-8 diff --git a/src/kivymd/vendor/circleLayout/LICENSE b/src/kivymd/vendor/circleLayout/LICENSE new file mode 100644 index 00000000..9d6e5b59 --- /dev/null +++ b/src/kivymd/vendor/circleLayout/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Davide Depau + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/src/kivymd/vendor/circleLayout/README.md b/src/kivymd/vendor/circleLayout/README.md new file mode 100644 index 00000000..6cf54bbe --- /dev/null +++ b/src/kivymd/vendor/circleLayout/README.md @@ -0,0 +1,21 @@ +CircularLayout +============== + +CircularLayout is a special layout that places widgets around a circle. + +See the widget's documentation and the example for more information. + +![Screenshot](screenshot.png) + +size_hint +--------- + +size_hint_x is used as an angle-quota hint (widget with higher +size_hint_x will be farther from each other, and viceversa), while +size_hint_y is used as a widget size hint (widgets with a higher size +hint will be bigger).size_hint_x cannot be None. + +Widgets are all squares, unless you set size_hint_y to None (in that +case you'll be able to specify your own size), and their size is the +difference between the outer and the inner circle's radii. To make the +widgets bigger you can just decrease inner_radius_hint. \ No newline at end of file diff --git a/src/kivymd/vendor/circleLayout/__init__.py b/src/kivymd/vendor/circleLayout/__init__.py new file mode 100644 index 00000000..9d62c99c --- /dev/null +++ b/src/kivymd/vendor/circleLayout/__init__.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +CircularLayout +============== + +CircularLayout is a special layout that places widgets around a circle. + +size_hint +--------- + +size_hint_x is used as an angle-quota hint (widget with higher +size_hint_x will be farther from each other, and vice versa), while +size_hint_y is used as a widget size hint (widgets with a higher size +hint will be bigger).size_hint_x cannot be None. + +Widgets are all squares, unless you set size_hint_y to None (in that +case you'll be able to specify your own size), and their size is the +difference between the outer and the inner circle's radii. To make the +widgets bigger you can just decrease inner_radius_hint. +""" + +from kivy.uix.layout import Layout +from kivy.properties import NumericProperty, ReferenceListProperty, OptionProperty, \ + BoundedNumericProperty, VariableListProperty, AliasProperty +from math import sin, cos, pi, radians + +__all__ = ('CircularLayout') + +try: + xrange(1, 2) +except NameError: + def xrange(first, second, third=None): + if third: + return range(first, second, third) + else: + return range(first, second) + + +class CircularLayout(Layout): + ''' + Circular layout class. See module documentation for more information. + ''' + + padding = VariableListProperty([0, 0, 0, 0]) + '''Padding between the layout box and it's children: [padding_left, + padding_top, padding_right, padding_bottom]. + + padding also accepts a two argument form [padding_horizontal, + padding_vertical] and a one argument form [padding]. + + .. version changed:: 1.7.0 + Replaced NumericProperty with VariableListProperty. + + :attr:`padding` is a :class:`~kivy.properties.VariableListProperty` and + defaults to [0, 0, 0, 0]. + ''' + + start_angle = NumericProperty(0) + '''Angle (in degrees) at which the first widget will be placed. + Start counting angles from the X axis, going counterclockwise. + + :attr:`start_angle` is a :class:`~kivy.properties.NumericProperty` and + defaults to 0 (start from the right). + ''' + + circle_quota = BoundedNumericProperty(360, min=0, max=360) + '''Size (in degrees) of the part of the circumference that will actually + be used to place widgets. + + :attr:`circle_quota` is a :class:`~kivy.properties.BoundedNumericProperty` + and defaults to 360 (all the circumference). + ''' + + direction = OptionProperty("ccw", options=("cw", "ccw")) + '''Direction of widgets in the circle. + + :attr:`direction` is an :class:`~kivy.properties.OptionProperty` and + defaults to 'ccw'. Can be 'ccw' (counterclockwise) or 'cw' (clockwise). + ''' + + outer_radius_hint = NumericProperty(1) + '''Sets the size of the outer circle. A number greater than 1 will make the + widgets larger than the actual widget, a number smaller than 1 will leave + a gap. + + :attr:`outer_radius_hint` is a :class:`~kivy.properties.NumericProperty` and + defaults to 1. + ''' + + inner_radius_hint = NumericProperty(.6) + '''Sets the size of the inner circle. A number greater than + :attr:`outer_radius_hint` will cause glitches. The closest it is to + :attr:`outer_radius_hint`, the smallest will be the widget in the layout. + + :attr:`outer_radius_hint` is a :class:`~kivy.properties.NumericProperty` and + defaults to 1. + ''' + + radius_hint = ReferenceListProperty(inner_radius_hint, outer_radius_hint) + '''Combined :attr:`outer_radius_hint` and :attr:`inner_radius_hint` in a list + for convenience. See their documentation for more details. + + :attr:`radius_hint` is a :class:`~kivy.properties.ReferenceListProperty`. + ''' + + def _get_delta_radii(self): + radius = min(self.width-self.padding[0]-self.padding[2], self.height-self.padding[1]-self.padding[3]) / 2. + outer_r = radius * self.outer_radius_hint + inner_r = radius * self.inner_radius_hint + return outer_r - inner_r + delta_radii = AliasProperty(_get_delta_radii, None, bind=("radius_hint", "padding", "size")) + + def __init__(self, **kwargs): + super(CircularLayout, self).__init__(**kwargs) + + self.bind( + start_angle=self._trigger_layout, + parent=self._trigger_layout, + # padding=self._trigger_layout, + children=self._trigger_layout, + size=self._trigger_layout, + radius_hint=self._trigger_layout, + pos=self._trigger_layout) + + def do_layout(self, *largs): + # optimize layout by preventing looking at the same attribute in a loop + len_children = len(self.children) + if len_children == 0: + return + selfcx = self.center_x + selfcy = self.center_y + direction = self.direction + cquota = radians(self.circle_quota) + start_angle_r = radians(self.start_angle) + padding_left = self.padding[0] + padding_top = self.padding[1] + padding_right = self.padding[2] + padding_bottom = self.padding[3] + padding_x = padding_left + padding_right + padding_y = padding_top + padding_bottom + + radius = min(self.width-padding_x, self.height-padding_y) / 2. + outer_r = radius * self.outer_radius_hint + inner_r = radius * self.inner_radius_hint + middle_r = radius * sum(self.radius_hint) / 2. + delta_r = outer_r - inner_r + + stretch_weight_angle = 0. + for w in self.children: + sha = w.size_hint_x + if sha is None: + raise ValueError("size_hint_x cannot be None in a CircularLayout") + else: + stretch_weight_angle += sha + + sign = +1. + angle_offset = start_angle_r + if direction == 'cw': + angle_offset = 2 * pi - start_angle_r + sign = -1. + + for c in reversed(self.children): + sha = c.size_hint_x + shs = c.size_hint_y + + angle_quota = cquota / stretch_weight_angle * sha + angle = angle_offset + (sign * angle_quota / 2) + angle_offset += sign * angle_quota + + # kived: looking it up, yes. x = cos(angle) * radius + centerx; y = sin(angle) * radius + centery + ccx = cos(angle) * middle_r + selfcx + padding_left - padding_right + ccy = sin(angle) * middle_r + selfcy + padding_bottom - padding_top + + c.center_x = ccx + c.center_y = ccy + if shs: + s = delta_r * shs + c.width = s + c.height = s + +if __name__ == "__main__": + from kivy.app import App + from kivy.uix.button import Button + + class CircLayoutApp(App): + def build(self): + cly = CircularLayout(direction="cw", start_angle=-75, inner_radius_hint=.7, padding="20dp") + + for i in xrange(1, 13): + cly.add_widget(Button(text=str(i), font_size="30dp")) + + return cly + + CircLayoutApp().run() diff --git a/src/kivymd/vendor/circularTimePicker/LICENSE b/src/kivymd/vendor/circularTimePicker/LICENSE new file mode 100644 index 00000000..9d6e5b59 --- /dev/null +++ b/src/kivymd/vendor/circularTimePicker/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Davide Depau + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/src/kivymd/vendor/circularTimePicker/README.md b/src/kivymd/vendor/circularTimePicker/README.md new file mode 100644 index 00000000..20ac2de9 --- /dev/null +++ b/src/kivymd/vendor/circularTimePicker/README.md @@ -0,0 +1,43 @@ +Circular Date & Time Picker for Kivy +==================================== + +(currently only time, date coming soon) + +Based on [CircularLayout](https://github.com/kivy-garden/garden.circularlayout). +The main aim is to provide a date and time selector similar to the +one found in Android KitKat+. + +![Screenshot](screenshot.png) + +Simple usage +------------ + +Import the widget with + +```python +from kivy.garden.circulardatetimepicker import CircularTimePicker +``` + +then use it! That's it! + +```python +c = CircularTimePicker() +c.bind(time=self.set_time) +root.add_widget(c) +``` + +in Kv language: + +``` +: + BoxLayout: + orientation: "vertical" + + CircularTimePicker + + Button: + text: "Dismiss" + size_hint_y: None + height: "40dp" + on_release: root.dismiss() +``` \ No newline at end of file diff --git a/src/kivymd/vendor/circularTimePicker/__init__.py b/src/kivymd/vendor/circularTimePicker/__init__.py new file mode 100644 index 00000000..fbc73954 --- /dev/null +++ b/src/kivymd/vendor/circularTimePicker/__init__.py @@ -0,0 +1,770 @@ +# -*- coding: utf-8 -*- + +""" +Circular Date & Time Picker for Kivy +==================================== + +(currently only time, date coming soon) + +Based on [CircularLayout](https://github.com/kivy-garden/garden.circularlayout). +The main aim is to provide a date and time selector similar to the +one found in Android KitKat+. + +Simple usage +------------ + +Import the widget with + +```python +from kivy.garden.circulardatetimepicker import CircularTimePicker +``` + +then use it! That's it! + +```python +c = CircularTimePicker() +c.bind(time=self.set_time) +root.add_widget(c) +``` + +in Kv language: + +``` +: + BoxLayout: + orientation: "vertical" + + CircularTimePicker + + Button: + text: "Dismiss" + size_hint_y: None + height: "40dp" + on_release: root.dismiss() +``` +""" + +from kivy.animation import Animation +from kivy.clock import Clock +from kivymd.vendor.circleLayout import CircularLayout +from kivy.graphics import Line, Color, Ellipse +from kivy.lang import Builder +from kivy.properties import NumericProperty, BoundedNumericProperty, \ + ObjectProperty, StringProperty, DictProperty, \ + ListProperty, OptionProperty, BooleanProperty, \ + ReferenceListProperty, AliasProperty +from kivy.uix.boxlayout import BoxLayout +from kivy.uix.label import Label +from kivy.metrics import dp +from kivymd.theming import ThemableBehavior +from math import atan, pi, radians, sin, cos +import sys +import datetime +if sys.version_info[0] > 2: + def xrange(first=None, second=None, third=None): + if third: + return range(first, second, third) + else: + return range(first, second) + + +def map_number(x, in_min, in_max, out_min, out_max): + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min + + +def rgb_to_hex(*color): + tor = "#" + for col in color: + tor += "{:>02}".format(hex(int(col * 255))[2:]) + return tor + + +Builder.load_string(""" + +: + text_size: self.size + valign: "middle" + halign: "center" + font_size: self.height * self.size_factor + +: + canvas.before: + PushMatrix + Scale: + origin: self.center_x + self.padding[0] - self.padding[2], self.center_y + self.padding[3] - self.padding[1] + x: self.scale + y: self.scale + + canvas.after: + PopMatrix + +: + orientation: "vertical" + spacing: "20dp" + + FloatLayout: + anchor_x: "center" + anchor_y: "center" + size_hint_y: 1./3 + size_hint_x: 1 + size: root.size + pos: root.pos + + GridLayout: + cols: 2 + spacing: "10dp" + size_hint_x: None + width: self.minimum_width + pos_hint: {'center_x': .5, 'center_y': .5} + + Label: + id: timelabel + text: root.time_text + markup: True + halign: "right" + valign: "middle" + # text_size: self.size + size_hint_x: None #.6 + width: self.texture_size[0] + font_size: self.height * .75 + + Label: + id: ampmlabel + text: root.ampm_text + markup: True + halign: "left" + valign: "middle" + # text_size: self.size + size_hint_x: None #.4 + width: self.texture_size[0] + font_size: self.height * .3 + + FloatLayout: + id: picker_container + #size_hint_y: 2./3 + _bound: {} +""") + + +class Number(Label): + """The class used to show the numbers in the selector. + """ + + size_factor = NumericProperty(.5) + """Font size scale. + + :attr:`size_factor` is a :class:`~kivy.properties.NumericProperty` and + defaults to 0.5. + """ + + +class CircularNumberPicker(CircularLayout): + """A circular number picker based on CircularLayout. A selector will + help you pick a number. You can also set :attr:`multiples_of` to make + it show only some numbers and use the space in between for the other + numbers. + """ + + min = NumericProperty(0) + """The first value of the range. + + :attr:`min` is a :class:`~kivy.properties.NumericProperty` and + defaults to 0. + """ + + max = NumericProperty(0) + """The last value of the range. Note that it behaves like xrange, so + the actual last displayed value will be :attr:`max` - 1. + + :attr:`max` is a :class:`~kivy.properties.NumericProperty` and + defaults to 0. + """ + + range = ReferenceListProperty(min, max) + """Packs :attr:`min` and :attr:`max` into a list for convenience. See + their documentation for further information. + + :attr:`range` is a :class:`~kivy.properties.ReferenceListProperty`. + """ + + multiples_of = NumericProperty(1) + """Only show numbers that are multiples of this number. The other numbers + will be selectable, but won't have their own label. + + :attr:`multiples_of` is a :class:`~kivy.properties.NumericProperty` and + defaults to 1. + """ + + # selector_color = ListProperty([.337, .439, .490]) + selector_color = ListProperty([1, 1, 1]) + """Color of the number selector. RGB. + + :attr:`selector_color` is a :class:`~kivy.properties.ListProperty` and + defaults to [.337, .439, .490] (material green). + """ + + color = ListProperty([0, 0, 0]) + """Color of the number labels and of the center dot. RGB. + + :attr:`color` is a :class:`~kivy.properties.ListProperty` and + defaults to [1, 1, 1] (white). + """ + + selector_alpha = BoundedNumericProperty(.3, min=0, max=1) + """Alpha value for the transparent parts of the selector. + + :attr:`selector_alpha` is a :class:`~kivy.properties.BoundedNumericProperty` and + defaults to 0.3 (min=0, max=1). + """ + + selected = NumericProperty(None) + """Currently selected number. + + :attr:`selected` is a :class:`~kivy.properties.NumericProperty` and + defaults to :attr:`min`. + """ + + number_size_factor = NumericProperty(.5) + """Font size scale factor fot the :class:`Number`s. + + :attr:`number_size_factor` is a :class:`~kivy.properties.NumericProperty` and + defaults to 0.5. + """ + + number_format_string = StringProperty("{}") + """String that will be formatted with the selected number as the first argument. + Can be anything supported by :meth:`str.format` (es. "{:02d}"). + + :attr:`number_format_string` is a :class:`~kivy.properties.StringProperty` and + defaults to "{}". + """ + + scale = NumericProperty(1) + """Canvas scale factor. Used in :class:`CircularTimePicker` transitions. + + :attr:`scale` is a :class:`~kivy.properties.NumericProperty` and + defaults to 1. + """ + + _selection_circle = ObjectProperty(None) + _selection_line = ObjectProperty(None) + _selection_dot = ObjectProperty(None) + _selection_dot_color = ObjectProperty(None) + _selection_color = ObjectProperty(None) + _center_dot = ObjectProperty(None) + _center_color = ObjectProperty(None) + + def _get_items(self): + return self.max - self.min + + items = AliasProperty(_get_items, None) + + def _get_shown_items(self): + sh = 0 + for i in xrange(*self.range): + if i % self.multiples_of == 0: + sh += 1 + return sh + + shown_items = AliasProperty(_get_shown_items, None) + + def __init__(self, **kw): + self._trigger_genitems = Clock.create_trigger(self._genitems, -1) + self.bind(min=self._trigger_genitems, + max=self._trigger_genitems, + multiples_of=self._trigger_genitems) + super(CircularNumberPicker, self).__init__(**kw) + self.selected = self.min + self.bind(selected=self.on_selected, + pos=self.on_selected, + size=self.on_selected) + + cx = self.center_x + self.padding[0] - self.padding[2] + cy = self.center_y + self.padding[3] - self.padding[1] + sx, sy = self.pos_for_number(self.selected) + epos = [i - (self.delta_radii * self.number_size_factor) for i in (sx, sy)] + esize = [self.delta_radii * self.number_size_factor * 2] * 2 + dsize = [i * .3 for i in esize] + dpos = [i + esize[0] / 2. - dsize[0] / 2. for i in epos] + csize = [i * .05 for i in esize] + cpos = [i - csize[0] / 2. for i in (cx, cy)] + dot_alpha = 0 if self.selected % self.multiples_of == 0 else 1 + color = list(self.selector_color) + + with self.canvas: + self._selection_color = Color(*(color + [self.selector_alpha])) + self._selection_circle = Ellipse(pos=epos, size=esize) + self._selection_line = Line(points=[cx, cy, sx, sy], width=dp(1.25)) + self._selection_dot_color = Color(*(color + [dot_alpha])) + self._selection_dot = Ellipse(pos=dpos, size=dsize) + self._center_color = Color(*self.color) + self._center_dot = Ellipse(pos=cpos, size=csize) + + self.bind(selector_color=lambda ign, u: setattr(self._selection_color, "rgba", u + [self.selector_alpha])) + self.bind(selector_color=lambda ign, u: setattr(self._selection_dot_color, "rgb", u)) + self.bind(selector_color=lambda ign, u: self.dot_is_none()) + self.bind(color=lambda ign, u: setattr(self._center_color, "rgb", u)) + Clock.schedule_once(self._genitems) + Clock.schedule_once(self.on_selected) # Just to make sure pos/size are set + + def dot_is_none(self, *args): + dot_alpha = 0 if self.selected % self.multiples_of == 0 else 1 + if self._selection_dot_color: + self._selection_dot_color.a = dot_alpha + + def _genitems(self, *a): + self.clear_widgets() + for i in xrange(*self.range): + if i % self.multiples_of != 0: + continue + n = Number(text=self.number_format_string.format(i), size_factor=self.number_size_factor, color=self.color) + self.bind(color=n.setter("color")) + self.add_widget(n) + + def on_touch_down(self, touch): + if not self.collide_point(*touch.pos): + return + touch.grab(self) + self.selected = self.number_at_pos(*touch.pos) + if self.selected == 60: + self.selected = 0 + + def on_touch_move(self, touch): + if touch.grab_current is not self: + return super(CircularNumberPicker, self).on_touch_move(touch) + self.selected = self.number_at_pos(*touch.pos) + if self.selected == 60: + self.selected = 0 + + def on_touch_up(self, touch): + if touch.grab_current is not self: + return super(CircularNumberPicker, self).on_touch_up(touch) + touch.ungrab(self) + + def on_selected(self, *a): + cx = self.center_x + self.padding[0] - self.padding[2] + cy = self.center_y + self.padding[3] - self.padding[1] + sx, sy = self.pos_for_number(self.selected) + epos = [i - (self.delta_radii * self.number_size_factor) for i in (sx, sy)] + esize = [self.delta_radii * self.number_size_factor * 2] * 2 + dsize = [i * .3 for i in esize] + dpos = [i + esize[0] / 2. - dsize[0] / 2. for i in epos] + csize = [i * .05 for i in esize] + cpos = [i - csize[0] / 2. for i in (cx, cy)] + dot_alpha = 0 if self.selected % self.multiples_of == 0 else 1 + + if self._selection_circle: + self._selection_circle.pos = epos + self._selection_circle.size = esize + if self._selection_line: + self._selection_line.points = [cx, cy, sx, sy] + if self._selection_dot: + self._selection_dot.pos = dpos + self._selection_dot.size = dsize + if self._selection_dot_color: + self._selection_dot_color.a = dot_alpha + if self._center_dot: + self._center_dot.pos = cpos + self._center_dot.size = csize + + def pos_for_number(self, n): + """Returns the center x, y coordinates for a given number. + """ + + if self.items == 0: + return 0, 0 + radius = min(self.width - self.padding[0] - self.padding[2], + self.height - self.padding[1] - self.padding[3]) / 2. + middle_r = radius * sum(self.radius_hint) / 2. + cx = self.center_x + self.padding[0] - self.padding[2] + cy = self.center_y + self.padding[3] - self.padding[1] + sign = +1. + angle_offset = radians(self.start_angle) + if self.direction == 'cw': + angle_offset = 2 * pi - angle_offset + sign = -1. + quota = 2 * pi / self.items + mult_quota = 2 * pi / self.shown_items + angle = angle_offset + n * sign * quota + + if self.items == self.shown_items: + angle += quota / 2 + else: + angle -= mult_quota / 2 + + # kived: looking it up, yes. x = cos(angle) * radius + centerx; y = sin(angle) * radius + centery + x = cos(angle) * middle_r + cx + y = sin(angle) * middle_r + cy + + return x, y + + def number_at_pos(self, x, y): + """Returns the number at a given x, y position. The number is found + using the widget's center as a starting point for angle calculations. + + Not thoroughly tested, may yield wrong results. + """ + if self.items == 0: + return self.min + cx = self.center_x + self.padding[0] - self.padding[2] + cy = self.center_y + self.padding[3] - self.padding[1] + lx = x - cx + ly = y - cy + quota = 2 * pi / self.items + mult_quota = 2 * pi / self.shown_items + if lx == 0 and ly > 0: + angle = pi / 2 + elif lx == 0 and ly < 0: + angle = 3 * pi / 2 + else: + angle = atan(ly / lx) + if lx < 0 < ly: + angle += pi + if lx > 0 > ly: + angle += 2 * pi + if lx < 0 and ly < 0: + angle += pi + angle += radians(self.start_angle) + if self.direction == "cw": + angle = 2 * pi - angle + if mult_quota != quota: + angle -= mult_quota / 2 + if angle < 0: + angle += 2 * pi + elif angle > 2 * pi: + angle -= 2 * pi + + return int(angle / quota) + self.min + + +class CircularMinutePicker(CircularNumberPicker): + """:class:`CircularNumberPicker` implementation for minutes. + """ + + def __init__(self, **kw): + super(CircularMinutePicker, self).__init__(**kw) + self.min = 0 + self.max = 60 + self.multiples_of = 5 + self.number_format_string = "{:02d}" + self.direction = "cw" + self.bind(shown_items=self._update_start_angle) + Clock.schedule_once(self._update_start_angle) + Clock.schedule_once(self.on_selected) + + def _update_start_angle(self, *a): + self.start_angle = -(360. / self.shown_items / 2) - 90 + + +class CircularHourPicker(CircularNumberPicker): + """:class:`CircularNumberPicker` implementation for hours. + """ + + # military = BooleanProperty(False) + + def __init__(self, **kw): + super(CircularHourPicker, self).__init__(**kw) + self.min = 1 + self.max = 13 + # 25 if self.military else 13 + # self.inner_radius_hint = .8 if self.military else .6 + self.multiples_of = 1 + self.number_format_string = "{}" + self.direction = "cw" + self.bind(shown_items=self._update_start_angle) + # self.bind(military=lambda v: setattr(self, "max", 25 if v else 13)) + # self.bind(military=lambda v: setattr(self, "inner_radius_hint", .8 if self.military else .6)) + # Clock.schedule_once(self._genitems) + Clock.schedule_once(self._update_start_angle) + Clock.schedule_once(self.on_selected) + + def _update_start_angle(self, *a): + self.start_angle = (360. / self.shown_items / 2) - 90 + + +class CircularTimePicker(BoxLayout, ThemableBehavior): + """Widget that makes use of :class:`CircularHourPicker` and + :class:`CircularMinutePicker` to create a user-friendly, animated + time picker like the one seen on Android. + + See module documentation for more details. + """ + + primary_dark = ListProperty([1, 1, 1]) + + hours = NumericProperty(0) + """The hours, in military format (0-23). + + :attr:`hours` is a :class:`~kivy.properties.NumericProperty` and + defaults to 0 (12am). + """ + + minutes = NumericProperty(0) + """The minutes. + + :attr:`minutes` is a :class:`~kivy.properties.NumericProperty` and + defaults to 0. + """ + + time_list = ReferenceListProperty(hours, minutes) + """Packs :attr:`hours` and :attr:`minutes` in a list for convenience. + + :attr:`time_list` is a :class:`~kivy.properties.ReferenceListProperty`. + """ + + # military = BooleanProperty(False) + time_format = StringProperty( + "[color={hours_color}][ref=hours]{hours}[/ref][/color][color={primary_dark}][ref=colon]:[/ref][/color]\ +[color={minutes_color}][ref=minutes]{minutes:02d}[/ref][/color]") + """String that will be formatted with the time and shown in the time label. + Can be anything supported by :meth:`str.format`. Make sure you don't + remove the refs. See the default for the arguments passed to format. + :attr:`time_format` is a :class:`~kivy.properties.StringProperty` and + defaults to "[color={hours_color}][ref=hours]{hours}[/ref][/color]:[color={minutes_color}][ref=minutes]\ + {minutes:02d}[/ref][/color]". + """ + + ampm_format = StringProperty( + "[color={am_color}][ref=am]AM[/ref][/color]\n[color={pm_color}][ref=pm]PM[/ref][/color]") + """String that will be formatted and shown in the AM/PM label. + Can be anything supported by :meth:`str.format`. Make sure you don't + remove the refs. See the default for the arguments passed to format. + + :attr:`ampm_format` is a :class:`~kivy.properties.StringProperty` and + defaults to "[color={am_color}][ref=am]AM[/ref][/color]\n[color={pm_color}][ref=pm]PM[/ref][/color]". + """ + + picker = OptionProperty("hours", options=("minutes", "hours")) + """Currently shown time picker. Can be one of "minutes", "hours". + + :attr:`picker` is a :class:`~kivy.properties.OptionProperty` and + defaults to "hours". + """ + + # selector_color = ListProperty([.337, .439, .490]) + selector_color = ListProperty([0, 0, 0]) + """Color of the number selector and of the highlighted text. RGB. + + :attr:`selector_color` is a :class:`~kivy.properties.ListProperty` and + defaults to [.337, .439, .490] (material green). + """ + + color = ListProperty([1, 1, 1]) + """Color of the number labels and of the center dot. RGB. + + :attr:`color` is a :class:`~kivy.properties.ListProperty` and + defaults to [1, 1, 1] (white). + """ + + selector_alpha = BoundedNumericProperty(.3, min=0, max=1) + """Alpha value for the transparent parts of the selector. + + :attr:`selector_alpha` is a :class:`~kivy.properties.BoundedNumericProperty` and + defaults to 0.3 (min=0, max=1). + """ + + _am = BooleanProperty(True) + _h_picker = ObjectProperty(None) + _m_picker = ObjectProperty(None) + _bound = DictProperty({}) + + def _get_time(self): + try: + return datetime.time(*self.time_list) + except ValueError: + self.time_list = [self.hours, 0] + return datetime.time(*self.time_list) + + def set_time(self, dt): + if dt.hour >= 12: + dt.strftime("%I:%M") + self._am = False + self.time_list = [dt.hour, dt.minute] + + time = AliasProperty(_get_time, set_time, bind=("time_list",)) + """Selected time as a datetime.time object. + + :attr:`time` is an :class:`~kivy.properties.AliasProperty`. + """ + + def _get_picker(self): + if self.picker == "hours": + return self._h_picker + return self._m_picker + + _picker = AliasProperty(_get_picker, None) + + def _get_time_text(self): + hc = rgb_to_hex(0, 0, 0) if self.picker == "hours" else rgb_to_hex(*self.primary_dark) + mc = rgb_to_hex(0, 0, 0) if self.picker == "minutes" else rgb_to_hex(*self.primary_dark) + h = self.hours == 0 and 12 or self.hours <= 12 and self.hours or self.hours - 12 + m = self.minutes + primary_dark = rgb_to_hex(*self.primary_dark) + return self.time_format.format(hours_color=hc, + minutes_color=mc, + hours=h, + minutes=m, + primary_dark=primary_dark) + time_text = AliasProperty(_get_time_text, None, bind=("hours", "minutes", "time_format", "picker")) + + def _get_ampm_text(self, *args): + amc = rgb_to_hex(0, 0, 0) if self._am else rgb_to_hex(*self.primary_dark) + pmc = rgb_to_hex(0, 0, 0) if not self._am else rgb_to_hex(*self.primary_dark) + return self.ampm_format.format(am_color=amc, + pm_color=pmc) + + ampm_text = AliasProperty(_get_ampm_text, None, bind=("hours", "ampm_format", "_am")) + + def __init__(self, **kw): + super(CircularTimePicker, self).__init__(**kw) + self.selector_color = self.theme_cls.primary_color[0], self.theme_cls.primary_color[1], \ + self.theme_cls.primary_color[2] + self.color = self.theme_cls.text_color + self.primary_dark = self.theme_cls.primary_dark[0] / 2, self.theme_cls.primary_dark[1] / 2, \ + self.theme_cls.primary_dark[2] / 2 + self.on_ampm() + if self.hours >= 12: + self._am = False + self.bind(time_list=self.on_time_list, + picker=self._switch_picker, + _am=self.on_ampm, + primary_dark=self._get_ampm_text) + self._h_picker = CircularHourPicker() + self.h_picker_touch = False + self._m_picker = CircularMinutePicker() + self.animating = False + Clock.schedule_once(self.on_selected) + Clock.schedule_once(self.on_time_list) + Clock.schedule_once(self._init_later) + Clock.schedule_once(lambda *a: self._switch_picker(noanim=True)) + + def _init_later(self, *args): + self.ids.timelabel.bind(on_ref_press=self.on_ref_press) + self.ids.ampmlabel.bind(on_ref_press=self.on_ref_press) + + def on_ref_press(self, ign, ref): + if not self.animating: + if ref == "hours": + self.picker = "hours" + elif ref == "minutes": + self.picker = "minutes" + if ref == "am": + self._am = True + elif ref == "pm": + self._am = False + + def on_selected(self, *a): + if not self._picker: + return + if self.picker == "hours": + hours = self._picker.selected if self._am else self._picker.selected + 12 + if hours == 24 and not self._am: + hours = 12 + elif hours == 12 and self._am: + hours = 0 + self.hours = hours + elif self.picker == "minutes": + self.minutes = self._picker.selected + + def on_time_list(self, *a): + if not self._picker: + return + self._h_picker.selected = self.hours == 0 and 12 or self._am and self.hours or self.hours - 12 + self._m_picker.selected = self.minutes + self.on_selected() + + def on_ampm(self, *a): + if self._am: + self.hours = self.hours if self.hours < 12 else self.hours - 12 + else: + self.hours = self.hours if self.hours >= 12 else self.hours + 12 + + def is_animating(self, *args): + self.animating = True + + def is_not_animating(self, *args): + self.animating = False + + def on_touch_down(self, touch): + if not self._h_picker.collide_point(*touch.pos): + self.h_picker_touch = False + else: + self.h_picker_touch = True + super(CircularTimePicker, self).on_touch_down(touch) + + def on_touch_up(self, touch): + try: + if not self.h_picker_touch: + return + if not self.animating: + if touch.grab_current is not self: + if self.picker == "hours": + self.picker = "minutes" + except AttributeError: + pass + super(CircularTimePicker, self).on_touch_up(touch) + + def _switch_picker(self, *a, **kw): + noanim = "noanim" in kw + if noanim: + noanim = kw["noanim"] + + try: + container = self.ids.picker_container + except (AttributeError, NameError): + Clock.schedule_once(lambda *a: self._switch_picker(noanim=noanim)) + + if self.picker == "hours": + picker = self._h_picker + prevpicker = self._m_picker + elif self.picker == "minutes": + picker = self._m_picker + prevpicker = self._h_picker + + if len(self._bound) > 0: + prevpicker.unbind(selected=self.on_selected) + self.unbind(**self._bound) + picker.bind(selected=self.on_selected) + self._bound = {"selector_color": picker.setter("selector_color"), + "color": picker.setter("color"), + "selector_alpha": picker.setter("selector_alpha")} + self.bind(**self._bound) + + if len(container._bound) > 0: + container.unbind(**container._bound) + container._bound = {"size": picker.setter("size"), + "pos": picker.setter("pos")} + container.bind(**container._bound) + + picker.pos = container.pos + picker.size = container.size + picker.selector_color = self.selector_color + picker.color = self.color + picker.selector_alpha = self.selector_alpha + if noanim: + if prevpicker in container.children: + container.remove_widget(prevpicker) + if picker.parent: + picker.parent.remove_widget(picker) + container.add_widget(picker) + else: + self.is_animating() + if prevpicker in container.children: + anim = Animation(scale=1.5, d=.5, t="in_back") & Animation(opacity=0, d=.5, t="in_cubic") + anim.start(prevpicker) + Clock.schedule_once(lambda *y: container.remove_widget(prevpicker), .5) # .31) + picker.scale = 1.5 + picker.opacity = 0 + if picker.parent: + picker.parent.remove_widget(picker) + container.add_widget(picker) + anim = Animation(scale=1, d=.5, t="out_back") & Animation(opacity=1, d=.5, t="out_cubic") + anim.bind(on_complete=self.is_not_animating) + Clock.schedule_once(lambda *y: anim.start(picker), .3) + + +if __name__ == "__main__": + from kivy.base import runTouchApp + + c = CircularTimePicker() + runTouchApp(c) diff --git a/src/knownnodes.py b/src/knownnodes.py index bb588fcb..5d1c003d 100644 --- a/src/knownnodes.py +++ b/src/knownnodes.py @@ -3,7 +3,6 @@ Manipulations with knownNodes dictionary. """ import json -import logging import os import pickle import threading @@ -11,33 +10,33 @@ import time import state from bmconfigparser import BMConfigParser -from network.node import Peer +from debug import logger +from helper_bootstrap import dns knownNodesLock = threading.Lock() -"""Thread lock for knownnodes modification""" knownNodes = {stream: {} for stream in range(1, 4)} -"""The dict of known nodes for each stream""" knownNodesTrimAmount = 2000 -"""trim stream knownnodes dict to this length""" +# forget a node after rating is this low knownNodesForgetRating = -0.5 -"""forget a node after rating is this low""" knownNodesActual = False -logger = logging.getLogger('default') - DEFAULT_NODES = ( - Peer('5.45.99.75', 8444), - Peer('75.167.159.54', 8444), - Peer('95.165.168.168', 8444), - Peer('85.180.139.241', 8444), - Peer('158.222.217.190', 8080), - Peer('178.62.12.187', 8448), - Peer('24.188.198.204', 8111), - Peer('109.147.204.113', 1195), - Peer('178.11.46.221', 8444) + state.Peer('5.45.99.75', 8444), + state.Peer('75.167.159.54', 8444), + state.Peer('95.165.168.168', 8444), + state.Peer('85.180.139.241', 8444), + state.Peer('158.222.217.190', 8080), + state.Peer('178.62.12.187', 8448), + state.Peer('24.188.198.204', 8111), + state.Peer('109.147.204.113', 1195), + state.Peer('178.11.46.221', 8444) +) + +DEFAULT_NODES_ONION = ( + state.Peer('quzwelsuziwqgpt2.onion', 8444), ) @@ -63,17 +62,20 @@ def json_deserialize_knownnodes(source): for node in json.load(source): peer = node['peer'] info = node['info'] - peer = Peer(str(peer['host']), peer.get('port', 8444)) + peer = state.Peer(str(peer['host']), peer.get('port', 8444)) knownNodes[node['stream']][peer] = info - if not (knownNodesActual - or info.get('self')) and peer not in DEFAULT_NODES: + if ( + not (knownNodesActual or info.get('self')) and + peer not in DEFAULT_NODES and + peer not in DEFAULT_NODES_ONION + ): knownNodesActual = True def pickle_deserialize_old_knownnodes(source): """ - Unpickle source and reorganize knownnodes dict if it has old format + Unpickle source and reorganize knownnodes dict if it's in old format the old format was {Peer:lastseen, ...} the new format is {Peer:{"lastseen":i, "rating":f}} """ @@ -86,7 +88,6 @@ def pickle_deserialize_old_knownnodes(source): def saveKnownNodes(dirName=None): - """Save knownnodes to filesystem""" if dirName is None: dirName = state.appdata with knownNodesLock: @@ -95,24 +96,21 @@ def saveKnownNodes(dirName=None): def addKnownNode(stream, peer, lastseen=None, is_self=False): - """Add a new node to the dict""" knownNodes[stream][peer] = { "lastseen": lastseen or time.time(), - "rating": 1 if is_self else 0, + "rating": 0, "self": is_self, } -def createDefaultKnownNodes(): - """Creating default Knownnodes""" +def createDefaultKnownNodes(onion=False): past = time.time() - 2418600 # 28 days - 10 min - for peer in DEFAULT_NODES: + for peer in DEFAULT_NODES_ONION if onion else DEFAULT_NODES: addKnownNode(1, peer, past) saveKnownNodes() def readKnownNodes(): - """Load knownnodes from filesystem""" try: with open(state.appdata + 'knownnodes.dat', 'rb') as source: with knownNodesLock: @@ -133,13 +131,12 @@ def readKnownNodes(): if onionhostname and ".onion" in onionhostname: onionport = config.safeGetInt('bitmessagesettings', 'onionport') if onionport: - self_peer = Peer(onionhostname, onionport) + self_peer = state.Peer(onionhostname, onionport) addKnownNode(1, self_peer, is_self=True) state.ownAddresses[self_peer] = True def increaseRating(peer): - """Increase rating of a peer node""" increaseAmount = 0.1 maxRating = 1 with knownNodesLock: @@ -154,7 +151,6 @@ def increaseRating(peer): def decreaseRating(peer): - """Decrease rating of a peer node""" decreaseAmount = 0.1 minRating = -1 with knownNodesLock: @@ -169,7 +165,6 @@ def decreaseRating(peer): def trimKnownNodes(recAddrStream=1): - """Triming Knownnodes""" if len(knownNodes[recAddrStream]) < \ BMConfigParser().safeGetInt("knownnodes", "maxnodes"): return @@ -182,38 +177,40 @@ def trimKnownNodes(recAddrStream=1): del knownNodes[recAddrStream][oldest] -def dns(): - """Add DNS names to knownnodes""" - for port in [8080, 8444]: - addKnownNode( - 1, Peer('bootstrap%s.bitmessage.org' % port, port)) - - def cleanupKnownNodes(): """ Cleanup knownnodes: remove old nodes and nodes with low rating """ now = int(time.time()) needToWriteKnownNodesToDisk = False + dns_done = False + spawnConnections = not BMConfigParser().safeGetBoolean( + 'bitmessagesettings', 'dontconnect' + ) and BMConfigParser().safeGetBoolean( + 'bitmessagesettings', 'sendoutgoingconnections') with knownNodesLock: for stream in knownNodes: if stream not in state.streamsInWhichIAmParticipating: continue keys = knownNodes[stream].keys() + if len(keys) <= 1: # leave at least one node + if not dns_done and spawnConnections: + dns() + dns_done = True + continue for node in keys: - if len(knownNodes[stream]) <= 1: # leave at least one node - break try: - age = now - knownNodes[stream][node]["lastseen"] - # scrap old nodes (age > 28 days) - if age > 2419200: + # scrap old nodes + if (now - knownNodes[stream][node]["lastseen"] > + 2419200): # 28 days needToWriteKnownNodesToDisk = True del knownNodes[stream][node] continue - # scrap old nodes (age > 3 hours) with low rating - if (age > 10800 and knownNodes[stream][node]["rating"] - <= knownNodesForgetRating): + # scrap old nodes with low rating + if (now - knownNodes[stream][node]["lastseen"] > 10800 and + knownNodes[stream][node]["rating"] <= + knownNodesForgetRating): needToWriteKnownNodesToDisk = True del knownNodes[stream][node] continue diff --git a/src/l10n.py b/src/l10n.py index 7a78525b..b3b16341 100644 --- a/src/l10n.py +++ b/src/l10n.py @@ -1,13 +1,13 @@ -""" -Localization -""" + import logging import os import time from bmconfigparser import BMConfigParser -logger = logging.getLogger('default') + +#logger = logging.getLogger(__name__) +logger = logging.getLogger('file_only') DEFAULT_ENCODING = 'ISO8859-1' @@ -50,7 +50,7 @@ except: if BMConfigParser().has_option('bitmessagesettings', 'timeformat'): time_format = BMConfigParser().get('bitmessagesettings', 'timeformat') - # Test the format string + #Test the format string try: time.strftime(time_format) except: @@ -59,52 +59,48 @@ if BMConfigParser().has_option('bitmessagesettings', 'timeformat'): else: time_format = DEFAULT_TIME_FORMAT -# It seems some systems lie about the encoding they use so we perform -# comprehensive decoding tests +#It seems some systems lie about the encoding they use so we perform +#comprehensive decoding tests if time_format != DEFAULT_TIME_FORMAT: try: - # Check day names + #Check day names for i in xrange(7): unicode(time.strftime(time_format, (0, 0, 0, 0, 0, 0, i, 0, 0)), encoding) - # Check month names + #Check month names for i in xrange(1, 13): unicode(time.strftime(time_format, (0, i, 0, 0, 0, 0, 0, 0, 0)), encoding) - # Check AM/PM + #Check AM/PM unicode(time.strftime(time_format, (0, 0, 0, 11, 0, 0, 0, 0, 0)), encoding) unicode(time.strftime(time_format, (0, 0, 0, 13, 0, 0, 0, 0, 0)), encoding) - # Check DST + #Check DST unicode(time.strftime(time_format, (0, 0, 0, 0, 0, 0, 0, 0, 1)), encoding) except: logger.exception('Could not decode locale formatted timestamp') time_format = DEFAULT_TIME_FORMAT encoding = DEFAULT_ENCODING - def setlocale(category, newlocale): - """Set the locale""" locale.setlocale(category, newlocale) # it looks like some stuff isn't initialised yet when this is called the # first time and its init gets the locale settings from the environment os.environ["LC_ALL"] = newlocale - -def formatTimestamp(timestamp=None, as_unicode=True): - """Return a formatted timestamp""" - # For some reason some timestamps are strings so we need to sanitize. +def formatTimestamp(timestamp = None, as_unicode = True): + #For some reason some timestamps are strings so we need to sanitize. if timestamp is not None and not isinstance(timestamp, int): try: timestamp = int(timestamp) except: timestamp = None - # timestamp can't be less than 0. + #timestamp can't be less than 0. if timestamp is not None and timestamp < 0: timestamp = None if timestamp is None: timestring = time.strftime(time_format) else: - # In case timestamp is too far in the future + #In case timestamp is too far in the future try: timestring = time.strftime(time_format, time.localtime(timestamp)) except ValueError: @@ -114,21 +110,17 @@ def formatTimestamp(timestamp=None, as_unicode=True): return unicode(timestring, encoding) return timestring - def getTranslationLanguage(): - """Return the user's language choice""" - userlocale = BMConfigParser().safeGet( - 'bitmessagesettings', 'userlocale', 'system') - return userlocale if userlocale and userlocale != 'system' else language + userlocale = None + if BMConfigParser().has_option('bitmessagesettings', 'userlocale'): + userlocale = BMConfigParser().get('bitmessagesettings', 'userlocale') + if userlocale in [None, '', 'system']: + return language + return userlocale + def getWindowsLocale(posixLocale): - """ - Get the Windows locale - Technically this converts the locale string from UNIX to Windows format, - because they use different ones in their - libraries. E.g. "en_EN.UTF-8" to "english". - """ if posixLocale in windowsLanguageMap: return windowsLanguageMap[posixLocale] if "." in posixLocale: diff --git a/src/main.py b/src/main.py index 22ea7c3e..969dbe56 100644 --- a/src/main.py +++ b/src/main.py @@ -1,8 +1,8 @@ """This module is for thread start.""" +from bitmessagemain import main import state if __name__ == '__main__': state.kivy = True - print("Kivy Loading for PyBitmessage......") - from bitmessagemain import main + print("Kivy Loading......") main() diff --git a/src/message_data_reader.py b/src/message_data_reader.py new file mode 100644 index 00000000..de6ed6c0 --- /dev/null +++ b/src/message_data_reader.py @@ -0,0 +1,136 @@ +# pylint: disable=too-many-locals +""" +This program can be used to print out everything in your Inbox or Sent folders and also take things out of the trash. +Scroll down to the bottom to see the functions that you can uncomment. Save then run this file. +The functions which only read the database file seem to function just +fine even if you have Bitmessage running but you should definitly close +it before running the functions that make changes (like taking items out +of the trash). +""" + +from __future__ import absolute_import + +import sqlite3 +from binascii import hexlify +from time import strftime, localtime + +import paths +import queues + + +appdata = paths.lookupAppdataFolder() + +conn = sqlite3.connect(appdata + 'messages.dat') +conn.text_factory = str +cur = conn.cursor() + + +def readInbox(): + """Print each row from inbox table""" + print 'Printing everything in inbox table:' + item = '''select * from inbox''' + parameters = '' + cur.execute(item, parameters) + output = cur.fetchall() + for row in output: + print row + + +def readSent(): + """Print each row from sent table""" + print 'Printing everything in Sent table:' + item = '''select * from sent where folder !='trash' ''' + parameters = '' + cur.execute(item, parameters) + output = cur.fetchall() + for row in output: + (msgid, toaddress, toripe, fromaddress, subject, message, ackdata, lastactiontime, + sleeptill, status, retrynumber, folder, encodingtype, ttl) = row # pylint: disable=unused-variable + print(hexlify(msgid), toaddress, 'toripe:', hexlify(toripe), 'fromaddress:', fromaddress, 'ENCODING TYPE:', + encodingtype, 'SUBJECT:', repr(subject), 'MESSAGE:', repr(message), 'ACKDATA:', hexlify(ackdata), + lastactiontime, status, retrynumber, folder) + + +def readSubscriptions(): + """Print each row from subscriptions table""" + print 'Printing everything in subscriptions table:' + item = '''select * from subscriptions''' + parameters = '' + cur.execute(item, parameters) + output = cur.fetchall() + for row in output: + print row + + +def readPubkeys(): + """Print each row from pubkeys table""" + print 'Printing everything in pubkeys table:' + item = '''select address, transmitdata, time, usedpersonally from pubkeys''' + parameters = '' + cur.execute(item, parameters) + output = cur.fetchall() + for row in output: + address, transmitdata, time, usedpersonally = row + print( + 'Address:', address, '\tTime first broadcast:', unicode( + strftime('%a, %d %b %Y %I:%M %p', localtime(time)), 'utf-8'), + '\tUsed by me personally:', usedpersonally, '\tFull pubkey message:', hexlify(transmitdata), + ) + + +def readInventory(): + """Print each row from inventory table""" + print 'Printing everything in inventory table:' + item = '''select hash, objecttype, streamnumber, payload, expirestime from inventory''' + parameters = '' + cur.execute(item, parameters) + output = cur.fetchall() + for row in output: + obj_hash, objecttype, streamnumber, payload, expirestime = row + print 'Hash:', hexlify(obj_hash), objecttype, streamnumber, '\t', hexlify(payload), '\t', unicode( + strftime('%a, %d %b %Y %I:%M %p', localtime(expirestime)), 'utf-8') + + +def takeInboxMessagesOutOfTrash(): + """Update all inbox messages with folder=trash to have folder=inbox""" + item = '''update inbox set folder='inbox' where folder='trash' ''' + parameters = '' + cur.execute(item, parameters) + _ = cur.fetchall() + conn.commit() + print 'done' + + +def takeSentMessagesOutOfTrash(): + """Update all sent messages with folder=trash to have folder=sent""" + item = '''update sent set folder='sent' where folder='trash' ''' + parameters = '' + cur.execute(item, parameters) + _ = cur.fetchall() + conn.commit() + print 'done' + + +def markAllInboxMessagesAsUnread(): + """Update all messages in inbox to have read=0""" + item = '''update inbox set read='0' ''' + parameters = '' + cur.execute(item, parameters) + _ = cur.fetchall() + conn.commit() + queues.UISignalQueue.put(('changedInboxUnread', None)) + print 'done' + + +def vacuum(): + """Perform a vacuum on the database""" + item = '''VACUUM''' + parameters = '' + cur.execute(item, parameters) + _ = cur.fetchall() + conn.commit() + print 'done' + + +if __name__ == '__main__': + readInbox() diff --git a/src/messagetypes/__init__.py b/src/messagetypes/__init__.py index 97ce693a..06783eac 100644 --- a/src/messagetypes/__init__.py +++ b/src/messagetypes/__init__.py @@ -1,26 +1,17 @@ -import logging from importlib import import_module -from os import listdir, path +from os import path, listdir from string import lower -try: - from kivy.utils import platform -except: - platform = '' +from debug import logger import messagetypes import paths -logger = logging.getLogger('default') - - -class MsgBase(object): # pylint: disable=too-few-public-methods - """Base class for message types""" - def __init__(self): +class MsgBase(object): + def encode(self): self.data = {"": lower(type(self).__name__)} def constructObject(data): - """Constructing an object""" whitelist = ["message"] if data[""] not in whitelist: return None @@ -41,8 +32,7 @@ def constructObject(data): else: return returnObj - -if paths.frozen is not None or platform == "android": +if paths.frozen is not None: import messagetypes.message import messagetypes.vote else: diff --git a/src/messagetypes/message.py b/src/messagetypes/message.py index 27bba13a..f52c6b35 100644 --- a/src/messagetypes/message.py +++ b/src/messagetypes/message.py @@ -1,30 +1,24 @@ -import logging - +from debug import logger from messagetypes import MsgBase -# pylint: disable=attribute-defined-outside-init - -logger = logging.getLogger('default') class Message(MsgBase): - """Encapsulate a message""" - # pylint: disable=attribute-defined-outside-init + def __init__(self): + return def decode(self, data): - """Decode a message""" # UTF-8 and variable type validator - if isinstance(data["subject"], str): + if type(data["subject"]) is str: self.subject = unicode(data["subject"], 'utf-8', 'replace') else: self.subject = unicode(str(data["subject"]), 'utf-8', 'replace') - if isinstance(data["body"], str): + if type(data["body"]) is str: self.body = unicode(data["body"], 'utf-8', 'replace') else: self.body = unicode(str(data["body"]), 'utf-8', 'replace') def encode(self, data): - """Encode a message""" - super(Message, self).__init__() + super(Message, self).encode() try: self.data["subject"] = data["subject"] self.data["body"] = data["body"] @@ -33,6 +27,5 @@ class Message(MsgBase): return self.data def process(self): - """Process a message""" logger.debug("Subject: %i bytes", len(self.subject)) logger.debug("Body: %i bytes", len(self.body)) diff --git a/src/messagetypes/vote.py b/src/messagetypes/vote.py index d20f5cd6..df8d267f 100644 --- a/src/messagetypes/vote.py +++ b/src/messagetypes/vote.py @@ -1,31 +1,23 @@ -import logging - +from debug import logger from messagetypes import MsgBase -# pylint: disable=attribute-defined-outside-init - -logger = logging.getLogger('default') - class Vote(MsgBase): - """Module used to vote""" + def __init__(self): + return def decode(self, data): - """decode a vote""" - # pylint: disable=attribute-defined-outside-init self.msgid = data["msgid"] self.vote = data["vote"] def encode(self, data): - """Encode a vote""" - super(Vote, self).__init__() + super(Vote, self).encode() try: self.data["msgid"] = data["msgid"] self.data["vote"] = data["vote"] except KeyError as e: - logger.error("Missing key %s", e) + logger.error("Missing key %s", e.name) return self.data def process(self): - """Encode a vote""" logger.debug("msgid: %s", self.msgid) logger.debug("vote: %s", self.vote) diff --git a/src/multiqueue.py b/src/multiqueue.py index d7c10847..8c64d33d 100644 --- a/src/multiqueue.py +++ b/src/multiqueue.py @@ -1,6 +1,6 @@ """ -A queue with multiple internal subqueues. -Elements are added into a random subqueue, and retrieval rotates +src/multiqueue.py +================= """ import Queue diff --git a/src/namecoin.py b/src/namecoin.py index ae2bde79..6674bdcd 100644 --- a/src/namecoin.py +++ b/src/namecoin.py @@ -1,7 +1,31 @@ -""" -Namecoin queries -""" # pylint: disable=too-many-branches,protected-access +""" +Copyright (C) 2013 by Daniel Kraft +This file is part of the Bitmessage project. + +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. + +.. todo:: from debug import logger crashes PyBitmessage due to a circular dependency. The debug module will also +override/disable logging.getLogger() # loggers so module level logging functions are used instead +""" + +from __future__ import absolute_import import base64 import httplib @@ -10,11 +34,11 @@ import os import socket import sys +from addresses import decodeAddress +from debug import logger import defaults import tr # translate -from addresses import decodeAddress from bmconfigparser import BMConfigParser -from debug import logger configSection = "bitmessagesettings" @@ -234,7 +258,7 @@ class namecoinConnection(object): resp = self.con.getresponse() result = resp.read() if resp.status != 200: - raise Exception("Namecoin returned status %i: %s" % (resp.status, resp.reason)) + raise Exception("Namecoin returned status %i: %s" % resp.status, resp.reason) except: logger.info("HTTP receive error") except: @@ -264,7 +288,7 @@ class namecoinConnection(object): return result except socket.error as exc: - raise Exception("Socket error in RPC connection: %s" % exc) + raise Exception("Socket error in RPC connection: %s" % str(exc)) def lookupNamecoinFolder(): diff --git a/src/navigationdrawer/__init__.py b/src/navigationdrawer/__init__.py new file mode 100644 index 00000000..a8fa5ce7 --- /dev/null +++ b/src/navigationdrawer/__init__.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +from kivy.animation import Animation +from kivy.lang import Builder +from kivy.properties import StringProperty, ObjectProperty +from kivymd.elevationbehavior import ElevationBehavior +from kivymd.icon_definitions import md_icons +from kivymd.label import MDLabel +from kivymd.list import OneLineIconListItem, ILeftBody, BaseListItem +from kivymd.slidingpanel import SlidingPanel +from kivymd.theming import ThemableBehavior + +Builder.load_string(''' + + canvas: + Color: + rgba: root.parent.parent.theme_cls.divider_color + Line: + points: self.x, self.y, self.x+self.width,self.y + + + widget_list: widget_list + elevation: 0 + canvas: + Color: + rgba: root.theme_cls.bg_light + Rectangle: + size: root.size + pos: root.pos + BoxLayout: + size_hint: (1, .4) + NavDrawerToolbar: + padding: 10, 10 + canvas.after: + Color: + rgba: (1, 1, 1, 1) + RoundedRectangle: + size: (self.size[1]-dp(14), self.size[1]-dp(14)) + pos: (self.pos[0]+(self.size[0]-self.size[1])/2, self.pos[1]+dp(7)) + source: root.image_source + radius: [self.size[1]-(self.size[1]/2)] + + ScrollView: + do_scroll_x: False + MDList: + id: ml + id: widget_list + + + NDIconLabel: + id: _icon + font_style: 'Icon' + theme_text_color: 'Secondary' +''') + + +class NavigationDrawer(SlidingPanel, ThemableBehavior, ElevationBehavior): + image_source = StringProperty() + widget_list = ObjectProperty() + + def add_widget(self, widget, index=0): + if issubclass(widget.__class__, BaseListItem): + self.widget_list.add_widget(widget, index) + widget.bind(on_release=lambda x: self.toggle()) + else: + super(NavigationDrawer, self).add_widget(widget, index) + + def _get_main_animation(self, duration, t, x, is_closing): + a = super(NavigationDrawer, self)._get_main_animation(duration, t, x, + is_closing) + a &= Animation(elevation=0 if is_closing else 5, t=t, duration=duration) + return a + + +class NDIconLabel(ILeftBody, MDLabel): + pass + + +class NavigationDrawerIconButton(OneLineIconListItem): + icon = StringProperty() + + def on_icon(self, instance, value): + self.ids['_icon'].text = u"{}".format(md_icons[value]) diff --git a/src/network/__init__.py b/src/network/__init__.py index 70613539..e69de29b 100644 --- a/src/network/__init__.py +++ b/src/network/__init__.py @@ -1,20 +0,0 @@ -""" -Network subsystem packages -""" -from addrthread import AddrThread -from announcethread import AnnounceThread -from connectionpool import BMConnectionPool -from dandelion import Dandelion -from downloadthread import DownloadThread -from invthread import InvThread -from networkthread import BMNetworkThread -from receivequeuethread import ReceiveQueueThread -from threads import StoppableThread -from uploadthread import UploadThread - - -__all__ = [ - "BMConnectionPool", "Dandelion", - "AddrThread", "AnnounceThread", "BMNetworkThread", "DownloadThread", - "InvThread", "ReceiveQueueThread", "UploadThread", "StoppableThread" -] diff --git a/src/network/addrthread.py b/src/network/addrthread.py index 3bf448d8..5b0ea638 100644 --- a/src/network/addrthread.py +++ b/src/network/addrthread.py @@ -1,19 +1,18 @@ -""" -Announce addresses as they are received from other hosts -""" import Queue +import threading -import state -from helper_random import randomshuffle -from network.assemble import assemble_addr +import addresses +from helper_threading import StoppableThread from network.connectionpool import BMConnectionPool from queues import addrQueue -from threads import StoppableThread +import protocol +import state - -class AddrThread(StoppableThread): - """(Node) address broadcasting thread""" - name = "AddrBroadcaster" +class AddrThread(threading.Thread, StoppableThread): + def __init__(self): + threading.Thread.__init__(self, name="AddrBroadcaster") + self.initStop() + self.name = "AddrBroadcaster" def run(self): while not state.shutdown: @@ -21,26 +20,15 @@ class AddrThread(StoppableThread): while True: try: data = addrQueue.get(False) - chunk.append(data) + chunk.append((data[0], data[1])) + if len(data) > 2: + source = BMConnectionPool().getConnectionByAddr(data[2]) except Queue.Empty: break + except KeyError: + continue - if chunk: - # Choose peers randomly - connections = BMConnectionPool().establishedConnections() - randomshuffle(connections) - for i in connections: - randomshuffle(chunk) - filtered = [] - for stream, peer, seen, destination in chunk: - # peer's own address or address received from peer - if i.destination in (peer, destination): - continue - if stream not in i.streams: - continue - filtered.append((stream, peer, seen)) - if filtered: - i.append_write_buf(assemble_addr(filtered)) + #finish addrQueue.iterate() for i in range(len(chunk)): diff --git a/src/network/advanceddispatcher.py b/src/network/advanceddispatcher.py index 982be819..c8f125f0 100644 --- a/src/network/advanceddispatcher.py +++ b/src/network/advanceddispatcher.py @@ -1,19 +1,21 @@ """ -Improved version of asyncore dispatcher +src/network/advanceddispatcher.py +================================= """ # pylint: disable=attribute-defined-outside-init + import socket import threading import time import network.asyncore_pollchoose as asyncore import state -from threads import BusyError, nonBlocking +from debug import logger +from helper_threading import BusyError, nonBlocking class ProcessingError(Exception): - """General class for protocol parser exception, - use as a base for others.""" + """General class for protocol parser exception, use as a base for others.""" pass @@ -23,8 +25,7 @@ class UnknownStateError(ProcessingError): class AdvancedDispatcher(asyncore.dispatcher): - """Improved version of asyncore dispatcher, - with buffers and protocol state.""" + """Improved version of asyncore dispatcher, with buffers and protocol state.""" # pylint: disable=too-many-instance-attributes _buf_len = 131072 # 128kB @@ -72,8 +73,7 @@ class AdvancedDispatcher(asyncore.dispatcher): del self.read_buf[0:length] def process(self): - """Process (parse) data that's in the buffer, - as long as there is enough data and the connection is open.""" + """Process (parse) data that's in the buffer, as long as there is enough data and the connection is open.""" while self.connected and not state.shutdown: try: with nonBlocking(self.processingLock): @@ -84,8 +84,7 @@ class AdvancedDispatcher(asyncore.dispatcher): try: cmd = getattr(self, "state_" + str(self.state)) except AttributeError: - self.logger.error( - 'Unknown state %s', self.state, exc_info=True) + logger.error("Unknown state %s", self.state, exc_info=True) raise UnknownStateError(self.state) if not cmd(): break @@ -105,9 +104,8 @@ class AdvancedDispatcher(asyncore.dispatcher): if asyncore.maxUploadRate > 0: self.uploadChunk = int(asyncore.uploadBucket) self.uploadChunk = min(self.uploadChunk, len(self.write_buf)) - return asyncore.dispatcher.writable(self) and ( - self.connecting or ( - self.connected and self.uploadChunk > 0)) + return asyncore.dispatcher.writable(self) and \ + (self.connecting or (self.connected and self.uploadChunk > 0)) def readable(self): """Is the read buffer ready to accept data from the network?""" @@ -116,15 +114,13 @@ class AdvancedDispatcher(asyncore.dispatcher): self.downloadChunk = int(asyncore.downloadBucket) try: if self.expectBytes > 0 and not self.fullyEstablished: - self.downloadChunk = min( - self.downloadChunk, self.expectBytes - len(self.read_buf)) + self.downloadChunk = min(self.downloadChunk, self.expectBytes - len(self.read_buf)) if self.downloadChunk < 0: self.downloadChunk = 0 except AttributeError: pass - return asyncore.dispatcher.readable(self) and ( - self.connecting or self.accepting or ( - self.connected and self.downloadChunk > 0)) + return asyncore.dispatcher.readable(self) and \ + (self.connecting or self.accepting or (self.connected and self.downloadChunk > 0)) def handle_read(self): """Append incoming data to the read buffer.""" @@ -148,21 +144,20 @@ class AdvancedDispatcher(asyncore.dispatcher): try: asyncore.dispatcher.handle_connect_event(self) except socket.error as e: - # pylint: disable=protected-access - if e.args[0] not in asyncore._DISCONNECTED: + if e.args[0] not in asyncore._DISCONNECTED: # pylint: disable=protected-access raise def handle_connect(self): """Method for handling connection established implementations.""" self.lastTx = time.time() - def state_close(self): # pylint: disable=no-self-use + def state_close(self): """Signal to the processing loop to end.""" + # pylint: disable=no-self-use return False def handle_close(self): - """Callback for connection being closed, - but can also be called directly when you want connection to close.""" + """Callback for connection being closed, but can also be called directly when you want connection to close.""" with self.readLock: self.read_buf = bytearray() with self.writeLock: diff --git a/src/network/announcethread.py b/src/network/announcethread.py index 19038ab6..a94eeb36 100644 --- a/src/network/announcethread.py +++ b/src/network/announcethread.py @@ -1,20 +1,20 @@ -""" -Announce myself (node address) -""" +import threading import time -import state from bmconfigparser import BMConfigParser -from network.assemble import assemble_addr +from debug import logger +from helper_threading import StoppableThread +from network.bmproto import BMProto from network.connectionpool import BMConnectionPool from network.udp import UDPSocket -from node import Peer -from threads import StoppableThread +import state - -class AnnounceThread(StoppableThread): - """A thread to manage regular announcing of this node""" - name = "Announcer" +class AnnounceThread(threading.Thread, StoppableThread): + def __init__(self): + threading.Thread.__init__(self, name="Announcer") + self.initStop() + self.name = "Announcer" + logger.info("init announce thread") def run(self): lastSelfAnnounced = 0 @@ -26,18 +26,10 @@ class AnnounceThread(StoppableThread): if processed == 0: self.stop.wait(10) - @staticmethod - def announceSelf(): - """Announce our presence""" + def announceSelf(self): for connection in BMConnectionPool().udpSockets.values(): if not connection.announcing: continue for stream in state.streamsInWhichIAmParticipating: - addr = ( - stream, - Peer( - '127.0.0.1', - BMConfigParser().safeGetInt( - 'bitmessagesettings', 'port')), - time.time()) - connection.append_write_buf(assemble_addr([addr])) + addr = (stream, state.Peer('127.0.0.1', BMConfigParser().safeGetInt("bitmessagesettings", "port")), time.time()) + connection.append_write_buf(BMProto.assembleAddr([addr])) diff --git a/src/network/assemble.py b/src/network/assemble.py deleted file mode 100644 index 32fad3e4..00000000 --- a/src/network/assemble.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -Create bitmessage protocol command packets -""" -import struct - -import addresses -from network.constants import MAX_ADDR_COUNT -from network.node import Peer -from protocol import CreatePacket, encodeHost - - -def assemble_addr(peerList): - """Create address command""" - if isinstance(peerList, Peer): - peerList = [peerList] - if not peerList: - return b'' - retval = b'' - for i in range(0, len(peerList), MAX_ADDR_COUNT): - payload = addresses.encodeVarint(len(peerList[i:i + MAX_ADDR_COUNT])) - for stream, peer, timestamp in peerList[i:i + MAX_ADDR_COUNT]: - # 64-bit time - payload += struct.pack('>Q', timestamp) - payload += struct.pack('>I', stream) - # service bit flags offered by this node - payload += struct.pack('>q', 1) - payload += encodeHost(peer.host) - # remote port - payload += struct.pack('>H', peer.port) - retval += CreatePacket('addr', payload) - return retval diff --git a/src/network/asyncore_pollchoose.py b/src/network/asyncore_pollchoose.py index 41757f37..3337c0f0 100644 --- a/src/network/asyncore_pollchoose.py +++ b/src/network/asyncore_pollchoose.py @@ -1,11 +1,56 @@ -""" -Basic infrastructure for asynchronous socket service clients and servers. -""" # -*- Mode: Python -*- # Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp # Author: Sam Rushing -# pylint: disable=too-many-branches,too-many-lines,global-statement -# pylint: disable=redefined-builtin,no-self-use +# pylint: disable=too-many-statements,too-many-branches,no-self-use,too-many-lines,attribute-defined-outside-init +# pylint: disable=global-statement +""" +src/network/asyncore_pollchoose.py +================================== + +# ====================================================================== +# Copyright 1996 by Sam Rushing +# +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appear in all +# copies and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of Sam +# Rushing not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, 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. +# ====================================================================== + +Basic infrastructure for asynchronous socket service clients and servers. + +There are only two ways to have a program on a single processor do "more +than one thing at a time". Multi-threaded programming is the simplest and +most popular way to do it, but there is another very different technique, +that lets you have nearly all the advantages of multi-threading, without +actually using multiple threads. it's really only practical if your program +is largely I/O bound. If your program is CPU bound, then pre-emptive +scheduled threads are probably what you really need. Network servers are +rarely CPU-bound, however. + +If your operating system supports the select() system call in its I/O +library (and nearly all do), then you can use it to juggle multiple +communication channels at once; doing other work while your I/O is taking +place in the "background." Although this strategy can seem strange and +complex, especially at first, it is in many ways easier to understand and +control than multi-threaded programming. The module documented here solves +many of the difficult problems for you, making the task of building +sophisticated high-performance network servers and clients a snap. +""" + import os import select import socket @@ -13,9 +58,8 @@ import sys import time import warnings from errno import ( - EADDRINUSE, EAGAIN, EALREADY, EBADF, ECONNABORTED, ECONNREFUSED, - ECONNRESET, EHOSTUNREACH, EINPROGRESS, EINTR, EINVAL, EISCONN, ENETUNREACH, - ENOTCONN, ENOTSOCK, EPIPE, ESHUTDOWN, ETIMEDOUT, EWOULDBLOCK, errorcode + EADDRINUSE, EAGAIN, EALREADY, EBADF, ECONNABORTED, ECONNREFUSED, ECONNRESET, EHOSTUNREACH, EINPROGRESS, EINTR, + EINVAL, EISCONN, ENETUNREACH, ENOTCONN, ENOTSOCK, EPIPE, ESHUTDOWN, ETIMEDOUT, EWOULDBLOCK, errorcode ) from threading import current_thread @@ -63,8 +107,7 @@ def _strerror(err): class ExitNow(Exception): - """We don't use directly but may be necessary as we replace - asyncore due to some library raising or expecting it""" + """We don't use directly but may be necessary as we replace asyncore due to some library raising or expecting it""" pass @@ -109,8 +152,7 @@ def write(obj): def set_rates(download, upload): """Set throttling rates""" - global maxDownloadRate, maxUploadRate, downloadBucket - global uploadBucket, downloadTimestamp, uploadTimestamp + global maxDownloadRate, maxUploadRate, downloadBucket, uploadBucket, downloadTimestamp, uploadTimestamp maxDownloadRate = float(download) * 1024 maxUploadRate = float(upload) * 1024 @@ -140,8 +182,7 @@ def update_received(download=0): currentTimestamp = time.time() receivedBytes += download if maxDownloadRate > 0: - bucketIncrease = \ - maxDownloadRate * (currentTimestamp - downloadTimestamp) + bucketIncrease = maxDownloadRate * (currentTimestamp - downloadTimestamp) downloadBucket += bucketIncrease if downloadBucket > maxDownloadRate: downloadBucket = int(maxDownloadRate) @@ -201,6 +242,7 @@ def readwrite(obj, flags): def select_poller(timeout=0.0, map=None): """A poller which uses select(), available on most platforms.""" + # pylint: disable=redefined-builtin if map is None: map = socket_map @@ -256,6 +298,7 @@ def select_poller(timeout=0.0, map=None): def poll_poller(timeout=0.0, map=None): """A poller which uses poll(), available on most UNIXen.""" + # pylint: disable=redefined-builtin if map is None: map = socket_map @@ -313,6 +356,7 @@ poll2 = poll3 = poll_poller def epoll_poller(timeout=0.0, map=None): """A poller which uses epoll(), supported on Linux 2.5.44 and newer.""" + # pylint: disable=redefined-builtin if map is None: map = socket_map @@ -368,7 +412,7 @@ def epoll_poller(timeout=0.0, map=None): def kqueue_poller(timeout=0.0, map=None): """A poller which uses kqueue(), BSD specific.""" - # pylint: disable=no-member,too-many-statements + # pylint: disable=redefined-builtin,no-member if map is None: map = socket_map @@ -396,20 +440,14 @@ def kqueue_poller(timeout=0.0, map=None): poller_flags |= select.KQ_EV_ENABLE else: poller_flags |= select.KQ_EV_DISABLE - updates.append( - select.kevent( - fd, filter=select.KQ_FILTER_READ, - flags=poller_flags)) + updates.append(select.kevent(fd, filter=select.KQ_FILTER_READ, flags=poller_flags)) if kq_filter & 2 != obj.poller_filter & 2: poller_flags = select.KQ_EV_ADD if kq_filter & 2: poller_flags |= select.KQ_EV_ENABLE else: poller_flags |= select.KQ_EV_DISABLE - updates.append( - select.kevent( - fd, filter=select.KQ_FILTER_WRITE, - flags=poller_flags)) + updates.append(select.kevent(fd, filter=select.KQ_FILTER_WRITE, flags=poller_flags)) obj.poller_filter = kq_filter if not selectables: @@ -443,6 +481,7 @@ def kqueue_poller(timeout=0.0, map=None): def loop(timeout=30.0, use_poll=False, map=None, count=None, poller=None): """Poll in a loop, until count or timeout is reached""" + # pylint: disable=redefined-builtin if map is None: map = socket_map @@ -481,9 +520,9 @@ def loop(timeout=30.0, use_poll=False, map=None, count=None, poller=None): count = count - 1 -class dispatcher(object): +class dispatcher: """Dispatcher for socket objects""" - # pylint: disable=too-many-public-methods,too-many-instance-attributes + # pylint: disable=too-many-public-methods,too-many-instance-attributes,old-style-class debug = False connected = False @@ -498,6 +537,7 @@ class dispatcher(object): minTx = 1500 def __init__(self, sock=None, map=None): + # pylint: disable=redefined-builtin if map is None: self._map = socket_map else: @@ -546,7 +586,8 @@ class dispatcher(object): def add_channel(self, map=None): """Add a channel""" - # pylint: disable=attribute-defined-outside-init + # pylint: disable=redefined-builtin + if map is None: map = self._map map[self._fileno] = self @@ -555,6 +596,8 @@ class dispatcher(object): def del_channel(self, map=None): """Delete a channel""" + # pylint: disable=redefined-builtin + fd = self._fileno if map is None: map = self._map @@ -562,14 +605,12 @@ class dispatcher(object): del map[fd] if self._fileno: try: - kqueue_poller.pollster.control([select.kevent( - fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE)], 0) - except(AttributeError, KeyError, TypeError, IOError, OSError): + kqueue_poller.pollster.control([select.kevent(fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE)], 0) + except (AttributeError, KeyError, TypeError, IOError, OSError): pass try: - kqueue_poller.pollster.control([select.kevent( - fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE)], 0) - except(AttributeError, KeyError, TypeError, IOError, OSError): + kqueue_poller.pollster.control([select.kevent(fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE)], 0) + except (AttributeError, KeyError, TypeError, IOError, OSError): pass try: epoll_poller.pollster.unregister(fd) @@ -586,10 +627,8 @@ class dispatcher(object): self.poller_filter = 0 self.poller_registered = False - def create_socket( - self, family=socket.AF_INET, socket_type=socket.SOCK_STREAM): + def create_socket(self, family=socket.AF_INET, socket_type=socket.SOCK_STREAM): """Create a socket""" - # pylint: disable=attribute-defined-outside-init self.family_and_type = family, socket_type sock = socket.socket(family, socket_type) sock.setblocking(0) @@ -597,16 +636,20 @@ class dispatcher(object): def set_socket(self, sock, map=None): """Set socket""" + # pylint: disable=redefined-builtin + self.socket = sock self._fileno = sock.fileno() self.add_channel(map) def set_reuse_addr(self): """try to re-use a server port if possible""" + try: self.socket.setsockopt( - socket.SOL_SOCKET, socket.SO_REUSEADDR, self.socket.getsockopt( - socket.SOL_SOCKET, socket.SO_REUSEADDR) | 1 + socket.SOL_SOCKET, socket.SO_REUSEADDR, + self.socket.getsockopt(socket.SOL_SOCKET, + socket.SO_REUSEADDR) | 1 ) except socket.error: pass @@ -661,16 +704,13 @@ class dispatcher(object): raise socket.error(err, errorcode[err]) def accept(self): - """Accept incoming connections. - Returns either an address pair or None.""" + """Accept incoming connections. Returns either an address pair or None.""" try: conn, addr = self.socket.accept() except TypeError: return None except socket.error as why: - if why.args[0] in ( - EWOULDBLOCK, WSAEWOULDBLOCK, ECONNABORTED, - EAGAIN, ENOTCONN): + if why.args[0] in (EWOULDBLOCK, WSAEWOULDBLOCK, ECONNABORTED, EAGAIN, ENOTCONN): return None else: raise @@ -729,12 +769,11 @@ class dispatcher(object): try: retattr = getattr(self.socket, attr) except AttributeError: - raise AttributeError( - "%s instance has no attribute '%s'" - % (self.__class__.__name__, attr)) + raise AttributeError("%s instance has no attribute '%s'" + % (self.__class__.__name__, attr)) else: - msg = "%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s"\ - " instead" % {'me': self.__class__.__name__, 'attr': attr} + msg = "%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s " \ + "instead" % {'me': self.__class__.__name__, 'attr': attr} warnings.warn(msg, DeprecationWarning, stacklevel=2) return retattr @@ -816,8 +855,13 @@ class dispatcher(object): self.log_info( 'uncaptured python exception, closing channel %s (%s:%s %s)' % ( - self_repr, t, v, tbinfo), - 'error') + self_repr, + t, + v, + tbinfo + ), + 'error' + ) self.handle_close() def handle_accept(self): @@ -858,8 +902,11 @@ class dispatcher_with_send(dispatcher): adds simple buffered output capability, useful for simple clients. [for more sophisticated usage use asynchat.async_chat] """ + # pylint: disable=redefined-builtin def __init__(self, sock=None, map=None): + # pylint: disable=redefined-builtin + dispatcher.__init__(self, sock, map) self.out_buffer = b'' @@ -894,8 +941,7 @@ def compact_traceback(): """Return a compact traceback""" t, v, tb = sys.exc_info() tbinfo = [] - # Must have a traceback - if not tb: + if not tb: # Must have a traceback raise AssertionError("traceback does not exist") while tb: tbinfo.append(( @@ -915,6 +961,7 @@ def compact_traceback(): def close_all(map=None, ignore_all=False): """Close all connections""" + # pylint: disable=redefined-builtin if map is None: map = socket_map @@ -951,13 +998,13 @@ def close_all(map=None, ignore_all=False): if os.name == 'posix': import fcntl - class file_wrapper: # pylint: disable=old-style-class + class file_wrapper: """ - Here we override just enough to make a file look - like a socket for the purposes of asyncore. + Here we override just enough to make a file look like a socket for the purposes of asyncore. The passed fd is automatically os.dup()'d """ + # pylint: disable=old-style-class def __init__(self, fd): self.fd = os.dup(fd) @@ -972,11 +1019,12 @@ if os.name == 'posix': def getsockopt(self, level, optname, buflen=None): """Fake getsockopt()""" - if (level == socket.SOL_SOCKET and optname == socket.SO_ERROR and + if (level == socket.SOL_SOCKET and + optname == socket.SO_ERROR and not buflen): return 0 - raise NotImplementedError( - "Only asyncore specific behaviour implemented.") + raise NotImplementedError("Only asyncore specific behaviour " + "implemented.") read = recv write = send @@ -993,6 +1041,8 @@ if os.name == 'posix': """A dispatcher for file_wrapper objects""" def __init__(self, fd, map=None): + # pylint: disable=redefined-builtin + dispatcher.__init__(self, None, map) self.connected = True try: diff --git a/src/network/bmobject.py b/src/network/bmobject.py index 12b997d7..0a4c12b7 100644 --- a/src/network/bmobject.py +++ b/src/network/bmobject.py @@ -1,27 +1,26 @@ """ -BMObject and it's exceptions. +src/network/bmobject.py +====================== + """ -import logging + import time import protocol import state from addresses import calculateInventoryHash +from debug import logger from inventory import Inventory from network.dandelion import Dandelion -logger = logging.getLogger('default') - class BMObjectInsufficientPOWError(Exception): - """Exception indicating the object - doesn't have sufficient proof of work.""" + """Exception indicating the object doesn't have sufficient proof of work.""" errorCodes = ("Insufficient proof of work") class BMObjectInvalidDataError(Exception): - """Exception indicating the data being parsed - does not match the specification.""" + """Exception indicating the data being parsed does not match the specification.""" errorCodes = ("Data invalid") @@ -31,8 +30,7 @@ class BMObjectExpiredError(Exception): class BMObjectUnwantedStreamError(Exception): - """Exception indicating the object is in a stream - we didn't advertise as being interested in.""" + """Exception indicating the object is in a stream we didn't advertise as being interested in.""" errorCodes = ("Object in unwanted stream") @@ -46,8 +44,9 @@ class BMObjectAlreadyHaveError(Exception): errorCodes = ("Already have this object") -class BMObject(object): # pylint: disable=too-many-instance-attributes +class BMObject(object): """Bitmessage Object as a class.""" + # pylint: disable=too-many-instance-attributes # max TTL, 28 days and 3 hours maxTTL = 28 * 24 * 60 * 60 + 10800 @@ -82,36 +81,31 @@ class BMObject(object): # pylint: disable=too-many-instance-attributes raise BMObjectInsufficientPOWError() def checkEOLSanity(self): - """Check if object's lifetime - isn't ridiculously far in the past or future.""" + """Check if object's lifetime isn't ridiculously far in the past or future.""" # EOL sanity check if self.expiresTime - int(time.time()) > BMObject.maxTTL: logger.info( - 'This object\'s End of Life time is too far in the future.' - ' Ignoring it. Time is %i', self.expiresTime) + 'This object\'s End of Life time is too far in the future. Ignoring it. Time is %i', + self.expiresTime) # .. todo:: remove from download queue raise BMObjectExpiredError() if self.expiresTime - int(time.time()) < BMObject.minTTL: logger.info( - 'This object\'s End of Life time was too long ago.' - ' Ignoring the object. Time is %i', self.expiresTime) + 'This object\'s End of Life time was too long ago. Ignoring the object. Time is %i', + self.expiresTime) # .. todo:: remove from download queue raise BMObjectExpiredError() def checkStream(self): """Check if object's stream matches streams we are interested in""" if self.streamNumber not in state.streamsInWhichIAmParticipating: - logger.debug( - 'The streamNumber %i isn\'t one we are interested in.', - self.streamNumber) + logger.debug('The streamNumber %i isn\'t one we are interested in.', self.streamNumber) raise BMObjectUnwantedStreamError() def checkAlreadyHave(self): """ - Check if we already have the object - (so that we don't duplicate it in inventory - or advertise it unnecessarily) + Check if we already have the object (so that we don't duplicate it in inventory or advertise it unnecessarily) """ # if it's a stem duplicate, pretend we don't have it if Dandelion().hasHash(self.inventoryHash): @@ -120,8 +114,7 @@ class BMObject(object): # pylint: disable=too-many-instance-attributes raise BMObjectAlreadyHaveError() def checkObjectByType(self): - """Call a object type specific check - (objects can have additional checks based on their types)""" + """Call a object type specific check (objects can have additional checks based on their types)""" if self.objectType == protocol.OBJECT_GETPUBKEY: self.checkGetpubkey() elif self.objectType == protocol.OBJECT_PUBKEY: @@ -132,21 +125,20 @@ class BMObject(object): # pylint: disable=too-many-instance-attributes self.checkBroadcast() # other objects don't require other types of tests - def checkMessage(self): # pylint: disable=no-self-use + def checkMessage(self): """"Message" object type checks.""" + # pylint: disable=no-self-use return def checkGetpubkey(self): """"Getpubkey" object type checks.""" if len(self.data) < 42: - logger.info( - 'getpubkey message doesn\'t contain enough data. Ignoring.') + logger.info('getpubkey message doesn\'t contain enough data. Ignoring.') raise BMObjectInvalidError() def checkPubkey(self): """"Pubkey" object type checks.""" - # sanity check - if len(self.data) < 146 or len(self.data) > 440: + if len(self.data) < 146 or len(self.data) > 440: # sanity check logger.info('pubkey object too short or too long. Ignoring.') raise BMObjectInvalidError() @@ -154,9 +146,8 @@ class BMObject(object): # pylint: disable=too-many-instance-attributes """"Broadcast" object type checks.""" if len(self.data) < 180: logger.debug( - 'The payload length of this broadcast' - ' packet is unreasonably low. Someone is probably' - ' trying funny business. Ignoring message.') + 'The payload length of this broadcast packet is unreasonably low.' + ' Someone is probably trying funny business. Ignoring message.') raise BMObjectInvalidError() # this isn't supported anymore diff --git a/src/network/bmproto.py b/src/network/bmproto.py index 64bde74c..c8efe91e 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -1,10 +1,5 @@ -""" -Bitmessage Protocol -""" -# pylint: disable=attribute-defined-outside-init, too-few-public-methods import base64 import hashlib -import logging import socket import struct import time @@ -16,26 +11,20 @@ import knownnodes import protocol import state from bmconfigparser import BMConfigParser +from debug import logger from inventory import Inventory from network.advanceddispatcher import AdvancedDispatcher -from network.bmobject import ( - BMObject, BMObjectAlreadyHaveError, BMObjectExpiredError, - BMObjectInsufficientPOWError, BMObjectInvalidDataError, - BMObjectInvalidError, BMObjectUnwantedStreamError -) -from network.constants import ( - ADDRESS_ALIVE, MAX_MESSAGE_SIZE, MAX_OBJECT_COUNT, - MAX_OBJECT_PAYLOAD_SIZE, MAX_TIME_OFFSET -) from network.dandelion import Dandelion +from network.bmobject import ( + BMObject, BMObjectInsufficientPOWError, BMObjectInvalidDataError, + BMObjectExpiredError, BMObjectUnwantedStreamError, + BMObjectInvalidError, BMObjectAlreadyHaveError) +from network.node import Node from network.proxy import ProxyError -from node import Node, Peer -from objectracker import ObjectTracker, missingObjects -from queues import invQueue, objectProcessorQueue, portCheckerQueue +from objectracker import missingObjects, ObjectTracker +from queues import objectProcessorQueue, portCheckerQueue, invQueue, addrQueue from randomtrackingdict import RandomTrackingDict -logger = logging.getLogger('default') - class BMProtoError(ProxyError): """A Bitmessage Protocol Base Error""" @@ -54,18 +43,26 @@ class BMProtoExcessiveDataError(BMProtoError): class BMProto(AdvancedDispatcher, ObjectTracker): """A parser for the Bitmessage Protocol""" - # pylint: disable=too-many-instance-attributes, too-many-public-methods + # ~1.6 MB which is the maximum possible size of an inv message. + maxMessageSize = 1600100 + # 2**18 = 256kB is the maximum size of an object payload + maxObjectPayloadSize = 2**18 + # protocol specification says max 1000 addresses in one addr command + maxAddrCount = 1000 + # protocol specification says max 50000 objects in one inv command + maxObjectCount = 50000 + # address is online if online less than this many seconds ago + addressAlive = 10800 + # maximum time offset + maxTimeOffset = 3600 timeOffsetWrongCount = 0 def __init__(self, address=None, sock=None): - # pylint: disable=unused-argument, super-init-not-called AdvancedDispatcher.__init__(self, sock) self.isOutbound = False # packet/connection from a local IP self.local = False self.pendingUpload = RandomTrackingDict() - # canonical identifier of network group - self.network_group = None def bm_proto_reset(self): """Reset the bitmessage object parser""" @@ -93,14 +90,14 @@ class BMProto(AdvancedDispatcher, ObjectTracker): self.close_reason = "Bad magic" self.set_state("close") return False - if self.payloadLength > MAX_MESSAGE_SIZE: + if self.payloadLength > BMProto.maxMessageSize: self.invalid = True self.set_state( "bm_command", length=protocol.Header.size, expectBytes=self.payloadLength) return True - def state_bm_command(self): # pylint: disable=too-many-branches + def state_bm_command(self): """Process incoming command""" self.payload = self.read_buf[:self.payloadLength] if self.checksum != hashlib.sha512(self.payload).digest()[0:4]: @@ -162,8 +159,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): def decode_payload_varint(self): """Decode a varint from the payload""" - value, offset = addresses.decodeVarint( - self.payload[self.payloadOffset:]) + value, offset = addresses.decodeVarint(self.payload[self.payloadOffset:]) self.payloadOffset += offset return value @@ -185,7 +181,6 @@ class BMProto(AdvancedDispatcher, ObjectTracker): return Node(services, host, port) - # pylint: disable=too-many-branches, too-many-statements def decode_payload_content(self, pattern="v"): """ Decode the payload depending on pattern: @@ -202,7 +197,6 @@ class BMProto(AdvancedDispatcher, ObjectTracker): , = end of array """ - # pylint: disable=inconsistent-return-statements def decode_simple(self, char="v"): """Decode the payload using one char pattern""" if char == "v": @@ -236,7 +230,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): while True: i = parserStack[-1][3][parserStack[-1][4]] if i in "0123456789" and ( - size is None or parserStack[-1][3][parserStack[-1][4] - 1] + size is None or parserStack[-1][3][parserStack[-1][4] - 1] not in "lL"): try: size = size * 10 + int(i) @@ -257,7 +251,6 @@ class BMProto(AdvancedDispatcher, ObjectTracker): for j in range(parserStack[-1][4], len(parserStack[-1][3])): if parserStack[-1][3][j] not in "lL0123456789": break - # pylint: disable=undefined-loop-variable parserStack.append([ size, size, isArray, parserStack[-1][3][parserStack[-1][4]:j + 1], 0, [] @@ -313,11 +306,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker): def bm_command_error(self): """Decode an error message and log it""" - err_values = self.decode_payload_content("vvlsls") - fatalStatus = err_values[0] - # banTime = err_values[1] - # inventoryVector = err_values[2] - errorText = err_values[3] + fatalStatus, banTime, inventoryVector, errorText = \ + self.decode_payload_content("vvlsls") logger.error( '%s:%i error: %i, %s', self.destination.host, self.destination.port, fatalStatus, errorText) @@ -341,7 +331,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): def _command_inv(self, dandelion=False): items = self.decode_payload_content("l32s") - if len(items) > MAX_OBJECT_COUNT: + if len(items) > BMProto.maxObjectCount: logger.error( 'Too many items in %sinv message!', 'd' if dandelion else '') raise BMProtoExcessiveDataError() @@ -376,7 +366,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): nonce, expiresTime, objectType, version, streamNumber, self.payload, self.payloadOffset) - if len(self.payload) - self.payloadOffset > MAX_OBJECT_PAYLOAD_SIZE: + if len(self.payload) - self.payloadOffset > BMProto.maxObjectPayloadSize: logger.info( 'The payload length of this object is too large (%d bytes).' ' Ignoring it.', len(self.payload) - self.payloadOffset) @@ -412,10 +402,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker): except KeyError: pass - if self.object.inventoryHash in Inventory() and Dandelion().hasHash( - self.object.inventoryHash): - Dandelion().removeHash( - self.object.inventoryHash, "cycle detection") + if self.object.inventoryHash in Inventory() and Dandelion().hasHash(self.object.inventoryHash): + Dandelion().removeHash(self.object.inventoryHash, "cycle detection") Inventory()[self.object.inventoryHash] = ( self.object.objectType, self.object.streamNumber, @@ -434,46 +422,39 @@ class BMProto(AdvancedDispatcher, ObjectTracker): def bm_command_addr(self): """Incoming addresses, process them""" - # pylint: disable=redefined-outer-name addresses = self._decode_addr() - for seenTime, stream, _, ip, port in addresses: + for i in addresses: + seenTime, stream, services, ip, port = i decodedIP = protocol.checkIPAddress(str(ip)) if stream not in state.streamsInWhichIAmParticipating: continue if ( decodedIP and time.time() - seenTime > 0 and - seenTime > time.time() - ADDRESS_ALIVE and + seenTime > time.time() - BMProto.addressAlive and port > 0 ): - peer = Peer(decodedIP, port) + peer = state.Peer(decodedIP, port) try: - if knownnodes.knownNodes[stream][peer]["lastseen"] > \ - seenTime: + if knownnodes.knownNodes[stream][peer]["lastseen"] > seenTime: continue except KeyError: pass - if len(knownnodes.knownNodes[stream]) < \ - BMConfigParser().safeGetInt("knownnodes", "maxnodes"): + if len(knownnodes.knownNodes[stream]) < BMConfigParser().safeGetInt("knownnodes", "maxnodes"): with knownnodes.knownNodesLock: try: - knownnodes.knownNodes[stream][peer]["lastseen"] = \ - seenTime + knownnodes.knownNodes[stream][peer]["lastseen"] = seenTime except (TypeError, KeyError): knownnodes.knownNodes[stream][peer] = { "lastseen": seenTime, "rating": 0, "self": False, } - # since we don't track peers outside of knownnodes, - # only spread if in knownnodes to prevent flood - # DISABLED TO WORKAROUND FLOOD/LEAK - # addrQueue.put((stream, peer, seenTime, - # self.destination)) + addrQueue.put((stream, peer, self.destination)) return True def bm_command_portcheck(self): """Incoming port check request, queue it.""" - portCheckerQueue.put(Peer(self.destination, self.peerNode.port)) + portCheckerQueue.put(state.Peer(self.destination, self.peerNode.port)) return True def bm_command_ping(self): @@ -481,7 +462,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): self.append_write_buf(protocol.CreatePacket('pong')) return True - def bm_command_pong(self): # pylint: disable=no-self-use + def bm_command_pong(self): """ Incoming pong. Ignore it. PyBitmessage pings connections after about 5 minutes @@ -519,7 +500,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): self.timeOffset = self.timestamp - int(time.time()) logger.debug('remoteProtocolVersion: %i', self.remoteProtocolVersion) logger.debug('services: 0x%08X', self.services) - logger.debug('time offset: %i', self.timeOffset) + logger.debug('time offset: %i', self.timestamp - int(time.time())) logger.debug('my external IP: %s', self.sockNode.host) logger.debug( 'remote node incoming address: %s:%i', @@ -549,7 +530,6 @@ class BMProto(AdvancedDispatcher, ObjectTracker): length=self.payloadLength, expectBytes=0) return False - # pylint: disable=too-many-return-statements def peerValidityChecks(self): """Check the validity of the peer""" if self.remoteProtocolVersion < 3: @@ -560,16 +540,16 @@ class BMProto(AdvancedDispatcher, ObjectTracker): 'Closing connection to old protocol version %s, node: %s', self.remoteProtocolVersion, self.destination) return False - if self.timeOffset > MAX_TIME_OFFSET: + if self.timeOffset > BMProto.maxTimeOffset: self.append_write_buf(protocol.assembleErrorMessage( - errorText="Your time is too far in the future" - " compared to mine. Closing connection.", fatal=2)) + errorText="Your time is too far in the future compared to mine." + " Closing connection.", fatal=2)) logger.info( "%s's time is too far in the future (%s seconds)." " Closing connection to it.", self.destination, self.timeOffset) BMProto.timeOffsetWrongCount += 1 return False - elif self.timeOffset < -MAX_TIME_OFFSET: + elif self.timeOffset < -BMProto.maxTimeOffset: self.append_write_buf(protocol.assembleErrorMessage( errorText="Your time is too far in the past compared to mine." " Closing connection.", fatal=2)) @@ -585,8 +565,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker): errorText="We don't have shared stream interests." " Closing connection.", fatal=2)) logger.debug( - 'Closed connection to %s because there is no overlapping' - ' interest in streams.', self.destination) + 'Closed connection to %s because there is no overlapping interest' + ' in streams.', self.destination) return False if self.destination in connectionpool.BMConnectionPool().inboundConnections: try: @@ -595,8 +575,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker): errorText="Too many connections from your IP." " Closing connection.", fatal=2)) logger.debug( - 'Closed connection to %s because we are already' - ' connected to that IP.', self.destination) + 'Closed connection to %s because we are already connected' + ' to that IP.', self.destination) return False except: pass @@ -604,14 +584,12 @@ class BMProto(AdvancedDispatcher, ObjectTracker): # incoming from a peer we're connected to as outbound, # or server full report the same error to counter deanonymisation if ( - Peer(self.destination.host, self.peerNode.port) - in connectionpool.BMConnectionPool().inboundConnections - or len(connectionpool.BMConnectionPool().inboundConnections) - + len(connectionpool.BMConnectionPool().outboundConnections) - > BMConfigParser().safeGetInt( - 'bitmessagesettings', 'maxtotalconnections') - + BMConfigParser().safeGetInt( - 'bitmessagesettings', 'maxbootstrapconnections') + state.Peer(self.destination.host, self.peerNode.port) in + connectionpool.BMConnectionPool().inboundConnections or + len(connectionpool.BMConnectionPool().inboundConnections) + + len(connectionpool.BMConnectionPool().outboundConnections) > + BMConfigParser().safeGetInt("bitmessagesettings", "maxtotalconnections") + + BMConfigParser().safeGetInt("bitmessagesettings", "maxbootstrapconnections") ): self.append_write_buf(protocol.assembleErrorMessage( errorText="Server full, please try again later.", fatal=2)) @@ -631,10 +609,36 @@ class BMProto(AdvancedDispatcher, ObjectTracker): return True + @staticmethod + def assembleAddr(peerList): + """Build up a packed address""" + if isinstance(peerList, state.Peer): + peerList = (peerList) + if not peerList: + return b'' + retval = b'' + for i in range(0, len(peerList), BMProto.maxAddrCount): + payload = addresses.encodeVarint( + len(peerList[i:i + BMProto.maxAddrCount])) + for address in peerList[i:i + BMProto.maxAddrCount]: + stream, peer, timestamp = address + payload += struct.pack( + '>Q', timestamp) # 64-bit time + payload += struct.pack('>I', stream) + payload += struct.pack( + '>q', 1) # service bit flags offered by this node + payload += protocol.encodeHost(peer.host) + payload += struct.pack('>H', peer.port) # remote port + retval += protocol.CreatePacket('addr', payload) + return retval + @staticmethod def stopDownloadingObject(hashId, forwardAnyway=False): """Stop downloading an object""" - for connection in connectionpool.BMConnectionPool().connections(): + for connection in ( + connectionpool.BMConnectionPool().inboundConnections.values() + + connectionpool.BMConnectionPool().outboundConnections.values() + ): try: del connection.objectsNewToMe[hashId] except KeyError: @@ -675,7 +679,7 @@ class BMStringParser(BMProto): """ def __init__(self): super(BMStringParser, self).__init__() - self.destination = Peer('127.0.0.1', 8444) + self.destination = state.Peer('127.0.0.1', 8444) self.payload = None ObjectTracker.__init__(self) diff --git a/src/network/connectionchooser.py b/src/network/connectionchooser.py index badd98b7..e116ec53 100644 --- a/src/network/connectionchooser.py +++ b/src/network/connectionchooser.py @@ -1,21 +1,14 @@ -""" -Select which node to connect to -""" -# pylint: disable=too-many-branches -import logging import random # nosec import knownnodes import protocol import state from bmconfigparser import BMConfigParser +from debug import logger from queues import Queue, portCheckerQueue -logger = logging.getLogger('default') - def getDiscoveredPeer(): - """Get a peer from the local peer discovery list""" try: peer = random.choice(state.discoveredPeers.keys()) except (IndexError, KeyError): @@ -28,11 +21,10 @@ def getDiscoveredPeer(): def chooseConnection(stream): - """Returns an appropriate connection""" haveOnion = BMConfigParser().safeGet( "bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS' - onionOnly = BMConfigParser().safeGetBoolean( - "bitmessagesettings", "onionservicesonly") + if state.trustedPeer: + return state.trustedPeer try: retval = portCheckerQueue.get(False) portCheckerQueue.task_done() @@ -46,23 +38,15 @@ def chooseConnection(stream): for _ in range(50): peer = random.choice(knownnodes.knownNodes[stream].keys()) try: - peer_info = knownnodes.knownNodes[stream][peer] - if peer_info.get('self'): - continue - rating = peer_info["rating"] + rating = knownnodes.knownNodes[stream][peer]['rating'] except TypeError: logger.warning('Error in %s', peer) rating = 0 if haveOnion: - # do not connect to raw IP addresses - # --keep all traffic within Tor overlay - if onionOnly and not peer.host.endswith('.onion'): - continue # onion addresses have a higher priority when SOCKS if peer.host.endswith('.onion') and rating > 0: rating = 1 - # TODO: need better check - elif not peer.host.startswith('bootstrap'): + else: encodedAddr = protocol.encodeHost(peer.host) # don't connect to local IPs when using SOCKS if not protocol.checkIPAddress(encodedAddr, False): diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index 6264191d..077f44a5 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -1,49 +1,27 @@ -""" -`BMConnectionPool` class definition -""" import errno -import logging import re import socket -import sys import time import asyncore_pollchoose as asyncore +import helper_bootstrap import helper_random import knownnodes import protocol import state from bmconfigparser import BMConfigParser from connectionchooser import chooseConnection -from node import Peer +from debug import logger from proxy import Proxy from singleton import Singleton from tcp import ( - bootstrap, Socks4aBMConnection, Socks5BMConnection, - TCPConnection, TCPServer) + TCPServer, Socks5BMConnection, Socks4aBMConnection, TCPConnection) from udp import UDPSocket -logger = logging.getLogger('default') - @Singleton class BMConnectionPool(object): """Pool of all existing connections""" - # pylint: disable=too-many-instance-attributes - - trustedPeer = None - """ - If the trustedpeer option is specified in keys.dat then this will - contain a Peer which will be connected to instead of using the - addresses advertised by other peers. - - The expected use case is where the user has a trusted server where - they run a Bitmessage daemon permanently. If they then run a second - instance of the client on a local machine periodically when they want - to check for messages it will sync with the network a lot faster - without compromising security. - """ - def __init__(self): asyncore.set_rates( BMConfigParser().safeGetInt( @@ -56,33 +34,9 @@ class BMConnectionPool(object): self.listeningSockets = {} self.udpSockets = {} self.streams = [] - self._lastSpawned = 0 - self._spawnWait = 2 - self._bootstrapped = False - - trustedPeer = BMConfigParser().safeGet( - 'bitmessagesettings', 'trustedpeer') - try: - if trustedPeer: - host, port = trustedPeer.split(':') - self.trustedPeer = Peer(host, int(port)) - except ValueError: - sys.exit( - 'Bad trustedpeer config setting! It should be set as' - ' trustedpeer=:' - ) - - def connections(self): - """ - Shortcut for combined list of connections from - `inboundConnections` and `outboundConnections` dicts - """ - return self.inboundConnections.values() + self.outboundConnections.values() - - def establishedConnections(self): - """Shortcut for list of connections having fullyEstablished == True""" - return [ - x for x in self.connections() if x.fullyEstablished] + self.lastSpawned = 0 + self.spawnWait = 2 + self.bootstrapped = False def connectToStream(self, streamNumber): """Connect to a bitmessage stream""" @@ -113,7 +67,10 @@ class BMConnectionPool(object): def isAlreadyConnected(self, nodeid): """Check if we're already connected to this peer""" - for i in self.connections(): + for i in ( + self.inboundConnections.values() + + self.outboundConnections.values() + ): try: if nodeid == i.nodeid: return True @@ -139,7 +96,7 @@ class BMConnectionPool(object): if isinstance(connection, UDPSocket): del self.udpSockets[connection.listening.host] elif isinstance(connection, TCPServer): - del self.listeningSockets[Peer( + del self.listeningSockets[state.Peer( connection.destination.host, connection.destination.port)] elif connection.isOutbound: try: @@ -156,8 +113,7 @@ class BMConnectionPool(object): pass connection.handle_close() - @staticmethod - def getListeningIP(): + def getListeningIP(self): """What IP are we supposed to be listening on?""" if BMConfigParser().safeGet( "bitmessagesettings", "onionhostname").endswith(".onion"): @@ -165,11 +121,10 @@ class BMConnectionPool(object): "bitmessagesettings", "onionbindip") else: host = '127.0.0.1' - if ( - BMConfigParser().safeGetBoolean("bitmessagesettings", "sockslisten") - or BMConfigParser().safeGet("bitmessagesettings", "socksproxytype") - == "none" - ): + if (BMConfigParser().safeGetBoolean( + "bitmessagesettings", "sockslisten") or + BMConfigParser().safeGet( + "bitmessagesettings", "socksproxytype") == "none"): # python doesn't like bind + INADDR_ANY? # host = socket.INADDR_ANY host = BMConfigParser().get("network", "bind") @@ -199,37 +154,8 @@ class BMConnectionPool(object): udpSocket = UDPSocket(host=bind, announcing=True) self.udpSockets[udpSocket.listening.host] = udpSocket - def startBootstrappers(self): - """Run the process of resolving bootstrap hostnames""" - proxy_type = BMConfigParser().safeGet( - 'bitmessagesettings', 'socksproxytype') - # A plugins may be added here - hostname = None - if not proxy_type or proxy_type == 'none': - connection_base = TCPConnection - elif proxy_type == 'SOCKS5': - connection_base = Socks5BMConnection - hostname = helper_random.randomchoice([ - 'quzwelsuziwqgpt2.onion', None - ]) - elif proxy_type == 'SOCKS4a': - connection_base = Socks4aBMConnection # FIXME: I cannot test - else: - # This should never happen because socksproxytype setting - # is handled in bitmessagemain before starting the connectionpool - return - - bootstrapper = bootstrap(connection_base) - if not hostname: - port = helper_random.randomchoice([8080, 8444]) - hostname = 'bootstrap%s.bitmessage.org' % port - else: - port = 8444 - self.addConnection(bootstrapper(hostname, port)) - - def loop(self): # pylint: disable=too-many-branches,too-many-statements + def loop(self): """Main Connectionpool's loop""" - # pylint: disable=too-many-locals # defaults to empty loop if outbound connections are maxed spawnConnections = False acceptConnections = True @@ -243,22 +169,18 @@ class BMConnectionPool(object): 'bitmessagesettings', 'socksproxytype', '') onionsocksproxytype = BMConfigParser().safeGet( 'bitmessagesettings', 'onionsocksproxytype', '') - if ( - socksproxytype[:5] == 'SOCKS' - and not BMConfigParser().safeGetBoolean( - 'bitmessagesettings', 'sockslisten') - and '.onion' not in BMConfigParser().safeGet( - 'bitmessagesettings', 'onionhostname', '') - ): + if (socksproxytype[:5] == 'SOCKS' and + not BMConfigParser().safeGetBoolean( + 'bitmessagesettings', 'sockslisten') and + '.onion' not in BMConfigParser().safeGet( + 'bitmessagesettings', 'onionhostname', '')): acceptConnections = False - # pylint: disable=too-many-nested-blocks if spawnConnections: if not knownnodes.knownNodesActual: - self.startBootstrappers() - knownnodes.knownNodesActual = True - if not self._bootstrapped: - self._bootstrapped = True + helper_bootstrap.dns() + if not self.bootstrapped: + self.bootstrapped = True Proxy.proxy = ( BMConfigParser().safeGet( 'bitmessagesettings', 'sockshostname'), @@ -287,7 +209,7 @@ class BMConnectionPool(object): for i in range( state.maximumNumberOfHalfOpenConnections - pending): try: - chosen = self.trustedPeer or chooseConnection( + chosen = chooseConnection( helper_random.randomchoice(self.streams)) except ValueError: continue @@ -298,22 +220,10 @@ class BMConnectionPool(object): # don't connect to self if chosen in state.ownAddresses: continue - # don't connect to the hosts from the same - # network group, defense against sibyl attacks - host_network_group = protocol.network_group( - chosen.host) - same_group = False - for j in self.outboundConnections.values(): - if host_network_group == j.network_group: - same_group = True - if chosen.host == j.destination.host: - knownnodes.decreaseRating(chosen) - break - if same_group: - continue try: - if chosen.host.endswith(".onion") and Proxy.onion_proxy: + if (chosen.host.endswith(".onion") and + Proxy.onion_proxy is not None): if onionsocksproxytype == "SOCKS5": self.addConnection(Socks5BMConnection(chosen)) elif onionsocksproxytype == "SOCKS4a": @@ -328,9 +238,12 @@ class BMConnectionPool(object): if e.errno == errno.ENETUNREACH: continue - self._lastSpawned = time.time() + self.lastSpawned = time.time() else: - for i in self.connections(): + for i in ( + self.inboundConnections.values() + + self.outboundConnections.values() + ): # FIXME: rating will be increased after next connection i.handle_close() @@ -340,7 +253,7 @@ class BMConnectionPool(object): self.startListening() else: for bind in re.sub( - r'[^\w.]+', ' ', + "[^\w.]+", " ", BMConfigParser().safeGet('network', 'bind') ).split(): self.startListening(bind) @@ -350,7 +263,7 @@ class BMConnectionPool(object): self.startUDPSocket() else: for bind in re.sub( - r'[^\w.]+', ' ', + "[^\w.]+", " ", BMConfigParser().safeGet('network', 'bind') ).split(): self.startUDPSocket(bind) @@ -368,13 +281,16 @@ class BMConnectionPool(object): i.accepting = i.connecting = i.connected = False logger.info('Stopped udp sockets.') - loopTime = float(self._spawnWait) - if self._lastSpawned < time.time() - self._spawnWait: + loopTime = float(self.spawnWait) + if self.lastSpawned < time.time() - self.spawnWait: loopTime = 2.0 asyncore.loop(timeout=loopTime, count=1000) reaper = [] - for i in self.connections(): + for i in ( + self.inboundConnections.values() + + self.outboundConnections.values() + ): minTx = time.time() - 20 if i.fullyEstablished: minTx -= 300 - 20 @@ -386,8 +302,10 @@ class BMConnectionPool(object): time.time() - i.lastTx) i.set_state("close") for i in ( - self.connections() - + self.listeningSockets.values() + self.udpSockets.values() + self.inboundConnections.values() + + self.outboundConnections.values() + + self.listeningSockets.values() + + self.udpSockets.values() ): if not (i.accepting or i.connecting or i.connected): reaper.append(i) diff --git a/src/network/constants.py b/src/network/constants.py deleted file mode 100644 index f8f4120f..00000000 --- a/src/network/constants.py +++ /dev/null @@ -1,17 +0,0 @@ -""" -Network protocol constants -""" - - -#: address is online if online less than this many seconds ago -ADDRESS_ALIVE = 10800 -#: protocol specification says max 1000 addresses in one addr command -MAX_ADDR_COUNT = 1000 -#: ~1.6 MB which is the maximum possible size of an inv message. -MAX_MESSAGE_SIZE = 1600100 -#: 2**18 = 256kB is the maximum size of an object payload -MAX_OBJECT_PAYLOAD_SIZE = 2**18 -#: protocol specification says max 50000 objects in one inv command -MAX_OBJECT_COUNT = 50000 -#: maximum time offset -MAX_TIME_OFFSET = 3600 diff --git a/src/network/dandelion.py b/src/network/dandelion.py index 03f45bd7..2678ca57 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -1,14 +1,11 @@ -""" -Dandelion class definition, tracks stages -""" -import logging from collections import namedtuple -from random import choice, expovariate, sample +from random import choice, sample, expovariate from threading import RLock from time import time import connectionpool import state +from debug import logging from queues import invQueue from singleton import Singleton @@ -23,11 +20,9 @@ MAX_STEMS = 2 Stem = namedtuple('Stem', ['child', 'stream', 'timeout']) -logger = logging.getLogger('default') - @Singleton -class Dandelion: # pylint: disable=old-style-class +class Dandelion(): """Dandelion class for tracking stem/fluff stages.""" def __init__(self): # currently assignable child stems @@ -40,8 +35,7 @@ class Dandelion: # pylint: disable=old-style-class self.refresh = time() + REASSIGN_INTERVAL self.lock = RLock() - @staticmethod - def poissonTimeout(start=None, average=0): + def poissonTimeout(self, start=None, average=0): """Generate deadline using Poisson distribution""" if start is None: start = time() @@ -73,10 +67,9 @@ class Dandelion: # pylint: disable=old-style-class def removeHash(self, hashId, reason="no reason specified"): """Switch inventory vector from stem to fluff mode""" - if logger.isEnabledFor(logging.DEBUG): - logger.debug( - '%s entering fluff mode due to %s.', - ''.join('%02x' % ord(i) for i in hashId), reason) + logging.debug( + "%s entering fluff mode due to %s.", + ''.join('%02x' % ord(i) for i in hashId), reason) with self.lock: try: del self.hashMap[hashId] @@ -104,8 +97,8 @@ class Dandelion: # pylint: disable=old-style-class for k in (k for k, v in self.nodeMap.iteritems() if v is None): self.nodeMap[k] = connection for k, v in { - k: v for k, v in self.hashMap.iteritems() - if v.child is None + k: v for k, v in self.hashMap.iteritems() + if v.child is None }.iteritems(): self.hashMap[k] = Stem( connection, v.stream, self.poissonTimeout()) @@ -122,13 +115,12 @@ class Dandelion: # pylint: disable=old-style-class self.stem.remove(connection) # active mappings to pointing to the removed node for k in ( - k for k, v in self.nodeMap.iteritems() - if v == connection + k for k, v in self.nodeMap.iteritems() if v == connection ): self.nodeMap[k] = None for k, v in { - k: v for k, v in self.hashMap.iteritems() - if v.child == connection + k: v for k, v in self.hashMap.iteritems() + if v.child == connection }.iteritems(): self.hashMap[k] = Stem( None, v.stream, self.poissonTimeout()) diff --git a/src/network/downloadthread.py b/src/network/downloadthread.py index 0ae83b5b..babce5da 100644 --- a/src/network/downloadthread.py +++ b/src/network/downloadthread.py @@ -1,20 +1,18 @@ -""" -`DownloadThread` class definition -""" +import threading import time import addresses import helper_random import protocol from dandelion import Dandelion +from debug import logger +from helper_threading import StoppableThread from inventory import Inventory from network.connectionpool import BMConnectionPool from objectracker import missingObjects -from threads import StoppableThread -class DownloadThread(StoppableThread): - """Thread-based class for downloading from connections""" +class DownloadThread(threading.Thread, StoppableThread): minPending = 200 maxRequestChunk = 1000 requestTimeout = 60 @@ -22,16 +20,16 @@ class DownloadThread(StoppableThread): requestExpires = 3600 def __init__(self): - super(DownloadThread, self).__init__(name="Downloader") + threading.Thread.__init__(self, name="Downloader") + self.initStop() + self.name = "Downloader" + logger.info("init download thread") self.lastCleaned = time.time() def cleanPending(self): - """Expire pending downloads eventually""" - deadline = time.time() - self.requestExpires + deadline = time.time() - DownloadThread.requestExpires try: - toDelete = [ - k for k, v in missingObjects.iteritems() - if v < deadline] + toDelete = [k for k, v in missingObjects.iteritems() if v < deadline] except RuntimeError: pass else: @@ -43,12 +41,12 @@ class DownloadThread(StoppableThread): while not self._stopped: requested = 0 # Choose downloading peers randomly - connections = BMConnectionPool().establishedConnections() + connections = [x for x in BMConnectionPool().inboundConnections.values() + BMConnectionPool().outboundConnections.values() if x.fullyEstablished] helper_random.randomshuffle(connections) - requestChunk = max(int( - min(self.maxRequestChunk, len(missingObjects)) - / len(connections)), 1) if connections else 1 - + try: + requestChunk = max(int(min(DownloadThread.maxRequestChunk, len(missingObjects)) / len(connections)), 1) + except ZeroDivisionError: + requestChunk = 1 for i in connections: now = time.time() # avoid unnecessary delay @@ -74,11 +72,9 @@ class DownloadThread(StoppableThread): continue payload[0:0] = addresses.encodeVarint(chunkCount) i.append_write_buf(protocol.CreatePacket('getdata', payload)) - self.logger.debug( - '%s:%i Requesting %i objects', - i.destination.host, i.destination.port, chunkCount) + logger.debug("%s:%i Requesting %i objects", i.destination.host, i.destination.port, chunkCount) requested += chunkCount - if time.time() >= self.lastCleaned + self.cleanInterval: + if time.time() >= self.lastCleaned + DownloadThread.cleanInterval: self.cleanPending() if not requested: self.stop.wait(1) diff --git a/src/network/http_old.py b/src/network/http-old.py similarity index 80% rename from src/network/http_old.py rename to src/network/http-old.py index 64d09983..56d24915 100644 --- a/src/network/http_old.py +++ b/src/network/http-old.py @@ -8,7 +8,6 @@ duration = 60 class HTTPClient(asyncore.dispatcher): - """An asyncore dispatcher""" port = 12345 def __init__(self, host, path, connect=True): @@ -20,33 +19,31 @@ class HTTPClient(asyncore.dispatcher): self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path def handle_close(self): - # pylint: disable=global-statement global requestCount requestCount += 1 self.close() def handle_read(self): - # print self.recv(8192) +# print self.recv(8192) self.recv(8192) def writable(self): - return len(self.buffer) > 0 + return (len(self.buffer) > 0) def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:] - if __name__ == "__main__": # initial fill for i in range(parallel): HTTPClient('127.0.0.1', '/') start = time.time() - while time.time() - start < duration: - if len(asyncore.socket_map) < parallel: + while (time.time() - start < duration): + if (len(asyncore.socket_map) < parallel): for i in range(parallel - len(asyncore.socket_map)): HTTPClient('127.0.0.1', '/') print "Active connections: %i" % (len(asyncore.socket_map)) - asyncore.loop(count=len(asyncore.socket_map) / 2) + asyncore.loop(count=len(asyncore.socket_map)/2) if requestCount % 100 == 0: print "Processed %i total messages" % (requestCount) diff --git a/src/network/http.py b/src/network/http.py index 8bba38ac..55cb81a1 100644 --- a/src/network/http.py +++ b/src/network/http.py @@ -2,17 +2,15 @@ import socket from advanceddispatcher import AdvancedDispatcher import asyncore_pollchoose as asyncore -from proxy import ProxyError -from socks5 import Socks5Connection, Socks5Resolver -from socks4a import Socks4aConnection, Socks4aResolver +from proxy import Proxy, ProxyError, GeneralProxyError +from socks5 import Socks5Connection, Socks5Resolver, Socks5AuthError, Socks5Error +from socks4a import Socks4aConnection, Socks4aResolver, Socks4aError - -class HttpError(ProxyError): - pass +class HttpError(ProxyError): pass class HttpConnection(AdvancedDispatcher): - def __init__(self, host, path="/"): # pylint: disable=redefined-outer-name + def __init__(self, host, path="/"): AdvancedDispatcher.__init__(self) self.path = path self.destination = (host, 80) @@ -21,15 +19,13 @@ class HttpConnection(AdvancedDispatcher): print "connecting in background to %s:%i" % (self.destination[0], self.destination[1]) def state_init(self): - self.append_write_buf( - "GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n" % ( - self.path, self.destination[0])) - print "Sending %ib" % (len(self.write_buf)) + self.append_write_buf("GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n" % (self.path, self.destination[0])) + print "Sending %ib" % (len(self.write_buf)) self.set_state("http_request_sent", 0) return False def state_http_request_sent(self): - if self.read_buf: + if len(self.read_buf) > 0: print "Received %ib" % (len(self.read_buf)) self.read_buf = b"" if not self.connected: @@ -38,7 +34,7 @@ class HttpConnection(AdvancedDispatcher): class Socks5HttpConnection(Socks5Connection, HttpConnection): - def __init__(self, host, path="/"): # pylint: disable=super-init-not-called, redefined-outer-name + def __init__(self, host, path="/"): self.path = path Socks5Connection.__init__(self, address=(host, 80)) @@ -48,7 +44,7 @@ class Socks5HttpConnection(Socks5Connection, HttpConnection): class Socks4aHttpConnection(Socks4aConnection, HttpConnection): - def __init__(self, host, path="/"): # pylint: disable=super-init-not-called, redefined-outer-name + def __init__(self, host, path="/"): Socks4aConnection.__init__(self, address=(host, 80)) self.path = path @@ -59,31 +55,32 @@ class Socks4aHttpConnection(Socks4aConnection, HttpConnection): if __name__ == "__main__": # initial fill + for host in ("bootstrap8080.bitmessage.org", "bootstrap8444.bitmessage.org"): proxy = Socks5Resolver(host=host) - while asyncore.socket_map: + while len(asyncore.socket_map) > 0: print "loop %s, len %i" % (proxy.state, len(asyncore.socket_map)) asyncore.loop(timeout=1, count=1) proxy.resolved() proxy = Socks4aResolver(host=host) - while asyncore.socket_map: + while len(asyncore.socket_map) > 0: print "loop %s, len %i" % (proxy.state, len(asyncore.socket_map)) asyncore.loop(timeout=1, count=1) proxy.resolved() for host in ("bitmessage.org",): direct = HttpConnection(host) - while asyncore.socket_map: - # print "loop, state = %s" % (direct.state) + while len(asyncore.socket_map) > 0: +# print "loop, state = %s" % (direct.state) asyncore.loop(timeout=1, count=1) proxy = Socks5HttpConnection(host) - while asyncore.socket_map: - # print "loop, state = %s" % (proxy.state) + while len(asyncore.socket_map) > 0: +# print "loop, state = %s" % (proxy.state) asyncore.loop(timeout=1, count=1) proxy = Socks4aHttpConnection(host) - while asyncore.socket_map: - # print "loop, state = %s" % (proxy.state) + while len(asyncore.socket_map) > 0: +# print "loop, state = %s" % (proxy.state) asyncore.loop(timeout=1, count=1) diff --git a/src/network/httpd.py b/src/network/httpd.py index b69ffa99..b8b6ba21 100644 --- a/src/network/httpd.py +++ b/src/network/httpd.py @@ -1,34 +1,28 @@ -""" -src/network/httpd.py -======================= -""" import asyncore import socket from tls import TLSHandshake - class HTTPRequestHandler(asyncore.dispatcher): - """Handling HTTP request""" response = """HTTP/1.0 200 OK\r - Date: Sun, 23 Oct 2016 18:02:00 GMT\r - Content-Type: text/html; charset=UTF-8\r - Content-Encoding: UTF-8\r - Content-Length: 136\r - Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT\r - Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)\r - ETag: "3f80f-1b6-3e1cb03b"\r - Accept-Ranges: bytes\r - Connection: close\r - \r - - - An Example Page - - - Hello World, this is a very simple HTML document. - - """ +Date: Sun, 23 Oct 2016 18:02:00 GMT\r +Content-Type: text/html; charset=UTF-8\r +Content-Encoding: UTF-8\r +Content-Length: 136\r +Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT\r +Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)\r +ETag: "3f80f-1b6-3e1cb03b"\r +Accept-Ranges: bytes\r +Connection: close\r +\r + + + An Example Page + + + Hello World, this is a very simple HTML document. + +""" def __init__(self, sock): if not hasattr(self, '_map'): @@ -68,17 +62,11 @@ class HTTPRequestHandler(asyncore.dispatcher): class HTTPSRequestHandler(HTTPRequestHandler, TLSHandshake): - """Handling HTTPS request""" def __init__(self, sock): if not hasattr(self, '_map'): - asyncore.dispatcher.__init__(self, sock) # pylint: disable=non-parent-init-called - # self.tlsDone = False - TLSHandshake.__init__( - self, - sock=sock, - certfile='/home/shurdeek/src/PyBitmessage/src/sslkeys/cert.pem', - keyfile='/home/shurdeek/src/PyBitmessage/src/sslkeys/key.pem', - server_side=True) + asyncore.dispatcher.__init__(self, sock) +# self.tlsDone = False + TLSHandshake.__init__(self, sock=sock, certfile='/home/shurdeek/src/PyBitmessage/src/sslkeys/cert.pem', keyfile='/home/shurdeek/src/PyBitmessage/src/sslkeys/key.pem', server_side=True) HTTPRequestHandler.__init__(self, sock) def handle_connect(self): @@ -93,7 +81,8 @@ class HTTPSRequestHandler(HTTPRequestHandler, TLSHandshake): def readable(self): if self.tlsDone: return HTTPRequestHandler.readable(self) - return TLSHandshake.readable(self) + else: + return TLSHandshake.readable(self) def handle_read(self): if self.tlsDone: @@ -104,7 +93,8 @@ class HTTPSRequestHandler(HTTPRequestHandler, TLSHandshake): def writable(self): if self.tlsDone: return HTTPRequestHandler.writable(self) - return TLSHandshake.writable(self) + else: + return TLSHandshake.writable(self) def handle_write(self): if self.tlsDone: @@ -114,7 +104,6 @@ class HTTPSRequestHandler(HTTPRequestHandler, TLSHandshake): class HTTPServer(asyncore.dispatcher): - """Handling HTTP Server""" port = 12345 def __init__(self): @@ -130,15 +119,14 @@ class HTTPServer(asyncore.dispatcher): pair = self.accept() if pair is not None: sock, addr = pair - # print 'Incoming connection from %s' % repr(addr) +# print 'Incoming connection from %s' % repr(addr) self.connections += 1 - # if self.connections % 1000 == 0: - # print "Processed %i connections, active %i" % (self.connections, len(asyncore.socket_map)) +# if self.connections % 1000 == 0: +# print "Processed %i connections, active %i" % (self.connections, len(asyncore.socket_map)) HTTPRequestHandler(sock) class HTTPSServer(HTTPServer): - """Handling HTTPS Server""" port = 12345 def __init__(self): @@ -149,13 +137,12 @@ class HTTPSServer(HTTPServer): pair = self.accept() if pair is not None: sock, addr = pair - # print 'Incoming connection from %s' % repr(addr) +# print 'Incoming connection from %s' % repr(addr) self.connections += 1 - # if self.connections % 1000 == 0: - # print "Processed %i connections, active %i" % (self.connections, len(asyncore.socket_map)) +# if self.connections % 1000 == 0: +# print "Processed %i connections, active %i" % (self.connections, len(asyncore.socket_map)) HTTPSRequestHandler(sock) - if __name__ == "__main__": client = HTTPSServer() asyncore.loop() diff --git a/src/network/https.py b/src/network/https.py index a7b8b57c..151efcb8 100644 --- a/src/network/https.py +++ b/src/network/https.py @@ -1,18 +1,10 @@ import asyncore from http import HTTPClient +import paths from tls import TLSHandshake -""" -self.sslSock = ssl.wrap_socket( - self.sock, - keyfile=os.path.join(paths.codePath(), 'sslkeys', 'key.pem'), - certfile=os.path.join(paths.codePath(), 'sslkeys', 'cert.pem'), - server_side=not self.initiatedConnection, - ssl_version=ssl.PROTOCOL_TLSv1, - do_handshake_on_connect=False, - ciphers='AECDH-AES256-SHA') -""" +# self.sslSock = ssl.wrap_socket(self.sock, keyfile = os.path.join(paths.codePath(), 'sslkeys', 'key.pem'), certfile = os.path.join(paths.codePath(), 'sslkeys', 'cert.pem'), server_side = not self.initiatedConnection, ssl_version=ssl.PROTOCOL_TLSv1, do_handshake_on_connect=False, ciphers='AECDH-AES256-SHA') class HTTPSClient(HTTPClient, TLSHandshake): @@ -20,15 +12,7 @@ class HTTPSClient(HTTPClient, TLSHandshake): if not hasattr(self, '_map'): asyncore.dispatcher.__init__(self) self.tlsDone = False - """ - TLSHandshake.__init__( - self, - address=(host, 443), - certfile='/home/shurdeek/src/PyBitmessage/sslsrc/keys/cert.pem', - keyfile='/home/shurdeek/src/PyBitmessage/src/sslkeys/key.pem', - server_side=False, - ciphers='AECDH-AES256-SHA') - """ +# TLSHandshake.__init__(self, address=(host, 443), certfile='/home/shurdeek/src/PyBitmessage/sslsrc/keys/cert.pem', keyfile='/home/shurdeek/src/PyBitmessage/src/sslkeys/key.pem', server_side=False, ciphers='AECDH-AES256-SHA') HTTPClient.__init__(self, host, path, connect=False) TLSHandshake.__init__(self, address=(host, 443), server_side=False) @@ -65,7 +49,6 @@ class HTTPSClient(HTTPClient, TLSHandshake): else: TLSHandshake.handle_write(self) - if __name__ == "__main__": client = HTTPSClient('anarchy.economicsofbitcoin.com', '/') asyncore.loop() diff --git a/src/network/invthread.py b/src/network/invthread.py index e68b7692..6f6f1364 100644 --- a/src/network/invthread.py +++ b/src/network/invthread.py @@ -1,17 +1,16 @@ -""" -Thread to send inv annoucements -""" import Queue -import random +from random import randint, shuffle +import threading from time import time import addresses -import protocol -import state +from bmconfigparser import BMConfigParser +from helper_threading import StoppableThread from network.connectionpool import BMConnectionPool from network.dandelion import Dandelion from queues import invQueue -from threads import StoppableThread +import protocol +import state def handleExpiredDandelion(expired): @@ -19,7 +18,9 @@ def handleExpiredDandelion(expired): the object""" if not expired: return - for i in BMConnectionPool().connections(): + for i in \ + BMConnectionPool().inboundConnections.values() + \ + BMConnectionPool().outboundConnections.values(): if not i.fullyEstablished: continue for x in expired: @@ -32,23 +33,23 @@ def handleExpiredDandelion(expired): i.objectsNewToThem[hashid] = time() -class InvThread(StoppableThread): - """Main thread that sends inv annoucements""" +class InvThread(threading.Thread, StoppableThread): + def __init__(self): + threading.Thread.__init__(self, name="InvBroadcaster") + self.initStop() + self.name = "InvBroadcaster" - name = "InvBroadcaster" - - @staticmethod - def handleLocallyGenerated(stream, hashId): - """Locally generated inventory items require special handling""" + def handleLocallyGenerated(self, stream, hashId): Dandelion().addHash(hashId, stream=stream) - for connection in BMConnectionPool().connections(): - if state.dandelion and connection != \ - Dandelion().objectChildStem(hashId): - continue - connection.objectsNewToThem[hashId] = time() + for connection in \ + BMConnectionPool().inboundConnections.values() + \ + BMConnectionPool().outboundConnections.values(): + if state.dandelion and connection != Dandelion().objectChildStem(hashId): + continue + connection.objectsNewToThem[hashId] = time() - def run(self): # pylint: disable=too-many-branches - while not state.shutdown: # pylint: disable=too-many-nested-blocks + def run(self): + while not state.shutdown: chunk = [] while True: # Dandelion fluff trigger by expiration @@ -63,7 +64,8 @@ class InvThread(StoppableThread): break if chunk: - for connection in BMConnectionPool().connections(): + for connection in BMConnectionPool().inboundConnections.values() + \ + BMConnectionPool().outboundConnections.values(): fluffs = [] stems = [] for inv in chunk: @@ -78,7 +80,7 @@ class InvThread(StoppableThread): if connection == Dandelion().objectChildStem(inv[1]): # Fluff trigger by RNG # auto-ignore if config set to 0, i.e. dandelion is off - if random.randint(1, 100) >= state.dandelion: + if randint(1, 100) >= state.dandelion: fluffs.append(inv[1]) # send a dinv only if the stem node supports dandelion elif connection.services & protocol.NODE_DANDELION > 0: @@ -89,20 +91,16 @@ class InvThread(StoppableThread): fluffs.append(inv[1]) if fluffs: - random.shuffle(fluffs) - connection.append_write_buf(protocol.CreatePacket( - 'inv', - addresses.encodeVarint( - len(fluffs)) + ''.join(fluffs))) + shuffle(fluffs) + connection.append_write_buf(protocol.CreatePacket('inv', \ + addresses.encodeVarint(len(fluffs)) + "".join(fluffs))) if stems: - random.shuffle(stems) - connection.append_write_buf(protocol.CreatePacket( - 'dinv', - addresses.encodeVarint( - len(stems)) + ''.join(stems))) + shuffle(stems) + connection.append_write_buf(protocol.CreatePacket('dinv', \ + addresses.encodeVarint(len(stems)) + "".join(stems))) invQueue.iterate() - for _ in range(len(chunk)): + for i in range(len(chunk)): invQueue.task_done() if Dandelion().refresh < time(): diff --git a/src/network/networkthread.py b/src/network/networkthread.py index 61ff6c09..9ceb856b 100644 --- a/src/network/networkthread.py +++ b/src/network/networkthread.py @@ -1,16 +1,19 @@ -""" -A thread to handle network concerns -""" +import threading + import network.asyncore_pollchoose as asyncore import state +from debug import logger +from helper_threading import StoppableThread from network.connectionpool import BMConnectionPool from queues import excQueue -from threads import StoppableThread -class BMNetworkThread(StoppableThread): - """Main network thread""" - name = "Asyncore" +class BMNetworkThread(threading.Thread, StoppableThread): + def __init__(self): + threading.Thread.__init__(self, name="Asyncore") + self.initStop() + self.name = "Asyncore" + logger.info("init asyncore thread") def run(self): try: diff --git a/src/network/node.py b/src/network/node.py index 4c532b81..ab9f5fbe 100644 --- a/src/network/node.py +++ b/src/network/node.py @@ -1,7 +1,3 @@ -""" -Named tuples representing the network peers -""" import collections -Peer = collections.namedtuple('Peer', ['host', 'port']) Node = collections.namedtuple('Node', ['services', 'host', 'port']) diff --git a/src/network/objectracker.py b/src/network/objectracker.py index ca29c023..f119b2d8 100644 --- a/src/network/objectracker.py +++ b/src/network/objectracker.py @@ -1,6 +1,3 @@ -""" -Module for tracking objects -""" import time from threading import RLock @@ -30,7 +27,6 @@ missingObjects = {} class ObjectTracker(object): - """Object tracker mixin""" invCleanPeriod = 300 invInitialCapacity = 50000 invErrorRate = 0.03 @@ -46,47 +42,37 @@ class ObjectTracker(object): self.lastCleaned = time.time() def initInvBloom(self): - """Init bloom filter for tracking. WIP.""" if haveBloom: # lock? - self.invBloom = BloomFilter( - capacity=ObjectTracker.invInitialCapacity, - error_rate=ObjectTracker.invErrorRate) + self.invBloom = BloomFilter(capacity=ObjectTracker.invInitialCapacity, + error_rate=ObjectTracker.invErrorRate) def initAddrBloom(self): - """Init bloom filter for tracking addrs, WIP. - This either needs to be moved to addrthread.py or removed.""" if haveBloom: # lock? - self.addrBloom = BloomFilter( - capacity=ObjectTracker.invInitialCapacity, - error_rate=ObjectTracker.invErrorRate) + self.addrBloom = BloomFilter(capacity=ObjectTracker.invInitialCapacity, + error_rate=ObjectTracker.invErrorRate) def clean(self): - """Clean up tracking to prevent memory bloat""" if self.lastCleaned < time.time() - ObjectTracker.invCleanPeriod: if haveBloom: - if missingObjects == 0: + if len(missingObjects) == 0: self.initInvBloom() self.initAddrBloom() else: # release memory deadline = time.time() - ObjectTracker.trackingExpires with self.objectsNewToThemLock: - self.objectsNewToThem = { - k: v - for k, v in self.objectsNewToThem.iteritems() - if v >= deadline} + self.objectsNewToThem = {k: v for k, v in self.objectsNewToThem.iteritems() if v >= deadline} self.lastCleaned = time.time() def hasObj(self, hashid): - """Do we already have object?""" if haveBloom: return hashid in self.invBloom - return hashid in self.objectsNewToMe + else: + return hashid in self.objectsNewToMe def handleReceivedInventory(self, hashId): - """Handling received inventory""" if haveBloom: self.invBloom.add(hashId) try: @@ -99,20 +85,18 @@ class ObjectTracker(object): self.objectsNewToMe[hashId] = True def handleReceivedObject(self, streamNumber, hashid): - """Handling received object""" - for i in network.connectionpool.BMConnectionPool().connections(): + for i in network.connectionpool.BMConnectionPool().inboundConnections.values() + network.connectionpool.BMConnectionPool().outboundConnections.values(): if not i.fullyEstablished: continue try: del i.objectsNewToMe[hashid] except KeyError: - if streamNumber in i.streams and ( - not Dandelion().hasHash(hashid) or - Dandelion().objectChildStem(hashid) == i): + if streamNumber in i.streams and \ + (not Dandelion().hasHash(hashid) or \ + Dandelion().objectChildStem(hashid) == i): with i.objectsNewToThemLock: i.objectsNewToThem[hashid] = time.time() - # update stream number, - # which we didn't have when we just received the dinv + # update stream number, which we didn't have when we just received the dinv # also resets expiration of the stem mode Dandelion().setHashStream(hashid, streamNumber) @@ -125,12 +109,23 @@ class ObjectTracker(object): self.objectsNewToMe.setLastObject() def hasAddr(self, addr): - """WIP, should be moved to addrthread.py or removed""" if haveBloom: return addr in self.invBloom - return None def addAddr(self, hashid): - """WIP, should be moved to addrthread.py or removed""" if haveBloom: self.addrBloom.add(hashid) + +# addr sending -> per node upload queue, and flush every minute or so +# inv sending -> if not in bloom, inv immediately, otherwise put into a per node upload queue and flush every minute or so +# data sending -> a simple queue + +# no bloom +# - if inv arrives +# - if we don't have it, add tracking and download queue +# - if we do have it, remove from tracking +# tracking downloads +# - per node hash of items the node has but we don't +# tracking inv +# - per node hash of items that neither the remote node nor we have +# diff --git a/src/network/proxy.py b/src/network/proxy.py index 38676d66..04f0ac13 100644 --- a/src/network/proxy.py +++ b/src/network/proxy.py @@ -1,17 +1,11 @@ -""" -Set proxy if avaiable otherwise exception -""" -# pylint: disable=protected-access -import logging import socket import time import asyncore_pollchoose as asyncore +import state from advanceddispatcher import AdvancedDispatcher from bmconfigparser import BMConfigParser -from node import Peer - -logger = logging.getLogger('default') +from debug import logger class ProxyError(Exception): @@ -62,7 +56,7 @@ class Proxy(AdvancedDispatcher): def proxy(self, address): """Set proxy IP and port""" if (not isinstance(address, tuple) or len(address) < 2 or - not isinstance(address[0], str) or + not isinstance(address[0], str) or not isinstance(address[1], int)): raise ValueError self.__class__._proxy = address @@ -89,10 +83,9 @@ class Proxy(AdvancedDispatcher): def onion_proxy(self, address): """Set onion proxy address""" if address is not None and ( - not isinstance(address, tuple) or len(address) < 2 - or not isinstance(address[0], str) - or not isinstance(address[1], int) - ): + not isinstance(address, tuple) or len(address) < 2 or + not isinstance(address[0], str) or + not isinstance(address[1], int)): raise ValueError self.__class__._onion_proxy = address @@ -107,13 +100,12 @@ class Proxy(AdvancedDispatcher): self.__class__._onion_auth = authTuple def __init__(self, address): - if not isinstance(address, Peer): + if not isinstance(address, state.Peer): raise ValueError AdvancedDispatcher.__init__(self) self.destination = address self.isOutbound = True self.fullyEstablished = False - self.connectedAt = 0 self.create_socket(socket.AF_INET, socket.SOCK_STREAM) if BMConfigParser().safeGetBoolean( "bitmessagesettings", "socksauthentication"): @@ -121,7 +113,8 @@ class Proxy(AdvancedDispatcher): BMConfigParser().safeGet( "bitmessagesettings", "socksusername"), BMConfigParser().safeGet( - "bitmessagesettings", "sockspassword")) + "bitmessagesettings", "sockspassword") + ) else: self.auth = None self.connect( @@ -145,6 +138,5 @@ class Proxy(AdvancedDispatcher): def state_proxy_handshake_done(self): """Handshake is complete at this point""" - # pylint: disable=attribute-defined-outside-init self.connectedAt = time.time() return False diff --git a/src/network/receivequeuethread.py b/src/network/receivequeuethread.py index bf1d8300..0a7562cb 100644 --- a/src/network/receivequeuethread.py +++ b/src/network/receivequeuethread.py @@ -1,22 +1,28 @@ -""" -Process data incoming from network -""" import errno import Queue import socket +import sys +import threading +import time -import state -from network.advanceddispatcher import UnknownStateError +import addresses +from bmconfigparser import BMConfigParser +from debug import logger +from helper_threading import StoppableThread +from inventory import Inventory from network.connectionpool import BMConnectionPool +from network.bmproto import BMProto +from network.advanceddispatcher import UnknownStateError from queues import receiveDataQueue -from threads import StoppableThread +import protocol +import state - -class ReceiveQueueThread(StoppableThread): - """This thread processes data received from the network - (which is done by the asyncore thread)""" +class ReceiveQueueThread(threading.Thread, StoppableThread): def __init__(self, num=0): - super(ReceiveQueueThread, self).__init__(name="ReceiveQueue_%i" % num) + threading.Thread.__init__(self, name="ReceiveQueue_%i" %(num)) + self.initStop() + self.name = "ReceiveQueue_%i" % (num) + logger.info("init receive queue thread %i", num) def run(self): while not self._stopped and state.shutdown == 0: @@ -29,28 +35,27 @@ class ReceiveQueueThread(StoppableThread): break # cycle as long as there is data - # methods should return False if there isn't enough data, - # or the connection is to be aborted + # methods should return False if there isn't enough data, or the connection is to be aborted - # state_* methods should return False if there isn't - # enough data, or the connection is to be aborted + # state_* methods should return False if there isn't enough data, + # or the connection is to be aborted try: connection = BMConnectionPool().getConnectionByAddr(dest) - # connection object not found + # KeyError = connection object not found except KeyError: receiveDataQueue.task_done() continue try: connection.process() - # state isn't implemented - except UnknownStateError: + # UnknownStateError = state isn't implemented + except (UnknownStateError): pass except socket.error as err: if err.errno == errno.EBADF: connection.set_state("close", 0) else: - self.logger.error('Socket error: %s', err) + logger.error("Socket error: %s", str(err)) except: - self.logger.error('Error processing', exc_info=True) + logger.error("Error processing", exc_info=True) receiveDataQueue.task_done() diff --git a/src/network/socks4a.py b/src/network/socks4a.py index 0d4310bc..bdf59944 100644 --- a/src/network/socks4a.py +++ b/src/network/socks4a.py @@ -1,11 +1,7 @@ -""" -SOCKS4a proxy module -""" -# pylint: disable=attribute-defined-outside-init import socket import struct -from proxy import GeneralProxyError, Proxy, ProxyError +from proxy import Proxy, ProxyError, GeneralProxyError class Socks4aError(ProxyError): @@ -86,7 +82,7 @@ class Socks4aConnection(Socks4a): self.append_write_buf(self.ipaddr) except socket.error: # Well it's not an IP number, so it's probably a DNS name. - if self._remote_dns: + if Proxy._remote_dns: # Resolve remotely rmtrslv = True self.ipaddr = None @@ -122,7 +118,6 @@ class Socks4aResolver(Socks4a): Socks4a.__init__(self, address=(self.host, self.port)) def state_auth_done(self): - """Request connection to be made""" # Now we can request the actual connection self.append_write_buf( struct.pack('>BBH', 0x04, 0xF0, self.destination[1])) diff --git a/src/network/socks5.py b/src/network/socks5.py index fc33f4df..2e0821da 100644 --- a/src/network/socks5.py +++ b/src/network/socks5.py @@ -1,12 +1,13 @@ """ -SOCKS5 proxy module +src/network/socks5.py +===================== + """ # pylint: disable=attribute-defined-outside-init import socket import struct -from node import Peer from proxy import GeneralProxyError, Proxy, ProxyError @@ -65,9 +66,10 @@ class Socks5(Proxy): elif ret[1] == 2: # username/password self.append_write_buf( - struct.pack( - 'BB', 1, len(self._auth[0])) + self._auth[0] + struct.pack( - 'B', len(self._auth[1])) + self._auth[1]) + struct.pack('BB', 1, len(self._auth[0])) + + self._auth[0] + struct.pack('B', len(self._auth[1])) + + self._auth[1] + ) self.set_state("auth_needed", length=2, expectBytes=2) else: if ret[1] == 0xff: @@ -153,13 +155,15 @@ class Socks5(Proxy): return True def proxy_sock_name(self): - """Handle return value when using SOCKS5 - for DNS resolving instead of connecting.""" + """Handle return value when using SOCKS5 for DNS resolving instead of connecting.""" return socket.inet_ntoa(self.__proxysockname[0]) class Socks5Connection(Socks5): """Child socks5 class used for making outbound connections.""" + def __init__(self, address): + Socks5.__init__(self, address=address) + def state_auth_done(self): """Request connection to be made""" # Now we can request the actual connection @@ -169,13 +173,16 @@ class Socks5Connection(Socks5): try: self.ipaddr = socket.inet_aton(self.destination[0]) self.append_write_buf(chr(0x01).encode() + self.ipaddr) - except socket.error: # may be IPv6! + except socket.error: # Well it's not an IP number, so it's probably a DNS name. - if self._remote_dns: + if Proxy._remote_dns: # pylint: disable=protected-access # Resolve remotely self.ipaddr = None - self.append_write_buf(chr(0x03).encode() + chr( - len(self.destination[0])).encode() + self.destination[0]) + self.append_write_buf( + chr(0x03).encode() + + chr(len(self.destination[0])).encode() + + self.destination[0] + ) else: # Resolve locally self.ipaddr = socket.inet_aton( @@ -199,14 +206,16 @@ class Socks5Resolver(Socks5): def __init__(self, host): self.host = host self.port = 8444 - Socks5.__init__(self, address=Peer(self.host, self.port)) + Socks5.__init__(self, address=(self.host, self.port)) def state_auth_done(self): """Perform resolving""" # Now we can request the actual connection self.append_write_buf(struct.pack('BBB', 0x05, 0xF0, 0x00)) - self.append_write_buf(chr(0x03).encode() + chr( - len(self.host)).encode() + str(self.host)) + self.append_write_buf( + chr(0x03).encode() + chr(len(self.host)).encode() + + str(self.host) + ) self.append_write_buf(struct.pack(">H", self.port)) self.set_state("pre_connect", length=0, expectBytes=4) return True diff --git a/src/network/stats.py b/src/network/stats.py index 82e6c87f..5a0f8064 100644 --- a/src/network/stats.py +++ b/src/network/stats.py @@ -1,13 +1,9 @@ -""" -Network statistics -""" import time import asyncore_pollchoose as asyncore from network.connectionpool import BMConnectionPool from objectracker import missingObjects - lastReceivedTimestamp = time.time() lastReceivedBytes = 0 currentReceivedSpeed = 0 @@ -15,64 +11,60 @@ lastSentTimestamp = time.time() lastSentBytes = 0 currentSentSpeed = 0 - def connectedHostsList(): - """List of all the connected hosts""" - return BMConnectionPool().establishedConnections() - + retval = [] + for i in BMConnectionPool().inboundConnections.values() + \ + BMConnectionPool().outboundConnections.values(): + if not i.fullyEstablished: + continue + try: + retval.append(i) + except AttributeError: + pass + return retval def sentBytes(): - """Sending Bytes""" return asyncore.sentBytes - def uploadSpeed(): - """Getting upload speed""" - # pylint: disable=global-statement global lastSentTimestamp, lastSentBytes, currentSentSpeed currentTimestamp = time.time() if int(lastSentTimestamp) < int(currentTimestamp): currentSentBytes = asyncore.sentBytes - currentSentSpeed = int( - (currentSentBytes - lastSentBytes) / ( - currentTimestamp - lastSentTimestamp)) + currentSentSpeed = int((currentSentBytes - lastSentBytes) / (currentTimestamp - lastSentTimestamp)) lastSentBytes = currentSentBytes lastSentTimestamp = currentTimestamp return currentSentSpeed - def receivedBytes(): - """Receiving Bytes""" return asyncore.receivedBytes - def downloadSpeed(): - """Getting download speed""" - # pylint: disable=global-statement global lastReceivedTimestamp, lastReceivedBytes, currentReceivedSpeed currentTimestamp = time.time() if int(lastReceivedTimestamp) < int(currentTimestamp): currentReceivedBytes = asyncore.receivedBytes - currentReceivedSpeed = int( - (currentReceivedBytes - lastReceivedBytes) / ( - currentTimestamp - lastReceivedTimestamp)) + currentReceivedSpeed = int((currentReceivedBytes - lastReceivedBytes) / + (currentTimestamp - lastReceivedTimestamp)) lastReceivedBytes = currentReceivedBytes lastReceivedTimestamp = currentTimestamp return currentReceivedSpeed - def pendingDownload(): - """Getting pending downloads""" return len(missingObjects) - + #tmp = {} + #for connection in BMConnectionPool().inboundConnections.values() + \ + # BMConnectionPool().outboundConnections.values(): + # for k in connection.objectsNewToMe.keys(): + # tmp[k] = True + #return len(tmp) def pendingUpload(): - """Getting pending uploads""" - # tmp = {} - # for connection in BMConnectionPool().inboundConnections.values() + \ - # BMConnectionPool().outboundConnections.values(): - # for k in connection.objectsNewToThem.keys(): - # tmp[k] = True - # This probably isn't the correct logic so it's disabled - # return len(tmp) + #tmp = {} + #for connection in BMConnectionPool().inboundConnections.values() + \ + # BMConnectionPool().outboundConnections.values(): + # for k in connection.objectsNewToThem.keys(): + # tmp[k] = True + #This probably isn't the correct logic so it's disabled + #return len(tmp) return 0 diff --git a/src/network/tcp.py b/src/network/tcp.py index d611b1ca..5ebd6a21 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -1,8 +1,9 @@ -""" -TCP protocol handler -""" # pylint: disable=too-many-ancestors -import logging +""" +src/network/tcp.py +================== +""" + import math import random import socket @@ -17,26 +18,23 @@ import protocol import shared import state from bmconfigparser import BMConfigParser +from debug import logger from helper_random import randomBytes from inventory import Inventory from network.advanceddispatcher import AdvancedDispatcher -from network.assemble import assemble_addr from network.bmproto import BMProto -from network.constants import MAX_OBJECT_COUNT from network.dandelion import Dandelion from network.objectracker import ObjectTracker from network.socks4a import Socks4aConnection from network.socks5 import Socks5Connection from network.tls import TLSDispatcher -from node import Peer -from queues import invQueue, receiveDataQueue, UISignalQueue - -logger = logging.getLogger('default') +from queues import UISignalQueue, invQueue, receiveDataQueue class TCPConnection(BMProto, TLSDispatcher): # pylint: disable=too-many-instance-attributes """ + .. todo:: Look to understand and/or fix the non-parent-init-called """ @@ -49,7 +47,7 @@ class TCPConnection(BMProto, TLSDispatcher): self.connectedAt = 0 self.skipUntil = 0 if address is None and sock is not None: - self.destination = Peer(*sock.getpeername()) + self.destination = state.Peer(*sock.getpeername()) self.isOutbound = False TLSDispatcher.__init__(self, sock, server_side=True) self.connectedAt = time.time() @@ -75,16 +73,11 @@ class TCPConnection(BMProto, TLSDispatcher): logger.debug( 'Connecting to %s:%i', self.destination.host, self.destination.port) - try: - self.local = ( - protocol.checkIPAddress( - protocol.encodeHost(self.destination.host), True) and - not protocol.checkSocksIP(self.destination.host) - ) - except socket.error: - # it's probably a hostname - pass - self.network_group = protocol.network_group(self.destination.host) + encodedAddr = protocol.encodeHost(self.destination.host) + self.local = all([ + protocol.checkIPAddress(encodedAddr, True), + not protocol.checkSocksIP(self.destination.host) + ]) ObjectTracker.__init__(self) # pylint: disable=non-parent-init-called self.bm_proto_reset() self.set_state("bm_header", expectBytes=protocol.Header.size) @@ -138,9 +131,10 @@ class TCPConnection(BMProto, TLSDispatcher): if not self.isOutbound and not self.local: shared.clientHasReceivedIncomingConnections = True UISignalQueue.put(('setStatusIcon', 'green')) - UISignalQueue.put( - ('updateNetworkStatusTab', ( - self.isOutbound, True, self.destination))) + UISignalQueue.put(( + 'updateNetworkStatusTab', + (self.isOutbound, True, self.destination) + )) self.antiIntersectionDelay(True) self.fullyEstablished = True if self.isOutbound: @@ -182,7 +176,7 @@ class TCPConnection(BMProto, TLSDispatcher): for peer, params in addrs[substream]: templist.append((substream, peer, params["lastseen"])) if templist: - self.append_write_buf(assemble_addr(templist)) + self.append_write_buf(BMProto.assembleAddr(templist)) def sendBigInv(self): """ @@ -212,8 +206,8 @@ class TCPConnection(BMProto, TLSDispatcher): bigInvList[objHash] = 0 objectCount = 0 payload = b'' - # Now let us start appending all of these hashes together. - # They will be sent out in a big inv message to our new peer. + # Now let us start appending all of these hashes together. They will be + # sent out in a big inv message to our new peer. for obj_hash, _ in bigInvList.items(): payload += obj_hash objectCount += 1 @@ -221,7 +215,7 @@ class TCPConnection(BMProto, TLSDispatcher): # Remove -1 below when sufficient time has passed for users to # upgrade to versions of PyBitmessage that accept inv with 50,000 # items - if objectCount >= MAX_OBJECT_COUNT - 1: + if objectCount >= BMProto.maxObjectCount - 1: sendChunk() payload = b'' objectCount = 0 @@ -328,39 +322,6 @@ class Socks4aBMConnection(Socks4aConnection, TCPConnection): return True -def bootstrap(connection_class): - """Make bootstrapper class for connection type (connection_class)""" - class Bootstrapper(connection_class): - """Base class for bootstrappers""" - _connection_base = connection_class - - def __init__(self, host, port): - self._connection_base.__init__(self, Peer(host, port)) - self.close_reason = self._succeed = False - - def bm_command_addr(self): - """ - Got addr message - the bootstrap succeed. - Let BMProto process the addr message and switch state to 'close' - """ - BMProto.bm_command_addr(self) - self._succeed = True - # pylint: disable=attribute-defined-outside-init - self.close_reason = "Thanks for bootstrapping!" - self.set_state("close") - - def handle_close(self): - """ - After closing the connection switch knownnodes.knownNodesActual - back to False if the bootstrapper failed. - """ - self._connection_base.handle_close(self) - if not self._succeed: - knownnodes.knownNodesActual = False - - return Bootstrapper - - class TCPServer(AdvancedDispatcher): """TCP connection server for Bitmessage protocol""" @@ -372,7 +333,6 @@ class TCPServer(AdvancedDispatcher): for attempt in range(50): try: if attempt > 0: - logger.warning('Failed to bind on port %s', port) port = random.randint(32767, 65535) self.bind((host, port)) except socket.error as e: @@ -380,12 +340,11 @@ class TCPServer(AdvancedDispatcher): continue else: if attempt > 0: - logger.warning('Setting port to %s', port) BMConfigParser().set( 'bitmessagesettings', 'port', str(port)) BMConfigParser().save() break - self.destination = Peer(host, port) + self.destination = state.Peer(host, port) self.bound = True self.listen(5) @@ -403,7 +362,7 @@ class TCPServer(AdvancedDispatcher): except (TypeError, IndexError): return - state.ownAddresses[Peer(*sock.getsockname())] = True + state.ownAddresses[state.Peer(*sock.getsockname())] = True if ( len(connectionpool.BMConnectionPool().inboundConnections) + len(connectionpool.BMConnectionPool().outboundConnections) > diff --git a/src/network/threads.py b/src/network/threads.py deleted file mode 100644 index 9bdaa85d..00000000 --- a/src/network/threads.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Threading primitives for the network package""" - -import logging -import random -import threading -from contextlib import contextmanager - - -class StoppableThread(threading.Thread): - """Base class for application threads with stopThread method""" - name = None - logger = logging.getLogger('default') - - def __init__(self, name=None): - if name: - self.name = name - super(StoppableThread, self).__init__(name=self.name) - self.stop = threading.Event() - self._stopped = False - random.seed() - self.logger.info('Init thread %s', self.name) - - def stopThread(self): - """Stop the thread""" - self._stopped = True - self.stop.set() - - -class BusyError(threading.ThreadError): - """ - Thread error raised when another connection holds the lock - we are trying to acquire. - """ - pass - - -@contextmanager -def nonBlocking(lock): - """ - A context manager which acquires given lock non-blocking - and raises BusyError if failed to acquire. - """ - locked = lock.acquire(False) - if not locked: - raise BusyError - try: - yield - finally: - lock.release() diff --git a/src/network/tls.py b/src/network/tls.py index 1b325696..c643f46e 100644 --- a/src/network/tls.py +++ b/src/network/tls.py @@ -1,18 +1,18 @@ """ SSL/TLS negotiation. """ -import logging + import os import socket import ssl import sys -import network.asyncore_pollchoose as asyncore -import paths +from debug import logger from network.advanceddispatcher import AdvancedDispatcher +import network.asyncore_pollchoose as asyncore from queues import receiveDataQueue +import paths -logger = logging.getLogger('default') _DISCONNECTED_SSL = frozenset((ssl.SSL_ERROR_EOF,)) @@ -23,8 +23,7 @@ if sys.version_info >= (2, 7, 13): # ssl.PROTOCOL_TLS1.2 sslProtocolVersion = ssl.PROTOCOL_TLS # pylint: disable=no-member elif sys.version_info >= (2, 7, 9): - # this means any SSL/TLS. - # SSLv2 and 3 are excluded with an option after context is created + # this means any SSL/TLS. SSLv2 and 3 are excluded with an option after context is created sslProtocolVersion = ssl.PROTOCOL_SSLv23 else: # this means TLSv1, there is no way to set "TLSv1 or higher" or @@ -33,28 +32,24 @@ else: # ciphers -if ssl.OPENSSL_VERSION_NUMBER >= 0x10100000 and not \ - ssl.OPENSSL_VERSION.startswith("LibreSSL"): +if ssl.OPENSSL_VERSION_NUMBER >= 0x10100000 and not ssl.OPENSSL_VERSION.startswith("LibreSSL"): sslProtocolCiphers = "AECDH-AES256-SHA@SECLEVEL=0" else: sslProtocolCiphers = "AECDH-AES256-SHA" class TLSDispatcher(AdvancedDispatcher): - """TLS functionality for classes derived from AdvancedDispatcher""" - # pylint: disable=too-many-instance-attributes, too-many-arguments - # pylint: disable=super-init-not-called - def __init__(self, _=None, sock=None, certfile=None, keyfile=None, - server_side=False, ciphers=sslProtocolCiphers): + def __init__( + self, address=None, sock=None, certfile=None, keyfile=None, + server_side=False, ciphers=sslProtocolCiphers + ): self.want_read = self.want_write = True if certfile is None: - self.certfile = os.path.join( - paths.codePath(), 'sslkeys', 'cert.pem') + self.certfile = os.path.join(paths.codePath(), 'sslkeys', 'cert.pem') else: self.certfile = certfile if keyfile is None: - self.keyfile = os.path.join( - paths.codePath(), 'sslkeys', 'key.pem') + self.keyfile = os.path.join(paths.codePath(), 'sslkeys', 'key.pem') else: self.keyfile = keyfile self.server_side = server_side @@ -65,27 +60,19 @@ class TLSDispatcher(AdvancedDispatcher): self.isSSL = False def state_tls_init(self): - """Prepare sockets for TLS handshake""" - # pylint: disable=attribute-defined-outside-init self.isSSL = True self.tlsStarted = True - # Once the connection has been established, - # it's safe to wrap the socket. - if sys.version_info >= (2, 7, 9): - context = ssl.create_default_context( - purpose=ssl.Purpose.SERVER_AUTH - if self.server_side else ssl.Purpose.CLIENT_AUTH) + # Once the connection has been established, it's safe to wrap the + # socket. + if sys.version_info >= (2,7,9): + context = ssl.create_default_context(purpose = ssl.Purpose.SERVER_AUTH if self.server_side else ssl.Purpose.CLIENT_AUTH) context.set_ciphers(self.ciphers) context.set_ecdh_curve("secp256k1") context.check_hostname = False context.verify_mode = ssl.CERT_NONE # also exclude TLSv1 and TLSv1.1 in the future - context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ - ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ - ssl.OP_CIPHER_SERVER_PREFERENCE - self.sslSocket = context.wrap_socket( - self.socket, server_side=self.server_side, - do_handshake_on_connect=False) + context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE | ssl.OP_CIPHER_SERVER_PREFERENCE + self.sslSocket = context.wrap_socket(self.socket, server_side = self.server_side, do_handshake_on_connect=False) else: self.sslSocket = ssl.wrap_socket( self.socket, server_side=self.server_side, @@ -99,16 +86,10 @@ class TLSDispatcher(AdvancedDispatcher): # if hasattr(self.socket, "context"): # self.socket.context.set_ecdh_curve("secp256k1") - @staticmethod - def state_tls_handshake(): - """ - Do nothing while TLS handshake is pending, as during this phase - we need to react to callbacks instead - """ + def state_tls_handshake(self): return False def writable(self): - """Handle writable checks for TLS-enabled sockets""" try: if self.tlsStarted and not self.tlsDone and not self.write_buf: return self.want_write @@ -117,39 +98,26 @@ class TLSDispatcher(AdvancedDispatcher): return AdvancedDispatcher.writable(self) def readable(self): - """Handle readable check for TLS-enabled sockets""" try: - # during TLS handshake, and after flushing write buffer, - # return status of last handshake attempt + # during TLS handshake, and after flushing write buffer, return status of last handshake attempt if self.tlsStarted and not self.tlsDone and not self.write_buf: - # print "tls readable, %r" % (self.want_read) + #print "tls readable, %r" % (self.want_read) return self.want_read - # prior to TLS handshake, - # receiveDataThread should emulate synchronous behaviour - elif not self.fullyEstablished and ( - self.expectBytes == 0 or not self.write_buf_empty()): + # prior to TLS handshake, receiveDataThread should emulate synchronous behaviour + elif not self.fullyEstablished and (self.expectBytes == 0 or not self.write_buf_empty()): return False return AdvancedDispatcher.readable(self) except AttributeError: return AdvancedDispatcher.readable(self) - def handle_read(self): # pylint: disable=inconsistent-return-statements - """ - Handle reads for sockets during TLS handshake. Requires special - treatment as during the handshake, buffers must remain empty - and normal reads must be ignored. - """ + def handle_read(self): try: # wait for write buffer flush if self.tlsStarted and not self.tlsDone and not self.write_buf: - # logger.debug( - # "%s:%i TLS handshaking (read)", self.destination.host, - # self.destination.port) + #logger.debug("%s:%i TLS handshaking (read)", self.destination.host, self.destination.port) self.tls_handshake() else: - # logger.debug( - # "%s:%i Not TLS handshaking (read)", self.destination.host, - # self.destination.port) + #logger.debug("%s:%i Not TLS handshaking (read)", self.destination.host, self.destination.port) return AdvancedDispatcher.handle_read(self) except AttributeError: return AdvancedDispatcher.handle_read(self) @@ -163,23 +131,14 @@ class TLSDispatcher(AdvancedDispatcher): self.handle_close() return - def handle_write(self): # pylint: disable=inconsistent-return-statements - """ - Handle writes for sockets during TLS handshake. Requires special - treatment as during the handshake, buffers must remain empty - and normal writes must be ignored. - """ + def handle_write(self): try: # wait for write buffer flush if self.tlsStarted and not self.tlsDone and not self.write_buf: - # logger.debug( - # "%s:%i TLS handshaking (write)", self.destination.host, - # self.destination.port) + #logger.debug("%s:%i TLS handshaking (write)", self.destination.host, self.destination.port) self.tls_handshake() else: - # logger.debug( - # "%s:%i Not TLS handshaking (write)", self.destination.host, - # self.destination.port) + #logger.debug("%s:%i Not TLS handshaking (write)", self.destination.host, self.destination.port) return AdvancedDispatcher.handle_write(self) except AttributeError: return AdvancedDispatcher.handle_write(self) @@ -194,28 +153,25 @@ class TLSDispatcher(AdvancedDispatcher): return def tls_handshake(self): - """Perform TLS handshake and handle its stages""" # wait for flush if self.write_buf: return False # Perform the handshake. try: - # print "handshaking (internal)" + #print "handshaking (internal)" self.sslSocket.do_handshake() except ssl.SSLError as err: - # print "%s:%i: handshake fail" % ( - # self.destination.host, self.destination.port) + #print "%s:%i: handshake fail" % (self.destination.host, self.destination.port) self.want_read = self.want_write = False if err.args[0] == ssl.SSL_ERROR_WANT_READ: - # print "want read" + #print "want read" self.want_read = True if err.args[0] == ssl.SSL_ERROR_WANT_WRITE: - # print "want write" + #print "want write" self.want_write = True if not (self.want_write or self.want_read): raise except socket.error as err: - # pylint: disable=protected-access if err.errno in asyncore._DISCONNECTED: self.handle_close() else: @@ -223,15 +179,11 @@ class TLSDispatcher(AdvancedDispatcher): else: if sys.version_info >= (2, 7, 9): self.tlsVersion = self.sslSocket.version() - logger.debug( - '%s:%i: TLS handshake success, TLS protocol version: %s', - self.destination.host, self.destination.port, - self.tlsVersion) + logger.debug("%s:%i: TLS handshake success, TLS protocol version: %s", + self.destination.host, self.destination.port, self.sslSocket.version()) else: self.tlsVersion = "TLSv1" - logger.debug( - '%s:%i: TLS handshake success', - self.destination.host, self.destination.port) + logger.debug("%s:%i: TLS handshake success", self.destination.host, self.destination.port) # The handshake has completed, so remove this channel and... self.del_channel() self.set_socket(self.sslSocket) diff --git a/src/network/udp.py b/src/network/udp.py index d5f1cccd..225aabf3 100644 --- a/src/network/udp.py +++ b/src/network/udp.py @@ -1,31 +1,23 @@ -""" -UDP protocol handler -""" -import logging -import socket import time +import socket -import protocol import state +import protocol from bmproto import BMProto -from node import Peer +from debug import logger from objectracker import ObjectTracker from queues import receiveDataQueue -logger = logging.getLogger('default') - -class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes - """Bitmessage protocol over UDP (class)""" +class UDPSocket(BMProto): port = 8444 announceInterval = 60 def __init__(self, host=None, sock=None, announcing=False): - # pylint: disable=bad-super-call super(BMProto, self).__init__(sock=sock) self.verackReceived = True self.verackSent = True - # .. todo:: sort out streams + # TODO sort out streams self.streams = [1] self.fullyEstablished = True self.connectedAt = 0 @@ -43,8 +35,8 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes else: self.socket = sock self.set_socket_reuse() - self.listening = Peer(*self.socket.getsockname()) - self.destination = Peer(*self.socket.getsockname()) + self.listening = state.Peer(*self.socket.getsockname()) + self.destination = state.Peer(*self.socket.getsockname()) ObjectTracker.__init__(self) self.connecting = False self.connected = True @@ -52,7 +44,6 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes self.set_state("bm_header", expectBytes=protocol.Header.size) def set_socket_reuse(self): - """Set socket reuse option""" self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: @@ -78,12 +69,12 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes if not self.local: return True remoteport = False - for seenTime, stream, _, ip, port in addresses: + for seenTime, stream, services, ip, port in addresses: decodedIP = protocol.checkIPAddress(str(ip)) if stream not in state.streamsInWhichIAmParticipating: continue - if (seenTime < time.time() - self.maxTimeOffset - or seenTime > time.time() + self.maxTimeOffset): + if (seenTime < time.time() - self.maxTimeOffset or + seenTime > time.time() + self.maxTimeOffset): continue if decodedIP is False: # if the address isn't local, interpret it as @@ -95,8 +86,9 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes "received peer discovery from %s:%i (port %i):", self.destination.host, self.destination.port, remoteport) if self.local: - state.discoveredPeers[Peer(self.destination.host, remoteport)] = \ - time.time() + state.discoveredPeers[ + state.Peer(self.destination.host, remoteport) + ] = time.time() return True def bm_command_portcheck(self): @@ -130,9 +122,12 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes logger.error("socket error: %s", e) return - self.destination = Peer(*addr) + self.destination = state.Peer(*addr) encodedAddr = protocol.encodeHost(addr[0]) - self.local = bool(protocol.checkIPAddress(encodedAddr, True)) + if protocol.checkIPAddress(encodedAddr, True): + self.local = True + else: + self.local = False # overwrite the old buffer to avoid mixing data and so that # self.local works correctly self.read_buf[0:] = recdata @@ -144,9 +139,6 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes retval = self.socket.sendto( self.write_buf, ('', self.port)) except socket.error as e: - logger.error("socket error on sendto: %s", e) - if e.errno == 101: - self.announcing = False - self.socket.close() + logger.error("socket error on sendato: %s", e) retval = 0 self.slice_write_buf(retval) diff --git a/src/network/uploadthread.py b/src/network/uploadthread.py index 7d80d789..61ee6fab 100644 --- a/src/network/uploadthread.py +++ b/src/network/uploadthread.py @@ -1,40 +1,46 @@ """ -`UploadThread` class definition +src/network/uploadthread.py """ +# pylint: disable=unsubscriptable-object +import threading import time import helper_random import protocol +from debug import logger +from helper_threading import StoppableThread from inventory import Inventory from network.connectionpool import BMConnectionPool from network.dandelion import Dandelion from randomtrackingdict import RandomTrackingDict -from threads import StoppableThread -class UploadThread(StoppableThread): - """ - This is a thread that uploads the objects that the peers requested from me - """ +class UploadThread(threading.Thread, StoppableThread): + """This is a thread that uploads the objects that the peers requested from me """ maxBufSize = 2097152 # 2MB - name = "Uploader" + + def __init__(self): + threading.Thread.__init__(self, name="Uploader") + self.initStop() + self.name = "Uploader" + logger.info("init upload thread") def run(self): while not self._stopped: uploaded = 0 - # Choose uploading peers randomly - connections = BMConnectionPool().establishedConnections() + # Choose downloading peers randomly + connections = [x for x in BMConnectionPool().inboundConnections.values() + + BMConnectionPool().outboundConnections.values() if x.fullyEstablished] helper_random.randomshuffle(connections) for i in connections: now = time.time() # avoid unnecessary delay if i.skipUntil >= now: continue - if len(i.write_buf) > self.maxBufSize: + if len(i.write_buf) > UploadThread.maxBufSize: continue try: - request = i.pendingUpload.randomKeys( - RandomTrackingDict.maxPending) + request = i.pendingUpload.randomKeys(RandomTrackingDict.maxPending) except KeyError: continue payload = bytearray() @@ -44,26 +50,22 @@ class UploadThread(StoppableThread): if Dandelion().hasHash(chunk) and \ i != Dandelion().objectChildStem(chunk): i.antiIntersectionDelay() - self.logger.info( - '%s asked for a stem object we didn\'t offer to it.', - i.destination) + logger.info('%s asked for a stem object we didn\'t offer to it.', + i.destination) break try: - payload.extend(protocol.CreatePacket( - 'object', Inventory()[chunk].payload)) + payload.extend(protocol.CreatePacket('object', + Inventory()[chunk].payload)) chunk_count += 1 except KeyError: i.antiIntersectionDelay() - self.logger.info( - '%s asked for an object we don\'t have.', - i.destination) + logger.info('%s asked for an object we don\'t have.', i.destination) break if not chunk_count: continue i.append_write_buf(payload) - self.logger.debug( - '%s:%i Uploading %i objects', - i.destination.host, i.destination.port, chunk_count) + logger.debug("%s:%i Uploading %i objects", + i.destination.host, i.destination.port, chunk_count) uploaded += chunk_count if not uploaded: self.stop.wait(1) diff --git a/src/nohup.out b/src/nohup.out deleted file mode 100644 index 1e343a48..00000000 --- a/src/nohup.out +++ /dev/null @@ -1,3 +0,0 @@ -python: can't open file 'main.py.py': [Errno 2] No such file or directory -[WARNING] [Config ] Older configuration version detected (21 instead of 20) -[WARNING] [Config ] Upgrading configuration in progress. diff --git a/src/openclpow.py b/src/openclpow.py index 35bf46d2..eb91a07f 100644 --- a/src/openclpow.py +++ b/src/openclpow.py @@ -1,15 +1,14 @@ #!/usr/bin/env python2.7 -""" -Module for Proof of Work using OpenCL -""" -import hashlib -import os from struct import pack, unpack +import time +import hashlib +import random +import os -import paths from bmconfigparser import BMConfigParser -from debug import logger +import paths from state import shutdown +from debug import logger libAvailable = True ctx = False @@ -28,8 +27,6 @@ except ImportError: def initCL(): - """Initlialise OpenCL engine""" - # pylint: disable=global-statement global ctx, queue, program, hash_dt, libAvailable if libAvailable is False: return @@ -43,13 +40,12 @@ def initCL(): for platform in cl.get_platforms(): gpus.extend(platform.get_devices(device_type=cl.device_type.GPU)) if BMConfigParser().safeGet("bitmessagesettings", "opencl") == platform.vendor: - enabledGpus.extend(platform.get_devices( - device_type=cl.device_type.GPU)) + enabledGpus.extend(platform.get_devices(device_type=cl.device_type.GPU)) if platform.vendor not in vendors: vendors.append(platform.vendor) except: pass - if enabledGpus: + if (len(enabledGpus) > 0): ctx = cl.Context(devices=enabledGpus) queue = cl.CommandQueue(ctx) f = open(os.path.join(paths.codePath(), "bitmsghash", 'bitmsghash.cl'), 'r') @@ -59,29 +55,23 @@ def initCL(): else: logger.info("No OpenCL GPUs found") del enabledGpus[:] - except Exception: + except Exception as e: logger.error("OpenCL fail: ", exc_info=True) del enabledGpus[:] - def openclAvailable(): - """Are there any OpenCL GPUs available?""" - return bool(gpus) - + return (len(gpus) > 0) def openclEnabled(): - """Is OpenCL enabled (and available)?""" - return bool(enabledGpus) + return (len(enabledGpus) > 0) - -def do_opencl_pow(hash_, target): - """Perform PoW using OpenCL""" +def do_opencl_pow(hash, target): output = numpy.zeros(1, dtype=[('v', numpy.uint64, 1)]) - if not enabledGpus: + if (len(enabledGpus) == 0): return output[0][0] data = numpy.zeros(1, dtype=hash_dt, order='C') - data[0]['v'] = ("0000000000000000" + hash_).decode("hex") + data[0]['v'] = ("0000000000000000" + hash).decode("hex") data[0]['target'] = target hash_buf = cl.Buffer(ctx, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=data) @@ -93,8 +83,9 @@ def do_opencl_pow(hash_, target): kernel.set_arg(0, hash_buf) kernel.set_arg(1, dest_buf) + start = time.time() progress = 0 - globamt = worksize * 2000 + globamt = worksize*2000 while output[0][0] == 0 and shutdown == 0: kernel.set_arg(2, pack("Q', hashlib.sha512(hashlib.sha512(pack('>Q', nonce) + initialHash).digest()).digest()[0:8]) - print "{} - value {} < {}".format(nonce, trialValue, target_) + target = 54227212183L + initialHash = "3758f55b5a8d902fd3597e4ce6a2d3f23daff735f65d9698c270987f4e67ad590b93f3ffeba0ef2fd08a8dc2f87b68ae5a0dc819ab57f22ad2c4c9c8618a43b3".decode("hex") + nonce = do_opencl_pow(initialHash.encode("hex"), target) + trialValue, = unpack('>Q',hashlib.sha512(hashlib.sha512(pack('>Q',nonce) + initialHash).digest()).digest()[0:8]) + print "{} - value {} < {}".format(nonce, trialValue, target) + diff --git a/src/paths.py b/src/paths.py index ac90da63..325fcd8b 100644 --- a/src/paths.py +++ b/src/paths.py @@ -1,94 +1,76 @@ -""" -Path related functions -""" -# pylint: disable=import-error -import logging -import os -import re +from os import environ, path import sys +import re from datetime import datetime -from shutil import move -from kivy.utils import platform - -logger = logging.getLogger('default') # When using py2exe or py2app, the variable frozen is added to the sys -# namespace. This can be used to setup a different code path for +# namespace. This can be used to setup a different code path for # binary distributions vs source distributions. -frozen = getattr(sys, 'frozen', None) - +frozen = getattr(sys,'frozen', None) def lookupExeFolder(): - """Returns executable folder path""" if frozen: - exeFolder = ( + if frozen == "macosx_app": # targetdir/Bitmessage.app/Contents/MacOS/Bitmessage - os.path.dirname(sys.executable).split(os.path.sep)[0] + os.path.sep - if frozen == "macosx_app" else - os.path.dirname(sys.executable) + os.path.sep) + exeFolder = path.dirname(path.dirname(path.dirname(path.dirname(sys.executable)))) + path.sep + else: + exeFolder = path.dirname(sys.executable) + path.sep elif __file__: - exeFolder = os.path.dirname(__file__) + os.path.sep + exeFolder = path.dirname(__file__) + path.sep else: exeFolder = '' return exeFolder - def lookupAppdataFolder(): - """Returns path of the folder where application data is stored""" APPNAME = "PyBitmessage" - dataFolder = os.environ.get('BITMESSAGE_HOME') - if dataFolder: - if dataFolder[-1] not in (os.path.sep, os.path.altsep): - dataFolder += os.path.sep + if "BITMESSAGE_HOME" in environ: + dataFolder = environ["BITMESSAGE_HOME"] + if dataFolder[-1] not in [path.sep, path.altsep]: + dataFolder += path.sep elif sys.platform == 'darwin': - try: - dataFolder = os.path.join( - os.environ['HOME'], - 'Library/Application Support/', APPNAME - ) + '/' + if "HOME" in environ: + dataFolder = path.join(environ["HOME"], "Library/Application Support/", APPNAME) + '/' + else: + stringToLog = 'Could not find home folder, please report this message and your OS X version to the BitMessage Github.' + if 'logger' in globals(): + logger.critical(stringToLog) + else: + print stringToLog + sys.exit() - except KeyError: - sys.exit( - 'Could not find home folder, please report this message' - ' and your OS X version to the BitMessage Github.') - elif platform == 'android': - dataFolder = os.path.join(os.environ['ANDROID_PRIVATE'] + '/', APPNAME) + '/' elif 'win32' in sys.platform or 'win64' in sys.platform: - dataFolder = os.path.join( - os.environ['APPDATA'].decode( - sys.getfilesystemencoding(), 'ignore'), APPNAME - ) + os.path.sep + dataFolder = path.join(environ['APPDATA'].decode(sys.getfilesystemencoding(), 'ignore'), APPNAME) + path.sep else: + from shutil import move try: - dataFolder = os.path.join(os.environ['XDG_CONFIG_HOME'], APPNAME) + dataFolder = path.join(environ["XDG_CONFIG_HOME"], APPNAME) except KeyError: - dataFolder = os.path.join(os.environ['HOME'], '.config', APPNAME) + dataFolder = path.join(environ["HOME"], ".config", APPNAME) - # Migrate existing data to the proper location - # if this is an existing install + # Migrate existing data to the proper location if this is an existing install try: - move(os.path.join(os.environ['HOME'], '.%s' % APPNAME), dataFolder) - logger.info('Moving data folder to %s', dataFolder) + move(path.join(environ["HOME"], ".%s" % APPNAME), dataFolder) + stringToLog = "Moving data folder to %s" % (dataFolder) + if 'logger' in globals(): + logger.info(stringToLog) + else: + print stringToLog except IOError: # Old directory may not exist. pass - dataFolder = dataFolder + os.path.sep + dataFolder = dataFolder + '/' return dataFolder - - + def codePath(): - """Returns path to the program sources""" - # pylint: disable=protected-access - if not frozen: - return os.path.dirname(__file__) - return ( - os.environ.get('RESOURCEPATH') - # pylint: disable=protected-access - if frozen == "macosx_app" else sys._MEIPASS) - + if frozen == "macosx_app": + codePath = environ.get("RESOURCEPATH") + elif frozen: # windows + codePath = sys._MEIPASS + else: + codePath = path.dirname(__file__) + return codePath def tail(f, lines=20): - """Returns last lines in the f file object""" total_lines_wanted = lines BLOCK_SIZE = 1024 @@ -96,17 +78,16 @@ def tail(f, lines=20): block_end_byte = f.tell() lines_to_go = total_lines_wanted block_number = -1 - blocks = [] - # blocks of size BLOCK_SIZE, in reverse order starting - # from the end of the file + blocks = [] # blocks of size BLOCK_SIZE, in reverse order starting + # from the end of the file while lines_to_go > 0 and block_end_byte > 0: - if block_end_byte - BLOCK_SIZE > 0: + if (block_end_byte - BLOCK_SIZE > 0): # read the last block we haven't yet read - f.seek(block_number * BLOCK_SIZE, 2) + f.seek(block_number*BLOCK_SIZE, 2) blocks.append(f.read(BLOCK_SIZE)) else: # file too small, start from begining - f.seek(0, 0) + f.seek(0,0) # only read what was not read blocks.append(f.read(block_end_byte)) lines_found = blocks[-1].count('\n') @@ -118,12 +99,9 @@ def tail(f, lines=20): def lastCommit(): - """ - Returns last commit information as dict with 'commit' and 'time' keys - """ - githeadfile = os.path.join(codePath(), '..', '.git', 'logs', 'HEAD') + githeadfile = path.join(codePath(), '..', '.git', 'logs', 'HEAD') result = {} - if os.path.isfile(githeadfile): + if path.isfile(githeadfile): try: with open(githeadfile, 'rt') as githead: line = tail(githead, 1) diff --git a/src/plugins/__init__.py b/src/plugins/__init__.py index 285009df..e69de29b 100644 --- a/src/plugins/__init__.py +++ b/src/plugins/__init__.py @@ -1,7 +0,0 @@ -""" -Simple plugin system based on setuptools ----------------------------------------- - - -""" -# .. include:: pybitmessage.plugins.plugin.rst diff --git a/src/plugins/indicator_libmessaging.py b/src/plugins/indicator_libmessaging.py index 60bf5e7e..36178663 100644 --- a/src/plugins/indicator_libmessaging.py +++ b/src/plugins/indicator_libmessaging.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -""" -Indicator plugin using libmessaging -""" import gi gi.require_version('MessagingMenu', '1.0') # noqa:E402 @@ -12,7 +9,6 @@ from pybitmessage.tr import _translate class IndicatorLibmessaging(object): - """Plugin for libmessage indicator""" def __init__(self, form): try: self.app = MessagingMenu.App(desktop_id='pybitmessage.desktop') @@ -36,18 +32,15 @@ class IndicatorLibmessaging(object): if self.app: self.app.unregister() - def activate(self, app, source): # pylint: disable=unused-argument - """Activate the libmessaging indicator plugin""" + def activate(self, app, source): self.form.appIndicatorInbox( self.new_message_item if source == 'messages' else self.new_broadcast_item ) + # show the number of unread messages and subscriptions + # on the messaging menu def show_unread(self, draw_attention=False): - """ - show the number of unread messages and subscriptions - on the messaging menu - """ for source, count in zip( ('messages', 'subscriptions'), self.form.getUnread() diff --git a/src/plugins/menu_qrcode.py b/src/plugins/menu_qrcode.py index 4cdedb2d..7f21c6b8 100644 --- a/src/plugins/menu_qrcode.py +++ b/src/plugins/menu_qrcode.py @@ -6,17 +6,15 @@ A menu plugin showing QR-Code for bitmessage address in modal dialog. import urllib import qrcode -from PyQt4 import QtCore, QtGui +from PyQt4 import QtGui, QtCore from pybitmessage.tr import _translate # http://stackoverflow.com/questions/20452486 -class Image(qrcode.image.base.BaseImage): # pylint: disable=abstract-method +class Image(qrcode.image.base.BaseImage): """Image output class for qrcode using QPainter""" - def __init__(self, border, width, box_size): - # pylint: disable=super-init-not-called self.border = border self.width = width self.box_size = box_size @@ -39,7 +37,7 @@ class Image(qrcode.image.base.BaseImage): # pylint: disable=abstract-method QtCore.Qt.black) -class QRCodeDialog(QtGui.QDialog): +class QRCodeDialog(QtGui.QDialog): """The dialog""" def __init__(self, parent): super(QRCodeDialog, self).__init__(parent) diff --git a/src/plugins/notification_notify2.py b/src/plugins/notification_notify2.py index 84ecbdde..3fd935c4 100644 --- a/src/plugins/notification_notify2.py +++ b/src/plugins/notification_notify2.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -""" -Notification plugin using notify2 -""" import gi gi.require_version('Notify', '0.7') @@ -9,13 +6,10 @@ from gi.repository import Notify Notify.init('pybitmessage') - -def connect_plugin(title, subtitle, category, _, icon): - """Plugin for notify2""" +def connect_plugin(title, subtitle, category, label, icon): if not icon: icon = 'mail-message-new' if category == 2 else 'pybitmessage' connect_plugin.notification.update(title, subtitle, icon) connect_plugin.notification.show() - connect_plugin.notification = Notify.Notification.new("Init", "Init") diff --git a/src/plugins/plugin.py b/src/plugins/plugin.py index 629de0a6..6601adaf 100644 --- a/src/plugins/plugin.py +++ b/src/plugins/plugin.py @@ -1,28 +1,16 @@ # -*- coding: utf-8 -*- -""" -Operating with plugins -""" -import logging import pkg_resources -logger = logging.getLogger('default') - - def get_plugins(group, point='', name=None, fallback=None): """ - :param str group: plugin group - :param str point: plugin name prefix - :param name: exact plugin name - :param fallback: fallback plugin name - - Iterate through plugins (``connect_plugin`` attribute of entry point) - which name starts with ``point`` or equals to ``name``. - If ``fallback`` kwarg specified, plugin with that name yield last. + Iterate through plugins (`connect_plugin` attribute of entry point) + which name starts with `point` or equals to `name`. + If `fallback` kwarg specified, plugin with that name yield last. """ for ep in pkg_resources.iter_entry_points('bitmessage.' + group): - if name and ep.name == name or not point or ep.name.startswith(point): + if name and ep.name == name or ep.name.startswith(point): try: plugin = ep.load().connect_plugin if ep.name == fallback: @@ -34,8 +22,6 @@ def get_plugins(group, point='', name=None, fallback=None): ValueError, pkg_resources.DistributionNotFound, pkg_resources.UnknownExtra): - logger.debug( - 'Problem while loading %s', ep.name, exc_info=True) continue try: yield _fallback @@ -44,8 +30,6 @@ def get_plugins(group, point='', name=None, fallback=None): def get_plugin(*args, **kwargs): - """ - :return: first available plugin from :func:`get_plugins` if any. - """ + """Returns first available plugin `from get_plugins()` if any.""" for plugin in get_plugins(*args, **kwargs): return plugin diff --git a/src/plugins/proxyconfig_stem.py b/src/plugins/proxyconfig_stem.py deleted file mode 100644 index 7e8dc089..00000000 --- a/src/plugins/proxyconfig_stem.py +++ /dev/null @@ -1,140 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Configure tor proxy and hidden service with -`stem `_ depending on *bitmessagesettings*: - - * try to start own tor instance on *socksport* if *sockshostname* - is unset or set to localhost; - * if *socksport* is already in use that instance is used only for - hidden service (if *sockslisten* is also set True); - * create ephemeral hidden service v3 if there is already *onionhostname*; - * otherwise use stem's 'BEST' version and save onion keys to the new - section using *onionhostname* as name for future use. -""" -import logging -import os -import random # noseq -import tempfile - -import stem -import stem.control -import stem.process -import stem.version - - -class DebugLogger(object): # pylint: disable=too-few-public-methods - """Safe logger wrapper for tor and plugin's logs""" - def __init__(self): - self._logger = logging.getLogger('default') - self._levels = { - 'err': 40, - 'warn': 30, - 'notice': 20 - } - - def __call__(self, line): - try: - level, line = line.split('[', 1)[1].split(']') - except IndexError: - # Plugin's debug or unexpected log line from tor - self._logger.debug(line) - else: - self._logger.log(self._levels.get(level, 10), '(tor) %s', line) - - -def connect_plugin(config): # pylint: disable=too-many-branches - """ - Run stem proxy configurator - - :param config: current configuration instance - :type config: :class:`pybitmessage.bmconfigparser.BMConfigParser` - :return: True if configuration was done successfully - """ - logwrite = DebugLogger() - if config.safeGet('bitmessagesettings', 'sockshostname', '') not in ( - 'localhost', '127.0.0.1', '' - ): - # remote proxy is choosen for outbound connections, - # nothing to do here, but need to set socksproxytype to SOCKS5! - config.set('bitmessagesettings', 'socksproxytype', 'SOCKS5') - logwrite( - 'sockshostname is set to remote address,' - ' aborting stem proxy configuration') - return - - datadir = tempfile.mkdtemp() - control_socket = os.path.join(datadir, 'control') - tor_config = { - 'SocksPort': '9050', - # 'DataDirectory': datadir, # had an exception with control socket - 'ControlSocket': control_socket - } - port = config.safeGet('bitmessagesettings', 'socksport', '9050') - for attempt in range(50): - if attempt > 0: - port = random.randint(32767, 65535) - tor_config['SocksPort'] = str(port) - # It's recommended to use separate tor instance for hidden services. - # So if there is a system wide tor, use it for outbound connections. - try: - stem.process.launch_tor_with_config( - tor_config, take_ownership=True, timeout=20, - init_msg_handler=logwrite) - except OSError: - if not attempt: - try: - stem.version.get_system_tor_version() - except IOError: - return - continue - else: - logwrite('Started tor on port %s' % port) - break - - config.setTemp('bitmessagesettings', 'socksproxytype', 'SOCKS5') - - if config.safeGetBoolean('bitmessagesettings', 'sockslisten'): - # need a hidden service for inbound connections - try: - controller = stem.control.Controller.from_socket_file( - control_socket) - controller.authenticate() - except stem.SocketError: - # something goes wrong way - logwrite('Failed to instantiate or authenticate on controller') - return - - onionhostname = config.safeGet('bitmessagesettings', 'onionhostname') - onionkey = config.safeGet(onionhostname, 'privsigningkey') - if onionhostname and not onionkey: - logwrite('The hidden service found in config ): %s' % - onionhostname) - onionkeytype = config.safeGet(onionhostname, 'keytype') - - response = controller.create_ephemeral_hidden_service( - {config.safeGetInt('bitmessagesettings', 'onionport', 8444): - config.safeGetInt('bitmessagesettings', 'port', 8444)}, - key_type=(onionkeytype or 'NEW'), - key_content=(onionkey or onionhostname and 'ED25519-V3' or 'BEST') - ) - - if not response.is_ok(): - logwrite('Bad response from controller ):') - return - - if not onionkey: - logwrite('Started hidden service %s.onion' % response.service_id) - # only save new service keys - # if onionhostname was not set previously - if not onionhostname: - onionhostname = response.service_id + '.onion' - config.set( - 'bitmessagesettings', 'onionhostname', onionhostname) - config.add_section(onionhostname) - config.set( - onionhostname, 'privsigningkey', response.private_key) - config.set( - onionhostname, 'keytype', response.private_key_type) - config.save() - - return True diff --git a/src/plugins/sound_canberra.py b/src/plugins/sound_canberra.py index 9fea8197..094901ed 100644 --- a/src/plugins/sound_canberra.py +++ b/src/plugins/sound_canberra.py @@ -1,10 +1,8 @@ # -*- coding: utf-8 -*- -""" -Sound theme plugin using pycanberra -""" + +from pybitmessage.bitmessageqt import sound import pycanberra -from pybitmessage.bitmessageqt import sound _canberra = pycanberra.Canberra() @@ -16,8 +14,7 @@ _theme = { } -def connect_plugin(category, label=None): # pylint: disable=unused-argument - """This function implements the entry point.""" +def connect_plugin(category, label=None): try: _canberra.play(0, pycanberra.CA_PROP_EVENT_ID, _theme[category], None) except (KeyError, pycanberra.CanberraException): diff --git a/src/plugins/sound_gstreamer.py b/src/plugins/sound_gstreamer.py index 8f3606dd..062da3f9 100644 --- a/src/plugins/sound_gstreamer.py +++ b/src/plugins/sound_gstreamer.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -""" -Sound notification plugin using gstreamer -""" + import gi gi.require_version('Gst', '1.0') from gi.repository import Gst # noqa: E402 @@ -11,7 +9,6 @@ _player = Gst.ElementFactory.make("playbin", "player") def connect_plugin(sound_file): - """Entry point for sound file""" _player.set_state(Gst.State.NULL) _player.set_property("uri", "file://" + sound_file) _player.set_state(Gst.State.PLAYING) diff --git a/src/plugins/sound_playfile.py b/src/plugins/sound_playfile.py index e36d9922..c8216d07 100644 --- a/src/plugins/sound_playfile.py +++ b/src/plugins/sound_playfile.py @@ -1,13 +1,10 @@ # -*- coding: utf-8 -*- -""" -Sound notification plugin using external executable or winsound (on Windows) -""" + try: import winsound def connect_plugin(sound_file): - """Plugin's entry point""" winsound.PlaySound(sound_file, winsound.SND_FILENAME) except ImportError: import os @@ -21,8 +18,7 @@ except ImportError: args, stdout=FNULL, stderr=subprocess.STDOUT, close_fds=True) def connect_plugin(sound_file): - """This function implements the entry point.""" - global play_cmd # pylint: disable=global-statement + global play_cmd ext = os.path.splitext(sound_file)[-1] try: diff --git a/src/proofofwork.py b/src/proofofwork.py index be53c373..bb16951c 100644 --- a/src/proofofwork.py +++ b/src/proofofwork.py @@ -1,6 +1,7 @@ # pylint: disable=too-many-branches,too-many-statements,protected-access """ -Proof of work calculation +src/proofofwork.py +================== """ import ctypes @@ -18,8 +19,6 @@ import state import tr from bmconfigparser import BMConfigParser from debug import logger -from kivy.utils import platform - bitmsglib = 'bitmsghash.so' bmpow = None @@ -293,7 +292,8 @@ def init(): global bitmsglib, bmpow openclpow.initCL() - if "win32" == sys.platform: + + if sys.platform == "win32": if ctypes.sizeof(ctypes.c_voidp) == 4: bitmsglib = 'bitmsghash32.dll' else: @@ -319,12 +319,6 @@ def init(): except: logger.error("C PoW test fail.", exc_info=True) bso = None - elif platform == "android": - try: - bso = ctypes.CDLL('libbitmsghash.so') - except Exception as e: - bso = None - else: try: bso = ctypes.CDLL(os.path.join(paths.codePath(), "bitmsghash", bitmsglib)) diff --git a/src/protocol.py b/src/protocol.py index 4f2d0856..c2bf3021 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -1,8 +1,12 @@ +# pylint: disable=too-many-boolean-expressions,too-many-return-statements,too-many-locals,too-many-statements """ +protocol.py +=========== + Low-level protocol-related functions. """ -# pylint: disable=too-many-boolean-expressions,too-many-return-statements -# pylint: disable=too-many-locals,too-many-statements + +from __future__ import absolute_import import base64 import hashlib @@ -10,8 +14,9 @@ import random import socket import sys import time +import traceback from binascii import hexlify -from struct import Struct, pack, unpack +from struct import pack, unpack, Struct import defaults import highlevelcrypto @@ -24,18 +29,10 @@ from fallback import RIPEMD160Hash from helper_sql import sqlExecute from version import softwareVersion + # Service flags -#: This is a normal network node NODE_NETWORK = 1 -#: This node supports SSL/TLS in the current connect (python < 2.7.9 -#: only supports an SSL client, so in that case it would only have this -#: on when the connection is a client). NODE_SSL = 2 -# (Proposal) This node may do PoW on behalf of some its peers -# (PoW offloading/delegating), but it doesn't have to. Clients may have -# to meet additional requirements (e.g. TLS authentication) -# NODE_POW = 4 -#: Node supports dandelion NODE_DANDELION = 8 # Bitfield flags @@ -97,8 +94,7 @@ def isBitSetWithinBitfield(fourByteString, n): def encodeHost(host): """Encode a given host to be used in low-level socket operations""" if host.find('.onion') > -1: - return '\xfd\x87\xd8\x7e\xeb\x43' + base64.b32decode( - host.split(".")[0], True) + return '\xfd\x87\xd8\x7e\xeb\x43' + base64.b32decode(host.split(".")[0], True) elif host.find(':') == -1: return '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + \ socket.inet_aton(host) @@ -114,39 +110,8 @@ def networkType(host): return 'IPv6' -def network_group(host): - """Canonical identifier of network group - simplified, borrowed from - GetGroup() in src/netaddresses.cpp in bitcoin core""" - if not isinstance(host, str): - return None - network_type = networkType(host) - try: - raw_host = encodeHost(host) - except socket.error: - return host - if network_type == 'IPv4': - decoded_host = checkIPv4Address(raw_host[12:], True) - if decoded_host: - # /16 subnet - return raw_host[12:14] - elif network_type == 'IPv6': - decoded_host = checkIPv6Address(raw_host, True) - if decoded_host: - # /32 subnet - return raw_host[0:12] - else: - # just host, e.g. for tor - return host - # global network type group for local, private, unroutable - return network_type - - def checkIPAddress(host, private=False): - """ - Returns hostStandardFormat if it is a valid IP address, - otherwise returns False - """ + """Returns hostStandardFormat if it is a valid IP address, otherwise returns False""" if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': hostStandardFormat = socket.inet_ntop(socket.AF_INET, host[12:]) return checkIPv4Address(host[12:], hostStandardFormat, private) @@ -162,46 +127,35 @@ def checkIPAddress(host, private=False): except ValueError: return False if hostStandardFormat == "": - # This can happen on Windows systems which are - # not 64-bit compatible so let us drop the IPv6 address. + # This can happen on Windows systems which are not 64-bit compatible + # so let us drop the IPv6 address. return False return checkIPv6Address(host, hostStandardFormat, private) def checkIPv4Address(host, hostStandardFormat, private=False): - """ - Returns hostStandardFormat if it is an IPv4 address, - otherwise returns False - """ + """Returns hostStandardFormat if it is an IPv4 address, otherwise returns False""" if host[0] == '\x7F': # 127/8 if not private: - logger.debug( - 'Ignoring IP address in loopback range: %s', - hostStandardFormat) + logger.debug('Ignoring IP address in loopback range: %s', hostStandardFormat) return hostStandardFormat if private else False if host[0] == '\x0A': # 10/8 if not private: - logger.debug( - 'Ignoring IP address in private range: %s', hostStandardFormat) + logger.debug('Ignoring IP address in private range: %s', hostStandardFormat) return hostStandardFormat if private else False if host[0:2] == '\xC0\xA8': # 192.168/16 if not private: - logger.debug( - 'Ignoring IP address in private range: %s', hostStandardFormat) + logger.debug('Ignoring IP address in private range: %s', hostStandardFormat) return hostStandardFormat if private else False if host[0:2] >= '\xAC\x10' and host[0:2] < '\xAC\x20': # 172.16/12 if not private: - logger.debug( - 'Ignoring IP address in private range: %s', hostStandardFormat) + logger.debug('Ignoring IP address in private range: %s', hostStandardFormat) return hostStandardFormat if private else False return False if private else hostStandardFormat def checkIPv6Address(host, hostStandardFormat, private=False): - """ - Returns hostStandardFormat if it is an IPv6 address, - otherwise returns False - """ + """Returns hostStandardFormat if it is an IPv6 address, otherwise returns False""" if host == ('\x00' * 15) + '\x01': if not private: logger.debug('Ignoring loopback address: %s', hostStandardFormat) @@ -212,8 +166,7 @@ def checkIPv6Address(host, hostStandardFormat, private=False): return hostStandardFormat if private else False if (ord(host[0]) & 0xfe) == 0xfc: if not private: - logger.debug( - 'Ignoring unique local address: %s', hostStandardFormat) + logger.debug('Ignoring unique local address: %s', hostStandardFormat) return hostStandardFormat if private else False return False if private else hostStandardFormat @@ -234,27 +187,28 @@ def haveSSL(server=False): def checkSocksIP(host): """Predicate to check if we're using a SOCKS proxy""" - sockshostname = BMConfigParser().safeGet( - 'bitmessagesettings', 'sockshostname') try: - if not state.socksIP: - state.socksIP = socket.gethostbyname(sockshostname) - except NameError: # uninitialised - state.socksIP = socket.gethostbyname(sockshostname) - except (TypeError, socket.gaierror): # None, resolving failure - state.socksIP = sockshostname + if state.socksIP is None or not state.socksIP: + state.socksIP = socket.gethostbyname(BMConfigParser().get("bitmessagesettings", "sockshostname")) + # uninitialised + except NameError: + state.socksIP = socket.gethostbyname(BMConfigParser().get("bitmessagesettings", "sockshostname")) + # resolving failure + except socket.gaierror: + state.socksIP = BMConfigParser().get("bitmessagesettings", "sockshostname") return state.socksIP == host -def isProofOfWorkSufficient( - data, nonceTrialsPerByte=0, payloadLengthExtraBytes=0, recvTime=0): +def isProofOfWorkSufficient(data, + nonceTrialsPerByte=0, + payloadLengthExtraBytes=0, + recvTime=0): """ - Validate an object's Proof of Work using method described - `here `_ - + Validate an object's Proof of Work using method described in: + https://bitmessage.org/wiki/Proof_of_work Arguments: - int nonceTrialsPerByte (default: from `.defaults`) - int payloadLengthExtraBytes (default: from `.defaults`) + int nonceTrialsPerByte (default: from default.py) + int payloadLengthExtraBytes (default: from default.py) float recvTime (optional) UNIX epoch time when object was received from the network (default: current system time) Returns: @@ -268,20 +222,18 @@ def isProofOfWorkSufficient( TTL = endOfLifeTime - (int(recvTime) if recvTime else int(time.time())) if TTL < 300: TTL = 300 - POW, = unpack('>Q', hashlib.sha512(hashlib.sha512( - data[:8] + hashlib.sha512(data[8:]).digest() - ).digest()).digest()[0:8]) - return POW <= 2 ** 64 / ( - nonceTrialsPerByte * ( - len(data) + payloadLengthExtraBytes + - ((TTL * (len(data) + payloadLengthExtraBytes)) / (2 ** 16)))) + POW, = unpack('>Q', hashlib.sha512(hashlib.sha512(data[ + :8] + hashlib.sha512(data[8:]).digest()).digest()).digest()[0:8]) + return POW <= 2 ** 64 / (nonceTrialsPerByte * + (len(data) + payloadLengthExtraBytes + + ((TTL * (len(data) + payloadLengthExtraBytes)) / (2 ** 16)))) # Packet creation def CreatePacket(command, payload=''): - """Construct and return a packet""" + """Construct and return a number of bytes from a payload""" payload_length = len(payload) checksum = hashlib.sha512(payload).digest()[0:4] @@ -291,13 +243,8 @@ def CreatePacket(command, payload=''): return bytes(b) -def assembleVersionMessage( - remoteHost, remotePort, participatingStreams, server=False, nodeid=None -): - """ - Construct the payload of a version message, - return the resulting bytes of running `CreatePacket` on it - """ +def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server=False, nodeid=None): + """Construct the payload of a version message, return the resultng bytes of running CreatePacket() on it""" payload = '' payload += pack('>L', 3) # protocol version. # bitflags of the services I offer. @@ -309,19 +256,15 @@ def assembleVersionMessage( ) payload += pack('>q', int(time.time())) - # boolservices of remote connection; ignored by the remote host. - payload += pack('>q', 1) - if checkSocksIP(remoteHost) and server: - # prevent leaking of tor outbound IP + payload += pack( + '>q', 1) # boolservices of remote connection; ignored by the remote host. + if checkSocksIP(remoteHost) and server: # prevent leaking of tor outbound IP payload += encodeHost('127.0.0.1') payload += pack('>H', 8444) else: # use first 16 bytes if host data is longer # for example in case of onion v3 service - try: - payload += encodeHost(remoteHost)[:16] - except socket.error: - payload += encodeHost('127.0.0.1') + payload += encodeHost(remoteHost)[:16] payload += pack('>H', remotePort) # remote IPv6 and port # bitflags of the services I offer. @@ -331,26 +274,23 @@ def assembleVersionMessage( (NODE_SSL if haveSSL(server) else 0) | (NODE_DANDELION if state.dandelion else 0) ) - # = 127.0.0.1. This will be ignored by the remote host. - # The actual remote connected IP will be used. - payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + pack( - '>L', 2130706433) + # = 127.0.0.1. This will be ignored by the remote host. The actual remote connected IP will be used. + payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + pack('>L', 2130706433) # we have a separate extPort and incoming over clearnet # or outgoing through clearnet extport = BMConfigParser().safeGetInt('bitmessagesettings', 'extport') if ( extport and ((server and not checkSocksIP(remoteHost)) or ( - BMConfigParser().get('bitmessagesettings', 'socksproxytype') - == 'none' and not server)) + BMConfigParser().get('bitmessagesettings', 'socksproxytype') == + 'none' and not server)) ): payload += pack('>H', extport) elif checkSocksIP(remoteHost) and server: # incoming connection over Tor - payload += pack( - '>H', BMConfigParser().getint('bitmessagesettings', 'onionport')) + payload += pack('>H', BMConfigParser().getint('bitmessagesettings', 'onionport')) else: # no extport and not incoming over Tor - payload += pack( - '>H', BMConfigParser().getint('bitmessagesettings', 'port')) + payload += pack('>H', BMConfigParser().getint('bitmessagesettings', 'port')) + random.seed() if nodeid is not None: payload += nodeid[0:8] else: @@ -373,10 +313,7 @@ def assembleVersionMessage( def assembleErrorMessage(fatal=0, banTime=0, inventoryVector='', errorText=''): - """ - Construct the payload of an error message, - return the resulting bytes of running `CreatePacket` on it - """ + """Construct the payload of an error message, return the resultng bytes of running CreatePacket() on it""" payload = encodeVarint(fatal) payload += encodeVarint(banTime) payload += encodeVarint(len(inventoryVector)) @@ -513,7 +450,7 @@ def decryptAndCheckPubkeyPayload(data, address): except Exception: logger.critical( 'Pubkey decryption was UNsuccessful because of' - ' an unhandled exception! This is definitely a bug!', - exc_info=True + ' an unhandled exception! This is definitely a bug! \n%s', + traceback.format_exc() ) return 'failed' diff --git a/src/pyelliptic/__init__.py b/src/pyelliptic/__init__.py index dbc1b2af..761d08af 100644 --- a/src/pyelliptic/__init__.py +++ b/src/pyelliptic/__init__.py @@ -1,28 +1,19 @@ -""" -Copyright (C) 2010 -Author: Yann GUIBET -Contact: - -Python OpenSSL wrapper. -For modern cryptography with ECC, AES, HMAC, Blowfish, ... - -This is an abandoned package maintained inside of the PyBitmessage. -""" - -from .cipher import Cipher -from .ecc import ECC -from .eccblind import ECCBlind -from .hash import hmac_sha256, hmac_sha512, pbkdf2 -from .openssl import OpenSSL +# Copyright (C) 2010 +# Author: Yann GUIBET +# Contact: __version__ = '1.3' __all__ = [ 'OpenSSL', 'ECC', - 'ECCBlind', 'Cipher', 'hmac_sha256', 'hmac_sha512', 'pbkdf2' ] + +from .openssl import OpenSSL +from .ecc import ECC +from .cipher import Cipher +from .hash import hmac_sha256, hmac_sha512, pbkdf2 diff --git a/src/pyelliptic/arithmetic.py b/src/pyelliptic/arithmetic.py index 83e634ad..95c85b93 100644 --- a/src/pyelliptic/arithmetic.py +++ b/src/pyelliptic/arithmetic.py @@ -1,6 +1,5 @@ -""" -Arithmetic Expressions -""" +# pylint: disable=missing-docstring,too-many-function-args + import hashlib import re @@ -12,7 +11,6 @@ G = (Gx, Gy) def inv(a, n): - """Inversion""" lm, hm = 1, 0 low, high = a % n, n while low > 1: @@ -23,7 +21,6 @@ def inv(a, n): def get_code_string(base): - """Returns string according to base value""" if base == 2: return '01' elif base == 10: @@ -39,7 +36,6 @@ def get_code_string(base): def encode(val, base, minlen=0): - """Returns the encoded string""" code_string = get_code_string(base) result = "" while val > 0: @@ -51,7 +47,6 @@ def encode(val, base, minlen=0): def decode(string, base): - """Returns the decoded string""" code_string = get_code_string(base) result = 0 if base == 16: @@ -64,13 +59,10 @@ def decode(string, base): def changebase(string, frm, to, minlen=0): - """Change base of the string""" return encode(decode(string, frm), to, minlen) def base10_add(a, b): - """Adding the numbers that are of base10""" - # pylint: disable=too-many-function-args if a is None: return b[0], b[1] if b is None: @@ -86,7 +78,6 @@ def base10_add(a, b): def base10_double(a): - """Double the numbers that are of base10""" if a is None: return None m = ((3 * a[0] * a[0] + A) * inv(2 * a[1], P)) % P @@ -96,7 +87,6 @@ def base10_double(a): def base10_multiply(a, n): - """Multiply the numbers that are of base10""" if n == 0: return G if n == 1: @@ -109,35 +99,28 @@ def base10_multiply(a, n): def hex_to_point(h): - """Converting hexadecimal to point value""" return (decode(h[2:66], 16), decode(h[66:], 16)) def point_to_hex(p): - """Converting point value to hexadecimal""" return '04' + encode(p[0], 16, 64) + encode(p[1], 16, 64) def multiply(privkey, pubkey): - """Multiplying keys""" - return point_to_hex(base10_multiply( - hex_to_point(pubkey), decode(privkey, 16))) + return point_to_hex(base10_multiply(hex_to_point(pubkey), decode(privkey, 16))) def privtopub(privkey): - """Converting key from private to public""" return point_to_hex(base10_multiply(G, decode(privkey, 16))) def add(p1, p2): - """Adding two public keys""" if len(p1) == 32: return encode(decode(p1, 16) + decode(p2, 16) % P, 16, 32) return point_to_hex(base10_add(hex_to_point(p1), hex_to_point(p2))) def hash_160(string): - """Hashed version of public key""" intermed = hashlib.sha256(string).digest() ripemd160 = hashlib.new('ripemd160') ripemd160.update(intermed) @@ -145,18 +128,17 @@ def hash_160(string): def dbl_sha256(string): - """Double hashing (SHA256)""" return hashlib.sha256(hashlib.sha256(string).digest()).digest() def bin_to_b58check(inp): - """Convert binary to base58""" inp_fmtd = '\x00' + inp leadingzbytes = len(re.match('^\x00*', inp_fmtd).group(0)) checksum = dbl_sha256(inp_fmtd)[:4] return '1' * leadingzbytes + changebase(inp_fmtd + checksum, 256, 58) +# Convert a public key (in hex) to a Bitcoin address + def pubkey_to_address(pubkey): - """Convert a public key (in hex) to a Bitcoin address""" return bin_to_b58check(hash_160(changebase(pubkey, 16, 256))) diff --git a/src/pyelliptic/cipher.py b/src/pyelliptic/cipher.py index 4057e169..b597cafa 100644 --- a/src/pyelliptic/cipher.py +++ b/src/pyelliptic/cipher.py @@ -1,18 +1,15 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -""" -Symmetric Encryption -""" + # Copyright (C) 2011 Yann GUIBET # See LICENSE for details. -from openssl import OpenSSL +from pyelliptic.openssl import OpenSSL -# pylint: disable=redefined-builtin -class Cipher(object): +class Cipher: """ - Main class for encryption + Symmetric encryption import pyelliptic iv = pyelliptic.Cipher.gen_IV('aes-256-cfb') @@ -47,34 +44,30 @@ class Cipher(object): @staticmethod def get_blocksize(ciphername): - """This Method returns cipher blocksize""" cipher = OpenSSL.get_cipher(ciphername) return cipher.get_blocksize() @staticmethod def gen_IV(ciphername): - """Generate random initialization vector""" cipher = OpenSSL.get_cipher(ciphername) return OpenSSL.rand(cipher.get_blocksize()) def update(self, input): - """Update result with more data""" i = OpenSSL.c_int(0) buffer = OpenSSL.malloc(b"", len(input) + self.cipher.get_blocksize()) inp = OpenSSL.malloc(input, len(input)) if OpenSSL.EVP_CipherUpdate(self.ctx, OpenSSL.byref(buffer), OpenSSL.byref(i), inp, len(input)) == 0: raise Exception("[OpenSSL] EVP_CipherUpdate FAIL ...") - return buffer.raw[0:i.value] # pylint: disable=invalid-slice-index + return buffer.raw[0:i.value] def final(self): - """Returning the final value""" i = OpenSSL.c_int(0) buffer = OpenSSL.malloc(b"", self.cipher.get_blocksize()) if (OpenSSL.EVP_CipherFinal_ex(self.ctx, OpenSSL.byref(buffer), OpenSSL.byref(i))) == 0: raise Exception("[OpenSSL] EVP_CipherFinal_ex FAIL ...") - return buffer.raw[0:i.value] # pylint: disable=invalid-slice-index + return buffer.raw[0:i.value] def ciphering(self, input): """ @@ -84,7 +77,6 @@ class Cipher(object): return buff + self.final() def __del__(self): - # pylint: disable=protected-access if OpenSSL._hexversion > 0x10100000 and not OpenSSL._libreSSL: OpenSSL.EVP_CIPHER_CTX_reset(self.ctx) else: diff --git a/src/pyelliptic/ecc.py b/src/pyelliptic/ecc.py index a7f5a6b7..fb0d6773 100644 --- a/src/pyelliptic/ecc.py +++ b/src/pyelliptic/ecc.py @@ -1,18 +1,20 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ -Asymmetric cryptography using elliptic curves +src/pyelliptic/ecc.py +===================== """ -# pylint: disable=protected-access, too-many-branches, too-many-locals +# pylint: disable=protected-access + # Copyright (C) 2011 Yann GUIBET # See LICENSE for details. from hashlib import sha512 from struct import pack, unpack -from cipher import Cipher -from hash import equals, hmac_sha256 -from openssl import OpenSSL +from pyelliptic.cipher import Cipher +from pyelliptic.hash import equals, hmac_sha256 +from pyelliptic.openssl import OpenSSL class ECC(object): @@ -171,8 +173,7 @@ class ECC(object): if OpenSSL.EC_POINT_get_affine_coordinates_GFp( group, pub_key, pub_key_x, pub_key_y, 0) == 0: - raise Exception( - "[OpenSSL] EC_POINT_get_affine_coordinates_GFp FAIL ...") + raise Exception("[OpenSSL] EC_POINT_get_affine_coordinates_GFp FAIL ...") privkey = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(priv_key)) pubkeyx = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(pub_key_x)) @@ -275,6 +276,7 @@ class ECC(object): def raw_check_key(self, privkey, pubkey_x, pubkey_y, curve=None): """Check key validity, key is supplied as binary data""" + # pylint: disable=too-many-branches if curve is None: curve = self.curve elif isinstance(curve, str): @@ -322,6 +324,7 @@ class ECC(object): """ Sign the input with ECDSA method and returns the signature """ + # pylint: disable=too-many-branches,too-many-locals try: size = len(inputb) buff = OpenSSL.malloc(inputb, size) @@ -391,6 +394,7 @@ class ECC(object): Verify the signature with the input and the local public key. Returns a boolean """ + # pylint: disable=too-many-branches try: bsig = OpenSSL.malloc(sig, len(sig)) binputb = OpenSSL.malloc(inputb, len(inputb)) @@ -433,13 +437,10 @@ class ECC(object): 0, digest, dgst_len.contents, bsig, len(sig), key) if ret == -1: - # Fail to Check - return False + return False # Fail to Check if ret == 0: - # Bad signature ! - return False - # Good - return True + return False # Bad signature ! + return True # Good finally: OpenSSL.EC_KEY_free(key) @@ -487,6 +488,7 @@ class ECC(object): """ Decrypt data with ECIES method using the local private key """ + # pylint: disable=too-many-locals blocksize = OpenSSL.get_cipher(ciphername).get_blocksize() iv = data[:blocksize] i = blocksize diff --git a/src/pyelliptic/eccblind.py b/src/pyelliptic/eccblind.py deleted file mode 100644 index 5b9b045e..00000000 --- a/src/pyelliptic/eccblind.py +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/env python -""" -ECC blind signature functionality based on -"An Efficient Blind Signature Scheme -Based on the Elliptic CurveDiscrete Logarithm Problem" by Morteza Nikooghadama - and Ali Zakerolhosseini , -http://www.isecure-journal.com/article_39171_47f9ec605dd3918c2793565ec21fcd7a.pdf -""" - -# variable names are based on the math in the paper, so they don't conform -# to PEP8 - -from .openssl import OpenSSL - - -class ECCBlind(object): # pylint: disable=too-many-instance-attributes - """ - Class for ECC blind signature functionality - """ - - # init - k = None - R = None - keypair = None - F = None - Q = None - a = None - b = None - c = None - binv = None - r = None - m = None - m_ = None - s_ = None - signature = None - - @staticmethod - def ec_get_random(group, ctx): - """ - Random point from finite field - """ - order = OpenSSL.BN_new() - OpenSSL.EC_GROUP_get_order(group, order, ctx) - OpenSSL.BN_rand(order, OpenSSL.BN_num_bits(order), 0, 0) - return order - - @staticmethod - def ec_invert(group, a, ctx): - """ - ECC inversion - """ - order = OpenSSL.BN_new() - OpenSSL.EC_GROUP_get_order(group, order, ctx) - inverse = OpenSSL.BN_mod_inverse(0, a, order, ctx) - return inverse - - @staticmethod - def ec_gen_keypair(group, ctx): - """ - Generate an ECC keypair - """ - d = ECCBlind.ec_get_random(group, ctx) - Q = OpenSSL.EC_POINT_new(group) - OpenSSL.EC_POINT_mul(group, Q, d, 0, 0, 0) - return (d, Q) - - @staticmethod - def ec_Ftor(F, group, ctx): - """ - x0 coordinate of F - """ - # F = (x0, y0) - x0 = OpenSSL.BN_new() - y0 = OpenSSL.BN_new() - OpenSSL.EC_POINT_get_affine_coordinates_GFp(group, F, x0, y0, ctx) - return x0 - - def __init__(self, curve="secp256k1", pubkey=None): - self.ctx = OpenSSL.BN_CTX_new() - - if pubkey: - self.group, self.G, self.n, self.Q = pubkey - else: - self.group = OpenSSL.EC_GROUP_new_by_curve_name( - OpenSSL.get_curve(curve)) - # Order n - self.n = OpenSSL.BN_new() - OpenSSL.EC_GROUP_get_order(self.group, self.n, self.ctx) - - # Generator G - self.G = OpenSSL.EC_GROUP_get0_generator(self.group) - - # new keypair - self.keypair = ECCBlind.ec_gen_keypair(self.group, self.ctx) - - self.Q = self.keypair[1] - - self.pubkey = (self.group, self.G, self.n, self.Q) - - # Identity O (infinity) - self.iO = OpenSSL.EC_POINT_new(self.group) - OpenSSL.EC_POINT_set_to_infinity(self.group, self.iO) - - def signer_init(self): - """ - Init signer - """ - # Signer: Random integer k - self.k = ECCBlind.ec_get_random(self.group, self.ctx) - - # R = kG - self.R = OpenSSL.EC_POINT_new(self.group) - OpenSSL.EC_POINT_mul(self.group, self.R, self.k, 0, 0, 0) - - return self.R - - def create_signing_request(self, R, msg): - """ - Requester creates a new signing request - """ - self.R = R - - # Requester: 3 random blinding factors - self.F = OpenSSL.EC_POINT_new(self.group) - OpenSSL.EC_POINT_set_to_infinity(self.group, self.F) - temp = OpenSSL.EC_POINT_new(self.group) - abinv = OpenSSL.BN_new() - - # F != O - while OpenSSL.EC_POINT_cmp(self.group, self.F, self.iO, self.ctx) == 0: - self.a = ECCBlind.ec_get_random(self.group, self.ctx) - self.b = ECCBlind.ec_get_random(self.group, self.ctx) - self.c = ECCBlind.ec_get_random(self.group, self.ctx) - - # F = b^-1 * R... - self.binv = ECCBlind.ec_invert(self.group, self.b, self.ctx) - OpenSSL.EC_POINT_mul(self.group, temp, 0, self.R, self.binv, 0) - OpenSSL.EC_POINT_copy(self.F, temp) - - # ... + a*b^-1 * Q... - OpenSSL.BN_mul(abinv, self.a, self.binv, self.ctx) - OpenSSL.EC_POINT_mul(self.group, temp, 0, self.Q, abinv, 0) - OpenSSL.EC_POINT_add(self.group, self.F, self.F, temp, 0) - - # ... + c*G - OpenSSL.EC_POINT_mul(self.group, temp, 0, self.G, self.c, 0) - OpenSSL.EC_POINT_add(self.group, self.F, self.F, temp, 0) - - # F = (x0, y0) - self.r = ECCBlind.ec_Ftor(self.F, self.group, self.ctx) - - # Requester: Blinding (m' = br(m) + a) - self.m = OpenSSL.BN_new() - OpenSSL.BN_bin2bn(msg, len(msg), self.m) - - self.m_ = OpenSSL.BN_new() - OpenSSL.BN_mod_mul(self.m_, self.b, self.r, self.n, self.ctx) - OpenSSL.BN_mod_mul(self.m_, self.m_, self.m, self.n, self.ctx) - OpenSSL.BN_mod_add(self.m_, self.m_, self.a, self.n, self.ctx) - return self.m_ - - def blind_sign(self, m_): - """ - Signer blind-signs the request - """ - self.m_ = m_ - self.s_ = OpenSSL.BN_new() - OpenSSL.BN_mod_mul(self.s_, self.keypair[0], self.m_, self.n, self.ctx) - OpenSSL.BN_mod_add(self.s_, self.s_, self.k, self.n, self.ctx) - return self.s_ - - def unblind(self, s_): - """ - Requester unblinds the signature - """ - self.s_ = s_ - s = OpenSSL.BN_new() - OpenSSL.BN_mod_mul(s, self.binv, self.s_, self.n, self.ctx) - OpenSSL.BN_mod_add(s, s, self.c, self.n, self.ctx) - self.signature = (s, self.F) - return self.signature - - def verify(self, msg, signature): - """ - Verify signature with certifier's pubkey - """ - - # convert msg to BIGNUM - self.m = OpenSSL.BN_new() - OpenSSL.BN_bin2bn(msg, len(msg), self.m) - - # init - s, self.F = signature - if self.r is None: - self.r = ECCBlind.ec_Ftor(self.F, self.group, self.ctx) - - lhs = OpenSSL.EC_POINT_new(self.group) - rhs = OpenSSL.EC_POINT_new(self.group) - - OpenSSL.EC_POINT_mul(self.group, lhs, s, 0, 0, 0) - - OpenSSL.EC_POINT_mul(self.group, rhs, 0, self.Q, self.m, 0) - OpenSSL.EC_POINT_mul(self.group, rhs, 0, rhs, self.r, 0) - OpenSSL.EC_POINT_add(self.group, rhs, rhs, self.F, self.ctx) - - retval = OpenSSL.EC_POINT_cmp(self.group, lhs, rhs, self.ctx) - if retval == -1: - raise RuntimeError("EC_POINT_cmp returned an error") - else: - return retval == 0 diff --git a/src/pyelliptic/hash.py b/src/pyelliptic/hash.py index f098d631..fb910dd4 100644 --- a/src/pyelliptic/hash.py +++ b/src/pyelliptic/hash.py @@ -1,10 +1,10 @@ -""" -Wrappers for hash functions from OpenSSL. -""" +#!/usr/bin/env python +# -*- coding: utf-8 -*- + # Copyright (C) 2011 Yann GUIBET # See LICENSE for details. -from openssl import OpenSSL +from pyelliptic.openssl import OpenSSL # For python3 @@ -27,10 +27,10 @@ def _equals_str(a, b): def equals(a, b): - """Compare two strings or bytearrays""" if isinstance(a, str): return _equals_str(a, b) - return _equals_bytes(a, b) + else: + return _equals_bytes(a, b) def hmac_sha256(k, m): @@ -58,7 +58,6 @@ def hmac_sha512(k, m): def pbkdf2(password, salt=None, i=10000, keylen=64): - """Key derivation function using SHA256""" if salt is None: salt = OpenSSL.rand(8) p_password = OpenSSL.malloc(password, len(password)) diff --git a/src/pyelliptic/openssl.py b/src/pyelliptic/openssl.py index 7cf1e2c5..115bdc08 100644 --- a/src/pyelliptic/openssl.py +++ b/src/pyelliptic/openssl.py @@ -1,53 +1,42 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + # Copyright (C) 2011 Yann GUIBET # See LICENSE for details. # # Software slightly changed by Jonathan Warren -# pylint: disable=protected-access, import-error -""" -This module loads openssl libs with ctypes and incapsulates -needed openssl functionality in class _OpenSSL. -""" -import ctypes -from kivy.utils import platform + import sys -# pylint: disable=protected-access +import ctypes OpenSSL = None -class CipherName(object): - """Class returns cipher name, pointer and blocksize""" - +class CipherName: def __init__(self, name, pointer, blocksize): self._name = name self._pointer = pointer self._blocksize = blocksize def __str__(self): - return "Cipher : " + self._name + \ - " | Blocksize : " + str(self._blocksize) + \ - " | Function pointer : " + str(self._pointer) + return "Cipher : " + self._name + " | Blocksize : " + str(self._blocksize) + " | Fonction pointer : " + str(self._pointer) def get_pointer(self): - """Method returns the pointer""" return self._pointer() def get_name(self): - """This method returns cipher name""" return self._name def get_blocksize(self): - """This method returns cipher blocksize""" return self._blocksize def get_version(library): - """Method returns the version of the OpenSSL Library""" version = None hexversion = None cflags = None try: - # OpenSSL 1.1 + #OpenSSL 1.1 OPENSSL_VERSION = 0 OPENSSL_CFLAGS = 1 library.OpenSSL_version.argtypes = [ctypes.c_int] @@ -58,7 +47,7 @@ def get_version(library): hexversion = library.OpenSSL_version_num() except AttributeError: try: - # OpenSSL 1.0 + #OpenSSL 1.0 SSLEAY_VERSION = 0 SSLEAY_CFLAGS = 2 library.SSLeay.restype = ctypes.c_long @@ -68,18 +57,19 @@ def get_version(library): cflags = library.SSLeay_version(SSLEAY_CFLAGS) hexversion = library.SSLeay() except AttributeError: - # raise NotImplementedError('Cannot determine version of this OpenSSL library.') + #raise NotImplementedError('Cannot determine version of this OpenSSL library.') pass return (version, hexversion, cflags) -class _OpenSSL(object): +class _OpenSSL: """ Wrapper for OpenSSL using ctypes """ - # pylint: disable=too-many-statements, too-many-instance-attributes def __init__(self, library): - """Build the wrapper""" + """ + Build the wrapper + """ self._lib = ctypes.CDLL(library) self._version, self._hexversion, self._cflags = get_version(self._lib) self._libreSSL = self._version.startswith("LibreSSL") @@ -138,14 +128,9 @@ class _OpenSSL(object): self.EC_KEY_get0_group.restype = ctypes.c_void_p self.EC_KEY_get0_group.argtypes = [ctypes.c_void_p] - self.EC_POINT_get_affine_coordinates_GFp = \ - self._lib.EC_POINT_get_affine_coordinates_GFp + self.EC_POINT_get_affine_coordinates_GFp = self._lib.EC_POINT_get_affine_coordinates_GFp self.EC_POINT_get_affine_coordinates_GFp.restype = ctypes.c_int - self.EC_POINT_get_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] + self.EC_POINT_get_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key self.EC_KEY_set_private_key.restype = ctypes.c_int @@ -159,17 +144,11 @@ class _OpenSSL(object): self.EC_KEY_set_group = self._lib.EC_KEY_set_group self.EC_KEY_set_group.restype = ctypes.c_int - self.EC_KEY_set_group.argtypes = [ctypes.c_void_p, - ctypes.c_void_p] + self.EC_KEY_set_group.argtypes = [ctypes.c_void_p, ctypes.c_void_p] - self.EC_POINT_set_affine_coordinates_GFp = \ - self._lib.EC_POINT_set_affine_coordinates_GFp + self.EC_POINT_set_affine_coordinates_GFp = self._lib.EC_POINT_set_affine_coordinates_GFp self.EC_POINT_set_affine_coordinates_GFp.restype = ctypes.c_int - self.EC_POINT_set_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] + self.EC_POINT_set_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] self.EC_POINT_new = self._lib.EC_POINT_new self.EC_POINT_new.restype = ctypes.c_void_p @@ -185,11 +164,7 @@ class _OpenSSL(object): self.EC_POINT_mul = self._lib.EC_POINT_mul self.EC_POINT_mul.restype = None - self.EC_POINT_mul.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] + self.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key self.EC_KEY_set_private_key.restype = ctypes.c_int @@ -200,11 +175,10 @@ class _OpenSSL(object): self.EC_KEY_OpenSSL = self._lib.EC_KEY_OpenSSL self._lib.EC_KEY_OpenSSL.restype = ctypes.c_void_p self._lib.EC_KEY_OpenSSL.argtypes = [] - + self.EC_KEY_set_method = self._lib.EC_KEY_set_method self._lib.EC_KEY_set_method.restype = ctypes.c_int - self._lib.EC_KEY_set_method.argtypes = [ctypes.c_void_p, - ctypes.c_void_p] + self._lib.EC_KEY_set_method.argtypes = [ctypes.c_void_p, ctypes.c_void_p] else: self.ECDH_OpenSSL = self._lib.ECDH_OpenSSL self._lib.ECDH_OpenSSL.restype = ctypes.c_void_p @@ -212,8 +186,7 @@ class _OpenSSL(object): self.ECDH_set_method = self._lib.ECDH_set_method self._lib.ECDH_set_method.restype = ctypes.c_int - self._lib.ECDH_set_method.argtypes = [ctypes.c_void_p, - ctypes.c_void_p] + self._lib.ECDH_set_method.argtypes = [ctypes.c_void_p, ctypes.c_void_p] self.BN_CTX_new = self._lib.BN_CTX_new self._lib.BN_CTX_new.restype = ctypes.c_void_p @@ -222,15 +195,12 @@ class _OpenSSL(object): self.ECDH_compute_key = self._lib.ECDH_compute_key self.ECDH_compute_key.restype = ctypes.c_int self.ECDH_compute_key.argtypes = [ctypes.c_void_p, - ctypes.c_int, - ctypes.c_void_p, - ctypes.c_void_p] + ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p] self.EVP_CipherInit_ex = self._lib.EVP_CipherInit_ex self.EVP_CipherInit_ex.restype = ctypes.c_int self.EVP_CipherInit_ex.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] + ctypes.c_void_p, ctypes.c_void_p] self.EVP_CIPHER_CTX_new = self._lib.EVP_CIPHER_CTX_new self.EVP_CIPHER_CTX_new.restype = ctypes.c_void_p @@ -253,13 +223,13 @@ class _OpenSSL(object): self.EVP_aes_256_cbc.restype = ctypes.c_void_p self.EVP_aes_256_cbc.argtypes = [] - # self.EVP_aes_128_ctr = self._lib.EVP_aes_128_ctr - # self.EVP_aes_128_ctr.restype = ctypes.c_void_p - # self.EVP_aes_128_ctr.argtypes = [] + #self.EVP_aes_128_ctr = self._lib.EVP_aes_128_ctr + #self.EVP_aes_128_ctr.restype = ctypes.c_void_p + #self.EVP_aes_128_ctr.argtypes = [] - # self.EVP_aes_256_ctr = self._lib.EVP_aes_256_ctr - # self.EVP_aes_256_ctr.restype = ctypes.c_void_p - # self.EVP_aes_256_ctr.argtypes = [] + #self.EVP_aes_256_ctr = self._lib.EVP_aes_256_ctr + #self.EVP_aes_256_ctr.restype = ctypes.c_void_p + #self.EVP_aes_256_ctr.argtypes = [] self.EVP_aes_128_ofb = self._lib.EVP_aes_128_ofb self.EVP_aes_128_ofb.restype = ctypes.c_void_p @@ -280,7 +250,7 @@ class _OpenSSL(object): self.EVP_rc4 = self._lib.EVP_rc4 self.EVP_rc4.restype = ctypes.c_void_p self.EVP_rc4.argtypes = [] - + if self._hexversion >= 0x10100000 and not self._libreSSL: self.EVP_CIPHER_CTX_reset = self._lib.EVP_CIPHER_CTX_reset self.EVP_CIPHER_CTX_reset.restype = ctypes.c_int @@ -297,8 +267,7 @@ class _OpenSSL(object): self.EVP_CipherUpdate = self._lib.EVP_CipherUpdate self.EVP_CipherUpdate.restype = ctypes.c_int self.EVP_CipherUpdate.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, ctypes.c_void_p, - ctypes.c_void_p, ctypes.c_int] + ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int] self.EVP_CipherFinal_ex = self._lib.EVP_CipherFinal_ex self.EVP_CipherFinal_ex.restype = ctypes.c_int @@ -312,7 +281,7 @@ class _OpenSSL(object): self.EVP_DigestInit_ex = self._lib.EVP_DigestInit_ex self.EVP_DigestInit_ex.restype = ctypes.c_int self._lib.EVP_DigestInit_ex.argtypes = 3 * [ctypes.c_void_p] - + self.EVP_DigestUpdate = self._lib.EVP_DigestUpdate self.EVP_DigestUpdate.restype = ctypes.c_int self.EVP_DigestUpdate.argtypes = [ctypes.c_void_p, @@ -327,24 +296,22 @@ class _OpenSSL(object): self.EVP_DigestFinal_ex.restype = ctypes.c_int self.EVP_DigestFinal_ex.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] - + self.ECDSA_sign = self._lib.ECDSA_sign self.ECDSA_sign.restype = ctypes.c_int self.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p, - ctypes.c_int, ctypes.c_void_p, - ctypes.c_void_p, ctypes.c_void_p] + ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] self.ECDSA_verify = self._lib.ECDSA_verify self.ECDSA_verify.restype = ctypes.c_int self.ECDSA_verify.argtypes = [ctypes.c_int, ctypes.c_void_p, - ctypes.c_int, ctypes.c_void_p, - ctypes.c_int, ctypes.c_void_p] + ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p] if self._hexversion >= 0x10100000 and not self._libreSSL: self.EVP_MD_CTX_new = self._lib.EVP_MD_CTX_new self.EVP_MD_CTX_new.restype = ctypes.c_void_p self.EVP_MD_CTX_new.argtypes = [] - + self.EVP_MD_CTX_reset = self._lib.EVP_MD_CTX_reset self.EVP_MD_CTX_reset.restype = None self.EVP_MD_CTX_reset.argtypes = [ctypes.c_void_p] @@ -362,11 +329,11 @@ class _OpenSSL(object): self.EVP_MD_CTX_create = self._lib.EVP_MD_CTX_create self.EVP_MD_CTX_create.restype = ctypes.c_void_p self.EVP_MD_CTX_create.argtypes = [] - + self.EVP_MD_CTX_init = self._lib.EVP_MD_CTX_init self.EVP_MD_CTX_init.restype = None self.EVP_MD_CTX_init.argtypes = [ctypes.c_void_p] - + self.EVP_MD_CTX_destroy = self._lib.EVP_MD_CTX_destroy self.EVP_MD_CTX_destroy.restype = None self.EVP_MD_CTX_destroy.argtypes = [ctypes.c_void_p] @@ -396,167 +363,36 @@ class _OpenSSL(object): self.HMAC = self._lib.HMAC self.HMAC.restype = ctypes.c_void_p self.HMAC.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, - ctypes.c_void_p, ctypes.c_int, - ctypes.c_void_p, ctypes.c_void_p] + ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p] try: self.PKCS5_PBKDF2_HMAC = self._lib.PKCS5_PBKDF2_HMAC except: # The above is not compatible with all versions of OSX. self.PKCS5_PBKDF2_HMAC = self._lib.PKCS5_PBKDF2_HMAC_SHA1 - + self.PKCS5_PBKDF2_HMAC.restype = ctypes.c_int self.PKCS5_PBKDF2_HMAC.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p] - # Blind signature requirements - self.BN_CTX_new = self._lib.BN_CTX_new - self.BN_CTX_new.restype = ctypes.c_void_p - self.BN_CTX_new.argtypes = [] - - self.BN_dup = self._lib.BN_dup - self.BN_dup.restype = ctypes.c_void_p - self.BN_dup.argtypes = [ctypes.c_void_p] - - self.BN_rand = self._lib.BN_rand - self.BN_rand.restype = ctypes.c_int - self.BN_rand.argtypes = [ctypes.c_void_p, - ctypes.c_int, - ctypes.c_int] - - self.BN_set_word = self._lib.BN_set_word - self.BN_set_word.restype = ctypes.c_int - self.BN_set_word.argtypes = [ctypes.c_void_p, - ctypes.c_ulong] - - self.BN_mul = self._lib.BN_mul - self.BN_mul.restype = ctypes.c_int - self.BN_mul.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] - - self.BN_mod_add = self._lib.BN_mod_add - self.BN_mod_add.restype = ctypes.c_int - self.BN_mod_add.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] - - self.BN_mod_inverse = self._lib.BN_mod_inverse - self.BN_mod_inverse.restype = ctypes.c_void_p - self.BN_mod_inverse.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] - - self.BN_mod_mul = self._lib.BN_mod_mul - self.BN_mod_mul.restype = ctypes.c_int - self.BN_mod_mul.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] - - self.BN_lshift = self._lib.BN_lshift - self.BN_lshift.restype = ctypes.c_int - self.BN_lshift.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_int] - - self.BN_sub_word = self._lib.BN_sub_word - self.BN_sub_word.restype = ctypes.c_int - self.BN_sub_word.argtypes = [ctypes.c_void_p, - ctypes.c_ulong] - - self.BN_cmp = self._lib.BN_cmp - self.BN_cmp.restype = ctypes.c_int - self.BN_cmp.argtypes = [ctypes.c_void_p, - ctypes.c_void_p] - - self.BN_bn2dec = self._lib.BN_bn2dec - self.BN_bn2dec.restype = ctypes.c_char_p - self.BN_bn2dec.argtypes = [ctypes.c_void_p] - - self.BN_CTX_free = self._lib.BN_CTX_free - self.BN_CTX_free.argtypes = [ctypes.c_void_p] - - self.EC_GROUP_new_by_curve_name = self._lib.EC_GROUP_new_by_curve_name - self.EC_GROUP_new_by_curve_name.restype = ctypes.c_void_p - self.EC_GROUP_new_by_curve_name.argtypes = [ctypes.c_int] - - self.EC_GROUP_get_order = self._lib.EC_GROUP_get_order - self.EC_GROUP_get_order.restype = ctypes.c_int - self.EC_GROUP_get_order.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] - - self.EC_GROUP_get_cofactor = self._lib.EC_GROUP_get_cofactor - self.EC_GROUP_get_cofactor.restype = ctypes.c_int - self.EC_GROUP_get_cofactor.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] - - self.EC_GROUP_get0_generator = self._lib.EC_GROUP_get0_generator - self.EC_GROUP_get0_generator.restype = ctypes.c_void_p - self.EC_GROUP_get0_generator.argtypes = [ctypes.c_void_p] - - self.EC_POINT_copy = self._lib.EC_POINT_copy - self.EC_POINT_copy.restype = ctypes.c_int - self.EC_POINT_copy.argtypes = [ctypes.c_void_p, - ctypes.c_void_p] - - self.EC_POINT_add = self._lib.EC_POINT_add - self.EC_POINT_add.restype = ctypes.c_int - self.EC_POINT_add.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] - - self.EC_POINT_cmp = self._lib.EC_POINT_cmp - self.EC_POINT_cmp.restype = ctypes.c_int - self.EC_POINT_cmp.argtypes = [ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_void_p] - - self.EC_POINT_set_to_infinity = self._lib.EC_POINT_set_to_infinity - self.EC_POINT_set_to_infinity.restype = ctypes.c_int - self.EC_POINT_set_to_infinity.argtypes = [ctypes.c_void_p, - ctypes.c_void_p] - self._set_ciphers() self._set_curves() def _set_ciphers(self): self.cipher_algo = { - 'aes-128-cbc': CipherName( - 'aes-128-cbc', self.EVP_aes_128_cbc, 16), - 'aes-256-cbc': CipherName( - 'aes-256-cbc', self.EVP_aes_256_cbc, 16), - 'aes-128-cfb': CipherName( - 'aes-128-cfb', self.EVP_aes_128_cfb128, 16), - 'aes-256-cfb': CipherName( - 'aes-256-cfb', self.EVP_aes_256_cfb128, 16), - 'aes-128-ofb': CipherName( - 'aes-128-ofb', self._lib.EVP_aes_128_ofb, 16), - 'aes-256-ofb': CipherName( - 'aes-256-ofb', self._lib.EVP_aes_256_ofb, 16), - # 'aes-128-ctr': CipherName( - # 'aes-128-ctr', self._lib.EVP_aes_128_ctr, 16), - # 'aes-256-ctr': CipherName( - # 'aes-256-ctr', self._lib.EVP_aes_256_ctr, 16), - 'bf-cfb': CipherName( - 'bf-cfb', self.EVP_bf_cfb64, 8), - 'bf-cbc': CipherName( - 'bf-cbc', self.EVP_bf_cbc, 8), - # 128 is the initialisation size not block size - 'rc4': CipherName( - 'rc4', self.EVP_rc4, 128), + 'aes-128-cbc': CipherName('aes-128-cbc', self.EVP_aes_128_cbc, 16), + 'aes-256-cbc': CipherName('aes-256-cbc', self.EVP_aes_256_cbc, 16), + 'aes-128-cfb': CipherName('aes-128-cfb', self.EVP_aes_128_cfb128, 16), + 'aes-256-cfb': CipherName('aes-256-cfb', self.EVP_aes_256_cfb128, 16), + 'aes-128-ofb': CipherName('aes-128-ofb', self._lib.EVP_aes_128_ofb, 16), + 'aes-256-ofb': CipherName('aes-256-ofb', self._lib.EVP_aes_256_ofb, 16), + #'aes-128-ctr': CipherName('aes-128-ctr', self._lib.EVP_aes_128_ctr, 16), + #'aes-256-ctr': CipherName('aes-256-ctr', self._lib.EVP_aes_256_ctr, 16), + 'bf-cfb': CipherName('bf-cfb', self.EVP_bf_cfb64, 8), + 'bf-cbc': CipherName('bf-cbc', self.EVP_bf_cbc, 8), + 'rc4': CipherName('rc4', self.EVP_rc4, 128), # 128 is the initialisation size not block size } def _set_curves(self): @@ -616,13 +452,13 @@ class _OpenSSL(object): raise Exception("Unknown curve") return self.curves[name] - def get_curve_by_id(self, id_): + def get_curve_by_id(self, id): """ returns the name of a elliptic curve with his id """ res = None for i in self.curves: - if self.curves[i] == id_: + if self.curves[i] == id: res = i break if res is None: @@ -633,64 +469,47 @@ class _OpenSSL(object): """ OpenSSL random function """ - buffer_ = self.malloc(0, size) - # This pyelliptic library, by default, didn't check the return value - # of RAND_bytes. It is evidently possible that it returned an error - # and not-actually-random data. However, in tests on various - # operating systems, while generating hundreds of gigabytes of random - # strings of various sizes I could not get an error to occur. - # Also Bitcoin doesn't check the return value of RAND_bytes either. + buffer = self.malloc(0, size) + # This pyelliptic library, by default, didn't check the return value of RAND_bytes. It is + # evidently possible that it returned an error and not-actually-random data. However, in + # tests on various operating systems, while generating hundreds of gigabytes of random + # strings of various sizes I could not get an error to occur. Also Bitcoin doesn't check + # the return value of RAND_bytes either. # Fixed in Bitmessage version 0.4.2 (in source code on 2013-10-13) - while self.RAND_bytes(buffer_, size) != 1: + while self.RAND_bytes(buffer, size) != 1: import time time.sleep(1) - return buffer_.raw + return buffer.raw def malloc(self, data, size): """ returns a create_string_buffer (ctypes) """ - buffer_ = None + buffer = None if data != 0: if sys.version_info.major == 3 and isinstance(data, type('')): data = data.encode() - buffer_ = self.create_string_buffer(data, size) + buffer = self.create_string_buffer(data, size) else: - buffer_ = self.create_string_buffer(size) - return buffer_ - + buffer = self.create_string_buffer(size) + return buffer def loadOpenSSL(): - """Method find and load the OpenSSL library""" - # pylint: disable=global-statement, protected-access, too-many-branches - global OpenSSL from os import path, environ from ctypes.util import find_library - + libdir = [] - if getattr(sys, 'frozen', None): + if getattr(sys,'frozen', None): if 'darwin' in sys.platform: libdir.extend([ - path.join( - environ['RESOURCEPATH'], '..', - 'Frameworks', 'libcrypto.dylib'), - path.join( - environ['RESOURCEPATH'], '..', - 'Frameworks', 'libcrypto.1.1.0.dylib'), - path.join( - environ['RESOURCEPATH'], '..', - 'Frameworks', 'libcrypto.1.0.2.dylib'), - path.join( - environ['RESOURCEPATH'], '..', - 'Frameworks', 'libcrypto.1.0.1.dylib'), - path.join( - environ['RESOURCEPATH'], '..', - 'Frameworks', 'libcrypto.1.0.0.dylib'), - path.join( - environ['RESOURCEPATH'], '..', - 'Frameworks', 'libcrypto.0.9.8.dylib'), - ]) + path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.dylib'), + path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.1.0.dylib'), + path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.2.dylib'), + path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.1.dylib'), + path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.1.0.0.dylib'), + path.join(environ['RESOURCEPATH'], '..', 'Frameworks','libcrypto.0.9.8.dylib'), + ]) elif 'win32' in sys.platform or 'win64' in sys.platform: libdir.append(path.join(sys._MEIPASS, 'libeay32.dll')) else: @@ -709,25 +528,16 @@ def loadOpenSSL(): path.join(sys._MEIPASS, 'libssl.so.0.9.8'), ]) if 'darwin' in sys.platform: - libdir.extend([ - 'libcrypto.dylib', '/usr/local/opt/openssl/lib/libcrypto.dylib']) + libdir.extend(['libcrypto.dylib', '/usr/local/opt/openssl/lib/libcrypto.dylib']) elif 'win32' in sys.platform or 'win64' in sys.platform: libdir.append('libeay32.dll') - elif platform == "android": - libdir.append('libcrypto1.0.2p.so') - libdir.append('libssl1.0.2p.so') - libdir.append('libcrypto1.1.so') - libdir.append('libssl1.1.so') else: libdir.append('libcrypto.so') libdir.append('libssl.so') libdir.append('libcrypto.so.1.0.0') libdir.append('libssl.so.1.0.0') if 'linux' in sys.platform or 'darwin' in sys.platform or 'bsd' in sys.platform: - try: - libdir.append(find_library('ssl')) - except OSError: - pass + libdir.append(find_library('ssl')) elif 'win32' in sys.platform or 'win64' in sys.platform: libdir.append(find_library('libeay32')) for library in libdir: @@ -736,8 +546,6 @@ def loadOpenSSL(): return except: pass - raise Exception( - "Couldn't find and load the OpenSSL library. You must install it.") - + raise Exception("Couldn't find and load the OpenSSL library. You must install it.") loadOpenSSL() diff --git a/src/qidenticon.py b/src/qidenticon.py index 6eab09cd..8db8430a 100644 --- a/src/qidenticon.py +++ b/src/qidenticon.py @@ -1,18 +1,22 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- # pylint: disable=too-many-locals,too-many-arguments,too-many-function-args """ -Usage ------ += usage = +== python == >>> import qtidenticon >>> qtidenticon.render_identicon(code, size) Return a PIL Image class instance which have generated identicon image. -``size`` specifies `patch size`. Generated image size is 3 * ``size``. +```size``` specifies `patch size`. Generated image size is 3 * ```size```. """ from PyQt4 import QtGui -from PyQt4.QtCore import QPointF, QSize, Qt -from PyQt4.QtGui import QPainter, QPixmap, QPolygonF +from PyQt4.QtCore import QSize, QPointF, Qt +from PyQt4.QtGui import QPixmap, QPainter, QPolygonF + +__all__ = ['render_identicon', 'IdenticonRendererBase'] class IdenticonRendererBase(object): @@ -22,7 +26,7 @@ class IdenticonRendererBase(object): def __init__(self, code): """ - :param code: code for icon + @param code code for icon """ if not isinstance(code, int): code = int(code) @@ -32,8 +36,8 @@ class IdenticonRendererBase(object): """ render identicon to QPicture - :param size: identicon patchsize. (image size is 3 * [size]) - :returns: :class:`QPicture` + @param size identicon patchsize. (image size is 3 * [size]) + @return QPicture """ # decode the code @@ -75,7 +79,7 @@ class IdenticonRendererBase(object): def drawPatchQt(self, pos, turn, invert, patch_type, image, size, foreColor, backColor, penwidth): # pylint: disable=unused-argument """ - :param size: patch size + @param size patch size """ path = self.PATH_SET[patch_type] if not path: @@ -130,7 +134,7 @@ class IdenticonRendererBase(object): class DonRenderer(IdenticonRendererBase): """ Don Park's implementation of identicon - see: http://www.docuverse.com/blog/donpark/2007/01/19/identicon-updated-and-source-released + see : http://www.docuverse.com/blog/donpark/2007/01/19/identicon-updated-and-source-released """ PATH_SET = [ diff --git a/src/queues.py b/src/queues.py index 7d9e284a..7b6bbade 100644 --- a/src/queues.py +++ b/src/queues.py @@ -1,51 +1,20 @@ -"""Most of the queues used by bitmessage threads are defined here.""" - import Queue -import threading -import time +from class_objectProcessorQueue import ObjectProcessorQueue from multiqueue import MultiQueue - -class ObjectProcessorQueue(Queue.Queue): - """Special queue class using lock for `.threads.objectProcessor`""" - - maxSize = 32000000 - - def __init__(self): - Queue.Queue.__init__(self) - self.sizeLock = threading.Lock() - #: in Bytes. We maintain this to prevent nodes from flooding us - #: with objects which take up too much memory. If this gets - #: too big we'll sleep before asking for further objects. - self.curSize = 0 - - def put(self, item, block=True, timeout=None): - while self.curSize >= self.maxSize: - time.sleep(1) - with self.sizeLock: - self.curSize += len(item[1]) - Queue.Queue.put(self, item, block, timeout) - - def get(self, block=True, timeout=None): - item = Queue.Queue.get(self, block, timeout) - with self.sizeLock: - self.curSize -= len(item[1]) - return item - - workerQueue = Queue.Queue() UISignalQueue = Queue.Queue() addressGeneratorQueue = Queue.Queue() -#: `.network.ReceiveQueueThread` instances dump objects they hear -#: on the network into this queue to be processed. +# receiveDataThreads dump objects they hear on the network into this +# queue to be processed. objectProcessorQueue = ObjectProcessorQueue() invQueue = MultiQueue() addrQueue = MultiQueue() portCheckerQueue = Queue.Queue() receiveDataQueue = Queue.Queue() -#: The address generator thread uses this queue to get information back -#: to the API thread. +# The address generator thread uses this queue to get information back +# to the API thread. apiAddressGeneratorReturnQueue = Queue.Queue() -#: for exceptions +# Exceptions excQueue = Queue.Queue() diff --git a/src/network/randomtrackingdict.py b/src/randomtrackingdict.py similarity index 85% rename from src/network/randomtrackingdict.py rename to src/randomtrackingdict.py index e87bf156..6c3300ab 100644 --- a/src/network/randomtrackingdict.py +++ b/src/randomtrackingdict.py @@ -1,6 +1,8 @@ """ -Track randomize ordered dict +src/randomtrackingdict.py +========================= """ + import random from threading import RLock from time import time @@ -12,12 +14,10 @@ class RandomTrackingDict(object): """ Dict with randomised order and tracking. - Keeps a track of how many items have been requested from the dict, - and timeouts. Resets after all objects have been retrieved and timed out. - The main purpose of this isn't as much putting related code together - as performance optimisation and anonymisation of downloading of objects - from other peers. If done using a standard dict or array, it takes - too much CPU (and looks convoluted). Randomisation helps with anonymity. + Keeps a track of how many items have been requested from the dict, and timeouts. Resets after all objects have been + retrieved and timed out. The main purpose of this isn't as much putting related code together as performance + optimisation and anonymisation of downloading of objects from other peers. If done using a standard dict or array, + it takes too much CPU (and looks convoluted). Randomisation helps with anonymity. """ # pylint: disable=too-many-instance-attributes maxPending = 10 @@ -85,14 +85,13 @@ class RandomTrackingDict(object): def setMaxPending(self, maxPending): """ - Sets maximum number of objects that can be retrieved from the class - simultaneously as long as there is no timeout + Sets maximum number of objects that can be retrieved from the class simultaneously as long as there is no + timeout """ self.maxPending = maxPending def setPendingTimeout(self, pendingTimeout): - """Sets how long to wait for a timeout if max pending is reached - (or all objects have been retrieved)""" + """Sets how long to wait for a timeout if max pending is reached (or all objects have been retrieved)""" self.pendingTimeout = pendingTimeout def setLastObject(self): @@ -100,8 +99,7 @@ class RandomTrackingDict(object): self.lastObject = time() def randomKeys(self, count=1): - """Retrieve count random keys from the dict - that haven't already been retrieved""" + """Retrieve count random keys from the dict that haven't already been retrieved""" if self.len == 0 or ((self.pendingLen >= self.maxPending or self.pendingLen == self.len) and self.lastPoll + self.pendingTimeout > time()): @@ -111,15 +109,13 @@ class RandomTrackingDict(object): with self.lock: # reset if we've requested all # and if last object received too long time ago - if self.pendingLen == self.len and self.lastObject + \ - self.pendingTimeout < time(): + if self.pendingLen == self.len and self.lastObject + self.pendingTimeout < time(): self.pendingLen = 0 self.setLastObject() available = self.len - self.pendingLen if count > available: count = available - randomIndex = helper_random.randomsample( - range(self.len - self.pendingLen), count) + randomIndex = helper_random.randomsample(range(self.len - self.pendingLen), count) retval = [self.indexDict[i] for i in randomIndex] for i in sorted(randomIndex, reverse=True): diff --git a/src/semaphores.py b/src/semaphores.py deleted file mode 100644 index 04120fe7..00000000 --- a/src/semaphores.py +++ /dev/null @@ -1,3 +0,0 @@ -from threading import Semaphore - -kivyuisignaler = Semaphore(0) \ No newline at end of file diff --git a/src/shared.py b/src/shared.py index cabc0f40..6d03bcca 100644 --- a/src/shared.py +++ b/src/shared.py @@ -1,33 +1,23 @@ -""" -Some shared functions - -.. deprecated:: 0.6.3 - Should be moved to different places and this file removed, - but it needs refactoring. -""" -from __future__ import division +from __future__ import division # Libraries. -import hashlib import os -import stat -import subprocess import sys +import stat import threading +import hashlib +import subprocess from binascii import hexlify from pyelliptic import arithmetic -from kivy.utils import platform # Project imports. -import highlevelcrypto import state -from addresses import decodeAddress, encodeVarint +import highlevelcrypto from bmconfigparser import BMConfigParser from debug import logger +from addresses import decodeAddress, encodeVarint from helper_sql import sqlQuery -from pyelliptic import arithmetic - verbose = 1 # This is obsolete with the change to protocol v3 @@ -66,7 +56,6 @@ maximumLengthOfTimeToBotherResendingMessages = 0 def isAddressInMyAddressBook(address): - """Is address in my addressbook?""" queryreturn = sqlQuery( '''select address from addressbook where address=?''', address) @@ -75,7 +64,6 @@ def isAddressInMyAddressBook(address): # At this point we should really just have a isAddressInMy(book, address)... def isAddressInMySubscriptionsList(address): - """Am I subscribed to this address?""" queryreturn = sqlQuery( '''select * from subscriptions where address=?''', str(address)) @@ -83,9 +71,6 @@ def isAddressInMySubscriptionsList(address): def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): - """ - Am I subscribed to this address, is it in my addressbook or whitelist? - """ if isAddressInMyAddressBook(address): return True @@ -106,11 +91,6 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): def decodeWalletImportFormat(WIFstring): - # pylint: disable=inconsistent-return-statements - """ - Convert private key from base58 that's used in the config file to - 8-bit binary string - """ fullString = arithmetic.changebase(WIFstring, 58, 256) privkey = fullString[:-4] if fullString[-4:] != \ @@ -121,7 +101,7 @@ def decodeWalletImportFormat(WIFstring): ' 6 characters of the PRIVATE key: %s', str(WIFstring)[:6] ) - os._exit(0) # pylint: disable=protected-access + os._exit(0) # return "" elif privkey[0] == '\x80': # checksum passed return privkey[1:] @@ -131,57 +111,54 @@ def decodeWalletImportFormat(WIFstring): ' the checksum passed but the key doesn\'t begin with hex 80.' ' Here is the PRIVATE key: %s', WIFstring ) - os._exit(0) # pylint: disable=protected-access + os._exit(0) def reloadMyAddressHashes(): - """Reload keys for user's addresses from the config file""" logger.debug('reloading keys from keys.dat file') - myECCryptorObjects.clear() myAddressesByHash.clear() myAddressesByTag.clear() # myPrivateKeys.clear() - keyfileSecure = checkSensitiveFilePermissions(os.path.join( - state.appdata, 'keys.dat')) + keyfileSecure = checkSensitiveFilePermissions(state.appdata + 'keys.dat') hasEnabledKeys = False for addressInKeysFile in BMConfigParser().addresses(): isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled') if isEnabled: hasEnabledKeys = True # status - addressVersionNumber, streamNumber, hashobj = decodeAddress(addressInKeysFile)[1:] + _, addressVersionNumber, streamNumber, hash = \ + decodeAddress(addressInKeysFile) if addressVersionNumber in (2, 3, 4): # Returns a simple 32 bytes of information encoded # in 64 Hex characters, or null if there was an error. privEncryptionKey = hexlify(decodeWalletImportFormat( - BMConfigParser().get(addressInKeysFile, 'privencryptionkey'))) + BMConfigParser().get(addressInKeysFile, 'privencryptionkey')) + ) + # It is 32 bytes encoded as 64 hex characters if len(privEncryptionKey) == 64: - myECCryptorObjects[hashobj] = \ + myECCryptorObjects[hash] = \ highlevelcrypto.makeCryptor(privEncryptionKey) - myAddressesByHash[hashobj] = addressInKeysFile + myAddressesByHash[hash] = addressInKeysFile tag = hashlib.sha512(hashlib.sha512( encodeVarint(addressVersionNumber) + - encodeVarint(streamNumber) + hashobj).digest()).digest()[32:] + encodeVarint(streamNumber) + hash).digest() + ).digest()[32:] myAddressesByTag[tag] = addressInKeysFile + else: logger.error( 'Error in reloadMyAddressHashes: Can\'t handle' ' address versions other than 2, 3, or 4.\n' ) - if not platform == "android": - if not keyfileSecure: - fixSensitiveFilePermissions(state.appdata + 'keys.dat', hasEnabledKeys) + if not keyfileSecure: + fixSensitiveFilePermissions(state.appdata + 'keys.dat', hasEnabledKeys) def reloadBroadcastSendersForWhichImWatching(): - """ - Reinitialize runtime data for the broadcasts I'm subscribed to - from the config file - """ broadcastSendersForWhichImWatching.clear() MyECSubscriptionCryptorObjects.clear() queryreturn = sqlQuery('SELECT address FROM subscriptions where enabled=1') @@ -189,9 +166,9 @@ def reloadBroadcastSendersForWhichImWatching(): for row in queryreturn: address, = row # status - addressVersionNumber, streamNumber, hashobj = decodeAddress(address)[1:] + _, addressVersionNumber, streamNumber, hash = decodeAddress(address) if addressVersionNumber == 2: - broadcastSendersForWhichImWatching[hashobj] = 0 + broadcastSendersForWhichImWatching[hash] = 0 # Now, for all addresses, even version 2 addresses, # we should create Cryptor objects in a dictionary which we will # use to attempt to decrypt encrypted broadcast messages. @@ -199,14 +176,14 @@ def reloadBroadcastSendersForWhichImWatching(): if addressVersionNumber <= 3: privEncryptionKey = hashlib.sha512( encodeVarint(addressVersionNumber) + - encodeVarint(streamNumber) + hashobj + encodeVarint(streamNumber) + hash ).digest()[:32] - MyECSubscriptionCryptorObjects[hashobj] = \ + MyECSubscriptionCryptorObjects[hash] = \ highlevelcrypto.makeCryptor(hexlify(privEncryptionKey)) else: doubleHashOfAddressData = hashlib.sha512(hashlib.sha512( encodeVarint(addressVersionNumber) + - encodeVarint(streamNumber) + hashobj + encodeVarint(streamNumber) + hash ).digest()).digest() tag = doubleHashOfAddressData[32:] privEncryptionKey = doubleHashOfAddressData[:32] @@ -215,22 +192,21 @@ def reloadBroadcastSendersForWhichImWatching(): def fixPotentiallyInvalidUTF8Data(text): - """Sanitise invalid UTF-8 strings""" try: unicode(text, 'utf-8') return text except: return 'Part of the message is corrupt. The message cannot be' \ - ' displayed the normal way.\n\n' + repr(text) + ' displayed the normal way.\n\n' + repr(text) +# Checks sensitive file permissions for inappropriate umask +# during keys.dat creation. (Or unwise subsequent chmod.) +# +# Returns true iff file appears to have appropriate permissions. def checkSensitiveFilePermissions(filename): - """ - :param str filename: path to the file - :return: True if file appears to have appropriate permissions. - """ if sys.platform == 'win32': - # .. todo:: This might deserve extra checks by someone familiar with + # TODO: This might deserve extra checks by someone familiar with # Windows systems. return True elif sys.platform[:7] == 'freebsd': @@ -238,30 +214,30 @@ def checkSensitiveFilePermissions(filename): present_permissions = os.stat(filename)[0] disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO return present_permissions & disallowed_permissions == 0 - try: - # Skip known problems for non-Win32 filesystems - # without POSIX permissions. - fstype = subprocess.check_output( - 'stat -f -c "%%T" %s' % (filename), - shell=True, - stderr=subprocess.STDOUT - ) - if 'fuseblk' in fstype: - logger.info( - 'Skipping file permissions check for %s.' - ' Filesystem fuseblk detected.', filename) - return True - except: - # Swallow exception here, but we might run into trouble later! - logger.error('Could not determine filesystem type. %s', filename) - present_permissions = os.stat(filename)[0] - disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO - return present_permissions & disallowed_permissions == 0 + else: + try: + # Skip known problems for non-Win32 filesystems + # without POSIX permissions. + fstype = subprocess.check_output( + 'stat -f -c "%%T" %s' % (filename), + shell=True, + stderr=subprocess.STDOUT + ) + if 'fuseblk' in fstype: + logger.info( + 'Skipping file permissions check for %s.' + ' Filesystem fuseblk detected.', filename) + return True + except: + # Swallow exception here, but we might run into trouble later! + logger.error('Could not determine filesystem type. %s', filename) + present_permissions = os.stat(filename)[0] + disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO + return present_permissions & disallowed_permissions == 0 # Fixes permissions on a sensitive file. def fixSensitiveFilePermissions(filename, hasEnabledKeys): - """Try to change file permissions to be more restrictive""" if hasEnabledKeys: logger.warning( 'Keyfile had insecure permissions, and there were enabled' @@ -286,7 +262,6 @@ def fixSensitiveFilePermissions(filename, hasEnabledKeys): def openKeysFile(): - """Open keys file with an external editor""" if 'linux' in sys.platform: subprocess.call(["xdg-open", state.appdata + 'keys.dat']) else: diff --git a/src/shutdown.py b/src/shutdown.py index dbc2af04..f136ac75 100644 --- a/src/shutdown.py +++ b/src/shutdown.py @@ -1,24 +1,22 @@ -"""shutdown function""" import os import Queue import threading import time -import shared -import state from debug import logger from helper_sql import sqlQuery, sqlStoredProcedure -from inventory import Inventory +from helper_threading import StoppableThread from knownnodes import saveKnownNodes -from network import StoppableThread +from inventory import Inventory from queues import ( addressGeneratorQueue, objectProcessorQueue, UISignalQueue, workerQueue) +import shared +import state def doCleanShutdown(): - """ - Used to tell all the treads to finish work and exit. - """ + # Used to tell proof of work worker threads + # and the objectProcessorThread to exit. state.shutdown = 1 objectProcessorQueue.put(('checkShutdownVariable', 'no data')) @@ -54,11 +52,9 @@ def doCleanShutdown(): time.sleep(.25) for thread in threading.enumerate(): - if ( - thread is not threading.currentThread() - and isinstance(thread, StoppableThread) - and thread.name != 'SQL' - ): + if (thread is not threading.currentThread() and + isinstance(thread, StoppableThread) and + thread.name != 'SQL'): logger.debug("Waiting for thread %s", thread.name) thread.join() @@ -80,10 +76,10 @@ def doCleanShutdown(): except Queue.Empty: break - if shared.thisapp.daemon or not state.enableGUI: # ..fixme:: redundant? + if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant? logger.info('Clean shutdown complete.') shared.thisapp.cleanup() - os._exit(0) # pylint: disable=protected-access + os._exit(0) else: logger.info('Core shutdown complete.') for thread in threading.enumerate(): diff --git a/src/singleinstance.py b/src/singleinstance.py index b061cbff..c2def912 100644 --- a/src/singleinstance.py +++ b/src/singleinstance.py @@ -1,13 +1,8 @@ -""" -This is based upon the singleton class from -`tendo `_ -which is under the Python Software Foundation License version 2 -""" +#! /usr/bin/env python import atexit import os import sys - import state try: @@ -16,10 +11,14 @@ except ImportError: pass -class singleinstance(object): +class singleinstance: """ Implements a single instance application by creating a lock file at appdata. + + This is based upon the singleton class from tendo + https://github.com/pycontribs/tendo + which is under the Python Software Foundation License version 2 """ def __init__(self, flavor_id="", daemon=False): self.initialized = False @@ -29,7 +28,7 @@ class singleinstance(object): self.lockfile = os.path.normpath( os.path.join(state.appdata, 'singleton%s.lock' % flavor_id)) - if state.enableGUI and not state.kivy and not self.daemon and not state.curses: + if state.enableGUI and not self.daemon and not state.curses: # Tells the already running (if any) application to get focus. import bitmessageqt bitmessageqt.init() @@ -40,7 +39,6 @@ class singleinstance(object): atexit.register(self.cleanup) def lock(self): - """Obtain single instance lock""" if self.lockPid is None: self.lockPid = os.getpid() if sys.platform == 'win32': @@ -53,7 +51,8 @@ class singleinstance(object): self.lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR | os.O_TRUNC ) - except OSError as e: + except OSError: + type, e, tb = sys.exc_info() if e.errno == 13: print( 'Another instance of this application' @@ -84,7 +83,6 @@ class singleinstance(object): self.fp.flush() def cleanup(self): - """Release single instance lock""" if not self.initialized: return if self.daemon and self.lockPid == os.getpid(): @@ -95,7 +93,7 @@ class singleinstance(object): os.close(self.fd) else: fcntl.lockf(self.fp, fcntl.LOCK_UN) - except Exception: + except Exception, e: pass return diff --git a/src/singleton.py b/src/singleton.py index 5c6c43be..1eef08e1 100644 --- a/src/singleton.py +++ b/src/singleton.py @@ -1,21 +1,6 @@ -""" -Singleton decorator definition -""" - -from functools import wraps - - def Singleton(cls): - """ - Decorator implementing the singleton pattern: - it restricts the instantiation of a class to one "single" instance. - """ instances = {} - - # https://github.com/sphinx-doc/sphinx/issues/3783 - @wraps(cls) def getinstance(): - """Find an instance or save newly created one""" if cls not in instances: instances[cls] = cls() return instances[cls] diff --git a/src/socks/BUGS b/src/socks/BUGS new file mode 100644 index 00000000..fa8ccfad --- /dev/null +++ b/src/socks/BUGS @@ -0,0 +1,25 @@ +SocksiPy version 1.00 +A Python SOCKS module. +(C) 2006 Dan-Haim. All rights reserved. +See LICENSE file for details. + + +KNOWN BUGS AND ISSUES +---------------------- + +There are no currently known bugs in this module. +There are some limits though: + +1) Only outgoing connections are supported - This module currently only supports +outgoing TCP connections, though some servers may support incoming connections +as well. UDP is not supported either. + +2) GSSAPI Socks5 authenticaion is not supported. + + +If you find any new bugs, please contact the author at: + +negativeiq@users.sourceforge.net + + +Thank you! diff --git a/src/socks/LICENSE b/src/socks/LICENSE new file mode 100644 index 00000000..04b6b1f3 --- /dev/null +++ b/src/socks/LICENSE @@ -0,0 +1,22 @@ +Copyright 2006 Dan-Haim. 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. +3. Neither the name of Dan Haim nor the names of his contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY DAN HAIM "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 DAN HAIM OR HIS 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, 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 DAMANGE. diff --git a/src/socks/README b/src/socks/README new file mode 100644 index 00000000..a52f55f3 --- /dev/null +++ b/src/socks/README @@ -0,0 +1,201 @@ +SocksiPy version 1.00 +A Python SOCKS module. +(C) 2006 Dan-Haim. All rights reserved. +See LICENSE file for details. + + +WHAT IS A SOCKS PROXY? +A SOCKS proxy is a proxy server at the TCP level. In other words, it acts as +a tunnel, relaying all traffic going through it without modifying it. +SOCKS proxies can be used to relay traffic using any network protocol that +uses TCP. + +WHAT IS SOCKSIPY? +This Python module allows you to create TCP connections through a SOCKS +proxy without any special effort. + +PROXY COMPATIBILITY +SocksiPy is compatible with three different types of proxies: +1. SOCKS Version 4 (Socks4), including the Socks4a extension. +2. SOCKS Version 5 (Socks5). +3. HTTP Proxies which support tunneling using the CONNECT method. + +SYSTEM REQUIREMENTS +Being written in Python, SocksiPy can run on any platform that has a Python +interpreter and TCP/IP support. +This module has been tested with Python 2.3 and should work with greater versions +just as well. + + +INSTALLATION +------------- + +Simply copy the file "socks.py" to your Python's lib/site-packages directory, +and you're ready to go. + + +USAGE +------ + +First load the socks module with the command: + +>>> import socks +>>> + +The socks module provides a class called "socksocket", which is the base to +all of the module's functionality. +The socksocket object has the same initialization parameters as the normal socket +object to ensure maximal compatibility, however it should be noted that socksocket +will only function with family being AF_INET and type being SOCK_STREAM. +Generally, it is best to initialize the socksocket object with no parameters + +>>> s = socks.socksocket() +>>> + +The socksocket object has an interface which is very similiar to socket's (in fact +the socksocket class is derived from socket) with a few extra methods. +To select the proxy server you would like to use, use the setproxy method, whose +syntax is: + +setproxy(proxytype, addr[, port[, rdns[, username[, password]]]]) + +Explaination of the parameters: + +proxytype - The type of the proxy server. This can be one of three possible +choices: PROXY_TYPE_SOCKS4, PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP for Socks4, +Socks5 and HTTP servers respectively. + +addr - The IP address or DNS name of the proxy server. + +port - The port of the proxy server. Defaults to 1080 for socks and 8080 for http. + +rdns - This is a boolean flag than modifies the behavior regarding DNS resolving. +If it is set to True, DNS resolving will be preformed remotely, on the server. +If it is set to False, DNS resolving will be preformed locally. Please note that +setting this to True with Socks4 servers actually use an extension to the protocol, +called Socks4a, which may not be supported on all servers (Socks5 and http servers +always support DNS). The default is True. + +username - For Socks5 servers, this allows simple username / password authentication +with the server. For Socks4 servers, this parameter will be sent as the userid. +This parameter is ignored if an HTTP server is being used. If it is not provided, +authentication will not be used (servers may accept unauthentication requests). + +password - This parameter is valid only for Socks5 servers and specifies the +respective password for the username provided. + +Example of usage: + +>>> s.setproxy(socks.PROXY_TYPE_SOCKS5,"socks.example.com") +>>> + +After the setproxy method has been called, simply call the connect method with the +traditional parameters to establish a connection through the proxy: + +>>> s.connect(("www.sourceforge.net",80)) +>>> + +Connection will take a bit longer to allow negotiation with the proxy server. +Please note that calling connect without calling setproxy earlier will connect +without a proxy (just like a regular socket). + +Errors: Any errors in the connection process will trigger exceptions. The exception +may either be generated by the underlying socket layer or may be custom module +exceptions, whose details follow: + +class ProxyError - This is a base exception class. It is not raised directly but +rather all other exception classes raised by this module are derived from it. +This allows an easy way to catch all proxy-related errors. + +class GeneralProxyError - When thrown, it indicates a problem which does not fall +into another category. The parameter is a tuple containing an error code and a +description of the error, from the following list: +1 - invalid data - This error means that unexpected data has been received from +the server. The most common reason is that the server specified as the proxy is +not really a Socks4/Socks5/HTTP proxy, or maybe the proxy type specified is wrong. +4 - bad proxy type - This will be raised if the type of the proxy supplied to the +setproxy function was not PROXY_TYPE_SOCKS4/PROXY_TYPE_SOCKS5/PROXY_TYPE_HTTP. +5 - bad input - This will be raised if the connect method is called with bad input +parameters. + +class Socks5AuthError - This indicates that the connection through a Socks5 server +failed due to an authentication problem. The parameter is a tuple containing a +code and a description message according to the following list: + +1 - authentication is required - This will happen if you use a Socks5 server which +requires authentication without providing a username / password at all. +2 - all offered authentication methods were rejected - This will happen if the proxy +requires a special authentication method which is not supported by this module. +3 - unknown username or invalid password - Self descriptive. + +class Socks5Error - This will be raised for Socks5 errors which are not related to +authentication. The parameter is a tuple containing a code and a description of the +error, as given by the server. The possible errors, according to the RFC are: + +1 - General SOCKS server failure - If for any reason the proxy server is unable to +fulfill your request (internal server error). +2 - connection not allowed by ruleset - If the address you're trying to connect to +is blacklisted on the server or requires authentication. +3 - Network unreachable - The target could not be contacted. A router on the network +had replied with a destination net unreachable error. +4 - Host unreachable - The target could not be contacted. A router on the network +had replied with a destination host unreachable error. +5 - Connection refused - The target server has actively refused the connection +(the requested port is closed). +6 - TTL expired - The TTL value of the SYN packet from the proxy to the target server +has expired. This usually means that there are network problems causing the packet +to be caught in a router-to-router "ping-pong". +7 - Command not supported - The client has issued an invalid command. When using this +module, this error should not occur. +8 - Address type not supported - The client has provided an invalid address type. +When using this module, this error should not occur. + +class Socks4Error - This will be raised for Socks4 errors. The parameter is a tuple +containing a code and a description of the error, as given by the server. The +possible error, according to the specification are: + +1 - Request rejected or failed - Will be raised in the event of an failure for any +reason other then the two mentioned next. +2 - request rejected because SOCKS server cannot connect to identd on the client - +The Socks server had tried an ident lookup on your computer and has failed. In this +case you should run an identd server and/or configure your firewall to allow incoming +connections to local port 113 from the remote server. +3 - request rejected because the client program and identd report different user-ids - +The Socks server had performed an ident lookup on your computer and has received a +different userid than the one you have provided. Change your userid (through the +username parameter of the setproxy method) to match and try again. + +class HTTPError - This will be raised for HTTP errors. The parameter is a tuple +containing the HTTP status code and the description of the server. + + +After establishing the connection, the object behaves like a standard socket. +Call the close method to close the connection. + +In addition to the socksocket class, an additional function worth mentioning is the +setdefaultproxy function. The parameters are the same as the setproxy method. +This function will set default proxy settings for newly created socksocket objects, +in which the proxy settings haven't been changed via the setproxy method. +This is quite useful if you wish to force 3rd party modules to use a socks proxy, +by overriding the socket object. +For example: + +>>> socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5,"socks.example.com") +>>> socket.socket = socks.socksocket +>>> urllib.urlopen("http://www.sourceforge.net/") + + +PROBLEMS +--------- + +If you have any problems using this module, please first refer to the BUGS file +(containing current bugs and issues). If your problem is not mentioned you may +contact the author at the following E-Mail address: + +negativeiq@users.sourceforge.net + +Please allow some time for your question to be received and handled. + + +Dan-Haim, +Author. diff --git a/src/socks/__init__.py b/src/socks/__init__.py new file mode 100644 index 00000000..7fd2cba3 --- /dev/null +++ b/src/socks/__init__.py @@ -0,0 +1,476 @@ +"""SocksiPy - Python SOCKS module. +Version 1.00 + +Copyright 2006 Dan-Haim. 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. + 3. Neither the name of Dan Haim nor the names of his contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY DAN HAIM "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 DAN HAIM OR HIS 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, 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 DAMANGE. + + +This module provides a standard socket-like interface for Python +for tunneling connections through SOCKS proxies. + +""" + +""" + +Minor modifications made by Christopher Gilbert (http://motomastyle.com/) +for use in PyLoris (http://pyloris.sourceforge.net/) + +Minor modifications made by Mario Vilas (http://breakingcode.wordpress.com/) +mainly to merge bug fixes found in Sourceforge + +""" + +import socket +import struct +import sys + +PROXY_TYPE_SOCKS4 = 1 +PROXY_TYPE_SOCKS5 = 2 +PROXY_TYPE_HTTP = 3 + +_defaultproxy = None +_orgsocket = socket.socket + +class ProxyError(Exception): pass +class GeneralProxyError(ProxyError): pass +class Socks5AuthError(ProxyError): pass +class Socks5Error(ProxyError): pass +class Socks4Error(ProxyError): pass +class HTTPError(ProxyError): pass + +_generalerrors = ("success", + "invalid data", + "not connected", + "not available", + "bad proxy type", + "bad input", + "timed out", + "network unreachable", + "connection refused", + "host unreachable") + +_socks5errors = ("succeeded", + "general SOCKS server failure", + "connection not allowed by ruleset", + "Network unreachable", + "Host unreachable", + "Connection refused", + "TTL expired", + "Command not supported", + "Address type not supported", + "Unknown error") + +_socks5autherrors = ("succeeded", + "authentication is required", + "all offered authentication methods were rejected", + "unknown username or invalid password", + "unknown error") + +_socks4errors = ("request granted", + "request rejected or failed", + "request rejected because SOCKS server cannot connect to identd on the client", + "request rejected because the client program and identd report different user-ids", + "unknown error") + +def setdefaultproxy(proxytype=None, addr=None, port=None, rdns=True, username=None, password=None): + """setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]]) + Sets a default proxy which all further socksocket objects will use, + unless explicitly changed. + """ + global _defaultproxy + _defaultproxy = (proxytype, addr, port, rdns, username, password) + +def wrapmodule(module): + """wrapmodule(module) + Attempts to replace a module's socket library with a SOCKS socket. Must set + a default proxy using setdefaultproxy(...) first. + This will only work on modules that import socket directly into the namespace; + most of the Python Standard Library falls into this category. + """ + if _defaultproxy != None: + module.socket.socket = socksocket + else: + raise GeneralProxyError((4, "no proxy specified")) + +class socksocket(socket.socket): + """socksocket([family[, type[, proto]]]) -> socket object + Open a SOCKS enabled socket. The parameters are the same as + those of the standard socket init. In order for SOCKS to work, + you must specify family=AF_INET, type=SOCK_STREAM and proto=0. + """ + + def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None): + _orgsocket.__init__(self, family, type, proto, _sock) + if _defaultproxy != None: + self.__proxy = _defaultproxy + else: + self.__proxy = (None, None, None, None, None, None) + self.__proxysockname = None + self.__proxypeername = None + + def __recvall(self, count): + """__recvall(count) -> data + Receive EXACTLY the number of bytes requested from the socket. + Blocks until the required number of bytes have been received. + """ + try: + data = self.recv(count) + except socket.timeout: + raise GeneralProxyError((6, "timed out")) + while len(data) < count: + d = self.recv(count-len(data)) + if not d: raise GeneralProxyError((0, "connection closed unexpectedly")) + data = data + d + return data + + def setproxy(self, proxytype=None, addr=None, port=None, rdns=True, username=None, password=None): + """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]]) + Sets the proxy to be used. + + proxytype + The type of the proxy to be used. Three types + are supported: PROXY_TYPE_SOCKS4 (including socks4a), + PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP + + addr + The address of the server (IP or DNS). + + port + The port of the server. Defaults to 1080 for SOCKS + servers and 8080 for HTTP proxy servers. + + rdns + Should DNS queries be preformed on the remote side + (rather than the local side). The default is True. + Note: This has no effect with SOCKS4 servers. + + username + Username to authenticate with to the server. + The default is no authentication. + + password + Password to authenticate with to the server. + Only relevant when username is also provided. + + """ + self.__proxy = (proxytype, addr, port, rdns, username, password) + + def __negotiatesocks5(self): + """__negotiatesocks5(self,destaddr,destport) + Negotiates a connection through a SOCKS5 server. + """ + # First we'll send the authentication packages we support. + if (self.__proxy[4]!=None) and (self.__proxy[5]!=None): + # The username/password details were supplied to the + # setproxy method so we support the USERNAME/PASSWORD + # authentication (in addition to the standard none). + self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02)) + else: + # No username/password were entered, therefore we + # only support connections with no authentication. + self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00)) + # We'll receive the server's response to determine which + # method was selected + chosenauth = self.__recvall(2) + if chosenauth[0:1] != chr(0x05).encode(): + self.close() + raise GeneralProxyError((1, _generalerrors[1])) + # Check the chosen authentication method + if chosenauth[1:2] == chr(0x00).encode(): + # No authentication is required + pass + elif chosenauth[1:2] == chr(0x02).encode(): + # Okay, we need to perform a basic username/password + # authentication. + self.sendall(chr(0x01).encode() + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5]) + authstat = self.__recvall(2) + if authstat[0:1] != chr(0x01).encode(): + # Bad response + self.close() + raise GeneralProxyError((1, _generalerrors[1])) + if authstat[1:2] != chr(0x00).encode(): + # Authentication failed + self.close() + raise Socks5AuthError((3, _socks5autherrors[3])) + # Authentication succeeded + else: + # Reaching here is always bad + self.close() + if chosenauth[1] == chr(0xFF).encode(): + raise Socks5AuthError((2, _socks5autherrors[2])) + else: + raise GeneralProxyError((1, _generalerrors[1])) + + def __connectsocks5(self, destaddr, destport): + # Now we can request the actual connection + req = struct.pack('BBB', 0x05, 0x01, 0x00) + # If the given destination address is an IP address, we'll + # use the IPv4 address request even if remote resolving was specified. + try: + ipaddr = socket.inet_aton(destaddr) + req = req + chr(0x01).encode() + ipaddr + except socket.error: + # Well it's not an IP number, so it's probably a DNS name. + if self.__proxy[3]: + # Resolve remotely + ipaddr = None + req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + destaddr + else: + # Resolve locally + ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) + req = req + chr(0x01).encode() + ipaddr + req = req + struct.pack(">H", destport) + self.sendall(req) + # Get the response + resp = self.__recvall(4) + if resp[0:1] != chr(0x05).encode(): + self.close() + raise GeneralProxyError((1, _generalerrors[1])) + elif resp[1:2] != chr(0x00).encode(): + # Connection failed + self.close() + if ord(resp[1:2])<=8: + raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])])) + else: + raise Socks5Error((9, _socks5errors[9])) + # Get the bound address/port + elif resp[3:4] == chr(0x01).encode(): + boundaddr = self.__recvall(4) + elif resp[3:4] == chr(0x03).encode(): + resp = resp + self.recv(1) + boundaddr = self.__recvall(ord(resp[4:5])) + else: + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + boundport = struct.unpack(">H", self.__recvall(2))[0] + self.__proxysockname = (boundaddr, boundport) + if ipaddr != None: + self.__proxypeername = (socket.inet_ntoa(ipaddr), destport) + else: + self.__proxypeername = (destaddr, destport) + + def __resolvesocks5(self, host): + # Now we can request the actual connection + req = struct.pack('BBB', 0x05, 0xF0, 0x00) + req += chr(0x03).encode() + chr(len(host)).encode() + host + req = req + struct.pack(">H", 8444) + self.sendall(req) + # Get the response + ip = "" + resp = self.__recvall(4) + if resp[0:1] != chr(0x05).encode(): + self.close() + raise GeneralProxyError((1, _generalerrors[1])) + elif resp[1:2] != chr(0x00).encode(): + # Connection failed + self.close() + if ord(resp[1:2])<=8: + raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])])) + else: + raise Socks5Error((9, _socks5errors[9])) + # Get the bound address/port + elif resp[3:4] == chr(0x01).encode(): + ip = socket.inet_ntoa(self.__recvall(4)) + elif resp[3:4] == chr(0x03).encode(): + resp = resp + self.recv(1) + ip = self.__recvall(ord(resp[4:5])) + else: + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + boundport = struct.unpack(">H", self.__recvall(2))[0] + return ip + + def getproxysockname(self): + """getsockname() -> address info + Returns the bound IP address and port number at the proxy. + """ + return self.__proxysockname + + def getproxypeername(self): + """getproxypeername() -> address info + Returns the IP and port number of the proxy. + """ + return _orgsocket.getpeername(self) + + def getpeername(self): + """getpeername() -> address info + Returns the IP address and port number of the destination + machine (note: getproxypeername returns the proxy) + """ + return self.__proxypeername + + def getproxytype(self): + return self.__proxy[0] + + def __negotiatesocks4(self,destaddr,destport): + """__negotiatesocks4(self,destaddr,destport) + Negotiates a connection through a SOCKS4 server. + """ + # Check if the destination address provided is an IP address + rmtrslv = False + try: + ipaddr = socket.inet_aton(destaddr) + except socket.error: + # It's a DNS name. Check where it should be resolved. + if self.__proxy[3]: + ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01) + rmtrslv = True + else: + ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) + # Construct the request packet + req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr + # The username parameter is considered userid for SOCKS4 + if self.__proxy[4] != None: + req = req + self.__proxy[4] + req = req + chr(0x00).encode() + # DNS name if remote resolving is required + # NOTE: This is actually an extension to the SOCKS4 protocol + # called SOCKS4A and may not be supported in all cases. + if rmtrslv: + req = req + destaddr + chr(0x00).encode() + self.sendall(req) + # Get the response from the server + resp = self.__recvall(8) + if resp[0:1] != chr(0x00).encode(): + # Bad data + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + if resp[1:2] != chr(0x5A).encode(): + # Server returned an error + self.close() + if ord(resp[1:2]) in (91, 92, 93): + self.close() + raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90])) + else: + raise Socks4Error((94, _socks4errors[4])) + # Get the bound address/port + self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0]) + if rmtrslv != None: + self.__proxypeername = (socket.inet_ntoa(ipaddr), destport) + else: + self.__proxypeername = (destaddr, destport) + + def __negotiatehttp(self, destaddr, destport): + """__negotiatehttp(self,destaddr,destport) + Negotiates a connection through an HTTP server. + """ + # If we need to resolve locally, we do this now + if not self.__proxy[3]: + addr = socket.gethostbyname(destaddr) + else: + addr = destaddr + self.sendall(("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode()) + # We read the response until we get the string "\r\n\r\n" + resp = self.recv(1) + while resp.find("\r\n\r\n".encode()) == -1: + resp = resp + self.recv(1) + # We just need the first line to check if the connection + # was successful + statusline = resp.splitlines()[0].split(" ".encode(), 2) + if statusline[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()): + self.close() + raise GeneralProxyError((1, _generalerrors[1])) + try: + statuscode = int(statusline[1]) + except ValueError: + self.close() + raise GeneralProxyError((1, _generalerrors[1])) + if statuscode != 200: + self.close() + raise HTTPError((statuscode, statusline[2])) + self.__proxysockname = ("0.0.0.0", 0) + self.__proxypeername = (addr, destport) + + def connect(self, destpair): + """connect(self, despair) + Connects to the specified destination through a proxy. + destpar - A tuple of the IP/DNS address and the port number. + (identical to socket's connect). + To select the proxy server use setproxy(). + """ + # Do a minimal input check first + if (not type(destpair) in (list,tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or (type(destpair[1]) != int): + raise GeneralProxyError((5, _generalerrors[5])) + if self.__proxy[0] == PROXY_TYPE_SOCKS5: + if self.__proxy[2] != None: + portnum = self.__proxy[2] + else: + portnum = 1080 + try: + _orgsocket.connect(self, (self.__proxy[1], portnum)) + except socket.error as e: + # ENETUNREACH, WSAENETUNREACH + if e[0] in [101, 10051]: + raise GeneralProxyError((7, _generalerrors[7])) + # ECONNREFUSED, WSAECONNREFUSED + if e[0] in [111, 10061]: + raise GeneralProxyError((8, _generalerrors[8])) + # EHOSTUNREACH, WSAEHOSTUNREACH + if e[0] in [113, 10065]: + raise GeneralProxyError((9, _generalerrors[9])) + raise + self.__negotiatesocks5() + self.__connectsocks5(destpair[0], destpair[1]) + elif self.__proxy[0] == PROXY_TYPE_SOCKS4: + if self.__proxy[2] != None: + portnum = self.__proxy[2] + else: + portnum = 1080 + _orgsocket.connect(self,(self.__proxy[1], portnum)) + self.__negotiatesocks4(destpair[0], destpair[1]) + elif self.__proxy[0] == PROXY_TYPE_HTTP: + if self.__proxy[2] != None: + portnum = self.__proxy[2] + else: + portnum = 8080 + try: + _orgsocket.connect(self,(self.__proxy[1], portnum)) + except socket.error as e: + # ENETUNREACH, WSAENETUNREACH + if e[0] in [101, 10051]: + raise GeneralProxyError((7, _generalerrors[7])) + # ECONNREFUSED, WSAECONNREFUSED + if e[0] in [111, 10061]: + raise GeneralProxyError((8, _generalerrors[8])) + # EHOSTUNREACH, WSAEHOSTUNREACH + if e[0] in [113, 10065]: + raise GeneralProxyError((9, _generalerrors[9])) + raise + self.__negotiatehttp(destpair[0], destpair[1]) + elif self.__proxy[0] == None: + _orgsocket.connect(self, (destpair[0], destpair[1])) + else: + raise GeneralProxyError((4, _generalerrors[4])) + + def resolve(self, host): + if self.__proxy[0] == PROXY_TYPE_SOCKS5: + if self.__proxy[2] != None: + portnum = self.__proxy[2] + else: + portnum = 1080 + _orgsocket.connect(self, (self.__proxy[1], portnum)) + self.__negotiatesocks5() + return self.__resolvesocks5(host) + else: + return None diff --git a/src/state.py b/src/state.py index 16bc016e..2cbc3a7c 100644 --- a/src/state.py +++ b/src/state.py @@ -1,49 +1,43 @@ -""" -Global runtime variables. -""" import collections neededPubkeys = {} streamsInWhichIAmParticipating = [] +# For UPnP extPort = None -"""For UPnP""" +# for Tor hidden service socksIP = None -"""for Tor hidden service""" -appdata = '' -"""holds the location of the application data storage directory""" +# Network protocols availability, initialised below +networkProtocolAvailability = None +appdata = '' # holds the location of the application data storage directory + +# Set to 1 by the doCleanShutdown function. +# Used to tell the proof of work worker threads to exit. shutdown = 0 -""" -Set to 1 by the `.shutdown.doCleanShutdown` function. -Used to tell the threads to exit. -""" # Component control flags - set on startup, do not change during runtime # The defaults are for standalone GUI (default operating mode) -enableNetwork = True -"""enable network threads""" -enableObjProc = True -"""enable object processing thread""" -enableAPI = True -"""enable API (if configured)""" -enableGUI = True -"""enable GUI (QT or ncurses)""" -enableSTDIO = False -"""enable STDIO threads""" +enableNetwork = True # enable network threads +enableObjProc = True # enable object processing threads +enableAPI = True # enable API (if configured) +enableGUI = True # enable GUI (QT or ncurses) +enableSTDIO = False # enable STDIO threads curses = False -sqlReady = False -"""set to true by `.threads.sqlThread` when ready for processing""" +sqlReady = False # set to true by sqlTread when ready for processing maximumNumberOfHalfOpenConnections = 0 + invThread = None addrThread = None downloadThread = None uploadThread = None + ownAddresses = {} + # If the trustedpeer option is specified in keys.dat then this will # contain a Peer which will be connected to instead of using the # addresses advertised by other peers. The client will only connect to @@ -55,21 +49,19 @@ ownAddresses = {} # it will sync with the network a lot faster without compromising # security. trustedPeer = None + discoveredPeers = {} + Peer = collections.namedtuple('Peer', ['host', 'port']) def resetNetworkProtocolAvailability(): - """This method helps to reset the availability of network protocol""" - # pylint: disable=global-statement global networkProtocolAvailability networkProtocolAvailability = {'IPv4': None, 'IPv6': None, 'onion': None} resetNetworkProtocolAvailability() -discoveredPeers = {} - dandelion = 0 testmode = False @@ -77,49 +69,3 @@ testmode = False kivy = False association = '' - -kivyapp = None - -navinstance = None - -mail_id = 0 - -myAddressObj = None - -detailPageType = None - -ackdata = None - -status = None - -screen_density = None - -msg_counter_objs = None - -check_sent_acc = None - -sent_count = 0 - -inbox_count = 0 - -trash_count = 0 - -draft_count = 0 - -all_count = 0 - -searcing_text = '' - -search_screen = '' - -send_draft_mail = None - -is_allmail = False - -in_composer = False - -availabe_credit = 0 - -in_sent_method = False - -in_search_mode = False diff --git a/src/storage/filesystem.py b/src/storage/filesystem.py index b19d9272..d64894a9 100644 --- a/src/storage/filesystem.py +++ b/src/storage/filesystem.py @@ -1,145 +1,94 @@ -""" -Module for using filesystem (directory with files) for inventory storage -""" -import string -import time from binascii import hexlify, unhexlify from os import listdir, makedirs, path, remove, rmdir +import string from threading import RLock +import time +import traceback from paths import lookupAppdataFolder -from storage import InventoryItem, InventoryStorage - +from storage import InventoryStorage, InventoryItem class FilesystemInventory(InventoryStorage): - """Filesystem for inventory storage""" - # pylint: disable=too-many-ancestors, abstract-method topDir = "inventory" objectDir = "objects" metadataFilename = "metadata" dataFilename = "data" def __init__(self): - super(FilesystemInventory, self).__init__() - self.baseDir = path.join( - lookupAppdataFolder(), FilesystemInventory.topDir) + super(self.__class__, self).__init__() + self.baseDir = path.join(lookupAppdataFolder(), FilesystemInventory.topDir) for createDir in [self.baseDir, path.join(self.baseDir, "objects")]: if path.exists(createDir): if not path.isdir(createDir): - raise IOError( - "%s exists but it's not a directory" % createDir) + raise IOError("%s exists but it's not a directory" % (createDir)) else: makedirs(createDir) - # Guarantees that two receiveDataThreads - # don't receive and process the same message - # concurrently (probably sent by a malicious individual) - self.lock = RLock() + self.lock = RLock() # Guarantees that two receiveDataThreads don't receive and process the same message concurrently (probably sent by a malicious individual) self._inventory = {} self._load() - def __contains__(self, hashval): + def __contains__(self, hash): + retval = False for streamDict in self._inventory.values(): - if hashval in streamDict: + if hash in streamDict: return True return False - def __getitem__(self, hashval): + def __getitem__(self, hash): for streamDict in self._inventory.values(): try: - retval = streamDict[hashval] + retval = streamDict[hash] except KeyError: continue if retval.payload is None: - retval = InventoryItem( - retval.type, - retval.stream, - self.getData(hashval), - retval.expires, - retval.tag) + retval = InventoryItem(retval.type, retval.stream, self.getData(hash), retval.expires, retval.tag) return retval - raise KeyError(hashval) + raise KeyError(hash) - def __setitem__(self, hashval, value): + def __setitem__(self, hash, value): with self.lock: value = InventoryItem(*value) try: - makedirs(path.join( - self.baseDir, - FilesystemInventory.objectDir, - hexlify(hashval))) + makedirs(path.join(self.baseDir, FilesystemInventory.objectDir, hexlify(hash))) except OSError: pass try: - with open( - path.join( - self.baseDir, - FilesystemInventory.objectDir, - hexlify(hashval), - FilesystemInventory.metadataFilename, - ), - "w", - ) as f: - f.write("%s,%s,%s,%s," % ( - value.type, - value.stream, - value.expires, - hexlify(value.tag))) - with open( - path.join( - self.baseDir, - FilesystemInventory.objectDir, - hexlify(hashval), - FilesystemInventory.dataFilename, - ), - "w", - ) as f: + with open(path.join(self.baseDir, FilesystemInventory.objectDir, hexlify(hash), FilesystemInventory.metadataFilename), 'w') as f: + f.write("%s,%s,%s,%s," % (value.type, value.stream, value.expires, hexlify(value.tag))) + with open(path.join(self.baseDir, FilesystemInventory.objectDir, hexlify(hash), FilesystemInventory.dataFilename), 'w') as f: f.write(value.payload) except IOError: raise KeyError try: - self._inventory[value.stream][hashval] = value + self._inventory[value.stream][hash] = value except KeyError: self._inventory[value.stream] = {} - self._inventory[value.stream][hashval] = value + self._inventory[value.stream][hash] = value - def delHashId(self, hashval): - """Remove object from inventory""" - for stream in self._inventory: + def delHashId(self, hash): + for stream in self._inventory.keys(): try: - del self._inventory[stream][hashval] + del self._inventory[stream][hash] except KeyError: pass with self.lock: try: - remove( - path.join( - self.baseDir, - FilesystemInventory.objectDir, - hexlify(hashval), - FilesystemInventory.metadataFilename)) + remove(path.join(self.baseDir, FilesystemInventory.objectDir, hexlify(hash), FilesystemInventory.metadataFilename)) except IOError: pass try: - remove( - path.join( - self.baseDir, - FilesystemInventory.objectDir, - hexlify(hashval), - FilesystemInventory.dataFilename)) + remove(path.join(self.baseDir, FilesystemInventory.objectDir, hexlify(hash), FilesystemInventory.dataFilename)) except IOError: pass try: - rmdir(path.join( - self.baseDir, - FilesystemInventory.objectDir, - hexlify(hashval))) + rmdir(path.join(self.baseDir, FilesystemInventory.objectDir, hexlify(hash))) except IOError: pass def __iter__(self): elems = [] for streamDict in self._inventory.values(): - elems.extend(streamDict.keys()) + elems.extend (streamDict.keys()) return elems.__iter__() def __len__(self): @@ -152,112 +101,73 @@ class FilesystemInventory(InventoryStorage): newInventory = {} for hashId in self.object_list(): try: - objectType, streamNumber, expiresTime, tag = self.getMetadata( - hashId) + objectType, streamNumber, expiresTime, tag = self.getMetadata(hashId) try: - newInventory[streamNumber][hashId] = InventoryItem( - objectType, streamNumber, None, expiresTime, tag) + newInventory[streamNumber][hashId] = InventoryItem(objectType, streamNumber, None, expiresTime, tag) except KeyError: newInventory[streamNumber] = {} - newInventory[streamNumber][hashId] = InventoryItem( - objectType, streamNumber, None, expiresTime, tag) + newInventory[streamNumber][hashId] = InventoryItem(objectType, streamNumber, None, expiresTime, tag) except KeyError: print "error loading %s" % (hexlify(hashId)) + pass self._inventory = newInventory # for i, v in self._inventory.items(): # print "loaded stream: %s, %i items" % (i, len(v)) def stream_list(self): - """Return list of streams""" return self._inventory.keys() def object_list(self): - """Return inventory vectors (hashes) from a directory""" - return [unhexlify(x) for x in listdir(path.join( - self.baseDir, FilesystemInventory.objectDir))] + return [unhexlify(x) for x in listdir(path.join(self.baseDir, FilesystemInventory.objectDir))] def getData(self, hashId): - """Get object data""" try: - with open( - path.join( - self.baseDir, - FilesystemInventory.objectDir, - hexlify(hashId), - FilesystemInventory.dataFilename, - ), - "r", - ) as f: + with open(path.join(self.baseDir, FilesystemInventory.objectDir, hexlify(hashId), FilesystemInventory.dataFilename), 'r') as f: return f.read() except IOError: raise AttributeError def getMetadata(self, hashId): - """Get object metadata""" try: - with open( - path.join( - self.baseDir, - FilesystemInventory.objectDir, - hexlify(hashId), - FilesystemInventory.metadataFilename, - ), - "r", - ) as f: - objectType, streamNumber, expiresTime, tag = string.split( - f.read(), ",", 4)[:4] - return [ - int(objectType), - int(streamNumber), - int(expiresTime), - unhexlify(tag)] + with open(path.join(self.baseDir, FilesystemInventory.objectDir, hexlify(hashId), FilesystemInventory.metadataFilename), 'r') as f: + objectType, streamNumber, expiresTime, tag, undef = string.split(f.read(), ",", 4) + return [int(objectType), int(streamNumber), int(expiresTime), unhexlify(tag)] except IOError: raise KeyError def by_type_and_tag(self, objectType, tag): - """Get a list of objects filtered by object type and tag""" retval = [] - for streamDict in self._inventory.values(): + for stream, streamDict in self._inventory: for hashId, item in streamDict: if item.type == objectType and item.tag == tag: - try: + try: if item.payload is None: item.payload = self.getData(hashId) except IOError: continue - retval.append(InventoryItem( - item.type, - item.stream, - item.payload, - item.expires, - item.tag)) + retval.append(InventoryItem(item.type, item.stream, item.payload, item.expires, item.tag)) return retval def hashes_by_stream(self, stream): - """Return inventory vectors (hashes) for a stream""" try: return self._inventory[stream].keys() except KeyError: return [] def unexpired_hashes_by_stream(self, stream): - """Return unexpired hashes in the inventory for a particular stream""" t = int(time.time()) try: - return [x for x, value in self._inventory[stream].items() - if value.expires > t] + return [x for x, value in self._inventory[stream].items() if value.expires > t] except KeyError: return [] def flush(self): - """Flush the inventory and create a new, empty one""" self._load() def clean(self): - """Clean out old items from the inventory""" minTime = int(time.time()) - (60 * 60 * 30) deletes = [] - for streamDict in self._inventory.values(): + for stream, streamDict in self._inventory.items(): for hashId, item in streamDict.items(): if item.expires < minTime: deletes.append(hashId) diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py index 0992c00e..438cbdcb 100644 --- a/src/storage/sqlite.py +++ b/src/storage/sqlite.py @@ -1,62 +1,45 @@ -""" -Sqlite Inventory -""" +import collections +from threading import current_thread, enumerate as threadingEnumerate, RLock +import Queue import sqlite3 import time -from threading import RLock -from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery -from storage import InventoryItem, InventoryStorage +from helper_sql import * +from storage import InventoryStorage, InventoryItem - -class SqliteInventory(InventoryStorage): # pylint: disable=too-many-ancestors - """Inventory using SQLite""" +class SqliteInventory(InventoryStorage): def __init__(self): - super(SqliteInventory, self).__init__() - # of objects (like msg payloads and pubkey payloads) - # Does not include protocol headers (the first 24 bytes of each packet). - self._inventory = {} - # cache for existing objects, used for quick lookups if we have an object. - # This is used for example whenever we receive an inv message from a peer - # to check to see what items are new to us. - # We don't delete things out of it; instead, - # the singleCleaner thread clears and refills it. - self._objects = {} - # Guarantees that two receiveDataThreads don't receive - # and process the same message concurrently - # (probably sent by a malicious individual) - self.lock = RLock() + super(self.__class__, self).__init__() + self._inventory = {} #of objects (like msg payloads and pubkey payloads) Does not include protocol headers (the first 24 bytes of each packet). + self._objects = {} # cache for existing objects, used for quick lookups if we have an object. This is used for example whenever we receive an inv message from a peer to check to see what items are new to us. We don't delete things out of it; instead, the singleCleaner thread clears and refills it. + self.lock = RLock() # Guarantees that two receiveDataThreads don't receive and process the same message concurrently (probably sent by a malicious individual) - def __contains__(self, hash_): + def __contains__(self, hash): with self.lock: - if hash_ in self._objects: + if hash in self._objects: return True - rows = sqlQuery( - 'SELECT streamnumber FROM inventory WHERE hash=?', - sqlite3.Binary(hash_)) + rows = sqlQuery('SELECT streamnumber FROM inventory WHERE hash=?', sqlite3.Binary(hash)) if not rows: return False - self._objects[hash_] = rows[0][0] + self._objects[hash] = rows[0][0] return True - def __getitem__(self, hash_): + def __getitem__(self, hash): with self.lock: - if hash_ in self._inventory: - return self._inventory[hash_] - rows = sqlQuery( - 'SELECT objecttype, streamnumber, payload, expirestime, tag' - ' FROM inventory WHERE hash=?', sqlite3.Binary(hash_)) + if hash in self._inventory: + return self._inventory[hash] + rows = sqlQuery('SELECT objecttype, streamnumber, payload, expirestime, tag FROM inventory WHERE hash=?', sqlite3.Binary(hash)) if not rows: - raise KeyError(hash_) + raise KeyError(hash) return InventoryItem(*rows[0]) - def __setitem__(self, hash_, value): + def __setitem__(self, hash, value): with self.lock: value = InventoryItem(*value) - self._inventory[hash_] = value - self._objects[hash_] = value.stream + self._inventory[hash] = value + self._objects[hash] = value.stream - def __delitem__(self, hash_): + def __delitem__(self, hash): raise NotImplementedError def __iter__(self): @@ -67,49 +50,32 @@ class SqliteInventory(InventoryStorage): # pylint: disable=too-many-ancestors def __len__(self): with self.lock: - return len(self._inventory) + sqlQuery( - 'SELECT count(*) FROM inventory')[0][0] + return len(self._inventory) + sqlQuery('SELECT count(*) FROM inventory')[0][0] def by_type_and_tag(self, objectType, tag): - """Return objects filtered by object type and tag""" with self.lock: - values = [value for value in self._inventory.values() - if value.type == objectType and value.tag == tag] - values += (InventoryItem(*value) for value in sqlQuery( - 'SELECT objecttype, streamnumber, payload, expirestime, tag' - ' FROM inventory WHERE objecttype=? AND tag=?', - objectType, sqlite3.Binary(tag))) + values = [value for value in self._inventory.values() if value.type == objectType and value.tag == tag] + values += (InventoryItem(*value) for value in sqlQuery('SELECT objecttype, streamnumber, payload, expirestime, tag FROM inventory WHERE objecttype=? AND tag=?', objectType, sqlite3.Binary(tag))) return values def unexpired_hashes_by_stream(self, stream): - """Return unexpired inventory vectors filtered by stream""" with self.lock: t = int(time.time()) - hashes = [x for x, value in self._inventory.items() - if value.stream == stream and value.expires > t] - hashes += (str(payload) for payload, in sqlQuery( - 'SELECT hash FROM inventory WHERE streamnumber=?' - ' AND expirestime>?', stream, t)) + hashes = [x for x, value in self._inventory.items() if value.stream == stream and value.expires > t] + hashes += (str(payload) for payload, in sqlQuery('SELECT hash FROM inventory WHERE streamnumber=? AND expirestime>?', stream, t)) return hashes def flush(self): - """Flush cache""" - with self.lock: - # If you use both the inventoryLock and the sqlLock, - # always use the inventoryLock OUTSIDE of the sqlLock. + with self.lock: # If you use both the inventoryLock and the sqlLock, always use the inventoryLock OUTSIDE of the sqlLock. with SqlBulkExecute() as sql: for objectHash, value in self._inventory.items(): - sql.execute( - 'INSERT INTO inventory VALUES (?, ?, ?, ?, ?, ?)', - sqlite3.Binary(objectHash), *value) + sql.execute('INSERT INTO inventory VALUES (?, ?, ?, ?, ?, ?)', sqlite3.Binary(objectHash), *value) self._inventory.clear() def clean(self): - """Free memory / perform garbage collection""" with self.lock: - sqlExecute( - 'DELETE FROM inventory WHERE expirestime 2: - return - if ( - not peer.host.endswith('.onion') - and not peer.host.startswith('bootstrap') - ): - self.fail( - 'Found non onion hostname %s in outbound connections!' - % peer.host) - self.fail('Failed to connect to at least 3 nodes within 360 sec') - def run(): """Starts all tests defined in this module""" diff --git a/src/tests/test_api.py b/src/tests/test_api.py index 44505ffe..dfe1b273 100644 --- a/src/tests/test_api.py +++ b/src/tests/test_api.py @@ -31,7 +31,7 @@ class TestAPIShutdown(TestAPIProto, TestProcessShutdown): """Separate test case for API command 'shutdown'""" def test_shutdown(self): """Shutdown the pybitmessage""" - self.assertEqual(self.api.shutdown(), 'done') + self.assertEquals(self.api.shutdown(), 'done') for _ in range(5): if not self.process.is_running(): break diff --git a/src/tests/test_blindsig.py b/src/tests/test_blindsig.py deleted file mode 100644 index b8d0248a..00000000 --- a/src/tests/test_blindsig.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -Test for ECC blind signatures -""" -import os -import unittest -from ctypes import cast, c_char_p - -from pybitmessage.pyelliptic.eccblind import ECCBlind -from pybitmessage.pyelliptic.openssl import OpenSSL - - -class TestBlindSig(unittest.TestCase): - """ - Test case for ECC blind signature - """ - def test_blind_sig(self): - """Test full sequence using a random certifier key and a random message""" - # See page 127 of the paper - # (1) Initialization - signer_obj = ECCBlind() - point_r = signer_obj.signer_init() - - # (2) Request - requester_obj = ECCBlind(pubkey=signer_obj.pubkey) - # only 64 byte messages are planned to be used in Bitmessage - msg = os.urandom(64) - msg_blinded = requester_obj.create_signing_request(point_r, msg) - - # check - msg_blinded_str = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(msg_blinded)) - OpenSSL.BN_bn2bin(msg_blinded, msg_blinded_str) - self.assertNotEqual(msg, cast(msg_blinded_str, c_char_p).value) - - # (3) Signature Generation - signature_blinded = signer_obj.blind_sign(msg_blinded) - - # (4) Extraction - signature = requester_obj.unblind(signature_blinded) - - # check - signature_blinded_str = OpenSSL.malloc(0, - OpenSSL.BN_num_bytes( - signature_blinded)) - signature_str = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(signature[0])) - OpenSSL.BN_bn2bin(signature_blinded, signature_blinded_str) - OpenSSL.BN_bn2bin(signature[0], signature_str) - self.assertNotEqual(cast(signature_str, c_char_p).value, - cast(signature_blinded_str, c_char_p).value) - - # (5) Verification - verifier_obj = ECCBlind(pubkey=signer_obj.pubkey) - self.assertTrue(verifier_obj.verify(msg, signature)) diff --git a/src/tests/test_config.py b/src/tests/test_config.py index 35ddd3fa..a0a727e5 100644 --- a/src/tests/test_config.py +++ b/src/tests/test_config.py @@ -26,7 +26,6 @@ class TestConfig(unittest.TestCase): False ) # no arg for default - # pylint: disable=too-many-function-args with self.assertRaises(TypeError): BMConfigParser().safeGetBoolean( 'nonexistent', 'nonexistent', True) @@ -48,9 +47,9 @@ class TestProcessConfig(TestProcessProto): config = BMConfigParser() config.read(os.path.join(self.home, 'keys.dat')) - self.assertEqual(config.safeGetInt( + self.assertEquals(config.safeGetInt( 'bitmessagesettings', 'settingsversion'), 10) - self.assertEqual(config.safeGetInt( + self.assertEquals(config.safeGetInt( 'bitmessagesettings', 'port'), 8444) # don't connect self.assertTrue(config.safeGetBoolean( @@ -60,7 +59,7 @@ class TestProcessConfig(TestProcessProto): 'bitmessagesettings', 'apienabled')) # extralowdifficulty is false - self.assertEqual(config.safeGetInt( + self.assertEquals(config.safeGetInt( 'bitmessagesettings', 'defaultnoncetrialsperbyte'), 1000) - self.assertEqual(config.safeGetInt( + self.assertEquals(config.safeGetInt( 'bitmessagesettings', 'defaultpayloadlengthextrabytes'), 1000) diff --git a/src/tests/test_logger.py b/src/tests/test_logger.py deleted file mode 100644 index 57448911..00000000 --- a/src/tests/test_logger.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -Testing the logger configuration -""" - -import logging -import os -import tempfile -import unittest - - -class TestLogger(unittest.TestCase): - """A test case for bmconfigparser""" - - conf_template = ''' -[loggers] -keys=root - -[handlers] -keys=default - -[formatters] -keys=default - -[formatter_default] -format=%(asctime)s {1} %(message)s - -[handler_default] -class=FileHandler -level=NOTSET -formatter=default -args=('{0}', 'w') - -[logger_root] -level=DEBUG -handlers=default -''' - - def test_fileConfig(self): - """Put logging.dat with special pattern and check it was used""" - tmp = os.environ['BITMESSAGE_HOME'] = tempfile.gettempdir() - log_config = os.path.join(tmp, 'logging.dat') - log_file = os.path.join(tmp, 'debug.log') - - def gen_log_config(pattern): - """A small closure to generate logging.dat with custom pattern""" - with open(log_config, 'wb') as dst: - dst.write(self.conf_template.format(log_file, pattern)) - - pattern = r' o_0 ' - gen_log_config(pattern) - - try: - from pybitmessage.debug import logger, resetLogging - if not os.path.isfile(log_file): # second pass - pattern = r' <===> ' - gen_log_config(pattern) - resetLogging() - except ImportError: - self.fail('There is no package pybitmessage. Things gone wrong.') - finally: - os.remove(log_config) - - logger_ = logging.getLogger('default') - - self.assertEqual(logger, logger_) - - logger_.info('Testing the logger...') - - self.assertRegexpMatches(open(log_file).read(), pattern) diff --git a/src/tests/test_networkgroup.py b/src/tests/test_networkgroup.py deleted file mode 100644 index 76cfb033..00000000 --- a/src/tests/test_networkgroup.py +++ /dev/null @@ -1,39 +0,0 @@ -""" -Test for network group -""" -import unittest - - -class TestNetworkGroup(unittest.TestCase): - """ - Test case for network group - """ - def test_network_group(self): - """Test various types of network groups""" - from pybitmessage.protocol import network_group - - test_ip = '1.2.3.4' - self.assertEqual('\x01\x02', network_group(test_ip)) - - test_ip = '127.0.0.1' - self.assertEqual('IPv4', network_group(test_ip)) - - test_ip = '0102:0304:0506:0708:090A:0B0C:0D0E:0F10' - self.assertEqual( - '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C', - network_group(test_ip)) - - test_ip = 'bootstrap8444.bitmessage.org' - self.assertEqual( - 'bootstrap8444.bitmessage.org', - network_group(test_ip)) - - test_ip = 'quzwelsuziwqgpt2.onion' - self.assertEqual( - test_ip, - network_group(test_ip)) - - test_ip = None - self.assertEqual( - None, - network_group(test_ip)) diff --git a/src/threads.py b/src/threads.py deleted file mode 100644 index b7471508..00000000 --- a/src/threads.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -PyBitmessage does various tasks in separate threads. Most of them inherit -from `.network.StoppableThread`. There are `addressGenerator` for -addresses generation, `objectProcessor` for processing the network objects -passed minimal validation, `singleCleaner` to periodically clean various -internal storages (like inventory and knownnodes) and do forced garbage -collection, `singleWorker` for doing PoW, `sqlThread` for querying sqlite -database. - -There are also other threads in the `.network` package. - -:func:`set_thread_name` is defined here for the threads that don't inherit from -:class:`.network.StoppableThread` -""" - -import threading - -from class_addressGenerator import addressGenerator -from class_objectProcessor import objectProcessor -from class_singleCleaner import singleCleaner -from class_singleWorker import singleWorker -from class_sqlThread import sqlThread - -try: - import prctl -except ImportError: - def set_thread_name(name): - """Set a name for the thread for python internal use.""" - threading.current_thread().name = name -else: - def set_thread_name(name): - """Set the thread name for external use (visible from the OS).""" - prctl.set_name(name) - - def _thread_name_hack(self): - set_thread_name(self.name) - threading.Thread.__bootstrap_original__(self) - # pylint: disable=protected-access - threading.Thread.__bootstrap_original__ = threading.Thread._Thread__bootstrap - threading.Thread._Thread__bootstrap = _thread_name_hack - - -__all__ = [ - "addressGenerator", "objectProcessor", "singleCleaner", "singleWorker", - "sqlThread" -] diff --git a/src/tr.py b/src/tr.py index 9f531a99..8b41167f 100644 --- a/src/tr.py +++ b/src/tr.py @@ -1,56 +1,39 @@ -""" -Translating text -""" import os import state - +# This is used so that the translateText function can be used when we are in daemon mode and not using any QT functions. class translateClass: - """ - This is used so that the translateText function can be used - when we are in daemon mode and not using any QT functions. - """ - # pylint: disable=old-style-class,too-few-public-methods def __init__(self, context, text): self.context = context self.text = text - - def arg(self, argument): # pylint: disable=unused-argument - """Replace argument placeholders""" + def arg(self,argument): if '%' in self.text: - return translateClass(self.context, self.text.replace('%', '', 1)) - # This doesn't actually do anything with the arguments - # because we don't have a UI in which to display this information anyway. - return self.text + return translateClass(self.context, self.text.replace('%','',1)) # This doesn't actually do anything with the arguments because we don't have a UI in which to display this information anyway. + else: + return self.text - -def _translate(context, text, disambiguation=None, encoding=None, n=None): - # pylint: disable=unused-argument +def _translate(context, text, disambiguation = None, encoding = None, n = None): return translateText(context, text, n) - -def translateText(context, text, n=None): - """Translate text in context""" +def translateText(context, text, n = None): try: enableGUI = state.enableGUI except AttributeError: # inside the plugin enableGUI = True - if not state.kivy and enableGUI: + if enableGUI: try: from PyQt4 import QtCore, QtGui except Exception as err: - print 'PyBitmessage requires PyQt unless you want to run it as a daemon'\ - ' and interact with it using the API.'\ - ' You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download'\ - ' or by searching Google for \'PyQt Download\'.'\ - ' If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon' + print 'PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download or by searching Google for \'PyQt Download\'. If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon' print 'Error message:', err - os._exit(0) # pylint: disable=protected-access + os._exit(0) if n is None: return QtGui.QApplication.translate(context, text) - return QtGui.QApplication.translate(context, text, None, QtCore.QCoreApplication.CodecForTr, n) + else: + return QtGui.QApplication.translate(context, text, None, QtCore.QCoreApplication.CodecForTr, n) else: if '%' in text: - return translateClass(context, text.replace('%', '', 1)) - return text + return translateClass(context, text.replace('%','',1)) + else: + return text diff --git a/src/upnp.py b/src/upnp.py index 99000413..da075c65 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -1,25 +1,28 @@ # pylint: disable=too-many-statements,too-many-branches,protected-access,no-self-use """ -Complete UPnP port forwarding implementation in separate thread. +src/upnp.py +=========== + +A simple upnp module to forward port for BitMessage Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port """ import httplib import socket +import threading import time import urllib2 from random import randint from urlparse import urlparse from xml.dom.minidom import Document, parseString -import knownnodes import queues import state import tr from bmconfigparser import BMConfigParser from debug import logger -from network import BMConnectionPool, StoppableThread -from network.node import Peer +from helper_threading import StoppableThread +from network.connectionpool import BMConnectionPool def createRequestXML(service, action, arguments=None): @@ -163,11 +166,9 @@ class Router: # pylint: disable=old-style-class def GetExternalIPAddress(self): """Get the external address""" - resp = self.soapRequest( - self.upnp_schema + ':1', 'GetExternalIPAddress') - dom = parseString(resp.read()) - return dom.getElementsByTagName( - 'NewExternalIPAddress')[0].childNodes[0].data + resp = self.soapRequest(self.upnp_schema + ':1', 'GetExternalIPAddress') + dom = parseString(resp) + return dom.getElementsByTagName('NewExternalIPAddress')[0].childNodes[0].data def soapRequest(self, service, action, arguments=None): """Make a request to a router""" @@ -197,7 +198,7 @@ class Router: # pylint: disable=old-style-class return resp -class uPnPThread(StoppableThread): +class uPnPThread(threading.Thread, StoppableThread): """Start a thread to handle UPnP activity""" SSDP_ADDR = "239.255.255.250" @@ -207,7 +208,7 @@ class uPnPThread(StoppableThread): SSDP_ST = "urn:schemas-upnp-org:device:InternetGatewayDevice:1" def __init__(self): - super(uPnPThread, self).__init__(name="uPnPThread") + threading.Thread.__init__(self, name="uPnPThread") try: self.extPort = BMConfigParser().getint('bitmessagesettings', 'extport') except: @@ -219,6 +220,7 @@ class uPnPThread(StoppableThread): self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) self.sock.settimeout(5) self.sendSleep = 60 + self.initStop() def run(self): """Start the thread to manage UPnP activity""" @@ -259,17 +261,6 @@ class uPnPThread(StoppableThread): logger.debug("Found UPnP router at %s", ip) self.routers.append(newRouter) self.createPortMapping(newRouter) - try: - self_peer = Peer( - newRouter.GetExternalIPAddress(), - self.extPort - ) - except: - logger.debug('Failed to get external IP') - else: - with knownnodes.knownNodesLock: - knownnodes.addKnownNode( - 1, self_peer, is_self=True) queues.UISignalQueue.put(('updateStatusBar', tr._translate( "MainWindow", 'UPnP port mapping established on port %1' ).arg(str(self.extPort))))