From 3875fe64aef2a742a023bf934e5907c43ab27802 Mon Sep 17 00:00:00 2001 From: pppscn <35696959@qq.com> Date: Wed, 10 Feb 2021 14:38:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 12 + README.md | 94 +++ _config.yml | 1 + app/build.gradle | 70 ++ app/proguard-rules.pro | 21 + app/release/output.json | 19 + .../sms/forwarder/ExampleInstrumentedTest.kt | 22 + app/src/main/AndroidManifest.xml | 70 ++ app/src/main/ic_launcher-playstore.png | Bin 0 -> 107424 bytes .../MessageBroadcastReceiver.java | 26 + .../RebootBroadcastReceiver.java | 33 + .../TSMSBroadcastReceiver.java | 68 ++ .../idormy/sms/forwarder/FrontService.java | 59 ++ .../idormy/sms/forwarder/MainActivity.java | 227 ++++++ .../idormy/sms/forwarder/MyApplication.java | 82 +++ .../idormy/sms/forwarder/ReFlashListView.java | 272 +++++++ .../idormy/sms/forwarder/RuleActivity.java | 201 ++++++ .../idormy/sms/forwarder/SenderActivity.java | 681 ++++++++++++++++++ .../idormy/sms/forwarder/SettingActivity.java | 185 +++++ .../sms/forwarder/adapter/LogAdapter.java | 113 +++ .../sms/forwarder/adapter/RuleAdapter.java | 115 +++ .../sms/forwarder/adapter/SenderAdapter.java | 128 ++++ .../idormy/sms/forwarder/model/LogModel.java | 52 ++ .../idormy/sms/forwarder/model/LogTable.java | 19 + .../idormy/sms/forwarder/model/RuleModel.java | 179 +++++ .../idormy/sms/forwarder/model/RuleTable.java | 20 + .../sms/forwarder/model/SenderModel.java | 125 ++++ .../sms/forwarder/model/SenderTable.java | 20 + .../sms/forwarder/model/vo/BarkSettingVo.java | 22 + .../forwarder/model/vo/DingDingSettingVo.java | 52 ++ .../forwarder/model/vo/EmailSettingVo.java | 72 ++ .../forwarder/model/vo/FeedBackResult.java | 30 + .../idormy/sms/forwarder/model/vo/LogVo.java | 57 ++ .../model/vo/QYWXGroupRobotSettingVo.java | 22 + .../idormy/sms/forwarder/model/vo/RuleVo.java | 6 + .../idormy/sms/forwarder/model/vo/SmsVo.java | 59 ++ .../model/vo/WebNotifySettingVo.java | 32 + .../idormy/sms/forwarder/utils/DbHelper.java | 84 +++ .../idormy/sms/forwarder/utils/Define.java | 11 + .../sms/forwarder/utils/DingdingMsg.java | 71 ++ .../com/idormy/sms/forwarder/utils/HttpI.java | 94 +++ .../idormy/sms/forwarder/utils/HttpUtil.java | 117 +++ .../idormy/sms/forwarder/utils/InitUtil.java | 24 + .../idormy/sms/forwarder/utils/LogUtil.java | 178 +++++ .../idormy/sms/forwarder/utils/MailInfo.java | 139 ++++ .../sms/forwarder/utils/MailSender.java | 205 ++++++ .../sms/forwarder/utils/MailSenderInfo.java | 147 ++++ .../sms/forwarder/utils/MyAuthenticator.java | 21 + .../idormy/sms/forwarder/utils/RuleUtil.java | 157 ++++ .../sms/forwarder/utils/SendHistory.java | 171 +++++ .../sms/forwarder/utils/SendMailUtil.java | 85 +++ .../idormy/sms/forwarder/utils/SendUtil.java | 234 ++++++ .../sms/forwarder/utils/SenderBarkMsg.java | 89 +++ .../forwarder/utils/SenderDingdingMsg.java | 184 +++++ .../sms/forwarder/utils/SenderMailMsg.java | 148 ++++ .../utils/SenderQyWxGroupRobotMsg.java | 79 ++ .../sms/forwarder/utils/SenderUtil.java | 194 +++++ .../forwarder/utils/SenderWebNotifyMsg.java | 100 +++ .../sms/forwarder/utils/SettingUtil.java | 74 ++ .../forwarder/utils/UpdateAppHttpUtil.java | 124 ++++ .../com/idormy/sms/forwarder/utils/aUtil.java | 56 ++ app/src/main/qywx-playstore.png | Bin 0 -> 125512 bytes .../drawable-v24/ic_launcher_foreground.xml | 34 + .../res/drawable/ic_baseline_email_24.xml | 10 + .../res/drawable/ic_launcher_background.xml | 170 +++++ .../activity_alter_dialog_setview_bark.xml | 82 +++ ...activity_alter_dialog_setview_dingding.xml | 147 ++++ .../activity_alter_dialog_setview_email.xml | 184 +++++ ...ty_alter_dialog_setview_qywxgrouprobot.xml | 82 +++ .../activity_alter_dialog_setview_rule.xml | 168 +++++ ...ctivity_alter_dialog_setview_webnotify.xml | 105 +++ app/src/main/res/layout/activity_main.xml | 62 ++ app/src/main/res/layout/activity_rule.xml | 26 + app/src/main/res/layout/activity_sender.xml | 34 + app/src/main/res/layout/activity_setting.xml | 162 +++++ app/src/main/res/layout/dialog_feedback.xml | 28 + app/src/main/res/layout/header_layout.xml | 51 ++ app/src/main/res/layout/rule_item.xml | 19 + app/src/main/res/layout/sender_item.xml | 17 + app/src/main/res/layout/tlog_item.xml | 44 ++ app/src/main/res/menu/menu_main.xml | 11 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-anydpi-v26/qywx.xml | 5 + .../main/res/mipmap-anydpi-v26/qywx_round.xml | 5 + app/src/main/res/mipmap-hdpi/dingding.jpg | Bin 0 -> 21628 bytes app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 5989 bytes .../mipmap-hdpi/ic_launcher_background.png | Bin 0 -> 40583 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 2235 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 7342 bytes app/src/main/res/mipmap-hdpi/ic_launchert.jpg | Bin 0 -> 14493 bytes app/src/main/res/mipmap-hdpi/qywx.png | Bin 0 -> 3848 bytes .../main/res/mipmap-hdpi/qywx_foreground.png | Bin 0 -> 9439 bytes app/src/main/res/mipmap-hdpi/qywx_round.png | Bin 0 -> 6238 bytes app/src/main/res/mipmap-mdpi/dingding.jpg | Bin 0 -> 21628 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 3312 bytes .../mipmap-mdpi/ic_launcher_background.png | Bin 0 -> 19194 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 1333 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 3853 bytes app/src/main/res/mipmap-mdpi/ic_launchert.jpg | Bin 0 -> 14493 bytes app/src/main/res/mipmap-mdpi/qywx.png | Bin 0 -> 2122 bytes .../main/res/mipmap-mdpi/qywx_foreground.png | Bin 0 -> 4677 bytes app/src/main/res/mipmap-mdpi/qywx_round.png | Bin 0 -> 3362 bytes app/src/main/res/mipmap-xhdpi/dingding.jpg | Bin 0 -> 21628 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 9550 bytes .../mipmap-xhdpi/ic_launcher_background.png | Bin 0 -> 64727 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 3180 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 11763 bytes .../main/res/mipmap-xhdpi/ic_launchert.jpg | Bin 0 -> 14493 bytes app/src/main/res/mipmap-xhdpi/qywx.png | Bin 0 -> 6004 bytes .../main/res/mipmap-xhdpi/qywx_foreground.png | Bin 0 -> 15672 bytes app/src/main/res/mipmap-xhdpi/qywx_round.png | Bin 0 -> 9811 bytes app/src/main/res/mipmap-xxhdpi/dingding.jpg | Bin 0 -> 21628 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 19254 bytes .../mipmap-xxhdpi/ic_launcher_background.png | Bin 0 -> 116457 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 5456 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 22450 bytes .../main/res/mipmap-xxhdpi/ic_launchert.jpg | Bin 0 -> 14493 bytes app/src/main/res/mipmap-xxhdpi/qywx.png | Bin 0 -> 11765 bytes .../res/mipmap-xxhdpi/qywx_foreground.png | Bin 0 -> 31700 bytes app/src/main/res/mipmap-xxhdpi/qywx_round.png | Bin 0 -> 18359 bytes app/src/main/res/mipmap-xxxhdpi/dingding.jpg | Bin 0 -> 21628 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 32098 bytes .../mipmap-xxxhdpi/ic_launcher_background.png | Bin 0 -> 142512 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 7921 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 36816 bytes .../main/res/mipmap-xxxhdpi/ic_launchert.jpg | Bin 0 -> 14493 bytes app/src/main/res/mipmap-xxxhdpi/qywx.png | Bin 0 -> 18961 bytes .../res/mipmap-xxxhdpi/qywx_foreground.png | Bin 0 -> 51737 bytes .../main/res/mipmap-xxxhdpi/qywx_round.png | Bin 0 -> 29187 bytes app/src/main/res/values/array.xml | 11 + app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/qywx_background.xml | 4 + app/src/main/res/values/strings.xml | 16 + app/src/main/res/values/styles.xml | 11 + app/src/main/res/xml/preference_setting.xml | 82 +++ .../idormy/sms/forwarder/ExampleUnitTest.kt | 16 + build.gradle | 31 + doc/POST_WEB.md | 89 +++ gradle.properties | 14 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 +++++ gradlew.bat | 84 +++ pic/app.jpg | Bin 0 -> 44816 bytes pic/dingding.jpg | Bin 0 -> 46042 bytes pic/dingdingmsg.jpg | Bin 0 -> 46042 bytes pic/dingdingtokenset.jpg | Bin 0 -> 46111 bytes pic/main.jpg | Bin 0 -> 47954 bytes pic/maindetail.jpg | Bin 0 -> 49963 bytes pic/rule.jpg | Bin 0 -> 11120 bytes pic/ruleset.jpg | Bin 0 -> 30364 bytes pic/sender.jpg | Bin 0 -> 14233 bytes pic/sendersetdingding.jpg | Bin 0 -> 29758 bytes pic/sendersetemail.jpg | Bin 0 -> 38255 bytes pic/sendersetwebnotify.jpg | Bin 0 -> 31500 bytes pic/setting.jpg | Bin 0 -> 17868 bytes pic/settingfeedback.jpg | Bin 0 -> 15569 bytes pic/showpic.png | Bin 0 -> 37987 bytes pic/taskbar.jpg | Bin 0 -> 20587 bytes pic/tsms-icon-bg0.png | Bin 0 -> 45763 bytes pic/tsms-icon.png | Bin 0 -> 51146 bytes pic/tsms-icon.xcf | Bin 0 -> 237176 bytes pic/tsms-icon0.png | Bin 0 -> 13011 bytes pic/update-dingdingsecret.jpg | Bin 0 -> 29213 bytes pic/webnotify.jpg | Bin 0 -> 16372 bytes settings.gradle | 1 + 167 files changed, 8051 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 _config.yml create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/release/output.json create mode 100644 app/src/androidTest/java/com/idormy/sms/forwarder/ExampleInstrumentedTest.kt create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/MessageBroadcastReceiver.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/RebootBroadcastReceiver.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/TSMSBroadcastReceiver.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/FrontService.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/MainActivity.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/MyApplication.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/ReFlashListView.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/SettingActivity.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/adapter/LogAdapter.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/adapter/RuleAdapter.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/adapter/SenderAdapter.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/LogModel.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/LogTable.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/RuleTable.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/SenderModel.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/SenderTable.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/BarkSettingVo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/DingDingSettingVo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/EmailSettingVo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/FeedBackResult.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/LogVo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/QYWXGroupRobotSettingVo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/RuleVo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/SmsVo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/model/vo/WebNotifySettingVo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/DbHelper.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/Define.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/DingdingMsg.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/HttpI.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/HttpUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/InitUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/MailInfo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/MailSender.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/MailSenderInfo.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/MyAuthenticator.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/RuleUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SendHistory.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SendMailUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SenderBarkMsg.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SenderDingdingMsg.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SenderMailMsg.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SenderQyWxGroupRobotMsg.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SenderUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SenderWebNotifyMsg.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/UpdateAppHttpUtil.java create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/aUtil.java create mode 100644 app/src/main/qywx-playstore.png create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_baseline_email_24.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/layout/activity_alter_dialog_setview_bark.xml create mode 100644 app/src/main/res/layout/activity_alter_dialog_setview_dingding.xml create mode 100644 app/src/main/res/layout/activity_alter_dialog_setview_email.xml create mode 100644 app/src/main/res/layout/activity_alter_dialog_setview_qywxgrouprobot.xml create mode 100644 app/src/main/res/layout/activity_alter_dialog_setview_rule.xml create mode 100644 app/src/main/res/layout/activity_alter_dialog_setview_webnotify.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_rule.xml create mode 100644 app/src/main/res/layout/activity_sender.xml create mode 100644 app/src/main/res/layout/activity_setting.xml create mode 100644 app/src/main/res/layout/dialog_feedback.xml create mode 100644 app/src/main/res/layout/header_layout.xml create mode 100644 app/src/main/res/layout/rule_item.xml create mode 100644 app/src/main/res/layout/sender_item.xml create mode 100644 app/src/main/res/layout/tlog_item.xml create mode 100644 app/src/main/res/menu/menu_main.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/qywx.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/qywx_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/dingding.jpg create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_background.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launchert.jpg create mode 100644 app/src/main/res/mipmap-hdpi/qywx.png create mode 100644 app/src/main/res/mipmap-hdpi/qywx_foreground.png create mode 100644 app/src/main/res/mipmap-hdpi/qywx_round.png create mode 100644 app/src/main/res/mipmap-mdpi/dingding.jpg create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_background.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launchert.jpg create mode 100644 app/src/main/res/mipmap-mdpi/qywx.png create mode 100644 app/src/main/res/mipmap-mdpi/qywx_foreground.png create mode 100644 app/src/main/res/mipmap-mdpi/qywx_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/dingding.jpg create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_background.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launchert.jpg create mode 100644 app/src/main/res/mipmap-xhdpi/qywx.png create mode 100644 app/src/main/res/mipmap-xhdpi/qywx_foreground.png create mode 100644 app/src/main/res/mipmap-xhdpi/qywx_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/dingding.jpg create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launchert.jpg create mode 100644 app/src/main/res/mipmap-xxhdpi/qywx.png create mode 100644 app/src/main/res/mipmap-xxhdpi/qywx_foreground.png create mode 100644 app/src/main/res/mipmap-xxhdpi/qywx_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/dingding.jpg create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launchert.jpg create mode 100644 app/src/main/res/mipmap-xxxhdpi/qywx.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/qywx_foreground.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/qywx_round.png create mode 100644 app/src/main/res/values/array.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/qywx_background.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/main/res/xml/preference_setting.xml create mode 100644 app/src/test/java/com/idormy/sms/forwarder/ExampleUnitTest.kt create mode 100644 build.gradle create mode 100644 doc/POST_WEB.md create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 pic/app.jpg create mode 100644 pic/dingding.jpg create mode 100644 pic/dingdingmsg.jpg create mode 100644 pic/dingdingtokenset.jpg create mode 100644 pic/main.jpg create mode 100644 pic/maindetail.jpg create mode 100644 pic/rule.jpg create mode 100644 pic/ruleset.jpg create mode 100644 pic/sender.jpg create mode 100644 pic/sendersetdingding.jpg create mode 100644 pic/sendersetemail.jpg create mode 100644 pic/sendersetwebnotify.jpg create mode 100644 pic/setting.jpg create mode 100644 pic/settingfeedback.jpg create mode 100644 pic/showpic.png create mode 100644 pic/taskbar.jpg create mode 100644 pic/tsms-icon-bg0.png create mode 100644 pic/tsms-icon.png create mode 100644 pic/tsms-icon.xcf create mode 100644 pic/tsms-icon0.png create mode 100644 pic/update-dingdingsecret.jpg create mode 100644 pic/webnotify.jpg create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ae21cc94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.idea/ +.gradle +.git +build +local.properties +*.iml +*.project +*/*.project +*.classpath +*/*.classpath +.settings/* +*/.settings/* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..9bf6174c --- /dev/null +++ b/README.md @@ -0,0 +1,94 @@ +# 短信转发 信息转发 TranspondSms, 把Android手动的短信通过邮件或者钉钉转出去 + + +博文连接[https://www.jianshu.com/p/608d1b1477e3] +官网[https://tsms.allmything.com] +APP下载 [https://pan.baidu.com/s/1kbelTFIf5nwkOY9g6itkvA] + + + +-------- +## 该工具实现特点和准则: +* **简单** 只做两件事:监听短信---》转发 + +由此带来的好处: +* 功能简单:(当时用Pad的时候,看手机验证码各种不方便,网上搜了好久也有解决方案) +> + AirDroid:手机管理工具功能太多,看着都耗电,权限太多,数据经过三方,账号分级 +> + IFTTT:功能太多,看着耗电,权限太多,数据经过三方,收费 +> + 还有些其他的也是这些毛病 +* 省电:运行时只监听广播,有短信才执行转发,并记录最近n条的转发内容和转发状态 +* 健壮:越简单越不会出错(UNIX设计哲学),就越少崩溃,运行越稳定持久 + +### 工作流程: +![工作流程](pic/showpic.png "工作流程") + + +### 功能列表: +| 功能 | 描述 | +| ---- | ---- | +| 转发监听 | 已实现 | +| 转发钉钉 | 单个钉钉群已实现 | +| 转发钉钉@某人 | 已实现 | +| 转发邮箱 | 单个邮箱已实现 | +| 转发企业微信群机器人 | 已实现 | +| 转发web页面 | 单个web页面已实现([向设置的url发送POST请求](doc/POST_WEB.md)) | +| 转发规则 | (规则即:什么短信转发到哪里)已实现实现 | +| 兼容 | 已兼容6.xx、7.xx、8.xx、9.xx、10.xx | + + +### 使用流程: +1. 在Android手机上安装TSMS 本APP后点击应用图标打开 +2. 在设置发送方页面,添加或点击已添加的发送方来设置转发短信使用的方式,现在支持钉钉机器人、邮箱、网页: + + 设置钉钉机器人请先在钉钉群中添加自定义机器人,复制机器人的token和secret,填入弹出框。点击测试会使用该机器人向群内发送一条消息;点击确认即可添加配置。 + + 配置邮箱请先在你邮箱的后台管理页面配置smtp选项,并设置密码(授权码),并参照说明配置TSMS弹出框的smtp信息。点击测试会使用该邮箱向配置的邮箱发送一条测试邮件;点击确认即可添加配置。 + + 配置网页通知请先在 msg.allmything.com 注册登陆并添加一个消息通道,复制消息通道token填入配置弹框。点击测试会向该消息通道推送一条测试消息,可在 msg.allmything.com 的消息页面查看(页面会自动刷新);点击确认即可添加配置。 +3. 在设置转发规则页面,添加或点击已添加的转发规则来设置转发什么样的短信,现在支持转发全部、根据手机号、根据短信内容: + + 当设置转发全部时,所以接收到的短信都会用转发出去。 + + 当设置根据手机号或短信内容时,请设置匹配的模式和值,例如:”手机号 是 10086 发送方选钉钉“。 +4. 点击主页面右上角的菜单可进入设置页面,在设置页面可以更新应用查看应用信息提交意见反馈等 +5. 在主页面下拉可刷新转发的短信,点击清空记录可删除转发的记录 + + +*注:该APP打开后会自动后台运行并在任务栏显示运行图标,请勿强杀,退出后请重新开启,并加入到系统白名单中,并允许后台运行* + + +### 应用截图: + +![主界面](pic/main.jpg "应用主界面") +![转发详情](pic/maindetail.jpg "转发详情") +![转发规则](pic/rule.jpg "转发规则") +![添加编辑转发规则](pic/ruleset.jpg "添加编辑转发规则") +![发送方](pic/sender.jpg "发送方") +![添加编辑发送方钉钉](pic/sendersetdingding.jpg "添加编辑发送方钉钉") +![添加编辑发送方邮箱](pic/sendersetemail.jpg "添加编辑发送方邮箱") +![添加编辑发送方网页通知](pic/sendersetwebnotify.jpg "添加编辑发送方网页通知") +![状态栏运行状态](pic/taskbar.jpg "状态栏运行状态") +![应用设置](pic/setting.jpg "应用设置") +![意见反馈](pic/settingfeedback.jpg "意见反馈") +![应用更新](pic/update-dingdingsecret.jpg "应用更新") + +### 更新记录: +> [v3.5.0](app/release/TSMS_release_20210126_3.5.0.apk) 1,钉钉机器人添加 @ 功能 + +> [v3.4.0](pic/TSMS_release_20210120_3.4.0.apk) 1,增加企业微信群机器人通知。2,修复设置开机启动崩溃 + +> [v3.3.0](pic/TSMS_release_20210113_3.3.0.apk) 1,增加网页通知验签。2,修复网页及钉钉配置测试崩溃 + +> [v3.2.0](pic/TSMS_release_20210106_3.2.0.apk) 1,增加邮箱SSL配置。2,邮箱测试结果通知 + +> [v3.1.0](pic/TSMS_release_20201231_3.1.0.apk) 1,界面重构。2,增加转发规则页面。3,增加发送方页面。4,升级配置页面 + +> [v2.1.0](pic/TSMS_release_20200806_2.1.0.apk) 1,增加新版钉钉群机器人安全设置中的加签 + +> [v2.00](pic/TSMS_release_20200729_2.00.apk) 1,移除热点管理,回归简单。2,修复Android9,Android10版本闪退。3,添加更新接口。4,修复bug + +> v1.1 减少手动配置启动参数:自启动配置、自动开启热点配置(设置好后手机重启也不用重新打开了,还能自动为pad开启热点) +热点管理 +可设置跟随设备启动时启动热点,并且在热点关闭后10秒自动重启热点(所以想关闭热点先把设置页码的开启热点关掉) +(热点助手功能会在后期2020/07/29转移到单独的APP)详见[https://www.jianshu.com/p/f70cf475eddc] + +> v1.0 项目初始化,实现转发 + + +## LICENSE +BSD diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..c4192631 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 00000000..1bdcb348 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,70 @@ +apply plugin: 'com.android.application' + +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "com.idormy.sms.forwarder" + minSdkVersion 23 + targetSdkVersion 28 + versionCode 1 + versionName "1.0.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + //apk file name + android.applicationVariants.all { variant -> + variant.outputs.all { + //def date = new Date().format("yyyyMMdd" , TimeZone.getTimeZone("Asia/Shanghai")) + def date = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08")) + if (variant.buildType.name.equals('debug')) { + outputFileName = "TSMS_debug_${date}_${versionName}.apk" + } + if (variant.buildType.name.equals('release')) { + outputFileName = "TSMS_release_${date}_${versionName}.apk" + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + //okhttp + implementation 'com.squareup.okhttp3:okhttp:3.6.0' + implementation 'com.squareup.okio:okio:1.11.0' + //mail + implementation 'com.sun.mail:android-mail:1.6.0' + implementation 'com.sun.mail:android-activation:1.6.0' + implementation 'com.android.support:design:28.0.0' + //android8.0以上需要使用到反射获取隐藏的系统api和动态代理隐藏的抽象类回调 + //。其中动态代理抽象类回调需要使用ProxyBuilder类,故依赖一个库 +// implementation 'com.linkedin.dexmaker:dexmaker-mockito:2.12.1' + //appupdate + implementation 'com.qianwen:update-app:3.5.2' + implementation 'com.qianwen:okhttp-utils:3.8.0' + implementation 'com.lzy.net:okgo:3.0.4' + // 友盟基础组件库(所有友盟业务SDK都依赖基础组件库) + implementation "com.umeng.umsdk:common:2.1.0" + + // 下面各SDK根据宿主App是否使用相关业务按需引入。 + // 友盟统计SDK + implementation "com.umeng.umsdk:analytics:8.1.3" + + //fastjson + implementation "com.alibaba:fastjson:1.2.75" + +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 00000000..f1b42451 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/release/output.json b/app/release/output.json new file mode 100644 index 00000000..652798b0 --- /dev/null +++ b/app/release/output.json @@ -0,0 +1,19 @@ +[ + { + "outputType": { + "type": "APK" + }, + "apkInfo": { + "type": "MAIN", + "splits": [], + "versionCode": 35, + "versionName": "3.5.0", + "enabled": true, + "outputFile": "TSMS_release_20210126_3.5.0.apk", + "fullName": "release", + "baseName": "release" + }, + "path": "TSMS_release_20210126_3.5.0.apk", + "properties": {} + } +] \ No newline at end of file diff --git a/app/src/androidTest/java/com/idormy/sms/forwarder/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/idormy/sms/forwarder/ExampleInstrumentedTest.kt new file mode 100644 index 00000000..7b7e4af7 --- /dev/null +++ b/app/src/androidTest/java/com/idormy/sms/forwarder/ExampleInstrumentedTest.kt @@ -0,0 +1,22 @@ +package com.idormy.sms.forwarder + +import android.support.test.InstrumentationRegistry +import android.support.test.runner.AndroidJUnit4 +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getTargetContext() + assertEquals("com.idormy.sms.forwarder", appContext.packageName) + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a14384b8 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..1760b0ae90e411e4e5c707c21794b2517c5a26fb GIT binary patch literal 107424 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 o(2TLM;Ng{Vg-Pghr7316)h<7FGKq!Bme*a literal 0 HcmV?d00001 diff --git a/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/MessageBroadcastReceiver.java b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/MessageBroadcastReceiver.java new file mode 100644 index 00000000..c1466a50 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/MessageBroadcastReceiver.java @@ -0,0 +1,26 @@ +package com.idormy.sms.forwarder.BroadCastReceiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; +import android.widget.Toast; + + +public class MessageBroadcastReceiver extends BroadcastReceiver { + public static String EXTRA_DATA = "data"; + public static String ACTION_DINGDING = "com.idormy.sms.forwarder.action_dingding"; + private String TAG = "MessageBroadcastReceiver"; + + @Override + public void onReceive(Context arg0, Intent intent) { + Log.d(TAG, "onReceive intent " + intent.getAction()); + String action = intent.getAction(); + if (action.equals(ACTION_DINGDING)) { + String sendStatus = intent.getStringExtra(EXTRA_DATA); + Toast.makeText(arg0, "dingding sendStatus: " + sendStatus, Toast.LENGTH_LONG).show(); + } + + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/RebootBroadcastReceiver.java b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/RebootBroadcastReceiver.java new file mode 100644 index 00000000..96cdacbe --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/RebootBroadcastReceiver.java @@ -0,0 +1,33 @@ +package com.idormy.sms.forwarder.BroadCastReceiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.util.Log; + +import com.idormy.sms.forwarder.FrontService; +import com.idormy.sms.forwarder.utils.InitUtil; + +public class RebootBroadcastReceiver extends BroadcastReceiver { + private String TAG = "RebootBroadcastReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + String receiveAction = intent.getAction(); + Log.d(TAG, "onReceive intent " + receiveAction); + if (receiveAction.equals("android.intent.action.BOOT_COMPLETED")) { + Log.d(TAG, "BOOT_COMPLETED"); + + InitUtil.init(context); + Intent frontServiceIntent = new Intent(context, FrontService.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(frontServiceIntent); + } else { + context.startService(frontServiceIntent); + } + } + + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/TSMSBroadcastReceiver.java b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/TSMSBroadcastReceiver.java new file mode 100644 index 00000000..5aace446 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/TSMSBroadcastReceiver.java @@ -0,0 +1,68 @@ +package com.idormy.sms.forwarder.BroadCastReceiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.telephony.SmsMessage; +import android.util.Log; + +import com.idormy.sms.forwarder.model.vo.SmsVo; +import com.idormy.sms.forwarder.utils.SendUtil; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class TSMSBroadcastReceiver extends BroadcastReceiver { + private String TAG = "TSMSBroadcastReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + String receiveAction = intent.getAction(); + Log.d(TAG, "onReceive intent " + receiveAction); + if (receiveAction.equals("android.provider.Telephony.SMS_RECEIVED")) { + try { + + Object[] object = (Object[]) Objects.requireNonNull(intent.getExtras()).get("pdus"); + if (object != null) { + List smsVoList = new ArrayList<>(); + String format = intent.getStringExtra("format"); + Map mobileToContent = new HashMap<>(); + Date date = new Date(); + for (Object pdus : object) { + byte[] pdusMsg = (byte[]) pdus; + SmsMessage sms = SmsMessage.createFromPdu(pdusMsg, format); + String mobile = sms.getOriginatingAddress();//发送短信的手机号 + if (mobile == null) { + continue; + } + //下面是获取短信的发送时间 + date = new Date(sms.getTimestampMillis()); + + String content = mobileToContent.get(mobile); + if (content == null) content = ""; + + content += sms.getMessageBody();//短信内容 + mobileToContent.put(mobile, content); + + } + for (String mobile : mobileToContent.keySet()) { + smsVoList.add(new SmsVo(mobile, mobileToContent.get(mobile), date)); + } + Log.d(TAG, "短信:" + smsVoList); + SendUtil.send_msg_list(context, smsVoList); + + } + + } catch (Throwable throwable) { + Log.e(TAG, "解析短信失败:" + throwable.getMessage()); + } + + } + + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/FrontService.java b/app/src/main/java/com/idormy/sms/forwarder/FrontService.java new file mode 100644 index 00000000..10b35002 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/FrontService.java @@ -0,0 +1,59 @@ +package com.idormy.sms.forwarder; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.support.annotation.Nullable; +import android.util.Log; + + +public class FrontService extends Service { + private static final String TAG = "FrontService"; + private static final String CHANNEL_ONE_ID = "com.idormy.sms.forwarder"; + private static final String CHANNEL_ONE_NAME = "com.idormy.sms.forwarderName"; + + @Override + public void onCreate() { + super.onCreate(); + Log.i(TAG, "onCreate"); + Notification.Builder builder = new Notification.Builder(this); + builder.setSmallIcon(R.mipmap.ic_launchert); + builder.setContentTitle("短信转发器"); + builder.setContentText("根据规则转发到钉钉/微信/邮箱/bark/webhook等"); + Intent intent = new Intent(this, MainActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity + (this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + builder.setContentIntent(pendingIntent); + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + //修改安卓8.1以上系统报错 + NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_MIN); + notificationChannel.enableLights(false);//如果使用中的设备支持通知灯,则说明此通知通道是否应显示灯 + notificationChannel.setShowBadge(false);//是否显示角标 + notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET); + NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + manager.createNotificationChannel(notificationChannel); + builder.setChannelId(CHANNEL_ONE_ID); + } + + Notification notification = builder.build(); + startForeground(1, notification); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.i(TAG, "flags: " + flags + " startId: " + startId); + return START_STICKY; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java b/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java new file mode 100644 index 00000000..97da1284 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java @@ -0,0 +1,227 @@ +package com.idormy.sms.forwarder; + +import android.Manifest; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.ActivityCompat; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; + +import com.idormy.sms.forwarder.BroadCastReceiver.TSMSBroadcastReceiver; +import com.idormy.sms.forwarder.adapter.LogAdapter; +import com.idormy.sms.forwarder.model.LogModel; +import com.idormy.sms.forwarder.model.vo.LogVo; +import com.idormy.sms.forwarder.utils.LogUtil; +import com.umeng.analytics.MobclickAgent; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class MainActivity extends AppCompatActivity implements ReFlashListView.IReflashListener { + + private IntentFilter intentFilter; + private TSMSBroadcastReceiver smsBroadcastReceiver; + private String TAG = "MainActivity"; + // logVoList用于存储数据 + private List logVos = new ArrayList<>(); + private LogAdapter adapter; + private ReFlashListView listView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.d(TAG, "oncreate"); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + LogUtil.init(this); + // 先拿到数据并放在适配器上 + initTLogs(); //初始化数据 + showList(logVos); + + // 为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法 + // 在这个方法中可以通过position参数判断出用户点击的是那一个子项 + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + LogVo logVo = logVos.get(position - 1); + logDetail(logVo); +// Toast.makeText(MainActivity.this,String.valueOf(position),Toast.LENGTH_SHORT).show(); + } + }); + +// textv_msg.setMovementMethod(ScrollingMovementMethod.getInstance()); +// textv_msg.setText(SendHistory.getHistory()); + + checkPermission(); + +// intentFilter=new IntentFilter(); +// intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED"); +// intentFilter.addAction(MessageBroadcastReceiver.ACTION_DINGDING); +// smsBroadcastReceiver=new SMSBroadcastReceiver(); +// //动态注册广播 +// registerReceiver(smsBroadcastReceiver, intentFilter); + } + + // 初始化数据 + private void initTLogs() { + logVos = LogUtil.getLog(null, null); + } + + private void showList(List logVosN) { + Log.d(TAG, "showList: " + logVosN); + if (adapter == null) { + // 将适配器上的数据传递给listView + listView = findViewById(R.id.list_view_log); + listView.setInterface(this); + adapter = new LogAdapter(MainActivity.this, R.layout.tlog_item, logVosN); + + listView.setAdapter(adapter); + } else { + adapter.onDateChange(logVosN); + } + } + + @Override + public void onReflash() { + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + + @Override + public void run() { + // TODO Auto-generated method stub + //获取最新数据 + initTLogs(); + //通知界面显示 + showList(logVos); + //通知listview 刷新数据完毕; + listView.reflashComplete(); + } + }, 2000); + } + + @Override + protected void onDestroy() { + Log.d(TAG, "onDestroy"); + super.onDestroy(); + //取消注册广播 + unregisterReceiver(smsBroadcastReceiver); + } + + public void logDetail(LogVo logVo) { + AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); + builder.setTitle("详情"); + builder.setMessage(logVo.getFrom() + "\n" + logVo.getContent() + "\n" + logVo.getRule() + "\n" + logVo.getTime()); + builder.show(); + } + + public void toSetting() { + Intent intent = new Intent(this, SettingActivity.class); + startActivity(intent); + } + + public void toRuleSetting(View view) { + Intent intent = new Intent(this, RuleActivity.class); + startActivity(intent); + } + + public void toSendSetting(View view) { + Intent intent = new Intent(this, SenderActivity.class); + startActivity(intent); + } + + public void cleanLog(View view) { + AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); + builder.setTitle("确定要清空转发记录吗?") + .setPositiveButton("清空", new DialogInterface.OnClickListener() {// 积极 + + @Override + public void onClick(DialogInterface dialog, + int which) { + // TODO Auto-generated method stub + LogUtil.delLog(null, null); + initTLogs(); + adapter.add(logVos); + } + }); + builder.show(); + + } + + public void addLog(View view) { + Log.d(TAG, "refreshLog"); + LogModel newModel = new LogModel("199999", "content" + (new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date())), 1l); + LogUtil.addLog(newModel); +// initTLogs(); +// adapter.add(logVos); + } + + //按返回键不退出回到桌面 + @Override + public void onBackPressed() { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addCategory(Intent.CATEGORY_HOME); + startActivity(intent); + } + + private void checkPermission() { + // 检查权限是否获取(android6.0及以上系统可能默认关闭权限,且没提示) + PackageManager pm = getPackageManager(); + boolean permission_receive_boot = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.RECEIVE_BOOT_COMPLETED", this.getPackageName())); + boolean permission_readsms = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.READ_SMS", this.getPackageName())); + + if (!( + permission_receive_boot + && permission_readsms + )) { + ActivityCompat.requestPermissions(this, new String[]{ + Manifest.permission.RECEIVE_BOOT_COMPLETED, + Manifest.permission.READ_SMS, + }, 0x01); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.to_setting: + toSetting(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_main, menu); + return true; + + } + + @Override + protected void onResume() { + super.onResume(); + MobclickAgent.onResume(this); + } + + @Override + protected void onPause() { + super.onPause(); + MobclickAgent.onPause(this); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java b/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java new file mode 100644 index 00000000..e476b40d --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java @@ -0,0 +1,82 @@ +package com.idormy.sms.forwarder; + +import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.text.TextUtils; +import android.util.Log; + +import com.idormy.sms.forwarder.utils.SendHistory; +import com.idormy.sms.forwarder.utils.SettingUtil; +import com.umeng.analytics.MobclickAgent; +import com.umeng.commonsdk.UMConfigure; + +public class MyApplication extends Application { + private static final String TAG = "MyApplication"; + + /** + * + * + * + * @param ctx + * @return + */ + // 获取渠道工具函数 + public static String getChannelName(Context ctx) { + if (ctx == null) { + return null; + } + String channelName = null; + try { + PackageManager packageManager = ctx.getPackageManager(); + if (packageManager != null) { + //注意此处为ApplicationInfo 而不是 ActivityInfo,因为友盟设置的meta-data是在application标签中,而不是activity标签中,所以用ApplicationInfo + ApplicationInfo applicationInfo = packageManager.getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA); + if (applicationInfo != null) { + if (applicationInfo.metaData != null) { + channelName = applicationInfo.metaData.get("UMENG_CHANNEL") + ""; + } + } + } + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (TextUtils.isEmpty(channelName)) { + channelName = "Unknown"; + } + Log.d(TAG, "getChannelName: " + channelName); + return channelName; + } + + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + } + + @Override + public void onCreate() { + Log.d(TAG, "onCreate"); + super.onCreate(); + //初始化组件化基础库, 所有友盟业务SDK都必须调用此初始化接口。 + //建议在宿主App的Application.onCreate函数中调用基础组件库初始化函数。 + UMConfigure.init(this, "5f217c02b4b08b653e8f6b3d", getChannelName(this), UMConfigure.DEVICE_TYPE_PHONE, ""); + // 选用LEGACY_AUTO页面采集模式 + MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.LEGACY_MANUAL); + //pro close log + UMConfigure.setLogEnabled(true); + Log.i(TAG, "uminit"); + Intent intent = new Intent(this, FrontService.class); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForegroundService(intent); + } else { + startService(intent); + } + SendHistory.init(this); + SettingUtil.init(this); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/ReFlashListView.java b/app/src/main/java/com/idormy/sms/forwarder/ReFlashListView.java new file mode 100644 index 00000000..ea15a998 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/ReFlashListView.java @@ -0,0 +1,272 @@ +package com.idormy.sms.forwarder; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.RotateAnimation; +import android.widget.AbsListView; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 自定义listview + */ +public class ReFlashListView extends ListView implements AbsListView.OnScrollListener { + private static final String TAG = "ReFlashListView"; + final int NONE = 0;// 正常状态; + final int PULL = 1;// 提示下拉状态; + final int RELESE = 2;// 提示释放状态; + final int REFLASHING = 3;// 刷新状态; + View header;// 顶部布局文件; + int headerHeight;// 顶部布局文件的高度; + int firstVisibleItem;// 当前第一个可见的item的位置; + int scrollState;// listview 当前滚动状态; + boolean isRemark;// 标记,当前是在listview最顶端摁下的; + int startY;// 摁下时的Y值; + int state;// 当前的状态; + IReflashListener iReflashListener;//刷新数据的接口 + + public ReFlashListView(Context context) { + super(context); + // TODO Auto-generated constructor stub + initView(context); + } + + public ReFlashListView(Context context, AttributeSet attrs) { + super(context, attrs); + // TODO Auto-generated constructor stub + initView(context); + } + + public ReFlashListView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + // TODO Auto-generated constructor stub + initView(context); + } + + /** + * 初始化界面,添加顶部布局文件到 listview + * + * @param context + */ + private void initView(Context context) { + LayoutInflater inflater = LayoutInflater.from(context); + header = inflater.inflate(R.layout.header_layout, null); + measureView(header); + headerHeight = header.getMeasuredHeight(); + Log.i("tag", "headerHeight = " + headerHeight); + topPadding(-headerHeight); + this.addHeaderView(header); + this.setOnScrollListener(this); + } + + /** + * 通知父布局,占用的宽,高; + * + * @param view + */ + private void measureView(View view) { + ViewGroup.LayoutParams p = view.getLayoutParams(); + if (p == null) { + p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + } + int width = ViewGroup.getChildMeasureSpec(0, 0, p.width); + int height; + int tempHeight = p.height; + if (tempHeight > 0) { + height = MeasureSpec.makeMeasureSpec(tempHeight, + MeasureSpec.EXACTLY); + } else { + height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + } + view.measure(width, height); + } + + /** + * 设置header 布局 上边距; + * + * @param topPadding + */ + private void topPadding(int topPadding) { + header.setPadding(header.getPaddingLeft(), topPadding, + header.getPaddingRight(), header.getPaddingBottom()); + header.invalidate(); + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, + int visibleItemCount, int totalItemCount) { + // TODO Auto-generated method stub + this.firstVisibleItem = firstVisibleItem; + } + + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + // TODO Auto-generated method stub + this.scrollState = scrollState; + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + // TODO Auto-generated method stub + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: + if (firstVisibleItem == 0) { + isRemark = true; + startY = (int) ev.getY(); + } + break; + + case MotionEvent.ACTION_MOVE: + onMove(ev); + break; + case MotionEvent.ACTION_UP: + if (state == RELESE || state == PULL) { + state = REFLASHING; + // 加载最新数据; + reflashViewByState(); + iReflashListener.onReflash(); + } +// if (state == RELESE) { +// Log.d(TAG, "onTouchEvent: up release"); +// state = REFLASHING; +// // 加载最新数据; +// reflashViewByState(); +// iReflashListener.onReflash(); +// } else if (state == PULL) { +// Log.d(TAG, "onTouchEvent: up pull"); +// state = NONE; +// isRemark = false; +// reflashViewByState(); +// } + break; + } + return super.onTouchEvent(ev); + } + + /** + * 判断移动过程操作; + * + * @param ev + */ + private void onMove(MotionEvent ev) { + if (!isRemark) { + return; + } + int tempY = (int) ev.getY(); + int space = tempY - startY; + int topPadding = space - headerHeight; + switch (state) { + case NONE: + if (space > 0) { + state = PULL; + reflashViewByState(); + } + break; + case PULL: + topPadding(topPadding); + if (space > headerHeight + 30 + && scrollState == SCROLL_STATE_TOUCH_SCROLL) { + state = RELESE; + reflashViewByState(); + } + break; + case RELESE: + topPadding(topPadding); + if (space < headerHeight + 30) { + state = PULL; + reflashViewByState(); + } else if (space <= 0) { + state = NONE; + isRemark = false; + reflashViewByState(); + } + break; + } + } + + /** + * 根据当前状态,改变界面显示; + */ + private void reflashViewByState() { + TextView tip = (TextView) header.findViewById(R.id.tip); + ImageView arrow = (ImageView) header.findViewById(R.id.arrow); + ProgressBar progress = (ProgressBar) header.findViewById(R.id.progress); + RotateAnimation anim = new RotateAnimation(0, 180, + RotateAnimation.RELATIVE_TO_SELF, 0.5f, + RotateAnimation.RELATIVE_TO_SELF, 0.5f); + anim.setDuration(500); + anim.setFillAfter(true); + RotateAnimation anim1 = new RotateAnimation(180, 0, + RotateAnimation.RELATIVE_TO_SELF, 0.5f, + RotateAnimation.RELATIVE_TO_SELF, 0.5f); + anim1.setDuration(500); + anim1.setFillAfter(true); + switch (state) { + case NONE: + arrow.clearAnimation(); + topPadding(-headerHeight); + break; + + case PULL: + arrow.setVisibility(View.VISIBLE); + progress.setVisibility(View.GONE); + tip.setText("下拉可以刷新!"); + arrow.clearAnimation(); + arrow.setAnimation(anim1); + break; + case RELESE: + arrow.setVisibility(View.VISIBLE); + progress.setVisibility(View.GONE); + tip.setText("松开可以刷新!"); + arrow.clearAnimation(); + arrow.setAnimation(anim); + break; + case REFLASHING: + topPadding(50); + arrow.setVisibility(View.GONE); + progress.setVisibility(View.VISIBLE); + tip.setText("正在刷新..."); + arrow.clearAnimation(); + break; + } + } + + /** + * 获取完数据; + */ + public void reflashComplete() { + state = NONE; + isRemark = false; + reflashViewByState(); + TextView lastupdatetime = (TextView) header + .findViewById(R.id.lastupdate_time); + SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss"); + Date date = new Date(System.currentTimeMillis()); + String time = format.format(date); + lastupdatetime.setText(time); + } + + public void setInterface(IReflashListener iReflashListener) { + this.iReflashListener = iReflashListener; + } + + /** + * 刷新数据接口 + * + * @author Administrator + */ + public interface IReflashListener { + public void onReflash(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java b/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java new file mode 100644 index 00000000..c455eaf5 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/RuleActivity.java @@ -0,0 +1,201 @@ +package com.idormy.sms.forwarder; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.RadioGroup; +import android.widget.TextView; +import android.widget.Toast; + +import com.idormy.sms.forwarder.adapter.RuleAdapter; +import com.idormy.sms.forwarder.model.RuleModel; +import com.idormy.sms.forwarder.model.SenderModel; +import com.idormy.sms.forwarder.utils.RuleUtil; +import com.idormy.sms.forwarder.utils.SenderUtil; +import com.umeng.analytics.MobclickAgent; + +import java.util.ArrayList; +import java.util.List; + +public class RuleActivity extends AppCompatActivity { + + private String TAG = "RuleActivity"; + // 用于存储数据 + private List ruleModels = new ArrayList<>(); + private RuleAdapter adapter; + private Long selectSenderId = 0l; + private String selectSenderName = ""; + + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.d(TAG, "oncreate"); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_sender); + RuleUtil.init(RuleActivity.this); + SenderUtil.init(RuleActivity.this); + + // 先拿到数据并放在适配器上 + initRules(); //初始化数据 + adapter = new RuleAdapter(RuleActivity.this, R.layout.rule_item, ruleModels); + + // 将适配器上的数据传递给listView + ListView listView = findViewById(R.id.list_view_sender); + listView.setAdapter(adapter); + + // 为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法 + // 在这个方法中可以通过position参数判断出用户点击的是那一个子项 + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + RuleModel ruleModel = ruleModels.get(position); + Log.d(TAG, "onItemClick: " + ruleModel); + setRule(ruleModel); + } + }); + + + } + + // 初始化数据 + private void initRules() { + ruleModels = RuleUtil.getRule(null, null); + } + + public void addSender(View view) { + setRule(null); + } + + + private void setRule(final RuleModel ruleModel) { + final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(RuleActivity.this); + final View view1 = View.inflate(RuleActivity.this, R.layout.activity_alter_dialog_setview_rule, null); + + final RadioGroup radioGroupRuleFiled = (RadioGroup) view1.findViewById(R.id.radioGroupRuleFiled); + if (ruleModel != null) radioGroupRuleFiled.check(ruleModel.getRuleFiledCheckId()); + + final RadioGroup radioGroupRuleCheck = (RadioGroup) view1.findViewById(R.id.radioGroupRuleCheck); + if (ruleModel != null) radioGroupRuleCheck.check(ruleModel.getRuleCheckCheckId()); + + final TextView ruleSenderTv = (TextView) view1.findViewById(R.id.ruleSenderTv); + if (ruleModel != null && ruleModel.getSenderId() != null) { + List getSeners = SenderUtil.getSender(ruleModel.getSenderId(), null); + if (!getSeners.isEmpty()) { + ruleSenderTv.setText(getSeners.get(0).getName()); + ruleSenderTv.setTag(getSeners.get(0).getId()); + } + } + final Button btSetRuleSender = (Button) view1.findViewById(R.id.btSetRuleSender); + btSetRuleSender.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Toast.makeText(RuleActivity.this, "selectSender", Toast.LENGTH_LONG).show(); + selectSender(ruleSenderTv); + } + }); + + final EditText editTextRuleValue = view1.findViewById(R.id.editTextRuleValue); + if (ruleModel != null) + editTextRuleValue.setText(ruleModel.getValue()); + + Button buttonruleok = view1.findViewById(R.id.buttonruleok); + Button buttonruledel = view1.findViewById(R.id.buttonruledel); + alertDialog71 + .setTitle(R.string.setrule) + .setView(view1) + .create(); + final AlertDialog show = alertDialog71.show(); + buttonruleok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Object senderId = ruleSenderTv.getTag(); + if (ruleModel == null) { + RuleModel newRuleModel = new RuleModel(); + newRuleModel.setFiled(RuleModel.getRuleFiledFromCheckId(radioGroupRuleFiled.getCheckedRadioButtonId())); + newRuleModel.setCheck(RuleModel.getRuleCheckFromCheckId(radioGroupRuleCheck.getCheckedRadioButtonId())); + newRuleModel.setValue(editTextRuleValue.getText().toString()); + if (senderId != null) { + newRuleModel.setSenderId(Long.valueOf(senderId.toString())); + } + RuleUtil.addRule(newRuleModel); + initRules(); + adapter.add(ruleModels); + } else { + ruleModel.setFiled(RuleModel.getRuleFiledFromCheckId(radioGroupRuleFiled.getCheckedRadioButtonId())); + ruleModel.setCheck(RuleModel.getRuleCheckFromCheckId(radioGroupRuleCheck.getCheckedRadioButtonId())); + ruleModel.setValue(editTextRuleValue.getText().toString()); + if (senderId != null) { + ruleModel.setSenderId(Long.valueOf(senderId.toString())); + } + RuleUtil.updateRule(ruleModel); + initRules(); + adapter.update(ruleModels); + } + + show.dismiss(); + + + } + }); + buttonruledel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (ruleModel != null) { + RuleUtil.delRule(ruleModel.getId()); + initRules(); + adapter.del(ruleModels); + } + show.dismiss(); + } + }); + } + + public void selectSender(final TextView showTv) { + final List senderModels = SenderUtil.getSender(null, null); + if (senderModels.isEmpty()) { + Toast.makeText(RuleActivity.this, "请先去设置发送方页面添加", Toast.LENGTH_SHORT).show(); + return; + } + final CharSequence[] senderNames = new CharSequence[senderModels.size()]; + for (int i = 0; i < senderModels.size(); i++) { + senderNames[i] = senderModels.get(i).getName(); + } + AlertDialog.Builder builder = new AlertDialog.Builder(RuleActivity.this); + builder.setTitle("选择发送方"); + builder.setItems(senderNames, new DialogInterface.OnClickListener() {//添加列表 + @Override + public void onClick(DialogInterface dialogInterface, int which) { + Toast.makeText(RuleActivity.this, senderNames[which], Toast.LENGTH_LONG).show(); + showTv.setText(senderNames[which]); + showTv.setTag(senderModels.get(which).getId()); + } + }); + builder.show(); + } + + @Override + protected void onDestroy() { + Log.d(TAG, "onDestroy"); + super.onDestroy(); + } + + + @Override + protected void onResume() { + super.onResume(); + MobclickAgent.onResume(this); + } + + @Override + protected void onPause() { + super.onPause(); + MobclickAgent.onPause(this); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java b/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java new file mode 100644 index 00000000..b1306585 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java @@ -0,0 +1,681 @@ +package com.idormy.sms.forwarder; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.Switch; +import android.widget.Toast; + +import com.alibaba.fastjson.JSON; +import com.idormy.sms.forwarder.adapter.SenderAdapter; +import com.idormy.sms.forwarder.model.SenderModel; +import com.idormy.sms.forwarder.model.vo.BarkSettingVo; +import com.idormy.sms.forwarder.model.vo.DingDingSettingVo; +import com.idormy.sms.forwarder.model.vo.EmailSettingVo; +import com.idormy.sms.forwarder.model.vo.QYWXGroupRobotSettingVo; +import com.idormy.sms.forwarder.model.vo.WebNotifySettingVo; +import com.idormy.sms.forwarder.utils.SenderBarkMsg; +import com.idormy.sms.forwarder.utils.SenderDingdingMsg; +import com.idormy.sms.forwarder.utils.SenderMailMsg; +import com.idormy.sms.forwarder.utils.SenderQyWxGroupRobotMsg; +import com.idormy.sms.forwarder.utils.SenderUtil; +import com.idormy.sms.forwarder.utils.SenderWebNotifyMsg; +import com.umeng.analytics.MobclickAgent; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static com.idormy.sms.forwarder.model.SenderModel.STATUS_ON; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_BARK; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_DINGDING; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_EMAIL; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_GROUP_ROBOT; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_WEB_NOTIFY; + +public class SenderActivity extends AppCompatActivity { + + public static final int NOTIFY = 0x9731993; + private String TAG = "SenderActivity"; + // 用于存储数据 + private List senderModels = new ArrayList<>(); + private SenderAdapter adapter; + //消息处理者,创建一个Handler的子类对象,目的是重写Handler的处理消息的方法(handleMessage()) + private Handler handler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case NOTIFY: + Toast.makeText(SenderActivity.this, msg.getData().getString("DATA"), Toast.LENGTH_LONG).show(); + break; + } + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.d(TAG, "oncreate"); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_sender); + SenderUtil.init(SenderActivity.this); + + // 先拿到数据并放在适配器上 + initSenders(); //初始化数据 + adapter = new SenderAdapter(SenderActivity.this, R.layout.sender_item, senderModels); + + // 将适配器上的数据传递给listView + ListView listView = findViewById(R.id.list_view_sender); + listView.setAdapter(adapter); + + // 为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法 + // 在这个方法中可以通过position参数判断出用户点击的是那一个子项 + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + SenderModel senderModel = senderModels.get(position); + Log.d(TAG, "onItemClick: " + senderModel); + + switch (senderModel.getType()) { + case TYPE_DINGDING: + setDingDing(senderModel); + break; + case TYPE_EMAIL: + setEmail(senderModel); + break; + case TYPE_WEB_NOTIFY: + setWebNotify(senderModel); + break; + case TYPE_QYWX_GROUP_ROBOT: + setQYWXGroupRobot(senderModel); + break; + case TYPE_BARK: + setBark(senderModel); + break; + default: + Toast.makeText(SenderActivity.this, "异常的发送方类型!删除", Toast.LENGTH_LONG).show(); + break; + } + + } + }); + + + } + + // 初始化数据 + private void initSenders() { + senderModels = SenderUtil.getSender(null, null); + ; + } + + public void addSender(View view) { + AlertDialog.Builder builder = new AlertDialog.Builder(SenderActivity.this); + builder.setTitle("选择发送方类型"); + builder.setItems(R.array.add_sender_menu, new DialogInterface.OnClickListener() {//添加列表 + @Override + public void onClick(DialogInterface dialogInterface, int which) { + switch (which) { + case TYPE_DINGDING: + setDingDing(null); + break; + case TYPE_EMAIL: + setEmail(null); + break; + case TYPE_WEB_NOTIFY: + setWebNotify(null); + break; + case TYPE_QYWX_GROUP_ROBOT: + setQYWXGroupRobot(null); + break; + case TYPE_BARK: + setBark(null); + break; + default: + Toast.makeText(SenderActivity.this, "暂不支持这种转发!", Toast.LENGTH_LONG).show(); + break; + } + } + }); + builder.show(); + Log.d(TAG, "setDingDing show" + senderModels.size()); + } + + + private void setDingDing(final SenderModel senderModel) { + DingDingSettingVo dingDingSettingVo = null; + //try phrase json setting + if (senderModel != null) { + String jsonSettingStr = senderModel.getJsonSetting(); + if (jsonSettingStr != null) { + dingDingSettingVo = JSON.parseObject(jsonSettingStr, DingDingSettingVo.class); + } + } + final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this); + View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_dingding, null); + + final EditText editTextDingdingName = view1.findViewById(R.id.editTextDingdingName); + if (senderModel != null) + editTextDingdingName.setText(senderModel.getName()); + final EditText editTextDingdingToken = view1.findViewById(R.id.editTextDingdingToken); + if (dingDingSettingVo != null) + editTextDingdingToken.setText(dingDingSettingVo.getToken()); + final EditText editTextDingdingSecret = view1.findViewById(R.id.editTextDingdingSecret); + if (dingDingSettingVo != null) + editTextDingdingSecret.setText(dingDingSettingVo.getSecret()); + final EditText editTextDingdingAtMobiles = view1.findViewById(R.id.editTextDingdingAtMobiles); + if (dingDingSettingVo != null && dingDingSettingVo.getAtMobils() != null) + editTextDingdingAtMobiles.setText(dingDingSettingVo.getAtMobils()); + final Switch switchDingdingAtAll = view1.findViewById(R.id.switchDingdingAtAll); + if (dingDingSettingVo != null && dingDingSettingVo.getAtAll() != null) + switchDingdingAtAll.setChecked(dingDingSettingVo.getAtAll()); + + Button buttondingdingok = view1.findViewById(R.id.buttondingdingok); + Button buttondingdingdel = view1.findViewById(R.id.buttondingdingdel); + Button buttondingdingtest = view1.findViewById(R.id.buttondingdingtest); + alertDialog71 + .setTitle(R.string.setdingdingtitle) + .setIcon(R.mipmap.dingding) + .setView(view1) + .create(); + final AlertDialog show = alertDialog71.show(); + buttondingdingok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + if (senderModel == null) { + SenderModel newSenderModel = new SenderModel(); + newSenderModel.setName(editTextDingdingName.getText().toString()); + newSenderModel.setType(TYPE_DINGDING); + newSenderModel.setStatus(STATUS_ON); + DingDingSettingVo dingDingSettingVonew = new DingDingSettingVo( + editTextDingdingToken.getText().toString(), + editTextDingdingSecret.getText().toString(), + editTextDingdingAtMobiles.getText().toString(), + switchDingdingAtAll.isChecked()); + newSenderModel.setJsonSetting(JSON.toJSONString(dingDingSettingVonew)); + SenderUtil.addSender(newSenderModel); + initSenders(); + adapter.add(senderModels); +// adapter.add(newSenderModel); + } else { + senderModel.setName(editTextDingdingName.getText().toString()); + senderModel.setType(TYPE_DINGDING); + senderModel.setStatus(STATUS_ON); + DingDingSettingVo dingDingSettingVonew = new DingDingSettingVo( + editTextDingdingToken.getText().toString(), + editTextDingdingSecret.getText().toString(), + editTextDingdingAtMobiles.getText().toString(), + switchDingdingAtAll.isChecked()); + senderModel.setJsonSetting(JSON.toJSONString(dingDingSettingVonew)); + SenderUtil.updateSender(senderModel); + initSenders(); + adapter.update(senderModels); +// adapter.update(senderModel,position); + } + + + show.dismiss(); + + + } + }); + buttondingdingdel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (senderModel != null) { + SenderUtil.delSender(senderModel.getId()); + initSenders(); + adapter.del(senderModels); +// adapter.del(position); + + } + show.dismiss(); + } + }); + buttondingdingtest.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String token = editTextDingdingToken.getText().toString(); + String secret = editTextDingdingSecret.getText().toString(); + String atMobiles = editTextDingdingAtMobiles.getText().toString(); + Boolean atAll = switchDingdingAtAll.isChecked(); + if (token != null && !token.isEmpty()) { + try { + SenderDingdingMsg.sendMsg(handler, token, secret, atMobiles, atAll, "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))); + } catch (Exception e) { + Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show(); + e.printStackTrace(); + } + } else { + Toast.makeText(SenderActivity.this, "token 不能为空", Toast.LENGTH_LONG).show(); + } + } + }); + } + + private void setEmail(final SenderModel senderModel) { + EmailSettingVo emailSettingVo = null; + //try phrase json setting + if (senderModel != null) { + String jsonSettingStr = senderModel.getJsonSetting(); + if (jsonSettingStr != null) { + emailSettingVo = JSON.parseObject(jsonSettingStr, EmailSettingVo.class); + } + } + + final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this); + View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_email, null); + + final EditText editTextEmailName = view1.findViewById(R.id.editTextEmailName); + if (senderModel != null) editTextEmailName.setText(senderModel.getName()); + final EditText editTextEmailHost = view1.findViewById(R.id.editTextEmailHost); + if (emailSettingVo != null) editTextEmailHost.setText(emailSettingVo.getHost()); + final EditText editTextEmailPort = view1.findViewById(R.id.editTextEmailPort); + if (emailSettingVo != null) editTextEmailPort.setText(emailSettingVo.getPort()); + + final Switch switchEmailSSl = view1.findViewById(R.id.switchEmailSSl); + if (emailSettingVo != null) switchEmailSSl.setChecked(emailSettingVo.getSsl()); + final EditText editTextEmailFromAdd = view1.findViewById(R.id.editTextEmailFromAdd); + if (emailSettingVo != null) editTextEmailFromAdd.setText(emailSettingVo.getFromEmail()); + final EditText editTextEmailPsw = view1.findViewById(R.id.editTextEmailPsw); + if (emailSettingVo != null) editTextEmailPsw.setText(emailSettingVo.getPwd()); + final EditText editTextEmailToAdd = view1.findViewById(R.id.editTextEmailToAdd); + if (emailSettingVo != null) editTextEmailToAdd.setText(emailSettingVo.getToEmail()); + + Button buttonemailok = view1.findViewById(R.id.buttonemailok); + Button buttonemaildel = view1.findViewById(R.id.buttonemaildel); + Button buttonemailtest = view1.findViewById(R.id.buttonemailtest); + alertDialog71 + .setTitle(R.string.setemailtitle) + .setIcon(R.drawable.ic_baseline_email_24) + .setView(view1) + .create(); + final AlertDialog show = alertDialog71.show(); + + buttonemailok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + if (senderModel == null) { + SenderModel newSenderModel = new SenderModel(); + newSenderModel.setName(editTextEmailName.getText().toString()); + newSenderModel.setType(TYPE_EMAIL); + newSenderModel.setStatus(STATUS_ON); + EmailSettingVo emailSettingVonew = new EmailSettingVo( + editTextEmailHost.getText().toString(), + editTextEmailPort.getText().toString(), + switchEmailSSl.isChecked(), + editTextEmailFromAdd.getText().toString(), + editTextEmailPsw.getText().toString(), + editTextEmailToAdd.getText().toString() + ); + newSenderModel.setJsonSetting(JSON.toJSONString(emailSettingVonew)); + SenderUtil.addSender(newSenderModel); + initSenders(); + adapter.add(senderModels); + } else { + senderModel.setName(editTextEmailName.getText().toString()); + senderModel.setType(TYPE_EMAIL); + senderModel.setStatus(STATUS_ON); + EmailSettingVo emailSettingVonew = new EmailSettingVo( + editTextEmailHost.getText().toString(), + editTextEmailPort.getText().toString(), + switchEmailSSl.isChecked(), + editTextEmailFromAdd.getText().toString(), + editTextEmailPsw.getText().toString(), + editTextEmailToAdd.getText().toString() + ); + senderModel.setJsonSetting(JSON.toJSONString(emailSettingVonew)); + SenderUtil.updateSender(senderModel); + initSenders(); + adapter.update(senderModels); + } + + + show.dismiss(); + + + } + }); + buttonemaildel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (senderModel != null) { + SenderUtil.delSender(senderModel.getId()); + initSenders(); + adapter.del(senderModels); + } + show.dismiss(); + } + }); + buttonemailtest.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String host = editTextEmailHost.getText().toString(); + String port = editTextEmailPort.getText().toString(); + Boolean ssl = switchEmailSSl.isChecked(); + String fromemail = editTextEmailFromAdd.getText().toString(); + String pwd = editTextEmailPsw.getText().toString(); + String toemail = editTextEmailToAdd.getText().toString(); + if (!host.isEmpty() && !port.isEmpty() && !fromemail.isEmpty() && !pwd.isEmpty() && !toemail.isEmpty()) { + try { + SenderMailMsg.sendEmail(handler, host, port, ssl, fromemail, pwd, toemail, "SmsForwarder Title", "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))); + } catch (Exception e) { + Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show(); + e.printStackTrace(); + } + } else { + Toast.makeText(SenderActivity.this, "token 不能为空", Toast.LENGTH_LONG).show(); + } + } + }); + } + + private void setWebNotify(final SenderModel senderModel) { + WebNotifySettingVo webNotifySettingVo = null; + //try phrase json setting + if (senderModel != null) { + String jsonSettingStr = senderModel.getJsonSetting(); + if (jsonSettingStr != null) { + webNotifySettingVo = JSON.parseObject(jsonSettingStr, WebNotifySettingVo.class); + } + } + + final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this); + View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_webnotify, null); + + final EditText editTextWebNotifyName = view1.findViewById(R.id.editTextWebNotifyName); + if (senderModel != null) editTextWebNotifyName.setText(senderModel.getName()); + final EditText editTextWebNotifyToken = view1.findViewById(R.id.editTextWebNotifyToken); + if (webNotifySettingVo != null) + editTextWebNotifyToken.setText(webNotifySettingVo.getToken()); + final EditText editTextWebNotifySecret = view1.findViewById(R.id.editTextWebNotifySecret); + if (webNotifySettingVo != null) + editTextWebNotifySecret.setText(webNotifySettingVo.getSecret()); + + Button buttonbebnotifyok = view1.findViewById(R.id.buttonbebnotifyok); + Button buttonbebnotifydel = view1.findViewById(R.id.buttonbebnotifydel); + Button buttonbebnotifytest = view1.findViewById(R.id.buttonbebnotifytest); + alertDialog71 + .setTitle(R.string.setwebnotifytitle) + .setIcon(R.mipmap.ic_launcher) + .setView(view1) + .create(); + final AlertDialog show = alertDialog71.show(); + + buttonbebnotifyok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + if (senderModel == null) { + SenderModel newSenderModel = new SenderModel(); + newSenderModel.setName(editTextWebNotifyName.getText().toString()); + newSenderModel.setType(TYPE_WEB_NOTIFY); + newSenderModel.setStatus(STATUS_ON); + WebNotifySettingVo webNotifySettingVoNew = new WebNotifySettingVo( + editTextWebNotifyToken.getText().toString(), + editTextWebNotifySecret.getText().toString() + ); + newSenderModel.setJsonSetting(JSON.toJSONString(webNotifySettingVoNew)); + SenderUtil.addSender(newSenderModel); + initSenders(); + adapter.add(senderModels); + } else { + senderModel.setName(editTextWebNotifyName.getText().toString()); + senderModel.setType(TYPE_WEB_NOTIFY); + senderModel.setStatus(STATUS_ON); + WebNotifySettingVo webNotifySettingVoNew = new WebNotifySettingVo( + editTextWebNotifyToken.getText().toString(), + editTextWebNotifySecret.getText().toString() + ); + senderModel.setJsonSetting(JSON.toJSONString(webNotifySettingVoNew)); + SenderUtil.updateSender(senderModel); + initSenders(); + adapter.update(senderModels); + } + + show.dismiss(); + + } + }); + buttonbebnotifydel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (senderModel != null) { + SenderUtil.delSender(senderModel.getId()); + initSenders(); + adapter.del(senderModels); + } + show.dismiss(); + } + }); + buttonbebnotifytest.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String token = editTextWebNotifyToken.getText().toString(); + String secret = editTextWebNotifySecret.getText().toString(); + if (!token.isEmpty()) { + try { + SenderWebNotifyMsg.sendMsg(handler, token, secret, "SmsForwarder Title", "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))); + } catch (Exception e) { + Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show(); + e.printStackTrace(); + } + } else { + Toast.makeText(SenderActivity.this, "token 不能为空", Toast.LENGTH_LONG).show(); + } + } + }); + } + + private void setQYWXGroupRobot(final SenderModel senderModel) { + QYWXGroupRobotSettingVo qywxGroupRobotSettingVo = null; + //try phrase json setting + if (senderModel != null) { + String jsonSettingStr = senderModel.getJsonSetting(); + if (jsonSettingStr != null) { + qywxGroupRobotSettingVo = JSON.parseObject(jsonSettingStr, QYWXGroupRobotSettingVo.class); + } + } + + final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this); + View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_qywxgrouprobot, null); + + final EditText editTextQYWXGroupRobotName = view1.findViewById(R.id.editTextQYWXGroupRobotName); + if (senderModel != null) editTextQYWXGroupRobotName.setText(senderModel.getName()); + final EditText editTextQYWXGroupRobotWebHook = view1.findViewById(R.id.editTextQYWXGroupRobotWebHook); + if (qywxGroupRobotSettingVo != null) + editTextQYWXGroupRobotWebHook.setText(qywxGroupRobotSettingVo.getWebHook()); + + Button buttonQyWxGroupRobotOk = view1.findViewById(R.id.buttonQyWxGroupRobotOk); + Button buttonQyWxGroupRobotDel = view1.findViewById(R.id.buttonQyWxGroupRobotDel); + Button buttonQyWxGroupRobotTest = view1.findViewById(R.id.buttonQyWxGroupRobotTest); + alertDialog71 + .setTitle(R.string.setqywxgrouprobottitle) + .setIcon(R.mipmap.ic_launcher) + .setView(view1) + .create(); + final AlertDialog show = alertDialog71.show(); + + buttonQyWxGroupRobotOk.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + if (senderModel == null) { + SenderModel newSenderModel = new SenderModel(); + newSenderModel.setName(editTextQYWXGroupRobotName.getText().toString()); + newSenderModel.setType(TYPE_QYWX_GROUP_ROBOT); + newSenderModel.setStatus(STATUS_ON); + QYWXGroupRobotSettingVo qywxGroupRobotSettingVoNew = new QYWXGroupRobotSettingVo( + editTextQYWXGroupRobotWebHook.getText().toString() + ); + newSenderModel.setJsonSetting(JSON.toJSONString(qywxGroupRobotSettingVoNew)); + SenderUtil.addSender(newSenderModel); + initSenders(); + adapter.add(senderModels); + } else { + senderModel.setName(editTextQYWXGroupRobotName.getText().toString()); + senderModel.setType(TYPE_QYWX_GROUP_ROBOT); + senderModel.setStatus(STATUS_ON); + QYWXGroupRobotSettingVo qywxGroupRobotSettingVoNew = new QYWXGroupRobotSettingVo( + editTextQYWXGroupRobotWebHook.getText().toString() + ); + senderModel.setJsonSetting(JSON.toJSONString(qywxGroupRobotSettingVoNew)); + SenderUtil.updateSender(senderModel); + initSenders(); + adapter.update(senderModels); + } + + show.dismiss(); + + } + }); + buttonQyWxGroupRobotDel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (senderModel != null) { + SenderUtil.delSender(senderModel.getId()); + initSenders(); + adapter.del(senderModels); + } + show.dismiss(); + } + }); + buttonQyWxGroupRobotTest.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String webHook = editTextQYWXGroupRobotWebHook.getText().toString(); + if (!webHook.isEmpty()) { + try { + SenderQyWxGroupRobotMsg.sendMsg(handler, webHook, "SmsForwarder Title", "测试内容(content)@" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))); + } catch (Exception e) { + Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show(); + e.printStackTrace(); + } + } else { + Toast.makeText(SenderActivity.this, "webHook 不能为空", Toast.LENGTH_LONG).show(); + } + } + }); + } + + private void setBark(final SenderModel senderModel) { + BarkSettingVo barkSettingVo = null; + //try phrase json setting + if (senderModel != null) { + String jsonSettingStr = senderModel.getJsonSetting(); + if (jsonSettingStr != null) { + barkSettingVo = JSON.parseObject(jsonSettingStr, BarkSettingVo.class); + } + } + + final AlertDialog.Builder alertDialog71 = new AlertDialog.Builder(SenderActivity.this); + View view1 = View.inflate(SenderActivity.this, R.layout.activity_alter_dialog_setview_bark, null); + + final EditText editTextBarkName = view1.findViewById(R.id.editTextBarkName); + if (senderModel != null) editTextBarkName.setText(senderModel.getName()); + final EditText editTextBarkServer = view1.findViewById(R.id.editTextBarkServer); + if (barkSettingVo != null) editTextBarkServer.setText(barkSettingVo.getServer()); + + Button buttonBarkOk = view1.findViewById(R.id.buttonBarkOk); + Button buttonBarkDel = view1.findViewById(R.id.buttonBarkDel); + Button buttonBarkTest = view1.findViewById(R.id.buttonBarkTest); + alertDialog71 + .setTitle(R.string.setbarktitle) + .setIcon(R.mipmap.ic_launcher) + .setView(view1) + .create(); + final AlertDialog show = alertDialog71.show(); + + buttonBarkOk.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + if (senderModel == null) { + SenderModel newSenderModel = new SenderModel(); + newSenderModel.setName(editTextBarkName.getText().toString()); + newSenderModel.setType(TYPE_BARK); + newSenderModel.setStatus(STATUS_ON); + BarkSettingVo barkSettingVoNew = new BarkSettingVo( + editTextBarkServer.getText().toString() + ); + newSenderModel.setJsonSetting(JSON.toJSONString(barkSettingVoNew)); + SenderUtil.addSender(newSenderModel); + initSenders(); + adapter.add(senderModels); + } else { + senderModel.setName(editTextBarkName.getText().toString()); + senderModel.setType(TYPE_BARK); + senderModel.setStatus(STATUS_ON); + BarkSettingVo barkSettingVoNew = new BarkSettingVo( + editTextBarkServer.getText().toString() + ); + senderModel.setJsonSetting(JSON.toJSONString(barkSettingVoNew)); + SenderUtil.updateSender(senderModel); + initSenders(); + adapter.update(senderModels); + } + + show.dismiss(); + + } + }); + buttonBarkDel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (senderModel != null) { + SenderUtil.delSender(senderModel.getId()); + initSenders(); + adapter.del(senderModels); + } + show.dismiss(); + } + }); + buttonBarkTest.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String barkServer = editTextBarkServer.getText().toString(); + if (!barkServer.isEmpty()) { + try { + SenderBarkMsg.sendMsg(handler, barkServer, "信息来源", "【京东】验证码为387481(切勿将验证码告知他人),请在页面中输入完成验证,如有问题请点击 ihelp.jd.com 联系京东客服"); + } catch (Exception e) { + Toast.makeText(SenderActivity.this, "发送失败:" + e.getMessage(), Toast.LENGTH_LONG).show(); + e.printStackTrace(); + } + } else { + Toast.makeText(SenderActivity.this, "bark-server 不能为空", Toast.LENGTH_LONG).show(); + } + } + }); + } + + @Override + protected void onDestroy() { + Log.d(TAG, "onDestroy"); + super.onDestroy(); + } + + + @Override + protected void onResume() { + super.onResume(); + MobclickAgent.onResume(this); + } + + @Override + protected void onPause() { + super.onPause(); + MobclickAgent.onPause(this); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/SettingActivity.java b/app/src/main/java/com/idormy/sms/forwarder/SettingActivity.java new file mode 100644 index 00000000..1add46a7 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/SettingActivity.java @@ -0,0 +1,185 @@ +package com.idormy.sms.forwarder; + +import android.content.ComponentName; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.idormy.sms.forwarder.BroadCastReceiver.RebootBroadcastReceiver; +import com.idormy.sms.forwarder.model.vo.FeedBackResult; +import com.idormy.sms.forwarder.utils.HttpI; +import com.idormy.sms.forwarder.utils.HttpUtil; +import com.idormy.sms.forwarder.utils.UpdateAppHttpUtil; +import com.idormy.sms.forwarder.utils.aUtil; +import com.vector.update_app.UpdateAppManager; +import com.vector.update_app.UpdateCallback; +import com.vector.update_app.listener.ExceptionHandler; + +import java.util.HashMap; +import java.util.Map; + + +public class SettingActivity extends AppCompatActivity { + private String TAG = "SettingActivity"; + + @Override + public void onCreate(Bundle savedInstanceState) { + Log.d(TAG, "oncreate"); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_setting); + Log.d(TAG, "onCreate: " + RebootBroadcastReceiver.class.getName()); + + Switch check_with_reboot = (Switch) findViewById(R.id.switch_with_reboot); + checkWithReboot(check_with_reboot); + + TextView version_now = (TextView) findViewById(R.id.version_now); + Button check_version_now = (Button) findViewById(R.id.check_version_now); + try { + version_now.setText(aUtil.getVersionName(SettingActivity.this)); + } catch (Exception e) { + e.printStackTrace(); + } + check_version_now.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + checkNewVersion(); + } + }); + + } + + //检查重启广播接受器状态并设置 + private void checkWithReboot(Switch withrebootSwitch) { + //获取组件 + final ComponentName cm = new ComponentName(this.getPackageName(), RebootBroadcastReceiver.class.getName()); + + final PackageManager pm = getPackageManager(); + int state = pm.getComponentEnabledSetting(cm); + if (state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED + && state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { + + withrebootSwitch.setChecked(true); + } else { + withrebootSwitch.setChecked(false); + } + withrebootSwitch.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + int newState = (Boolean) isChecked ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + pm.setComponentEnabledSetting(cm, newState, PackageManager.DONT_KILL_APP); + Log.d(TAG, "onCheckedChanged:" + isChecked); + } + }); + } + + private void checkNewVersion() { + String geturl = "http://api.allmything.com/api/version/hasnew?versioncode="; + + try { + geturl += aUtil.getVersionCode(SettingActivity.this); + + Log.i("SettingActivity", geturl); + new UpdateAppManager + .Builder() + //当前Activity + .setActivity(SettingActivity.this) + //更新地址 + .setUpdateUrl(geturl) + //全局异常捕获 + .handleException(new ExceptionHandler() { + @Override + public void onException(Exception e) { + Log.e(TAG, "onException: ", e); + Toast.makeText(SettingActivity.this, "更新失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); + } + }) + //实现httpManager接口的对象 + .setHttpManager(new UpdateAppHttpUtil()) + .build() + .checkNewApp(new UpdateCallback() { + /** + * 没有新版本 + */ + protected void noNewApp(String error) { + Toast.makeText(SettingActivity.this, "没有新版本", Toast.LENGTH_SHORT).show(); + } + }); +// .update(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void feedbackcommit(View view) { + final AlertDialog.Builder builder = new AlertDialog.Builder(SettingActivity.this); + View view1 = View.inflate(SettingActivity.this, R.layout.dialog_feedback, null); + + final EditText feedback_et_email = view1.findViewById(R.id.feedback_et_email); + final EditText feedback_et_text = view1.findViewById(R.id.feedback_et_text); + + builder + .setTitle(R.string.feedback_input_text) + .setView(view1) + .create(); + builder.setPositiveButton("提交反馈", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + try { + Map feedBackData = new HashMap<>(); + feedBackData.put("email", feedback_et_email.getText().toString()); + feedBackData.put("text", feedback_et_text.getText().toString()); + new HttpUtil().asyncPost("https://api.sl.willanddo.com/api/tsms/feedBack", feedBackData, new HttpI.Callback() { + @Override + public void onResponse(String result) { + Log.i(TAG, "onResponse: " + result); + if (result != null) { + FeedBackResult feedBackResult = JSON.parseObject(result, FeedBackResult.class); + Log.i(TAG, "feedBackResult: " + feedBackResult); + + if (feedBackResult != null) { + JSONObject feedBackResultObject = JSON.parseObject(result); + Toast.makeText(SettingActivity.this, feedBackResultObject.getString("message"), Toast.LENGTH_LONG).show(); + } else { + Toast.makeText(SettingActivity.this, "感谢您的反馈,我们将尽快处理!", Toast.LENGTH_LONG).show(); + + } + } else { + Toast.makeText(SettingActivity.this, "感谢您的反馈,我们将尽快处理!", Toast.LENGTH_LONG).show(); + + } + + } + + @Override + public void onError(String error) { + Log.i(TAG, "onError: " + error); + Toast.makeText(SettingActivity.this, error, Toast.LENGTH_LONG).show(); + + } + }); + + } catch (Exception e) { + Toast.makeText(SettingActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); + Log.d(TAG, "feedback e: " + e.getMessage()); + } + + + } + }).show(); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/LogAdapter.java b/app/src/main/java/com/idormy/sms/forwarder/adapter/LogAdapter.java new file mode 100644 index 00000000..a3f5e694 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/adapter/LogAdapter.java @@ -0,0 +1,113 @@ +package com.idormy.sms.forwarder.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.idormy.sms.forwarder.R; +import com.idormy.sms.forwarder.model.vo.LogVo; + +import java.util.List; + +public class LogAdapter extends ArrayAdapter { + private int resourceId; + private List list; + + // 适配器的构造函数,把要适配的数据传入这里 + public LogAdapter(Context context, int textViewResourceId, List objects) { + super(context, textViewResourceId, objects); + resourceId = textViewResourceId; + list = objects; + } + + @Override + public int getCount() { + return list.size(); + } + + @Override + public LogVo getItem(int position) { + return list.get(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + // convertView 参数用于将之前加载好的布局进行缓存 + @Override + public View getView(int position, View convertView, ViewGroup parent) { + LogVo logVo = getItem(position); //获取当前项的TLog实例 + + // 加个判断,以免ListView每次滚动时都要重新加载布局,以提高运行效率 + View view; + ViewHolder viewHolder; + if (convertView == null) { + + // 避免ListView每次滚动时都要重新加载布局,以提高运行效率 + view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); + + // 避免每次调用getView()时都要重新获取控件实例 + viewHolder = new ViewHolder(); + viewHolder.tLogFrom = view.findViewById(R.id.tlog_from); + viewHolder.tLogContent = view.findViewById(R.id.tlog_content); + viewHolder.tLogRule = view.findViewById(R.id.tlog_rule); + viewHolder.senderImage = view.findViewById(R.id.tlog_sender_image); + + // 将ViewHolder存储在View中(即将控件的实例存储在其中) + view.setTag(viewHolder); + } else { + view = convertView; + viewHolder = (ViewHolder) view.getTag(); + } + + // 获取控件实例,并调用set...方法使其显示出来 + if (logVo != null) { + viewHolder.tLogFrom.setText(logVo.getFrom()); + viewHolder.tLogContent.setText(logVo.getContent()); + viewHolder.tLogRule.setText(logVo.getRule()); + viewHolder.senderImage.setImageResource(logVo.getSenderImageId()); + } + + return view; + } + + public void add(List logVos) { + if (list != null) { + list = logVos; + notifyDataSetChanged(); + } + } + + public void del(List logVos) { + if (list != null) { + list = logVos; + notifyDataSetChanged(); + } + } + + public void update(List logVos) { + if (list != null) { + list = logVos; + notifyDataSetChanged(); + } + } + + public void onDateChange(List logVos) { + list = logVos; + notifyDataSetChanged(); + } + + // 定义一个内部类,用于对控件的实例进行缓存 + class ViewHolder { + TextView tLogFrom; + TextView tLogContent; + TextView tLogRule; + ImageView senderImage; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/RuleAdapter.java b/app/src/main/java/com/idormy/sms/forwarder/adapter/RuleAdapter.java new file mode 100644 index 00000000..354e5e5d --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/adapter/RuleAdapter.java @@ -0,0 +1,115 @@ +package com.idormy.sms.forwarder.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +import com.idormy.sms.forwarder.R; +import com.idormy.sms.forwarder.model.RuleModel; +import com.idormy.sms.forwarder.model.SenderModel; +import com.idormy.sms.forwarder.utils.SenderUtil; + +import java.util.List; + +public class RuleAdapter extends ArrayAdapter { + private int resourceId; + private List list; + + // 适配器的构造函数,把要适配的数据传入这里 + public RuleAdapter(Context context, int textViewResourceId, List objects) { + super(context, textViewResourceId, objects); + resourceId = textViewResourceId; + list = objects; + } + + @Override + public int getCount() { + return list.size(); + } + + @Override + public RuleModel getItem(int position) { + return list.get(position); + } + + @Override + public long getItemId(int position) { + RuleModel item = list.get(position); + if (item == null) { + return 0; + } + return item.getId(); + } + + // convertView 参数用于将之前加载好的布局进行缓存 + @Override + public View getView(int position, View convertView, ViewGroup parent) { + RuleModel ruleModel = getItem(position); //获取当前项的TLog实例 + + // 加个判断,以免ListView每次滚动时都要重新加载布局,以提高运行效率 + View view; + ViewHolder viewHolder; + if (convertView == null) { + + // 避免ListView每次滚动时都要重新加载布局,以提高运行效率 + view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); + + // 避免每次调用getView()时都要重新获取控件实例 + viewHolder = new ViewHolder(); + viewHolder.ruleMatch = view.findViewById(R.id.rule_match); + viewHolder.ruleSender = view.findViewById(R.id.rule_sender); + + // 将ViewHolder存储在View中(即将控件的实例存储在其中) + view.setTag(viewHolder); + } else { + view = convertView; + viewHolder = (ViewHolder) view.getTag(); + } + + // 获取控件实例,并调用set...方法使其显示出来 + if (ruleModel != null) { + List senderModel = SenderUtil.getSender(ruleModel.getSenderId(), null); + viewHolder.ruleMatch.setText(ruleModel.getRuleMatch()); + if (!senderModel.isEmpty()) { + viewHolder.ruleSender.setText(senderModel.get(0).getName()); + + } else { + viewHolder.ruleSender.setText(""); + + } + } + + return view; + } + + public void add(List ruleModels) { + if (list != null) { + list = ruleModels; + notifyDataSetChanged(); + } + } + + public void del(List ruleModels) { + if (list != null) { + list = ruleModels; + notifyDataSetChanged(); + } + } + + public void update(List ruleModels) { + if (list != null) { + list = ruleModels; + notifyDataSetChanged(); + } + } + + // 定义一个内部类,用于对控件的实例进行缓存 + class ViewHolder { + TextView ruleMatch; + TextView ruleSender; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/SenderAdapter.java b/app/src/main/java/com/idormy/sms/forwarder/adapter/SenderAdapter.java new file mode 100644 index 00000000..abb25860 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/adapter/SenderAdapter.java @@ -0,0 +1,128 @@ +package com.idormy.sms.forwarder.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.idormy.sms.forwarder.R; +import com.idormy.sms.forwarder.model.SenderModel; + +import java.util.List; + +public class SenderAdapter extends ArrayAdapter { + private int resourceId; + private List list; + + // 适配器的构造函数,把要适配的数据传入这里 + public SenderAdapter(Context context, int textViewResourceId, List objects) { + super(context, textViewResourceId, objects); + resourceId = textViewResourceId; + list = objects; + } + + @Override + public int getCount() { + return list.size(); + } + + @Override + public SenderModel getItem(int position) { + return list.get(position); + } + + @Override + public long getItemId(int position) { + SenderModel item = list.get(position); + if (item == null) { + return 0; + } + return item.getId(); + } + + // convertView 参数用于将之前加载好的布局进行缓存 + @Override + public View getView(int position, View convertView, ViewGroup parent) { + SenderModel senderModel = getItem(position); //获取当前项的TLog实例 + + // 加个判断,以免ListView每次滚动时都要重新加载布局,以提高运行效率 + View view; + ViewHolder viewHolder; + if (convertView == null) { + + // 避免ListView每次滚动时都要重新加载布局,以提高运行效率 + view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); + + // 避免每次调用getView()时都要重新获取控件实例 + viewHolder = new ViewHolder(); + viewHolder.senderImage = view.findViewById(R.id.sender_image); + viewHolder.senderName = view.findViewById(R.id.sender_name); + + // 将ViewHolder存储在View中(即将控件的实例存储在其中) + view.setTag(viewHolder); + } else { + view = convertView; + viewHolder = (ViewHolder) view.getTag(); + } + + // 获取控件实例,并调用set...方法使其显示出来 + if (senderModel != null) { + viewHolder.senderImage.setImageResource(senderModel.getImageId()); + viewHolder.senderName.setText(senderModel.getName()); + } + + return view; + } + + public void add(SenderModel senderModel) { + if (list != null) { + list.add(senderModel); + notifyDataSetChanged(); + } + } + + public void del(int position) { + if (list != null) { + list.remove(position); + notifyDataSetChanged(); + } + } + + public void update(SenderModel senderModel, int position) { + if (list != null) { + list.set(position, senderModel); + notifyDataSetChanged(); + } + } + + public void add(List senderModels) { + if (list != null) { + list = senderModels; + notifyDataSetChanged(); + } + } + + public void del(List senderModels) { + if (list != null) { + list = senderModels; + notifyDataSetChanged(); + } + } + + public void update(List senderModels) { + if (list != null) { + list = senderModels; + notifyDataSetChanged(); + } + } + + // 定义一个内部类,用于对控件的实例进行缓存 + class ViewHolder { + ImageView senderImage; + TextView senderName; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/LogModel.java b/app/src/main/java/com/idormy/sms/forwarder/model/LogModel.java new file mode 100644 index 00000000..322a2c28 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/LogModel.java @@ -0,0 +1,52 @@ +package com.idormy.sms.forwarder.model; + +public class LogModel { + private String from; + private String content; + private Long ruleId; + private Long time; + + public LogModel(String from, String content, Long ruleId) { + this.from = from; + this.content = content; + this.ruleId = ruleId; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Long getRuleId() { + return ruleId; + } + + public void setRuleId(Long ruleId) { + this.ruleId = ruleId; + } + + public Long getTime() { + return time; + } + + @Override + public String toString() { + return "LogModel{" + + "from='" + from + '\'' + + ", content='" + content + '\'' + + ", ruleId=" + ruleId + + ", time=" + time + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/LogTable.java b/app/src/main/java/com/idormy/sms/forwarder/model/LogTable.java new file mode 100644 index 00000000..74008890 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/LogTable.java @@ -0,0 +1,19 @@ +package com.idormy.sms.forwarder.model; + +import android.provider.BaseColumns; + +public final class LogTable { + // To prevent someone from accidentally instantiating the contract class, + // make the constructor private. + private LogTable() { + } + + /* Inner class that defines the table contents */ + public static class LogEntry implements BaseColumns { + public static final String TABLE_NAME = "log"; + public static final String COLUMN_NAME_FROM = "l_from"; + public static final String COLUMN_NAME_CONTENT = "content"; + public static final String COLUMN_NAME_RULE_ID = "rule_id"; + public static final String COLUMN_NAME_TIME = "time"; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java b/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java new file mode 100644 index 00000000..15f76064 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/RuleModel.java @@ -0,0 +1,179 @@ +package com.idormy.sms.forwarder.model; + +import com.idormy.sms.forwarder.R; + +import java.util.HashMap; +import java.util.Map; + +public class RuleModel { + public static final String FILED_TRANSPOND_ALL = "transpond_all"; + public static final String FILED_PHONE_NUM = "phone_num"; + public static final String FILED_MSG_CONTENT = "msg_content"; + public static final Map FILED_MAP = new HashMap(); + public static final String CHECK_IS = "is"; + public static final String CHECK_CONTAIN = "contain"; + public static final String CHECK_START_WITH = "startwith"; + public static final String CHECK_END_WITH = "endwith"; + public static final String CHECK_NOT_IS = "notis"; + public static final Map CHECK_MAP = new HashMap(); + + static { + FILED_MAP.put("transpond_all", "转发全部"); + FILED_MAP.put("phone_num", "手机号"); + FILED_MAP.put("msg_content", "内容"); + } + + static { + CHECK_MAP.put("is", "是"); + CHECK_MAP.put("contain", "包含"); + CHECK_MAP.put("startwith", "开头是"); + CHECK_MAP.put("endwith", "结尾是"); + CHECK_MAP.put("notis", "不是"); + } + + private Long id; + private String filed; + private String check; + + private String value; + + private Long senderId; + private Long time; + + public static String getRuleMatch(String filed, String check, String value) { + switch (filed) { + case FILED_TRANSPOND_ALL: + return "全部转发到 "; + default: + return "当 " + FILED_MAP.get(filed) + " " + CHECK_MAP.get(check) + " " + value; + + } + + } + + public static String getRuleFiledFromCheckId(int id) { + switch (id) { + case R.id.btnContent: + return FILED_MSG_CONTENT; + case R.id.btnPhone: + return FILED_PHONE_NUM; + default: + return FILED_TRANSPOND_ALL; + } + } + + public static String getRuleCheckFromCheckId(int id) { + switch (id) { + case R.id.btnContain: + return CHECK_CONTAIN; + case R.id.btnStartWith: + return CHECK_START_WITH; + case R.id.btnEndWith: + return CHECK_END_WITH; + case R.id.btnNotIs: + return CHECK_NOT_IS; + default: + return CHECK_IS; + } + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getSenderId() { + return senderId; + } + + public void setSenderId(Long senderId) { + this.senderId = senderId; + } + + public Long getTime() { + return time; + } + + public void setTime(Long time) { + this.time = time; + } + + public String getFiled() { + return filed; + } + + public void setFiled(String filed) { + this.filed = filed; + } + + public String getCheck() { + return check; + } + + public void setCheck(String check) { + this.check = check; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getRuleMatch() { + switch (filed) { + case FILED_TRANSPOND_ALL: + return "全部转发到 "; + default: + return "当 " + FILED_MAP.get(filed) + " " + CHECK_MAP.get(check) + " " + value + " 转发到 "; + } + + } + + public Long getRuleSenderId() { + return senderId; + } + + public int getRuleFiledCheckId() { + switch (filed) { + case FILED_MSG_CONTENT: + return R.id.btnContent; + case FILED_PHONE_NUM: + return R.id.btnPhone; + default: + return R.id.btnTranspondAll; + } + } + + public int getRuleCheckCheckId() { + switch (check) { + case CHECK_CONTAIN: + return R.id.btnContain; + case CHECK_START_WITH: + return R.id.btnStartWith; + case CHECK_END_WITH: + return R.id.btnEndWith; + case CHECK_NOT_IS: + return R.id.btnNotIs; + default: + return R.id.btnIs; + } + } + + @Override + public String toString() { + return "RuleModel{" + + "id=" + id + + ", filed='" + filed + '\'' + + ", check='" + check + '\'' + + ", value='" + value + '\'' + + ", senderId=" + senderId + + ", time=" + time + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/RuleTable.java b/app/src/main/java/com/idormy/sms/forwarder/model/RuleTable.java new file mode 100644 index 00000000..d1dd54f7 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/RuleTable.java @@ -0,0 +1,20 @@ +package com.idormy.sms.forwarder.model; + +import android.provider.BaseColumns; + +public final class RuleTable { + // To prevent someone from accidentally instantiating the contract class, + // make the constructor private. + private RuleTable() { + } + + /* Inner class that defines the table contents */ + public static class RuleEntry implements BaseColumns { + public static final String TABLE_NAME = "rule"; + public static final String COLUMN_NAME_FILED = "filed"; + public static final String COLUMN_NAME_CHECK = "tcheck"; + public static final String COLUMN_NAME_VALUE = "value"; + public static final String COLUMN_NAME_SENDER_ID = "sender_id"; + public static final String COLUMN_NAME_TIME = "time"; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/SenderModel.java b/app/src/main/java/com/idormy/sms/forwarder/model/SenderModel.java new file mode 100644 index 00000000..2396d117 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/SenderModel.java @@ -0,0 +1,125 @@ +package com.idormy.sms.forwarder.model; + +import com.idormy.sms.forwarder.R; + + +public class SenderModel { + public static final int STATUS_ON = 1; + public static final int STATUS_OFF = 0; + public static final int TYPE_DINGDING = 0; + public static final int TYPE_EMAIL = 1; + public static final int TYPE_MESSAGE = 2; + public static final int TYPE_WEB_NOTIFY = 3; + public static final int TYPE_QYWX_GROUP_ROBOT = 4; + public static final int TYPE_BARK = 5; + private Long id; + private String name; + private int status; + private int type; + + private String jsonSetting; + + private long time; + + public SenderModel() { + } + + public SenderModel(String name, int status, int type, String jsonSetting) { + this.name = name; + this.status = status == STATUS_ON ? STATUS_ON : STATUS_OFF; + this.type = type; + this.jsonSetting = jsonSetting; + } + + public static int getImageId(int type) { + switch (type) { + case (TYPE_DINGDING): + return R.mipmap.dingding; + case (TYPE_EMAIL): + return R.drawable.ic_baseline_email_24; + case (TYPE_QYWX_GROUP_ROBOT): + return R.mipmap.qywx; + case (TYPE_BARK): + return R.mipmap.qywx; + default: + return R.mipmap.ic_launcher_round; + + } + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status == STATUS_ON ? STATUS_ON : STATUS_OFF; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getJsonSetting() { + return jsonSetting; + } + + public void setJsonSetting(String jsonSetting) { + this.jsonSetting = jsonSetting; + } + + public int getImageId() { + switch (type) { + case (TYPE_DINGDING): + return R.mipmap.dingding; + case (TYPE_EMAIL): + return R.drawable.ic_baseline_email_24; + case (TYPE_QYWX_GROUP_ROBOT): + return R.mipmap.qywx; + case (TYPE_BARK): + return R.mipmap.qywx; + default: + return R.mipmap.ic_launcher_round; + + } + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + @Override + public String toString() { + return "SenderModel{" + + "id=" + id + + ", name='" + name + '\'' + + ", status=" + status + + ", type=" + type + + ", jsonSetting='" + jsonSetting + '\'' + + ", time=" + time + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/SenderTable.java b/app/src/main/java/com/idormy/sms/forwarder/model/SenderTable.java new file mode 100644 index 00000000..8c0a49af --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/SenderTable.java @@ -0,0 +1,20 @@ +package com.idormy.sms.forwarder.model; + +import android.provider.BaseColumns; + +public final class SenderTable { + // To prevent someone from accidentally instantiating the contract class, + // make the constructor private. + private SenderTable() { + } + + /* Inner class that defines the table contents */ + public static class SenderEntry implements BaseColumns { + public static final String TABLE_NAME = "sender"; + public static final String COLUMN_NAME_NAME = "name"; + public static final String COLUMN_NAME_STATUS = "status"; + public static final String COLUMN_NAME_TYPE = "type"; + public static final String COLUMN_NAME_JSON_SETTING = "json_setting"; + public static final String COLUMN_NAME_TIME = "time"; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/BarkSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/BarkSettingVo.java new file mode 100644 index 00000000..fabd9e79 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/BarkSettingVo.java @@ -0,0 +1,22 @@ +package com.idormy.sms.forwarder.model.vo; + +import java.io.Serializable; + +public class BarkSettingVo implements Serializable { + private String server; + + public BarkSettingVo() { + } + + public BarkSettingVo(String server) { + this.server = server; + } + + public String getServer() { + return server; + } + + public void setServer(String server) { + this.server = server; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/DingDingSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/DingDingSettingVo.java new file mode 100644 index 00000000..2057efe4 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/DingDingSettingVo.java @@ -0,0 +1,52 @@ +package com.idormy.sms.forwarder.model.vo; + +import java.io.Serializable; + +public class DingDingSettingVo implements Serializable { + private String token; + private String secret; + private String atMobils; + private Boolean atAll; + + public DingDingSettingVo() { + } + + public DingDingSettingVo(String token, String secret, String atMobils, Boolean atAll) { + this.token = token; + this.secret = secret; + this.atMobils = atMobils; + this.atAll = atAll; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public String getAtMobils() { + return atMobils; + } + + public void setAtMobils(String atMobils) { + this.atMobils = atMobils; + } + + public Boolean getAtAll() { + return atAll; + } + + public void setAtAll(Boolean atAll) { + this.atAll = atAll; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/EmailSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/EmailSettingVo.java new file mode 100644 index 00000000..b771c2bc --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/EmailSettingVo.java @@ -0,0 +1,72 @@ +package com.idormy.sms.forwarder.model.vo; + +import java.io.Serializable; + +public class EmailSettingVo implements Serializable { + private String host; + private String port; + private Boolean ssl = true; + private String fromEmail; + private String pwd; + private String toEmail; + + public EmailSettingVo() { + } + + public EmailSettingVo(String host, String port, Boolean ssl, String fromEmail, String pwd, String toEmail) { + this.host = host; + this.port = port; + this.ssl = ssl; + this.fromEmail = fromEmail; + this.pwd = pwd; + this.toEmail = toEmail; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + public Boolean getSsl() { + return ssl; + } + + public void setSsl(Boolean ssl) { + this.ssl = ssl; + } + + public String getFromEmail() { + return fromEmail; + } + + public void setFromEmail(String fromEmail) { + this.fromEmail = fromEmail; + } + + public String getPwd() { + return pwd; + } + + public void setPwd(String pwd) { + this.pwd = pwd; + } + + public String getToEmail() { + return toEmail; + } + + public void setToEmail(String toEmail) { + this.toEmail = toEmail; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/FeedBackResult.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/FeedBackResult.java new file mode 100644 index 00000000..1c85a619 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/FeedBackResult.java @@ -0,0 +1,30 @@ +package com.idormy.sms.forwarder.model.vo; + +import java.io.Serializable; + +public class FeedBackResult implements Serializable { + Integer code; + String message; + Object result; + + public FeedBackResult() { + + } + + public String getMessage() { + return message; + } + + public boolean isSuccess() { + return 1 == code; + } + + @Override + public String toString() { + return "FeedBackResult{" + + "code=" + code + + ", message='" + message + '\'' + + ", result=" + result + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/LogVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/LogVo.java new file mode 100644 index 00000000..4df8843f --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/LogVo.java @@ -0,0 +1,57 @@ +package com.idormy.sms.forwarder.model.vo; + +public class LogVo { + private String from; + private String content; + private String rule; + private int senderImageId; + private String time; + + public LogVo(String from, String content, String time, String rule, int senderImageId) { + this.from = from; + this.content = content; + this.time = time; + this.rule = rule; + this.senderImageId = senderImageId; + } + + public LogVo() { + + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getRule() { + return rule; + } + + public void setRule(String rule) { + this.rule = rule; + } + + public String getTime() { + return time; + } + + public int getSenderImageId() { + return senderImageId; + } + + public void setSenderImageId(int senderImageId) { + this.senderImageId = senderImageId; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/QYWXGroupRobotSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/QYWXGroupRobotSettingVo.java new file mode 100644 index 00000000..045256f8 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/QYWXGroupRobotSettingVo.java @@ -0,0 +1,22 @@ +package com.idormy.sms.forwarder.model.vo; + +import java.io.Serializable; + +public class QYWXGroupRobotSettingVo implements Serializable { + private String webHook; + + public QYWXGroupRobotSettingVo() { + } + + public QYWXGroupRobotSettingVo(String webHook) { + this.webHook = webHook; + } + + public String getWebHook() { + return webHook; + } + + public void setWebHook(String webHook) { + this.webHook = webHook; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/RuleVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/RuleVo.java new file mode 100644 index 00000000..702844ad --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/RuleVo.java @@ -0,0 +1,6 @@ +package com.idormy.sms.forwarder.model.vo; + +public class RuleVo { + private String matchStr; + private String senderStr; +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/SmsVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/SmsVo.java new file mode 100644 index 00000000..8bea6c13 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/SmsVo.java @@ -0,0 +1,59 @@ +package com.idormy.sms.forwarder.model.vo; + +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class SmsVo implements Serializable { + String mobile; + String content; + Date date; + + public SmsVo() { + } + + public SmsVo(String mobile, String content, Date date) { + this.mobile = mobile; + this.content = content; + this.date = date; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getSmsVoForSend() { + return mobile + "\n" + + content + "\n" + + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); + } + + @Override + public String toString() { + return "SmsVo{" + + "mobile='" + mobile + '\'' + + ", content='" + content + '\'' + + ", date=" + date + + '}'; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/WebNotifySettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/WebNotifySettingVo.java new file mode 100644 index 00000000..7c4232be --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/WebNotifySettingVo.java @@ -0,0 +1,32 @@ +package com.idormy.sms.forwarder.model.vo; + +import java.io.Serializable; + +public class WebNotifySettingVo implements Serializable { + private String token; + private String secret; + + public WebNotifySettingVo() { + } + + public WebNotifySettingVo(String token, String secret) { + this.token = token; + this.secret = secret; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/DbHelper.java b/app/src/main/java/com/idormy/sms/forwarder/utils/DbHelper.java new file mode 100644 index 00000000..d951266b --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/DbHelper.java @@ -0,0 +1,84 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import com.idormy.sms.forwarder.model.LogTable; +import com.idormy.sms.forwarder.model.RuleTable; +import com.idormy.sms.forwarder.model.SenderTable; + +import java.util.Arrays; +import java.util.List; + +public class DbHelper extends SQLiteOpenHelper { + // If you change the database schema, you must increment the database version. + public static final String TAG = "DbHelper"; + public static final int DATABASE_VERSION = 1; + public static final String DATABASE_NAME = "sms_forwarder.db"; + + private static final List SQL_CREATE_ENTRIES = + Arrays.asList( + "CREATE TABLE " + LogTable.LogEntry.TABLE_NAME + " (" + + LogTable.LogEntry._ID + " INTEGER PRIMARY KEY," + + LogTable.LogEntry.COLUMN_NAME_FROM + " TEXT," + + LogTable.LogEntry.COLUMN_NAME_CONTENT + " TEXT," + + LogTable.LogEntry.COLUMN_NAME_RULE_ID + " INTEGER," + + LogTable.LogEntry.COLUMN_NAME_TIME + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)" + , "CREATE TABLE " + RuleTable.RuleEntry.TABLE_NAME + " (" + + RuleTable.RuleEntry._ID + " INTEGER PRIMARY KEY," + + RuleTable.RuleEntry.COLUMN_NAME_FILED + " TEXT," + + RuleTable.RuleEntry.COLUMN_NAME_CHECK + " TEXT," + + RuleTable.RuleEntry.COLUMN_NAME_VALUE + " TEXT," + + RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID + " INTEGER," + + RuleTable.RuleEntry.COLUMN_NAME_TIME + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)" + , "CREATE TABLE " + SenderTable.SenderEntry.TABLE_NAME + " (" + + SenderTable.SenderEntry._ID + " INTEGER PRIMARY KEY," + + SenderTable.SenderEntry.COLUMN_NAME_NAME + " TEXT," + + SenderTable.SenderEntry.COLUMN_NAME_STATUS + " INTEGER," + + SenderTable.SenderEntry.COLUMN_NAME_TYPE + " INTEGER," + + SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING + " TEXT," + + SenderTable.SenderEntry.COLUMN_NAME_TIME + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)" + ); + + private static final List SQL_DELETE_ENTRIES = + Arrays.asList( + "DROP TABLE IF EXISTS " + LogTable.LogEntry.TABLE_NAME + " ; " + , "DROP TABLE IF EXISTS " + RuleTable.RuleEntry.TABLE_NAME + " ; " + , "DROP TABLE IF EXISTS " + SenderTable.SenderEntry.TABLE_NAME + " ; " + + ); + + + public DbHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + public void onCreate(SQLiteDatabase db) { + for (String createEntries : SQL_CREATE_ENTRIES + ) { + Log.d(TAG, "onCreate:createEntries " + createEntries); + db.execSQL(createEntries); + } + } + + public void delCreateTable(SQLiteDatabase db) { + for (String delCreateEntries : SQL_DELETE_ENTRIES + ) { + Log.d(TAG, "delCreateTable:delCreateEntries " + delCreateEntries); + db.execSQL(delCreateEntries); + } + } + + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + // This database is only a cache for online data, so its upgrade policy is + // to simply to discard the data and start over + delCreateTable(db); + onCreate(db); + } + + public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { + onUpgrade(db, oldVersion, newVersion); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/Define.java b/app/src/main/java/com/idormy/sms/forwarder/utils/Define.java new file mode 100644 index 00000000..ef7018a9 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/Define.java @@ -0,0 +1,11 @@ +package com.idormy.sms.forwarder.utils; + +public class Define { + public static String SP_MSG = "tsms_msg"; + public static String SP_MSG_SET_KEY = "tsms_msg_set_key"; + public static String SP_MSG_SEND_UTIL_EMAIL_HOST_KEY = "tsms_msg_send_util_email_host_key"; + public static String SP_MSG_SEND_UTIL_EMAIL_PORT_KEY = "tsms_msg_send_util_email_port_key"; + public static String SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY = "tsms_msg_send_util_email_fromadd_key"; + public static String SP_MSG_SEND_UTIL_EMAIL_PSW_KEY = "tsms_msg_send_util_email_psw_key"; + public static String SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY = "tsms_msg_send_util_email_toadd_key"; +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/DingdingMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/DingdingMsg.java new file mode 100644 index 00000000..0b329efd --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/DingdingMsg.java @@ -0,0 +1,71 @@ +package com.idormy.sms.forwarder.utils; + +import android.util.Base64; +import android.util.Log; + +import java.io.IOException; +import java.net.URLEncoder; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +public class DingdingMsg { + + static String TAG = "DingdingMsg"; + + public static void sendMsg(String msg) throws Exception { + + String webhook_token = SettingUtil.get_using_dingding_token(); + String webhook_secret = SettingUtil.get_using_dingding_secret(); + if (webhook_token.equals("")) { + return; + } + if (!webhook_secret.equals("")) { + Long timestamp = System.currentTimeMillis(); + + String stringToSign = timestamp + "\n" + webhook_secret; + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(webhook_secret.getBytes("UTF-8"), "HmacSHA256")); + byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); + String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8"); + webhook_token += "×tamp=" + timestamp + "&sign=" + sign; + Log.i(TAG, "webhook_token:" + webhook_token); + + } + + final String msgf = msg; + String textMsg = "{ \"msgtype\": \"text\", \"text\": {\"content\": \"" + msg + "\"}}"; + OkHttpClient client = new OkHttpClient(); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), + textMsg); + + final Request request = new Request.Builder() + .url(webhook_token) + .addHeader("Content-Type", "application/json; charset=utf-8") + .post(requestBody) + .build(); + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + Log.d(TAG, "onFailure:" + e.getMessage()); + SendHistory.addHistory("钉钉转发:" + msgf + "onFailure:" + e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + final String responseStr = response.body().string(); + Log.d(TAG, "Code:" + String.valueOf(response.code()) + responseStr); + SendHistory.addHistory("钉钉转发:" + msgf + "Code:" + String.valueOf(response.code()) + responseStr); + } + }); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/HttpI.java b/app/src/main/java/com/idormy/sms/forwarder/utils/HttpI.java new file mode 100644 index 00000000..2c6f645f --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/HttpI.java @@ -0,0 +1,94 @@ +package com.idormy.sms.forwarder.utils; + + +import android.support.annotation.NonNull; + +import java.io.File; +import java.io.Serializable; +import java.util.Map; + +/** + * app版本更新接口 + */ +public interface HttpI extends Serializable { + /** + * 异步get + * + * @param url get请求地址 + * @param params get参数 + * @param callBack 回调 + */ + void asyncGet(@NonNull String url, @NonNull Map params, @NonNull Callback callBack); + + + /** + * 异步post + * + * @param url post请求地址 + * @param params post请求参数 + * @param callBack 回调 + */ + void asyncPost(@NonNull String url, @NonNull Map params, @NonNull Callback callBack); + + /** + * 下载 + * + * @param url 下载地址 + * @param path 文件保存路径 + * @param fileName 文件名称 + * @param callback 回调 + */ + void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull FileCallback callback); + + /** + * 下载回调 + */ + interface FileCallback { + /** + * 进度 + * + * @param progress 进度0.00 - 0.50 - 1.00 + * @param total 文件总大小 单位字节 + */ + void onProgress(float progress, long total); + + /** + * 错误回调 + * + * @param error 错误提示 + */ + void onError(String error); + + /** + * 结果回调 + * + * @param file 下载好的文件 + */ + void onResponse(File file); + + /** + * 请求之前 + */ + void onBefore(); + } + + /** + * 网络请求回调 + */ + interface Callback { + /** + * 结果回调 + * + * @param result 结果 + */ + void onResponse(String result); + + /** + * 错误回调 + * + * @param error 错误提示 + */ + void onError(String error); + } +} + diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/HttpUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/HttpUtil.java new file mode 100644 index 00000000..b0cb782c --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/HttpUtil.java @@ -0,0 +1,117 @@ +package com.idormy.sms.forwarder.utils; + + +import android.support.annotation.NonNull; + +import com.zhy.http.okhttp.OkHttpUtils; +import com.zhy.http.okhttp.callback.FileCallBack; +import com.zhy.http.okhttp.callback.StringCallback; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import okhttp3.Call; +import okhttp3.Request; +import okhttp3.Response; + + +public class HttpUtil implements HttpI { + /** + * 异步get + * + * @param url get请求地址 + * @param params get参数 + * @param callBack 回调 + */ + public void asyncGet(@NonNull String url, @NonNull Map params, @NonNull final Callback callBack) { + params.put("aaa", "bbbbb"); + params.put("ccc", "ddd"); + Map headers = new HashMap<>(); + OkHttpUtils.get() + .url(url) + .headers(headers) + .params(params) + .build() + .execute(new StringCallback() { + @Override + public void onError(Call call, Response response, Exception e, int id) { + callBack.onError(validateError(e, response)); + } + + @Override + public void onResponse(String response, int id) { + callBack.onResponse(response); + } + }); + } + + /** + * 异步post + * + * @param url post请求地址 + * @param params post请求参数 + * @param callBack 回调 + */ + public void asyncPost(@NonNull String url, @NonNull Map params, @NonNull final Callback callBack) { + params.put("eeee", "fff"); + params.put("gggg", "hhhh"); + Map headers = new HashMap<>(); + headers.put("heada", "bb"); + OkHttpUtils.post() + .url(url) + .headers(headers) + .params(params) + .build() + .execute(new StringCallback() { + @Override + public void onError(Call call, Response response, Exception e, int id) { + callBack.onError(validateError(e, response)); + } + + @Override + public void onResponse(String response, int id) { + callBack.onResponse(response); + } + }); + + } + + /** + * 下载 + * + * @param url 下载地址 + * @param path 文件保存路径 + * @param fileName 文件名称 + * @param callback 回调 + */ + public void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull final FileCallback callback) { + OkHttpUtils.get() + .url(url) + .build() + .execute(new FileCallBack(path, fileName) { + @Override + public void inProgress(float progress, long total, int id) { + callback.onProgress(progress, total); + } + + @Override + public void onError(Call call, Response response, Exception e, int id) { + callback.onError(validateError(e, response)); + } + + @Override + public void onResponse(File response, int id) { + callback.onResponse(response); + + } + + @Override + public void onBefore(Request request, int id) { + super.onBefore(request, id); + callback.onBefore(); + } + }); + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/InitUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/InitUtil.java new file mode 100644 index 00000000..9b33957e --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/InitUtil.java @@ -0,0 +1,24 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.Context; +import android.util.Log; + +public class InitUtil { + static Boolean hasInit = false; + private static String TAG = "InitUtil"; + private static Context context = null; + + public static void init(Context context1) { + Log.d(TAG, "TMSG init"); + synchronized (hasInit) { + if (hasInit) return; + hasInit = true; + context = context1; + Log.d(TAG, "init context"); + SettingUtil.init(context); + } + + + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java new file mode 100644 index 00000000..c35f9ed3 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java @@ -0,0 +1,178 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.provider.BaseColumns; +import android.util.Log; + +import com.idormy.sms.forwarder.model.LogModel; +import com.idormy.sms.forwarder.model.LogTable; +import com.idormy.sms.forwarder.model.RuleModel; +import com.idormy.sms.forwarder.model.RuleTable; +import com.idormy.sms.forwarder.model.SenderModel; +import com.idormy.sms.forwarder.model.SenderTable; +import com.idormy.sms.forwarder.model.vo.LogVo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class LogUtil { + static String TAG = "LogUtil"; + static Boolean hasInit = false; + + static Context context; + static DbHelper dbHelper; + static SQLiteDatabase db; + + public static void init(Context context1) { + synchronized (hasInit) { + if (hasInit) return; + hasInit = true; + context = context1; + dbHelper = new DbHelper(context); + // Gets the data repository in write mode + db = dbHelper.getReadableDatabase(); + } + + } + + public static long addLog(LogModel logModel) { + Log.i(TAG, "addLog logModel: " + logModel); + //不保存转发消息 + if (logModel == null) return 0; + + // Create a new map of values, where column names are the keys + ContentValues values = new ContentValues(); + values.put(LogTable.LogEntry.COLUMN_NAME_FROM, logModel.getFrom()); + values.put(LogTable.LogEntry.COLUMN_NAME_CONTENT, logModel.getContent()); + values.put(LogTable.LogEntry.COLUMN_NAME_RULE_ID, logModel.getRuleId()); + + // Insert the new row, returning the primary key value of the new row + + return db.insert(LogTable.LogEntry.TABLE_NAME, null, values); + } + + public static int delLog(Long id, String key) { + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + if (id != null) { + // Define 'where' part of query. + selection += " and " + LogTable.LogEntry._ID + " = ? "; + // Specify arguments in placeholder order. + selectionArgList.add(String.valueOf(id)); + + } + + if (key != null) { + // Define 'where' part of query. + selection = " and (" + LogTable.LogEntry.COLUMN_NAME_FROM + " LIKE ? or " + LogTable.LogEntry.COLUMN_NAME_CONTENT + " LIKE ? ) "; + // Specify arguments in placeholder order. + selectionArgList.add(key); + selectionArgList.add(key); + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + // Issue SQL statement. + return db.delete(LogTable.LogEntry.TABLE_NAME, selection, selectionArgs); + + } + + public static List getLog(Long id, String key) { + // Define a projection that specifies which columns from the database + // you will actually use after this query. + String[] projection = { + LogTable.LogEntry.TABLE_NAME + "." + BaseColumns._ID, + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_FROM, + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_TIME, + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_CONTENT, + RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_FILED, + RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_CHECK, + RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_VALUE, + SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry.COLUMN_NAME_NAME, + SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry.COLUMN_NAME_TYPE + }; + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + if (id != null) { + // Define 'where' part of query. + selection += " and " + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry._ID + " = ? "; + // Specify arguments in placeholder order. + selectionArgList.add(String.valueOf(id)); + } + + if (key != null) { + // Define 'where' part of query. + selection = " and (" + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_FROM + " LIKE ? or " + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_CONTENT + " LIKE ? ) "; + // Specify arguments in placeholder order. + selectionArgList.add(key); + selectionArgList.add(key); + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + + // How you want the results sorted in the resulting Cursor + String sortOrder = + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry._ID + " DESC"; + + Cursor cursor = db.query( + // The table to query + LogTable.LogEntry.TABLE_NAME + + " LEFT JOIN " + RuleTable.RuleEntry.TABLE_NAME + " ON " + LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_RULE_ID + "=" + RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry._ID + + " LEFT JOIN " + SenderTable.SenderEntry.TABLE_NAME + " ON " + SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry._ID + "=" + RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID, + projection, // The array of columns to return (pass null to get all) + selection, // The columns for the WHERE clause + selectionArgs, // The values for the WHERE clause + null, // don't group the rows + null, // don't filter by row groups + sortOrder // The sort order + ); + + + Log.d(TAG, "getLog: " + db.getPath()); + List LogVos = new ArrayList<>(); + + Log.d(TAG, "getLog: itemId cursor" + Arrays.toString(cursor.getColumnNames())); + while (cursor.moveToNext()) { + try { + String itemfrom = cursor.getString( + cursor.getColumnIndexOrThrow(LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_FROM)); + String content = cursor.getString( + cursor.getColumnIndexOrThrow(LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_CONTENT)); + String time = cursor.getString( + cursor.getColumnIndexOrThrow(LogTable.LogEntry.TABLE_NAME + "." + LogTable.LogEntry.COLUMN_NAME_TIME)); + String ruleFiled = cursor.getString( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_FILED)); + String ruleCheck = cursor.getString( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_CHECK)); + String ruleValue = cursor.getString( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.TABLE_NAME + "." + RuleTable.RuleEntry.COLUMN_NAME_VALUE)); + String senderName = cursor.getString( + cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry.COLUMN_NAME_NAME)); + Integer senderType = cursor.getInt( + cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.TABLE_NAME + "." + SenderTable.SenderEntry.COLUMN_NAME_TYPE)); + + Log.d(TAG, "getLog: time" + time); + String rule = RuleModel.getRuleMatch(ruleFiled, ruleCheck, ruleValue) + " 转发到 " + senderName; +// String rule = time+" 转发到 "+senderName; + int senderImageId = SenderModel.getImageId(senderType); + LogVo logVo = new LogVo(itemfrom, content, time, rule, senderImageId); + + LogVos.add(logVo); + } catch (Exception e) { + Log.i(TAG, "getLog e:" + e.getMessage()); + } + + } + + + cursor.close(); + + return LogVos; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/MailInfo.java b/app/src/main/java/com/idormy/sms/forwarder/utils/MailInfo.java new file mode 100644 index 00000000..9a562322 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/MailInfo.java @@ -0,0 +1,139 @@ +package com.idormy.sms.forwarder.utils; + +import java.util.Properties; + +public class MailInfo { + + private String mailServerHost;// 发送邮件的服务器的IP + private String mailServerPort;// 发送邮件的服务器的端口 + private String fromAddress;// 邮件发送者的地址 + private String toAddress; // 邮件接收者的地址 + private String userName;// 登陆邮件发送服务器的用户名 + private String password;// 登陆邮件发送服务器的密码 + private boolean validate = true;// 是否需要身份验证 + private boolean ssl = true;// ssl + private String subject;// 邮件主题 + private String content;// 邮件的文本内容 + private String[] attachFileNames;// 邮件附件的文件名 + + + public String toString() { + return "mailServerHost:" + this.mailServerHost + + "mailServerPort:" + this.mailServerPort + + "fromAddress:" + this.fromAddress + + "toAddress:" + this.toAddress + + "userName:" + this.userName + + "password:" + this.password + + "subject:" + this.subject + + "content:" + this.content; + } + + /** + * 获得邮件会话属性 + */ + public Properties getProperties() { + Properties p = new Properties(); + p.put("mail.smtp.host", this.mailServerHost); + p.put("mail.smtp.port", this.mailServerPort); + p.put("mail.smtp.auth", validate ? "true" : "false"); + + // 设置SSL加密(未采用SSL时,端口一般为25,可以不用设置;采用SSL时,端口为465,需要显示设置) + if (ssl) { + p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + p.put("mail.smtp.socketFactory.fallback", "false"); + p.put("mail.smtp.socketFactory.port", this.mailServerPort); + } + + +// props.setProperty("mail.smtp.port", "465"); +// props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); +// props.setProperty("mail.smtp.socketFactory.fallback", "false"); +// props.setProperty("mail.smtp.socketFactory.port", "465"); + return p; + } + + public String getMailServerHost() { + return mailServerHost; + } + + public void setMailServerHost(String mailServerHost) { + this.mailServerHost = mailServerHost; + } + + public String getMailServerPort() { + return mailServerPort; + } + + public void setMailServerPort(String mailServerPort) { + this.mailServerPort = mailServerPort; + } + + public boolean isValidate() { + return validate; + } + + public void setValidate(boolean validate) { + this.validate = validate; + } + + public void ssl(boolean ssl) { + this.ssl = ssl; + } + + public String[] getAttachFileNames() { + return attachFileNames; + } + + public void setAttachFileNames(String[] fileNames) { + this.attachFileNames = fileNames; + } + + public String getFromAddress() { + return fromAddress; + } + + public void setFromAddress(String fromAddress) { + this.fromAddress = fromAddress; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getToAddress() { + return toAddress; + } + + public void setToAddress(String toAddress) { + this.toAddress = toAddress; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getContent() { + return content; + } + + public void setContent(String textContent) { + this.content = textContent; + } +} + diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/MailSender.java b/app/src/main/java/com/idormy/sms/forwarder/utils/MailSender.java new file mode 100644 index 00000000..f52c41a3 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/MailSender.java @@ -0,0 +1,205 @@ +package com.idormy.sms.forwarder.utils; + +import android.util.Log; + +import java.io.File; +import java.util.Date; +import java.util.Properties; + +import javax.activation.DataHandler; +import javax.activation.FileDataSource; +import javax.mail.Address; +import javax.mail.Authenticator; +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import javax.mail.internet.MimeUtility; + +/** + * 发送器 + */ +public class MailSender { + private static String TAG = "MailSender"; + + /** + * 以HTML格式发送邮件 + * + * @param mailInfo 待发送的邮件信息 + */ + public static boolean sendHtmlMail(MailInfo mailInfo) { + Log.d(TAG, "sendHtmlMail MailInfo " + mailInfo.toString()); + // 判断是否需要身份认证 + MyAuthenticator authenticator = null; + Properties pro = mailInfo.getProperties(); + // 如果需要身份认证,则创建一个密码验证器 + if (mailInfo.isValidate()) { + authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword()); + } + // 根据邮件会话属性和密码验证器构造一个发送邮件的session + Session sendMailSession = Session.getDefaultInstance(pro, authenticator); + try { + // 根据session创建一个邮件消息 + Message mailMessage = new MimeMessage(sendMailSession); + // 创建邮件发送者地址 + Address from = new InternetAddress(mailInfo.getFromAddress()); + // 设置邮件消息的发送者 + mailMessage.setFrom(from); + // 创建邮件的接收者地址,并设置到邮件消息中 + Address to = new InternetAddress(mailInfo.getToAddress()); + // Message.RecipientType.TO属性表示接收者的类型为TO + mailMessage.setRecipient(Message.RecipientType.TO, to); + // 设置邮件消息的主题 + mailMessage.setSubject(mailInfo.getSubject()); + // 设置邮件消息发送的时间 + mailMessage.setSentDate(new Date()); + // MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象 + Multipart mainPart = new MimeMultipart(); + // 创建一个包含HTML内容的MimeBodyPart + BodyPart html = new MimeBodyPart(); + // 设置HTML内容 + html.setContent(mailInfo.getContent(), "text/html; charset=utf-8"); + mainPart.addBodyPart(html); + // 将MiniMultipart对象设置为邮件内容 + mailMessage.setContent(mainPart); + // 发送邮件 + Transport.send(mailMessage); + return true; + } catch (MessagingException ex) { + ex.printStackTrace(); + } + return false; + } + + /** + * 以文本格式发送邮件 + * + * @param mailInfo 待发送的邮件的信息 + */ + public boolean sendTextMail(final MailInfo mailInfo) { + Log.d(TAG, "sendTextMail MailInfo " + mailInfo.toString()); + // 判断是否需要身份认证 + MyAuthenticator authenticator = null; + Properties pro = mailInfo.getProperties(); + if (mailInfo.isValidate()) { + // 如果需要身份认证,则创建一个密码验证器 + authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword()); + } + // 根据邮件会话属性和密码验证器构造一个发送邮件的session + Session sendMailSession = Session.getDefaultInstance(pro, authenticator); + + try { + // 根据session创建一个邮件消息 + Message mailMessage = new MimeMessage(sendMailSession); + // 创建邮件发送者地址 + Address from = new InternetAddress(mailInfo.getFromAddress()); + // 设置邮件消息的发送者 + mailMessage.setFrom(from); + // 创建邮件的接收者地址,并设置到邮件消息中 + Address to = new InternetAddress(mailInfo.getToAddress()); + mailMessage.setRecipient(Message.RecipientType.TO, to); + // 设置邮件消息的主题 + mailMessage.setSubject(mailInfo.getSubject()); + // 设置邮件消息发送的时间 + mailMessage.setSentDate(new Date()); + + // 设置邮件消息的主要内容 + String mailContent = mailInfo.getContent(); + mailMessage.setText(mailContent); + // 发送邮件 + Transport.send(mailMessage); + SendHistory.addHistory("Email mailInfo:" + mailInfo.toString()); + return true; + } catch (MessagingException ex) { + SendHistory.addHistory("Email Fail mailInfo:" + mailInfo.toString()); + Log.d(TAG, "sendTextMail MailInfo " + ex.getMessage()); + ex.printStackTrace(); + } + return false; + } + + /** + * 发送带附件的邮件 + * + * @param info + * @return + */ + public boolean sendFileMail(MailInfo info, File file) { + Log.d(TAG, "sendFileMail MailInfo " + info.toString()); + Message attachmentMail = createAttachmentMail(info, file); + try { + Transport.send(attachmentMail); + return true; + } catch (MessagingException e) { + e.printStackTrace(); + return false; + } + + } + + /** + * 创建带有附件的邮件 + * + * @return + */ + private Message createAttachmentMail(final MailInfo info, File file) { + Log.d(TAG, "createAttachmentMail MailInfo " + info.toString()); + //创建邮件 + MimeMessage message = null; + Properties pro = info.getProperties(); + try { + + Session sendMailSession = Session.getInstance(pro, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(info.getUserName(), info.getPassword()); + } + }); + + message = new MimeMessage(sendMailSession); + // 设置邮件的基本信息 + //创建邮件发送者地址 + Address from = new InternetAddress(info.getFromAddress()); + //设置邮件消息的发送者 + message.setFrom(from); + //创建邮件的接受者地址,并设置到邮件消息中 + Address to = new InternetAddress(info.getToAddress()); + //设置邮件消息的接受者, Message.RecipientType.TO属性表示接收者的类型为TO + message.setRecipient(Message.RecipientType.TO, to); + //邮件标题 + message.setSubject(info.getSubject()); + + // 创建邮件正文,为了避免邮件正文中文乱码问题,需要使用CharSet=UTF-8指明字符编码 + MimeBodyPart text = new MimeBodyPart(); + text.setContent(info.getContent(), "text/html;charset=UTF-8"); + + // 创建容器描述数据关系 + MimeMultipart mp = new MimeMultipart(); + mp.addBodyPart(text); + // 创建邮件附件 + MimeBodyPart attach = new MimeBodyPart(); + + FileDataSource ds = new FileDataSource(file); + DataHandler dh = new DataHandler(ds); + attach.setDataHandler(dh); + attach.setFileName(MimeUtility.encodeText(dh.getName())); + mp.addBodyPart(attach); + mp.setSubType("mixed"); + message.setContent(mp); + message.saveChanges(); + + } catch (Exception e) { + Log.e("TAG", "创建带附件的邮件失败"); + e.printStackTrace(); + } + // 返回生成的邮件 + return message; + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/MailSenderInfo.java b/app/src/main/java/com/idormy/sms/forwarder/utils/MailSenderInfo.java new file mode 100644 index 00000000..51d2d95b --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/MailSenderInfo.java @@ -0,0 +1,147 @@ +package com.idormy.sms.forwarder.utils; + +import android.util.Log; + +import com.sun.mail.util.MailSSLSocketFactory; + +import java.security.GeneralSecurityException; +import java.util.Properties; + +public class MailSenderInfo { + private static String TAG = "MailSenderInfo"; + // 发送邮件的服务器的IP和端口 + private String mailServerHost; + private String mailServerPort = "25"; + + // 邮件发送者的地址 + private String fromAddress; + // 邮件接收者的地址 + private String toAddress; + // 登陆邮件发送服务器的用户名和密码 + private String userName; + private String password; + // 是否需要身份验证 + private boolean validate = true; + //开启ssl + private boolean ssl = true; + // 邮件主题 + private String subject; + // 邮件的文本内容 + private String content; + // 邮件附件的文件名 + private String[] attachFileNames; + + /** + * 获得邮件会话属性 + */ + public Properties getProperties() { + Properties props = new Properties(); + props.put("mail.smtp.host", this.mailServerHost); + props.put("mail.smtp.port", this.mailServerPort); + props.put("mail.smtp.auth", validate ? "true" : "false"); + + if (ssl) { + try { + MailSSLSocketFactory sf = new MailSSLSocketFactory(); + sf.setTrustAllHosts(true); + props.put("mail.smtp.ssl.enable", "true"); + props.put("mail.smtp.ssl.socketFactory", sf); + Log.i(TAG, "set ssl success"); + } catch (GeneralSecurityException e) { + Log.e(TAG, "set ssl fail: " + e.getMessage()); + e.printStackTrace(); + } + } + + return props; + } + + public String getMailServerHost() { + return mailServerHost; + } + + public void setMailServerHost(String mailServerHost) { + this.mailServerHost = mailServerHost; + } + + public String getMailServerPort() { + return mailServerPort; + } + + public void setMailServerPort(String mailServerPort) { + this.mailServerPort = mailServerPort; + } + + public boolean isValidate() { + return validate; + } + + public void setValidate(boolean validate) { + this.validate = validate; + } + + public String[] getAttachFileNames() { + return attachFileNames; + } + + public void setAttachFileNames(String[] fileNames) { + this.attachFileNames = fileNames; + } + + public String getFromAddress() { + return fromAddress; + } + + public void setFromAddress(String fromAddress) { + this.fromAddress = fromAddress; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getToAddress() { + return toAddress; + } + + public void setToAddress(String toAddress) { + this.toAddress = toAddress; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getContent() { + return content; + } + + public void setContent(String textContent) { + this.content = textContent; + } + + public boolean isSsl() { + return ssl; + } + + public void setSsl(boolean ssl) { + this.ssl = ssl; + } +} + diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/MyAuthenticator.java b/app/src/main/java/com/idormy/sms/forwarder/utils/MyAuthenticator.java new file mode 100644 index 00000000..6c78d78a --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/MyAuthenticator.java @@ -0,0 +1,21 @@ +package com.idormy.sms.forwarder.utils; + +import javax.mail.Authenticator; +import javax.mail.PasswordAuthentication; + +public class MyAuthenticator extends Authenticator { + String userName = null; + String password = null; + + public MyAuthenticator() { + } + + public MyAuthenticator(String username, String password) { + this.userName = username; + this.password = password; + } + + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(userName, password); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/RuleUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleUtil.java new file mode 100644 index 00000000..f487806f --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/RuleUtil.java @@ -0,0 +1,157 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.provider.BaseColumns; +import android.util.Log; + +import com.idormy.sms.forwarder.model.RuleModel; +import com.idormy.sms.forwarder.model.RuleTable; + +import java.util.ArrayList; +import java.util.List; + +public class RuleUtil { + static String TAG = "RuleUtil"; + static Boolean hasInit = false; + static Context context; + static DbHelper dbHelper; + static SQLiteDatabase db; + + public static void init(Context context1) { + synchronized (hasInit) { + if (hasInit) return; + hasInit = true; + context = context1; + dbHelper = new DbHelper(context); + // Gets the data repository in write mode + db = dbHelper.getReadableDatabase(); + } + + } + + public static long addRule(RuleModel ruleModel) { + + // Create a new map of values, where column names are the keys + ContentValues values = new ContentValues(); + values.put(RuleTable.RuleEntry.COLUMN_NAME_FILED, ruleModel.getFiled()); + values.put(RuleTable.RuleEntry.COLUMN_NAME_CHECK, ruleModel.getCheck()); + values.put(RuleTable.RuleEntry.COLUMN_NAME_VALUE, ruleModel.getValue()); + values.put(RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID, ruleModel.getSenderId()); + + // Insert the new row, returning the primary key value of the new row + + return db.insert(RuleTable.RuleEntry.TABLE_NAME, null, values); + } + + public static long updateRule(RuleModel ruleModel) { + if (ruleModel == null) return 0; + + // Create a new map of values, where column names are the keys + ContentValues values = new ContentValues(); + values.put(RuleTable.RuleEntry.COLUMN_NAME_FILED, ruleModel.getFiled()); + values.put(RuleTable.RuleEntry.COLUMN_NAME_CHECK, ruleModel.getCheck()); + values.put(RuleTable.RuleEntry.COLUMN_NAME_VALUE, ruleModel.getValue()); + values.put(RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID, ruleModel.getSenderId()); + + String selection = RuleTable.RuleEntry._ID + " = ? "; + String[] whereArgs = {String.valueOf(ruleModel.getId())}; + + return db.update(RuleTable.RuleEntry.TABLE_NAME, values, selection, whereArgs); + } + + public static int delRule(Long id) { + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + if (id != null) { + // Define 'where' part of query. + selection += " and " + RuleTable.RuleEntry._ID + " = ? "; + // Specify arguments in placeholder order. + selectionArgList.add(String.valueOf(id)); + + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + // Issue SQL statement. + return db.delete(RuleTable.RuleEntry.TABLE_NAME, selection, selectionArgs); + + } + + public static List getRule(Long id, String key) { + // Define a projection that specifies which columns from the database + // you will actually use after this query. + String[] projection = { + BaseColumns._ID, + RuleTable.RuleEntry.COLUMN_NAME_FILED, + RuleTable.RuleEntry.COLUMN_NAME_CHECK, + RuleTable.RuleEntry.COLUMN_NAME_VALUE, + RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID, + RuleTable.RuleEntry.COLUMN_NAME_TIME + }; + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + if (id != null) { + // Define 'where' part of query. + selection += " and " + RuleTable.RuleEntry._ID + " = ? "; + // Specify arguments in placeholder order. + selectionArgList.add(String.valueOf(id)); + } + + if (key != null) { + // Define 'where' part of query. + selection = " and (" + RuleTable.RuleEntry.COLUMN_NAME_VALUE + " LIKE ? "; + // Specify arguments in placeholder order. + selectionArgList.add(key); + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + + // How you want the results sorted in the resulting Cursor + String sortOrder = + RuleTable.RuleEntry._ID + " DESC"; + + Cursor cursor = db.query( + RuleTable.RuleEntry.TABLE_NAME, // The table to query + projection, // The array of columns to return (pass null to get all) + selection, // The columns for the WHERE clause + selectionArgs, // The values for the WHERE clause + null, // don't group the rows + null, // don't filter by row groups + sortOrder // The sort order + ); + List tRules = new ArrayList<>(); + while (cursor.moveToNext()) { + + long itemId = cursor.getLong( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry._ID)); + String itemFiled = cursor.getString( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_FILED)); + String itemCheck = cursor.getString( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_CHECK)); + String itemValue = cursor.getString( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_VALUE)); + long itemSenderId = cursor.getLong( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_SENDER_ID)); + long itemTime = cursor.getLong( + cursor.getColumnIndexOrThrow(RuleTable.RuleEntry.COLUMN_NAME_TIME)); + + Log.d(TAG, "getRule: itemId" + itemId); + RuleModel ruleModel = new RuleModel(); + ruleModel.setId(itemId); + ruleModel.setFiled(itemFiled); + ruleModel.setCheck(itemCheck); + ruleModel.setValue(itemValue); + ruleModel.setSenderId(itemSenderId); + ruleModel.setTime(itemTime); + + tRules.add(ruleModel); + } + cursor.close(); + return tRules; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SendHistory.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SendHistory.java new file mode 100644 index 00000000..fb17f8fd --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SendHistory.java @@ -0,0 +1,171 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.ContentValues; +import android.content.Context; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.provider.BaseColumns; +import android.util.Log; + +import com.idormy.sms.forwarder.model.LogModel; +import com.idormy.sms.forwarder.model.LogTable; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class SendHistory { + static String TAG = "SendHistory"; + static Boolean hasInit = false; + + static Context context; + static DbHelper dbHelper; + static SQLiteDatabase db; + + public static void init(Context context1) { + synchronized (hasInit) { + if (hasInit) return; + hasInit = true; + context = context1; + dbHelper = new DbHelper(context); + db = dbHelper.getReadableDatabase(); + } + + + } + + public static void addHistory(String msg) { + //不保存转发消息 + if (!SettingUtil.saveMsgHistory()) return; + //保存 + SharedPreferences sp = context.getSharedPreferences(Define.SP_MSG, Context.MODE_PRIVATE); + Set msg_set_default = new HashSet<>(); + Set msg_set; + msg_set = sp.getStringSet(Define.SP_MSG_SET_KEY, msg_set_default); + Log.d(TAG, "msg_set:" + msg_set.toString()); + Log.d(TAG, "msg_set:" + Integer.toString(msg_set.size())); + msg_set.add(msg); + sp.edit().putStringSet(Define.SP_MSG_SET_KEY, msg_set).apply(); + } + + public static String getHistory() { + SharedPreferences sp = context.getSharedPreferences(Define.SP_MSG, Context.MODE_PRIVATE); + Set msg_set = new HashSet<>(); + msg_set = sp.getStringSet(Define.SP_MSG_SET_KEY, msg_set); + Log.d(TAG, "msg_set.toString()" + msg_set.toString()); + String getMsg = ""; + for (String str : msg_set) { + getMsg += str + "\n"; + } + return getMsg; + } + + public static long addHistoryDb(LogModel logModel) { + //不保存转发消息 + if (!SettingUtil.saveMsgHistory()) return 0; + + // Gets the data repository in write mode + SQLiteDatabase db = dbHelper.getWritableDatabase(); + + // Create a new map of values, where column names are the keys + ContentValues values = new ContentValues(); + values.put(LogTable.LogEntry.COLUMN_NAME_FROM, logModel.getFrom()); + values.put(LogTable.LogEntry.COLUMN_NAME_CONTENT, logModel.getContent()); + values.put(LogTable.LogEntry.COLUMN_NAME_TIME, logModel.getTime()); + + // Insert the new row, returning the primary key value of the new row + + return db.insert(LogTable.LogEntry.TABLE_NAME, null, values); + } + + public static int delHistoryDb(Long id, String key) { + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + if (id != null) { + // Define 'where' part of query. + selection += " and " + LogTable.LogEntry._ID + " = ? "; + // Specify arguments in placeholder order. + selectionArgList.add(String.valueOf(id)); + + } + + if (key != null) { + // Define 'where' part of query. + selection = " and (" + LogTable.LogEntry.COLUMN_NAME_FROM + " LIKE ? or " + LogTable.LogEntry.COLUMN_NAME_CONTENT + " LIKE ? ) "; + // Specify arguments in placeholder order. + selectionArgList.add(key); + selectionArgList.add(key); + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + // Issue SQL statement. + return db.delete(LogTable.LogEntry.TABLE_NAME, selection, selectionArgs); + + } + + public static String getHistoryDb(Long id, String key) { + // Define a projection that specifies which columns from the database + // you will actually use after this query. + String[] projection = { + BaseColumns._ID, + LogTable.LogEntry.COLUMN_NAME_FROM, + LogTable.LogEntry.COLUMN_NAME_CONTENT, + LogTable.LogEntry.COLUMN_NAME_TIME + }; + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + if (id != null) { + // Define 'where' part of query. + selection += " and " + LogTable.LogEntry._ID + " = ? "; + // Specify arguments in placeholder order. + selectionArgList.add(String.valueOf(id)); + } + + if (key != null) { + // Define 'where' part of query. + selection = " and (" + LogTable.LogEntry.COLUMN_NAME_FROM + " LIKE ? or " + LogTable.LogEntry.COLUMN_NAME_CONTENT + " LIKE ? ) "; + // Specify arguments in placeholder order. + selectionArgList.add(key); + selectionArgList.add(key); + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + + // How you want the results sorted in the resulting Cursor + String sortOrder = + LogTable.LogEntry._ID + " DESC"; + + Cursor cursor = db.query( + LogTable.LogEntry.TABLE_NAME, // The table to query + projection, // The array of columns to return (pass null to get all) + selection, // The columns for the WHERE clause + selectionArgs, // The values for the WHERE clause + null, // don't group the rows + null, // don't filter by row groups + sortOrder // The sort order + ); + List tLogs = new ArrayList<>(); + while (cursor.moveToNext()) { + long itemId = cursor.getLong( + cursor.getColumnIndexOrThrow(LogTable.LogEntry._ID)); + tLogs.add(itemId); + } + cursor.close(); + + + SharedPreferences sp = context.getSharedPreferences(Define.SP_MSG, Context.MODE_PRIVATE); + Set msg_set = new HashSet<>(); + msg_set = sp.getStringSet(Define.SP_MSG_SET_KEY, msg_set); + Log.d(TAG, "msg_set.toString()" + msg_set.toString()); + String getMsg = ""; + for (String str : msg_set) { + getMsg += str + "\n"; + } + return getMsg; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SendMailUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SendMailUtil.java new file mode 100644 index 00000000..129e04ea --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SendMailUtil.java @@ -0,0 +1,85 @@ +package com.idormy.sms.forwarder.utils; + +import android.util.Log; + +import java.io.File; + + +public class SendMailUtil { + private static String TAG = "SendMailUtil"; + //qq +// private static final String HOST = "smtp.qq.com"; +// private static final String PORT = "587"; +// private static final String FROM_ADD = "teprinciple@foxmail.com"; //发送方邮箱 +// private static final String FROM_PSW = "lfrlpganzjrwbeci";//发送方邮箱授权码 + +// //163 +// private static final String HOST = "smtp.163.com"; +// private static final String PORT = "465"; //nossl 25或者ssl465 994 +// private static final String FROM_ADD = "xxxxxx@163.com"; +// private static final String FROM_PSW = "xx"; + + public static void send(final File file, String toAdd, String title, String content) { + Log.d(TAG, "send file to " + toAdd); + final MailInfo mailInfo = creatMail(toAdd, title, content); + final MailSender sms = new MailSender(); + new Thread(new Runnable() { + @Override + public void run() { + sms.sendFileMail(mailInfo, file); + } + }).start(); + } + + public static void send(String toAdd, String title, String content) { + Log.d(TAG, "send to " + toAdd); + final MailInfo mailInfo = creatMail(toAdd, title, content); + final MailSender sms = new MailSender(); + new Thread(new Runnable() { + @Override + public void run() { + sms.sendTextMail(mailInfo); + } + }).start(); + } + + private static MailInfo creatMail(String toAdd, String title, String content) { + Log.d(TAG, "creatMail to " + toAdd); + final MailInfo mailInfo = new MailInfo(); + mailInfo.setMailServerHost(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_HOST_KEY)); + mailInfo.setMailServerPort(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_PORT_KEY)); + mailInfo.setValidate(true); + mailInfo.ssl(true); + mailInfo.setUserName(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY)); // 你的邮箱地址 + mailInfo.setPassword(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_PSW_KEY));// 您的邮箱密码 + mailInfo.setFromAddress(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY)); // 发送的邮箱 + mailInfo.setToAddress(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY)); // 发到哪个邮件去 + mailInfo.setSubject(title); // 邮件主题 + mailInfo.setContent(content); // 邮件文本 + return mailInfo; + } +} + +/** + * public void sendFileMail(View view) { + *

+ * File file = new File(Environment.getExternalStorageDirectory()+File.separator+"test.txt"); + * OutputStream os = null; + * try { + * os = new FileOutputStream(file); + * String str = "hello world"; + * byte[] data = str.getBytes(); + * os.write(data); + * } catch (FileNotFoundException e) { + * e.printStackTrace(); + * } catch (IOException e) { + * e.printStackTrace(); + * }finally{ + * try { + * if (os != null)os.close(); + * } catch (IOException e) { + * } + * } + * SendMailUtil.send(file,editText.getText().toString()); + * } + */ \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java new file mode 100644 index 00000000..429f022e --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SendUtil.java @@ -0,0 +1,234 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.Context; +import android.util.Log; + +import com.alibaba.fastjson.JSON; +import com.idormy.sms.forwarder.model.LogModel; +import com.idormy.sms.forwarder.model.RuleModel; +import com.idormy.sms.forwarder.model.SenderModel; +import com.idormy.sms.forwarder.model.vo.BarkSettingVo; +import com.idormy.sms.forwarder.model.vo.DingDingSettingVo; +import com.idormy.sms.forwarder.model.vo.EmailSettingVo; +import com.idormy.sms.forwarder.model.vo.QYWXGroupRobotSettingVo; +import com.idormy.sms.forwarder.model.vo.SmsVo; +import com.idormy.sms.forwarder.model.vo.WebNotifySettingVo; + +import java.util.List; + +import static com.idormy.sms.forwarder.model.RuleModel.CHECK_CONTAIN; +import static com.idormy.sms.forwarder.model.RuleModel.CHECK_END_WITH; +import static com.idormy.sms.forwarder.model.RuleModel.CHECK_IS; +import static com.idormy.sms.forwarder.model.RuleModel.CHECK_NOT_IS; +import static com.idormy.sms.forwarder.model.RuleModel.CHECK_START_WITH; +import static com.idormy.sms.forwarder.model.RuleModel.FILED_MSG_CONTENT; +import static com.idormy.sms.forwarder.model.RuleModel.FILED_PHONE_NUM; +import static com.idormy.sms.forwarder.model.RuleModel.FILED_TRANSPOND_ALL; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_BARK; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_DINGDING; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_EMAIL; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_QYWX_GROUP_ROBOT; +import static com.idormy.sms.forwarder.model.SenderModel.TYPE_WEB_NOTIFY; + +public class SendUtil { + private static String TAG = "SendUtil"; + + public static void send_msg(String msg) { + if (SettingUtil.using_dingding()) { + try { + SenderDingdingMsg.sendMsg(msg); + } catch (Exception e) { + Log.d(TAG, "发送出错:" + e.getMessage()); + } + + } + if (SettingUtil.using_email()) { +// SenderMailMsg.send(SettingUtil.get_send_util_email(Define.SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY),"转发",msg); + } + + } + + public static void send_msg_list(Context context, List smsVoList) { + Log.i(TAG, "send_msg_list size: " + smsVoList.size()); + for (SmsVo smsVo : smsVoList) { + SendUtil.send_msg(context, smsVo); + } + } + + public static void send_msg(Context context, SmsVo smsVo) { + Log.i(TAG, "send_msg smsVo:" + smsVo); + RuleUtil.init(context); + LogUtil.init(context); + + List rulelist = RuleUtil.getRule(null, null); + if (!rulelist.isEmpty()) { + SenderUtil.init(context); + for (RuleModel ruleModel : rulelist + ) { + boolean canSend = false; + //使用转发规则制定的字段 匹配 + switch (ruleModel.getFiled()) { + case FILED_TRANSPOND_ALL: + canSend = true; + break; + case FILED_PHONE_NUM: + switch (ruleModel.getCheck()) { + case CHECK_IS: + if (smsVo.getMobile() != null && smsVo.getMobile().equals(ruleModel.getValue())) { + canSend = true; + } + break; + case CHECK_NOT_IS: + if (smsVo.getMobile() != null && !smsVo.getMobile().equals(ruleModel.getValue())) { + canSend = true; + } + break; + case CHECK_START_WITH: + if (smsVo.getMobile() != null && smsVo.getMobile().startsWith(ruleModel.getValue())) { + canSend = true; + } + break; + case CHECK_END_WITH: + if (smsVo.getMobile() != null && smsVo.getMobile().endsWith(ruleModel.getValue())) { + canSend = true; + } + break; + case CHECK_CONTAIN: + if (smsVo.getMobile() != null && smsVo.getMobile().contains(ruleModel.getValue())) { + canSend = true; + } + break; + } + break; + case FILED_MSG_CONTENT: + switch (ruleModel.getCheck()) { + case CHECK_IS: + if (smsVo.getContent() != null && smsVo.getContent().equals(ruleModel.getValue())) { + canSend = true; + } + break; + case CHECK_NOT_IS: + if (smsVo.getContent() != null && !smsVo.getContent().equals(ruleModel.getValue())) { + canSend = true; + } + break; + case CHECK_START_WITH: + if (smsVo.getContent() != null && smsVo.getContent().startsWith(ruleModel.getValue())) { + canSend = true; + } + break; + case CHECK_END_WITH: + if (smsVo.getContent() != null && smsVo.getContent().endsWith(ruleModel.getValue())) { + canSend = true; + } + break; + case CHECK_CONTAIN: + if (smsVo.getContent() != null && smsVo.getContent().contains(ruleModel.getValue())) { + canSend = true; + } + break; + } + break; + + } + //规则匹配发现需要发送 + if (canSend) { + List senderModels = SenderUtil.getSender(ruleModel.getSenderId(), null); + for (SenderModel senderModel : senderModels + ) { + LogUtil.addLog(new LogModel(smsVo.getMobile(), smsVo.getContent(), senderModel.getId())); + SendUtil.senderSendMsg(smsVo, senderModel); + } + } + + } + + } + } + + public static void senderSendMsg(SmsVo smsVo, SenderModel senderModel) { + + Log.i(TAG, "senderSendMsg smsVo:" + smsVo + "senderModel:" + senderModel); + switch (senderModel.getType()) { + case TYPE_DINGDING: + //try phrase json setting + if (senderModel.getJsonSetting() != null) { + DingDingSettingVo dingDingSettingVo = JSON.parseObject(senderModel.getJsonSetting(), DingDingSettingVo.class); + if (dingDingSettingVo != null) { + try { + SenderDingdingMsg.sendMsg(null, dingDingSettingVo.getToken(), dingDingSettingVo.getSecret(), dingDingSettingVo.getAtMobils(), dingDingSettingVo.getAtAll(), smsVo.getSmsVoForSend()); + } catch (Exception e) { + Log.e(TAG, "senderSendMsg: dingding error " + e.getMessage()); + } + + } + } + + break; + case TYPE_EMAIL: + //try phrase json setting + if (senderModel.getJsonSetting() != null) { + EmailSettingVo emailSettingVo = JSON.parseObject(senderModel.getJsonSetting(), EmailSettingVo.class); + if (emailSettingVo != null) { + try { + SenderMailMsg.sendEmail(null, emailSettingVo.getHost(), emailSettingVo.getPort(), emailSettingVo.getSsl(), emailSettingVo.getFromEmail(), + emailSettingVo.getPwd(), emailSettingVo.getToEmail(), smsVo.getMobile(), smsVo.getSmsVoForSend()); + } catch (Exception e) { + Log.e(TAG, "senderSendMsg: SenderMailMsg error " + e.getMessage()); + } + + } + } + + break; + case TYPE_WEB_NOTIFY: + //try phrase json setting + if (senderModel.getJsonSetting() != null) { + WebNotifySettingVo webNotifySettingVo = JSON.parseObject(senderModel.getJsonSetting(), WebNotifySettingVo.class); + if (webNotifySettingVo != null) { + try { + SenderWebNotifyMsg.sendMsg(null, webNotifySettingVo.getToken(), webNotifySettingVo.getSecret(), smsVo.getMobile(), smsVo.getSmsVoForSend()); + } catch (Exception e) { + Log.e(TAG, "senderSendMsg: SenderWebNotifyMsg error " + e.getMessage()); + } + + } + } + + break; + case TYPE_QYWX_GROUP_ROBOT: + //try phrase json setting + if (senderModel.getJsonSetting() != null) { + QYWXGroupRobotSettingVo qywxGroupRobotSettingVo = JSON.parseObject(senderModel.getJsonSetting(), QYWXGroupRobotSettingVo.class); + if (qywxGroupRobotSettingVo != null) { + try { + SenderQyWxGroupRobotMsg.sendMsg(null, qywxGroupRobotSettingVo.getWebHook(), smsVo.getMobile(), smsVo.getSmsVoForSend()); + } catch (Exception e) { + Log.e(TAG, "senderSendMsg: SenderQyWxGroupRobotMsg error " + e.getMessage()); + } + + } + } + + break; + case TYPE_BARK: + //try phrase json setting + if (senderModel.getJsonSetting() != null) { + BarkSettingVo barkSettingVo = JSON.parseObject(senderModel.getJsonSetting(), BarkSettingVo.class); + if (barkSettingVo != null) { + try { + SenderBarkMsg.sendMsg(null, barkSettingVo.getServer(), smsVo.getMobile(), smsVo.getContent()); + } catch (Exception e) { + Log.e(TAG, "senderSendMsg: SenderBarkMsg error " + e.getMessage()); + } + + } + } + + break; + default: + break; + } + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderBarkMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderBarkMsg.java new file mode 100644 index 00000000..2e52a1ba --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderBarkMsg.java @@ -0,0 +1,89 @@ +package com.idormy.sms.forwarder.utils; + +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; + +import java.io.IOException; +import java.net.URLEncoder; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import static com.idormy.sms.forwarder.SenderActivity.NOTIFY; + +public class SenderBarkMsg { + + static String TAG = "SenderBarkMsg"; + + public static void sendMsg(final Handler handError, String barkServer, String from, String content) throws Exception { + Log.i(TAG, "sendMsg barkServer:" + barkServer + " from:" + from + " content:" + content); + + if (barkServer == null || barkServer.isEmpty()) { + return; + } + + barkServer += URLEncoder.encode(from, "UTF-8"); + String body = "短信内容:" + content + "\n转发时间:" + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + barkServer += "/" + URLEncoder.encode(content, "UTF-8"); + barkServer += "?isArchive=1"; //自动保存 + int isCode = content.indexOf("验证码"); + if (isCode != -1) { + Pattern p = Pattern.compile("(\\d{4,6})"); + Matcher m = p.matcher(content); + if (m.find()) { + System.out.println(m.group()); + barkServer += "&automaticallyCopy=1©=" + m.group(); + } + } + + OkHttpClient client = new OkHttpClient(); + final Request request = new Request.Builder() + .url(barkServer) + .addHeader("Content-Type", "application/json; charset=utf-8") + .get() + .build(); + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, final IOException e) { + Log.d(TAG, "onFailure:" + e.getMessage()); + + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送失败:" + e.getMessage()); + msg.setData(bundle); + handError.sendMessage(msg); + } + + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + final String responseStr = response.body().string(); + Log.d(TAG, "Code:" + response.code() + responseStr); + + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送状态:" + responseStr); + msg.setData(bundle); + handError.sendMessage(msg); + Log.d(TAG, "Response:" + response.code() + responseStr); + } + + } + }); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderDingdingMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderDingdingMsg.java new file mode 100644 index 00000000..ed40e3d1 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderDingdingMsg.java @@ -0,0 +1,184 @@ +package com.idormy.sms.forwarder.utils; + +import android.os.Bundle; +import android.os.Handler; +import android.text.TextUtils; +import android.util.Base64; +import android.util.Log; + +import com.alibaba.fastjson.JSON; + +import java.io.IOException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import static com.idormy.sms.forwarder.SenderActivity.NOTIFY; + +public class SenderDingdingMsg { + + static String TAG = "SenderDingdingMsg"; + + public static void sendMsg(String msg) throws Exception { + + String webhook_token = "https://oapi.dingtalk.com/robot/send?access_token=" + SettingUtil.get_using_dingding_token(); + String webhook_secret = SettingUtil.get_using_dingding_secret(); + if (webhook_token.equals("")) { + return; + } + if (!webhook_secret.equals("")) { + Long timestamp = System.currentTimeMillis(); + + String stringToSign = timestamp + "\n" + webhook_secret; + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(webhook_secret.getBytes("UTF-8"), "HmacSHA256")); + byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); + String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8"); + webhook_token += "×tamp=" + timestamp + "&sign=" + sign; + Log.i(TAG, "webhook_token:" + webhook_token); + + } + + final String msgf = msg; + String textMsg = "{ \"msgtype\": \"text\", \"text\": {\"content\": \"" + msg + "\"}}"; + OkHttpClient client = new OkHttpClient(); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), + textMsg); + + final Request request = new Request.Builder() + .url(webhook_token) + .addHeader("Content-Type", "application/json; charset=utf-8") + .post(requestBody) + .build(); + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + Log.d(TAG, "onFailure:" + e.getMessage()); + SendHistory.addHistory("钉钉转发:" + msgf + "onFailure:" + e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + final String responseStr = response.body().string(); + Log.d(TAG, "Code:" + String.valueOf(response.code()) + responseStr); + SendHistory.addHistory("钉钉转发:" + msgf + "Code:" + String.valueOf(response.code()) + responseStr); + } + }); + } + + public static void sendMsg(final Handler handError, String token, String secret, String atMobiles, Boolean atAll, String msg) throws Exception { + Log.i(TAG, "sendMsg token:" + token + " secret:" + secret + " atMobiles:" + atMobiles + " atAll:" + atAll + " msg:" + msg); + + if (token == null || token.isEmpty()) { + return; + } + if (secret != null && !secret.isEmpty()) { + Long timestamp = System.currentTimeMillis(); + + String stringToSign = timestamp + "\n" + secret; + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256")); + byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); + String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8"); + token = "https://oapi.dingtalk.com/robot/send?access_token=" + token; + token += "×tamp=" + timestamp + "&sign=" + sign; + Log.i(TAG, "webhook_token:" + token); + + } + + Map textMsgMap = new HashMap(); + textMsgMap.put("msgtype", "text"); + Map textText = new HashMap(); + textText.put("content", msg); + textMsgMap.put("text", textText); + if (atMobiles != null || atAll != null) { + Map AtMap = new HashMap(); + if (atMobiles != null) { + String[] atMobilesArray = atMobiles.split(","); + List atMobilesList = new ArrayList<>(); + for (String atMobile : atMobilesArray + ) { + if (TextUtils.isDigitsOnly(atMobile)) { + atMobilesList.add(atMobile); + } + } + if (!atMobilesList.isEmpty()) { + AtMap.put("atMobiles", atMobilesList); + + } + } + + AtMap.put("isAtAll", false); + if (atAll != null) { + AtMap.put("isAtAll", atAll); + + } + + textMsgMap.put("at", AtMap); + } + + String textMsg = JSON.toJSONString(textMsgMap); + Log.i(TAG, "textMsg:" + textMsg); + + OkHttpClient client = new OkHttpClient(); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), + textMsg); + + final Request request = new Request.Builder() + .url(token) + .addHeader("Content-Type", "application/json; charset=utf-8") + .post(requestBody) + .build(); + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, final IOException e) { + Log.d(TAG, "onFailure:" + e.getMessage()); + + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送失败:" + e.getMessage()); + msg.setData(bundle); + handError.sendMessage(msg); + } + + + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + final String responseStr = response.body().string(); + Log.d(TAG, "Code:" + String.valueOf(response.code()) + responseStr); + + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送状态:" + responseStr); + msg.setData(bundle); + handError.sendMessage(msg); + Log.d(TAG, "Coxxyyde:" + String.valueOf(response.code()) + responseStr); + } + + } + }); + } + + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderMailMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderMailMsg.java new file mode 100644 index 00000000..37641217 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderMailMsg.java @@ -0,0 +1,148 @@ +package com.idormy.sms.forwarder.utils; + +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; + +import java.util.Date; +import java.util.Properties; + +import javax.mail.Address; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; + +import static com.idormy.sms.forwarder.SenderActivity.NOTIFY; + + +public class SenderMailMsg { + private static String TAG = "SenderMailMsg"; + //qq +// private static final String HOST = "smtp.qq.com"; +// private static final String PORT = "587"; +// private static final String FROM_ADD = "teprinciple@foxmail.com"; //发送方邮箱 +// private static final String FROM_PSW = "lfrlpganzjrwbeci";//发送方邮箱授权码 + +// //163 +// private static final String HOST = "smtp.163.com"; +// private static final String PORT = "465"; //nossl 25或者ssl465 994 +// private static final String FROM_ADD = "xxxxxx@163.com"; +// private static final String FROM_PSW = "xx"; + + public static void sendEmail(final Handler handError, final String host, final String port, final boolean ssl, final String fromemail, final String pwd, final String toAdd, final String title, final String content) { + + Log.d(TAG, "sendEmail: host:" + host + " port:" + port + " ssl:" + ssl + " fromemail:" + fromemail + " pwd:" + pwd + " toAdd:" + toAdd); + new Thread(new Runnable() { + @Override + public void run() { + + try { + final MailSenderInfo mailInfo = new MailSenderInfo(); + mailInfo.setMailServerHost(host); + mailInfo.setMailServerPort(port); + mailInfo.setValidate(true); + mailInfo.setUserName(fromemail); //你的邮箱地址 + mailInfo.setPassword(pwd);//您的邮箱密码 + mailInfo.setFromAddress(fromemail);//和上面username的邮箱地址一致 + mailInfo.setToAddress(toAdd); + mailInfo.setSubject(title); + mailInfo.setContent(content); + mailInfo.setSsl(ssl); + + //这个类主要来发送邮件 + // 判断是否需要身份认证 + MyAuthenticator authenticator = null; + Properties pro = mailInfo.getProperties(); + if (mailInfo.isValidate()) { + // 如果需要身份认证,则创建一个密码验证器 + authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword()); + } + // 根据邮件会话属性和密码验证器构造一个发送邮件的session + Session sendMailSession = Session.getDefaultInstance(pro, authenticator); + try { + // 根据session创建一个邮件消息 + final Message mailMessage = new MimeMessage(sendMailSession); + // 创建邮件发送者地址 + Address from = new InternetAddress(mailInfo.getFromAddress()); + // 设置邮件消息的发送者 + mailMessage.setFrom(from); + // 创建邮件的接收者地址,并设置到邮件消息中 + Address to = new InternetAddress(mailInfo.getToAddress()); + mailMessage.setRecipient(Message.RecipientType.TO, to); + // 设置邮件消息的主题 + mailMessage.setSubject(mailInfo.getSubject()); + // 设置邮件消息发送的时间 + mailMessage.setSentDate(new Date()); + // 设置邮件消息的主要内容 + String mailContent = mailInfo.getContent(); + mailMessage.setText(mailContent); + // 发送邮件 + Transport.send(mailMessage); + + } catch (MessagingException ex) { + ex.printStackTrace(); + Log.e(TAG, "error" + ex.getMessage()); + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", ex.getMessage()); + msg.setData(bundle); + handError.sendMessage(msg); + } + + } + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送成功"); + msg.setData(bundle); + handError.sendMessage(msg); + } + + Log.e(TAG, "sendEmail success");//sms.sendHtmlMail(mailInfo);//发送html格式 + + } catch (Exception e) { + Log.e(TAG, e.getMessage(), e); + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", e.getMessage()); + msg.setData(bundle); + handError.sendMessage(msg); + } + + } + } + }).start(); + } +} + +/** + * public void sendFileMail(View view) { + *

+ * File file = new File(Environment.getExternalStorageDirectory()+File.separator+"test.txt"); + * OutputStream os = null; + * try { + * os = new FileOutputStream(file); + * String str = "hello world"; + * byte[] data = str.getBytes(); + * os.write(data); + * } catch (FileNotFoundException e) { + * e.printStackTrace(); + * } catch (IOException e) { + * e.printStackTrace(); + * }finally{ + * try { + * if (os != null)os.close(); + * } catch (IOException e) { + * } + * } + * SenderMailMsg.send(file,editText.getText().toString()); + * } + */ \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderQyWxGroupRobotMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderQyWxGroupRobotMsg.java new file mode 100644 index 00000000..63dadbc3 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderQyWxGroupRobotMsg.java @@ -0,0 +1,79 @@ +package com.idormy.sms.forwarder.utils; + +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import static com.idormy.sms.forwarder.SenderActivity.NOTIFY; + +public class SenderQyWxGroupRobotMsg { + + static String TAG = "SenderQyWxGroupRobotMsg"; + + public static void sendMsg(final Handler handError, String webHook, String from, String content) throws Exception { + Log.i(TAG, "sendMsg webHook:" + webHook + " from:" + from + " content:" + content); + + if (webHook == null || webHook.isEmpty()) { + return; + } + + String textMsg = "{ \"msgtype\": \"text\", \"text\": {\"content\": \"" + from + " : " + content + "\"}}"; + OkHttpClient client = new OkHttpClient(); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), + textMsg); + + final Request request = new Request.Builder() + .url(webHook) + .addHeader("Content-Type", "application/json; charset=utf-8") + .post(requestBody) + .build(); + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, final IOException e) { + Log.d(TAG, "onFailure:" + e.getMessage()); + +// SendHistory.addHistory("钉钉转发:"+msgf+"onFailure:" + e.getMessage()); + + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送失败:" + e.getMessage()); + msg.setData(bundle); + handError.sendMessage(msg); + } + + + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + final String responseStr = response.body().string(); + Log.d(TAG, "Code:" + String.valueOf(response.code()) + responseStr); + + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送状态:" + responseStr); + msg.setData(bundle); + handError.sendMessage(msg); + Log.d(TAG, "Coxxyyde:" + String.valueOf(response.code()) + responseStr); + } + + } + }); + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderUtil.java new file mode 100644 index 00000000..1ea75100 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderUtil.java @@ -0,0 +1,194 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.provider.BaseColumns; +import android.util.Log; + +import com.idormy.sms.forwarder.model.SenderModel; +import com.idormy.sms.forwarder.model.SenderTable; + +import java.util.ArrayList; +import java.util.List; + +public class SenderUtil { + static String TAG = "SenderUtil"; + static Boolean hasInit = false; + + static Context context; + static DbHelper dbHelper; + static SQLiteDatabase db; + + public static void init(Context context1) { + synchronized (hasInit) { + if (hasInit) return; + hasInit = true; + context = context1; + dbHelper = new DbHelper(context); + // Gets the data repository in write mode + db = dbHelper.getReadableDatabase(); + } + + } + + public static long addSender(SenderModel senderModel) { + + // Create a new map of values, where column names are the keys + ContentValues values = new ContentValues(); + values.put(SenderTable.SenderEntry.COLUMN_NAME_NAME, senderModel.getName()); + values.put(SenderTable.SenderEntry.COLUMN_NAME_TYPE, senderModel.getType()); + values.put(SenderTable.SenderEntry.COLUMN_NAME_STATUS, senderModel.getStatus()); + values.put(SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING, senderModel.getJsonSetting()); + + // Insert the new row, returning the primary key value of the new row + + return db.insert(SenderTable.SenderEntry.TABLE_NAME, null, values); + } + + public static long updateSender(SenderModel senderModel) { + if (senderModel == null) return 0; + + // Create a new map of values, where column names are the keys + ContentValues values = new ContentValues(); + values.put(SenderTable.SenderEntry.COLUMN_NAME_NAME, senderModel.getName()); + values.put(SenderTable.SenderEntry.COLUMN_NAME_TYPE, senderModel.getType()); + values.put(SenderTable.SenderEntry.COLUMN_NAME_STATUS, senderModel.getStatus()); + values.put(SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING, senderModel.getJsonSetting()); + + String selection = SenderTable.SenderEntry._ID + " = ? "; + String[] whereArgs = {String.valueOf(senderModel.getId())}; + + return db.update(SenderTable.SenderEntry.TABLE_NAME, values, selection, whereArgs); + } + + public static int delSender(Long id) { + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + if (id != null) { + // Define 'where' part of query. + selection += " and " + SenderTable.SenderEntry._ID + " = ? "; + // Specify arguments in placeholder order. + selectionArgList.add(String.valueOf(id)); + + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + // Issue SQL statement. + return db.delete(SenderTable.SenderEntry.TABLE_NAME, selection, selectionArgs); + + } + + public static List getSender(Long id, String key) { + // Define a projection that specifies which columns from the database + // you will actually use after this query. + String[] projection = { + BaseColumns._ID, + SenderTable.SenderEntry.COLUMN_NAME_NAME, + SenderTable.SenderEntry.COLUMN_NAME_TYPE, + SenderTable.SenderEntry.COLUMN_NAME_STATUS, + SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING, + SenderTable.SenderEntry.COLUMN_NAME_TIME + }; + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + if (id != null) { + // Define 'where' part of query. + selection += " and " + SenderTable.SenderEntry._ID + " = ? "; + // Specify arguments in placeholder order. + selectionArgList.add(String.valueOf(id)); + } + + if (key != null) { + // Define 'where' part of query. + selection = " and (" + SenderTable.SenderEntry.COLUMN_NAME_NAME + " LIKE ? or " + SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING + " LIKE ? ) "; + // Specify arguments in placeholder order. + selectionArgList.add(key); + selectionArgList.add(key); + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + + // How you want the results sorted in the resulting Cursor + String sortOrder = + SenderTable.SenderEntry._ID + " DESC"; + + Cursor cursor = db.query( + SenderTable.SenderEntry.TABLE_NAME, // The table to query + projection, // The array of columns to return (pass null to get all) + selection, // The columns for the WHERE clause + selectionArgs, // The values for the WHERE clause + null, // don't group the rows + null, // don't filter by row groups + sortOrder // The sort order + ); + List tSenders = new ArrayList<>(); + while (cursor.moveToNext()) { + + long itemId = cursor.getLong( + cursor.getColumnIndexOrThrow(SenderTable.SenderEntry._ID)); + String itemName = cursor.getString( + cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_NAME)); + int itemStatus = cursor.getInt( + cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_STATUS)); + int itemType = cursor.getInt( + cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_TYPE)); + String itemJsonSetting = cursor.getString( + cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING)); + long itemTime = cursor.getLong( + cursor.getColumnIndexOrThrow(SenderTable.SenderEntry.COLUMN_NAME_TIME)); + Log.d(TAG, "getSender: itemId" + itemId); + + SenderModel senderModel = new SenderModel(); + senderModel.setId(itemId); + senderModel.setName(itemName); + senderModel.setStatus(itemStatus); + senderModel.setType(itemType); + senderModel.setJsonSetting(itemJsonSetting); + senderModel.setTime(itemTime); + + tSenders.add(senderModel); + } + cursor.close(); + return tSenders; + } + + public static int countSender(String key) { + // Define a projection that specifies which columns from the database + // you will actually use after this query. + String[] projection = { + }; + // Define 'where' part of query. + String selection = " 1 "; + // Specify arguments in placeholder order. + List selectionArgList = new ArrayList<>(); + + if (key != null) { + // Define 'where' part of query. + selection = " and (" + SenderTable.SenderEntry.COLUMN_NAME_NAME + " LIKE ? or " + SenderTable.SenderEntry.COLUMN_NAME_JSON_SETTING + " LIKE ? ) "; + // Specify arguments in placeholder order. + selectionArgList.add(key); + selectionArgList.add(key); + } + String[] selectionArgs = selectionArgList.toArray(new String[selectionArgList.size()]); + + // How you want the results sorted in the resulting Cursor + + Cursor cursor = db.query( + SenderTable.SenderEntry.TABLE_NAME, // The table to query + projection, // The array of columns to return (pass null to get all) + selection, // The columns for the WHERE clause + selectionArgs, // The values for the WHERE clause + null, // don't group the rows + null, // don't filter by row groups + null // The sort order + ); + int count = cursor.getCount(); + cursor.close(); + return count; + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SenderWebNotifyMsg.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderWebNotifyMsg.java new file mode 100644 index 00000000..54560215 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SenderWebNotifyMsg.java @@ -0,0 +1,100 @@ +package com.idormy.sms.forwarder.utils; + +import android.os.Bundle; +import android.os.Handler; +import android.util.Base64; +import android.util.Log; + +import java.io.IOException; +import java.net.URLEncoder; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import static com.idormy.sms.forwarder.SenderActivity.NOTIFY; + +public class SenderWebNotifyMsg { + + static String TAG = "SenderWebNotifyMsg"; + + public static void sendMsg(final Handler handError, String token, String secret, String from, String content) throws Exception { + Log.i(TAG, "sendMsg token:" + token + " from:" + from + " content:" + content); + + if (token == null || token.isEmpty()) { + return; + } + + OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + MediaType mediaType = MediaType.parse("text/plain"); + MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("from", from) + .addFormDataPart("content", content); + + if (secret != null && !secret.isEmpty()) { + Long timestamp = System.currentTimeMillis(); + + String stringToSign = timestamp + "\n" + secret; + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256")); + byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); + String sign = URLEncoder.encode(new String(Base64.encode(signData, Base64.NO_WRAP)), "UTF-8"); + Log.i(TAG, "sign:" + sign); + builder.addFormDataPart("content", content); + } + + RequestBody body = builder.build(); + Request request = new Request.Builder() + .url(token) + .method("POST", body) + .build(); +// Response response = client.newCall(request).execute(); + + + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, final IOException e) { + Log.d(TAG, "onFailure:" + e.getMessage()); + + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送失败:" + e.getMessage()); + msg.setData(bundle); + handError.sendMessage(msg); + } + + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + final String responseStr = response.body().string(); + Log.d(TAG, "Code:" + String.valueOf(response.code()) + responseStr); + + if (handError != null) { + android.os.Message msg = new android.os.Message(); + msg.what = NOTIFY; + Bundle bundle = new Bundle(); + bundle.putString("DATA", "发送状态:" + responseStr); + msg.setData(bundle); + handError.sendMessage(msg); + Log.d(TAG, "Coxxyyde:" + String.valueOf(response.code()) + responseStr); + } + + } + }); + } + + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java new file mode 100644 index 00000000..213cab6f --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java @@ -0,0 +1,74 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +public class SettingUtil { + static Boolean hasInit = false; + private static String TAG = "SettingUtil"; + private static SharedPreferences sp_setting = null; + private static Context context = null; + + public static void init(Context context1) { + synchronized (hasInit) { + if (hasInit) return; + hasInit = true; + context = context1; + Log.d(TAG, "init "); + sp_setting = PreferenceManager.getDefaultSharedPreferences(context1); + + } + } + + public static boolean option_withreboot() { + return sp_setting.getBoolean("option_withreboot", false); + } + + public static boolean using_dingding() { + return sp_setting.getBoolean("option_dingding_on", false); + } + + public static String get_using_dingding_token() { + return sp_setting.getString("option_dingding_token", ""); + } + + public static String get_using_dingding_secret() { + return sp_setting.getString("option_dingding_secret", ""); + } + + public static boolean using_email() { + return sp_setting.getBoolean("option_email_on", false); + } + + public static void set_send_util_email(String host, String port, String from_add, String psw, String to_add) { + Log.d(TAG, "set_send_util_email host:" + host + "port" + port + "from_add" + from_add + "psw" + psw + "to_add" + to_add); + //验证 + if (host.equals("") || port.equals("") || from_add.equals("") || psw.equals("") || to_add.equals("")) { + return; + } + sp_setting.edit() + .putString(Define.SP_MSG_SEND_UTIL_EMAIL_HOST_KEY, host) + .putString(Define.SP_MSG_SEND_UTIL_EMAIL_PORT_KEY, port) + .putString(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY, from_add) + .putString(Define.SP_MSG_SEND_UTIL_EMAIL_PSW_KEY, psw) + .putString(Define.SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY, to_add) + .apply(); + } + + public static String get_send_util_email(String key) { + Log.d(TAG, "get_send_util_email key" + key); + String defaultstt = ""; + if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_HOST_KEY)) defaultstt = "stmp服务器"; + if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_PORT_KEY)) defaultstt = "端口"; + if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_FROMADD_KEY)) defaultstt = "发送邮箱"; + if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_PSW_KEY)) defaultstt = "密码"; + if (key.equals(Define.SP_MSG_SEND_UTIL_EMAIL_TOADD_KEY)) defaultstt = "接收邮箱"; + return sp_setting.getString(key, defaultstt); + } + + public static boolean saveMsgHistory() { + return sp_setting.getBoolean("option_save_history_on", false); + } +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/UpdateAppHttpUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/UpdateAppHttpUtil.java new file mode 100644 index 00000000..76b75f4b --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/UpdateAppHttpUtil.java @@ -0,0 +1,124 @@ +package com.idormy.sms.forwarder.utils; + +import android.support.annotation.NonNull; +import android.util.Log; + +import com.vector.update_app.HttpManager; +import com.zhy.http.okhttp.OkHttpUtils; +import com.zhy.http.okhttp.callback.FileCallBack; +import com.zhy.http.okhttp.callback.StringCallback; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import okhttp3.Call; +import okhttp3.Request; +import okhttp3.Response; + + +public class UpdateAppHttpUtil implements HttpManager { + /** + * 异步get + * + * @param url get请求地址 + * @param params get参数 + * @param callBack 回调 + */ + @Override + public void asyncGet(@NonNull String url, @NonNull Map params, @NonNull final HttpManager.Callback callBack) { + Log.i("UpdateAppHttpUtil", "asyncGet" + url); + Map headers = new HashMap<>(); + headers.put("heada", "bb"); + OkHttpUtils.get() + .url(url) + .headers(headers) + .params(params) + .build() + .execute(new StringCallback() { + @Override + public void onError(Call call, Response response, Exception e, int id) { + Log.i("UpdateAppHttpUtil", "err response" + response); + callBack.onError(validateError(e, response)); + } + + @Override + public void onResponse(String response, int id) { + Log.i("UpdateAppHttpUtil", "response" + response); + callBack.onResponse(response); + } + }); + } + + /** + * 异步post + * + * @param url post请求地址 + * @param params post请求参数 + * @param callBack 回调 + */ + @Override + public void asyncPost(@NonNull String url, @NonNull Map params, @NonNull final HttpManager.Callback callBack) { + Log.i("UpdateAppHttpUtil", "asyncPost" + url); + +// params.put("gggg","hhhh"); + Map headers = new HashMap<>(); + headers.put("heada", "bb"); + OkHttpUtils.post() + .url(url) + .headers(headers) + .params(params) + .build() + .execute(new StringCallback() { + @Override + public void onError(Call call, Response response, Exception e, int id) { + callBack.onError(validateError(e, response)); + } + + @Override + public void onResponse(String response, int id) { + callBack.onResponse(response); + } + }); + + } + + /** + * 下载 + * + * @param url 下载地址 + * @param path 文件保存路径 + * @param fileName 文件名称 + * @param callback 回调 + */ + @Override + public void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull final HttpManager.FileCallback callback) { + OkHttpUtils.get() + .url(url) + .build() + .execute(new FileCallBack(path, fileName) { + @Override + public void inProgress(float progress, long total, int id) { + callback.onProgress(progress, total); + } + + @Override + public void onError(Call call, Response response, Exception e, int id) { + callback.onError(validateError(e, response)); + } + + @Override + public void onResponse(File response, int id) { + callback.onResponse(response); + + } + + @Override + public void onBefore(Request request, int id) { + super.onBefore(request, id); + callback.onBefore(); + } + }); + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/aUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/aUtil.java new file mode 100644 index 00000000..7a138c29 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/aUtil.java @@ -0,0 +1,56 @@ +package com.idormy.sms.forwarder.utils; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Environment; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +public class aUtil { + private static String TAG = "aUtil"; + + private static Context context = null; + + /** + * 判断是否为MIUI系统,参考http://blog.csdn.net/xx326664162/article/details/52438706 + * + * @return + */ + public static boolean isMIUI() { + try { + String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code"; + String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name"; + String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage"; + Properties prop = new Properties(); + prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"))); + + return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null + || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null + || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null; + } catch (final IOException e) { + return false; + } + } + + public static String getVersionName(Context context) throws Exception { + // 获取packagemanager的实例 + PackageManager packageManager = context.getPackageManager(); + // getPackageName()是你当前类的包名,0代表是获取版本信息 + PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0); + String version = packInfo.versionName; + return version; + } + + public static Integer getVersionCode(Context context) throws Exception { + // 获取packagemanager的实例 + PackageManager packageManager = context.getPackageManager(); + // getPackageName()是你当前类的包名,0代表是获取版本信息 + PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0); + Integer versionCode = packInfo.versionCode; + return versionCode; + } +} diff --git a/app/src/main/qywx-playstore.png b/app/src/main/qywx-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..6816f0c1552f8f4ef25f96f4f3cdf8942d29af65 GIT binary patch literal 125512 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�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

s+s6^ z8LLta9_K$CYqk@bj~$r&{_O!%W%4s6W1jw#^`8rsnj~`L_KJFNhllNw+f>Mm^TbV= zAf1`|9N{O{+xqrnSb5tI6)|(`u~CbtHk}-DD9Wm5eB@g2^~}uxjp}}!0G|_KzB~OK zzE9)RW!mQ3On+6n7ro5PiaaTQs(qNr@T&hquaN=o=OuTYy*&-x=0u<_=6Mr2$csMa za`~oy#L9At+oRxS_;T-UBq=^Hi^D>)nFBN>t(bJP^Qcp0kql>j@||wM$J4mzYD9)p zyzyZMWURS@{)p(lyOJ)g!h6r0XnlDLr$-S=K*nzJa9Fy@750G*Bw@2u#${u{W&l$uHB#^*83$RiMMgvw- zQqsgH2HAod3t+?rZc+&1y{~1UTeVKWb^J}M{w}S3sDeif^H%Qs6XxMCp|3My03$3y z)6b7_lqBDGL}k=~maKaRA86IEIHZ3~e36`e^ShY6&3R1b0~{pZyf8ME7;ur?%@f%? zs@Hr!>or{pf4^JKslKV0s;?D#&$O?zK40fFLu?#o{LN90WqItWHC=Q1@qH*CT* zW$t9$aM9(?ZpTK*A^_y7l~D(kA;4mn9f3}!0IVi&RMBx8R!4WEQ)Bn(IQ}Jnz6j(e zDC}q6x?NLaGj5z5C9ZdS7mk5z!P4+P(lyQh*p9`p+{H6O`jOV0((-J;;gyo|6&evf z8~Sfuuc#%lFgivn(cNO&r(tk9uZDblG>K&^=^Rymoz!?8AEdurnR{?s`M9zaVW?X( zU3~1C_;ybpa`8&uEGP9*teEGVyisH|I(Y)V*8E5%5q9isDvhx z_cMZaDnaPA(Y$UfZy<38DMDN0%3@LeX~wFQv|6YWjS(qEE&WqBH>+^L-e~%no~_Bw z3+12vmt|AKLA;#iZn)0>%D8M>#{AR0{294yg`R4?gDxy~Pzi%k1J*_w8=56YvJ?2u z2L=hM=7skR=TBu)rN0`X=Uz4v9+IJt5m(NI(-xiQoFQNL5Uh7D*<33(^H23k-mEd0 zS=fnZii3|NH)YBXP~!|zTf@thso20P2Orwg6K6XN5n_h zOa{ov-eM`=npb~byc6r(;ivVIe*grJ{Bk!VaGeVg5n{y@qz`cILskh*Pt4jISK=-=9?Z)=SI@9C8 zb9#s^GH__Sa?7dtKd1zXbZfN21uz&=j|v~2=N6b4x_ghHwT1Brrco(&DpkKu^c6OX z4+LrKyX%D?g!FE@(~;Y61ez$M-i>yd_^Dh=3CKE*e|lxxkDj|i{O2ntC@=^mg|~|U zl%!x@vn3nE_k=@Eh&VU~<`cmNyuBSl9vGqPqN%`Sm1`e=9F~>hmZxtT8NduLwN8Cq zLqhx%9QhUqy-U00C>Nm%)0{%}hrCVc8la`lwLm{Q;g=oh7+t%}a9w6yu&09ps~taj zQLo?nbRjeD%<4Qj_j!&ox9KVWBd-xsQ@G$c0w%}ZVwYt1eakk-YkK<UB``hQi+@Nu-W46-v7w8?q2E`QXX22qA@x)c>&8)qDMc5p`p(eil#xJ9W4E;5}Dm4yj%(fn?jf` zMY*wSVIYN85oH1WN#7&1=1>Ra;yfg0*2~;5%tJUDQs~JNK#g9$f8fY=$U`N%3(1W- zJQqM7-#FAQ(H%Th1}tvT=>m%qrF=NL3o>cdlLP11loqH3LW@;+GmJ}=9}BquDK9$2 z_s5o?Tr9=(ztmv-pJ_nq3H*^$ZJ!ju7@qF|r#d{9XPUVX_d>--w^f}~su~RU8JWgx zJ($0M#J-NfXXh13>+3GTUR^qvMKTFPY#6HIr0bQnQCyR+;3`{JiO&w&aod{!e`4(s49{nW;qka48HZ z*h7J14_r&lpgPj}lm=cPG`j89L&&NHzIn>|=R^4c>EDEd8Vq58*z*HQ{(acB3gi`0 z$?GT==BZCA?osdYJ3r_FK%L;w7Ol5q`8;>%BfS9DOSN@M<>I)1VavIBaiV$!3ATbN zV8r%$nWzPkFct6DaflDFU>me5y`7@xu$r%_MhbPvqoE)px*z9MUXMG^j-i0#e3^l< zHoo6)zEJ{*Apwk?X2nx}3=ABUA&G@e5{;DCc5 zUdIJzl8?^IH#%_wSSOR2Bi8#*domGBvspX`rQ*HSnen&+qrG3I*}Y)MnUI1oW4$~2 zOlGQZ5#EQ$rO(qG_RHG!@WyGq)CH8VzVO+z3#ko8xP*} zWo-4vw@e9qF?ojibdGuZ{EVcCT%Lq{TD4eP_-XK^RK>Vg!1b(3y+_jSizftzf)^kK zLgNi7Cej?dBLC~^M427H4sXZ2ynh|w~=)B=f;>F2lPl1G>)u>3$q+mJoyli zNF2&O_$L_Ud6^02SQh1m)s>x97%Dj3RlsniEN1-*V^ga$Ek5=7u}A51c}ojB??BmL zR_7k}hNd0R z1*SSV+;g-H1T`j~rytw15B17##K>%RF|c~!wyLw{ZAFhphHT26$^Z;aQVS;)fWb+VM%Q1 zEPR2bA68;lF5-fg35`;{pX{v9JPF5$>rby3Cy&)^(;+ZI1lPvua@IZaI$JqVMI!|-#Fz5pN;Z%CU#)?UN|D2jf4o4|F@w1FQ zcUsWq<7!@RRF*`3I&@Lamj_Gmt%h*JDAH|$?N+u zI)hOYPWL6I(U3xW<|KWj^YNs;cIsn@cKSvDM-|u(Rxn*HG|ZPYE>HH*hoZX{Dkadp z);@|a|2(b|=GO4lCPCBOj29W@P+{)A)MTgnKB%PdI8e<4IM5-W`;>PmDit5Ta94{Q zp%KB7P3|#4&x*HU9c_`Nncx~}{{#*xeP?SsB0m~J-#iFfYfn=kjxmntK&ih z`&pw;$aC?hNE}4jiXBGCbddyLKK?SM!OgH882J``!QfB2fi0oBhhJA;Fy~MXM^3(J zkb$vkqPuR}E7I9r7h+or~MnRYHF@$h={T&$u?$FtC3kJs4RZwnN za8~U0@oXv<#R!OSq~4^hjFiQ)lLQsXWR=E>0P!lt2LSzkIkbIY^k&Lf(%DBDw)Tpc zC=N)i(gNx4l7FvuTLPhNrK;pB$ejmOBk6{R^zGgzX7u`7r1wbI3d^80_O0pnC2Q+H z9x6Za2@jj6W3>M$#lM|^9cFdd9^d^$)~KN7?#i=htqE_9!$RC%ZwngI##q(zi^Biz z=(w$JYqNgZ0rdu_Ktk&4CUPn<*u5&Qfx`B(AT&KWV=Sz6OVv7dQcJErVjyWqh-GG})4UMFSJ+aA> z?vQxD+|o~%3iFulEoV?T?MX}CHukntlO=1!jLZA20^&=8b@hRQxhXmnLF1I^0J+4PSNEopCVP~zRn{gOB^)+q)A zSigiV#Ec-&Pe^tC3iTkLvc3v2WD-(wL5GXaFuMG?XdN9TMOR_=<~<%$FUL0`s6RUj zR+N0VdN8n-r(P{RcwaVy7Tgw%D5;hnos0GF?@lG`={z2@nFAwD@^XbheFdJK}Z{^tx@Tl zfbYc$TB{}{_fw*<&|B*-U=}cF`eudP;)Oh+h4cqFpqmw#uaGw_d^(BbgPL<5cAkj4 z>FyLWNK}KpejPA&REm1ooqcM!q|-E-v#f*RkHh|=>_ys^+Hq;=!AnPRqkGXqY#fhE z!q19a<-2KwA^95G_{l7mopK+lHBbTzj#KBYTOavG)1VqSeCou$h}P?Nu8}uOEF&cd z?%^NMdb#B`uGmB}E^YX*`QY$543@(k5Hu~MLRj>*FIkTvkAvAqQx z6Pn~_@FmCUn^oVHmn0>?QrD9zOIUli1;I$netd;!A-}w?Y!<; zLW5XF(5MaES*M!!b%O{Ha+$t=4@)hKY<|OvrV*8LwOV0|SK%?wu-dhaSQGjlqQmST zIYeG&ZF=C}1NFdNdz3EIC;%h|h8T&OfDiC9nAnpcy99Uo1^oh-`R{(8%XP=?zGoaP z6}Bu?9!BDy3?*$3#h?A8w?v-31;6;<2ux=({6F z=6$1>j#hQQQy zaAZDWfOIFSi>bvPkej=hEN=i5CSQ!*+8$f*WQH_sBWaEMi=pnniQANH;pkGBD<-Tg zIT*u09o|ar!A`g4of9fCN!`#(=AH@i*kPFD_nwc-g7d-$aJ^kAUQtQ>?iXzF_UPNC zrgg~vfPFWl1EpX@2Db~R$N91l!h(+z&xx5ahOCEUp}j~1?AN1TSaMw{;@Q@ybt4l7 z3#?xF=6aic`<;5}#Fvr^i(l>~!SPLA&&!t8g&^C61oG}v? z4OU}_tr1NSh7QuPEa?ChESEu^!=8GWCnK;BNiS@9tp|rT9?gaMO8=^}bphu@n`lzh|HDBm$`UR$j zLr1Ng0&KA!9b07pClyE&^w_C%haSm885^d}(ql8;Y?bC=a(6guHC9;xMaj5_6|di^ zMYDHUOQD={ul!YlE%!&oza5k>^Hmlm z-{kO^(UxzeR3q>i zMBXrtuXPt%I47o8g?y>KT9o-~{~YIIcV;y}a-6l~d>r8&A-*QTUU^3Kvf}w*M{d9y zcO&F}c+Gn1|L027#p&I=>GAOTKJXl=O0a&WAe!h)az4hwaIrv*(iyw z;5IDR&;LmdKw-uGs^KLRkaRs|5DHuvTvh$KA^>E#WPx9dF~n;eo0-Wmsjd3wo@IW! z#&h|TU7OD~b#7<-=I+ZXc1N>}2Br^lzI=u(OE76lIi+pynOgJFi?a-p^u%lQS>~jz ztB4|{j>M3|xS`#0r9H(*P5T!vp}{l5x`BVhmJ*A8a__z=8PKk^l62k*x5(6=iX^vf zi=EwK-FV3gX%-%ePONdIOKovu32dD-UM;35%F%L97ho|jTXu}Z-rONLY2CgoR}7_teFxhDk4*$h^ZNGMs! z-!)+z(I8UF)!LACeSdoTmhtXfOw||mY$pht`;|-qPwAo3UKix@l%a_2{X)ADU`bCD zx#X68Z_{$@&QSBORm1?~iZn(==H|cN`kl^r4 zlSG=M!uH&YyT3jdt*Car;g7a1vqTMDet@Nj>9~^qw#!@@#hh*)%jea7Wgzd!AKD=O zyFu0)0gwLkV!rsE$Jzid-bDX5vv;4gW;V2FqAfC?MU*cpGSf7cOjVyh%jA_PK9-!8 z@X0uOSUZMgA$%3zbK7oVLPafn{7WoNy12*+bH3*<75ce`@t>8k@EZmy?cCIwe;f0D z>L+_IH!zQVbazhQoCgs8F#Fa2#O#NCHVz!}hI}o(eIEuwxEb6{#VB%oE_x)5(IF14 z?kw31boX8@eiQfdyg^7|LA6#m^S|>?aCIgm{&P+H zdvE{Mge*#fSj1FA|Dbj(@Y)zJmF+!R1Jn`Nq;+6>8V>icgCPGIsdb;fTe_+2RR%HltV zaAUXXrmxn`XD=V~Nxi+Y^pK*X^4Zkp85@LKs}f=T$Vh&$YlVd_?Cn{r)_z&D-OH4y zb6Q@!@4e!J3Qz3wit5vNnUe04INW73reM38jSc>8T|N3I_x`VT+XC6iuk#>g;?IXU zp_oBpf`UdeR$r?{wxVlSPO4SEPa=GrU3=h-@Q5dE;=!I~o z>u$>O+HH&Q!-05QKNajEV`;AB8?|4!MRz5V&@oV(*@gxFNpzoKe$qz|&#vEEMk-=) z-S#K{nV0H6(r%~gB%H5}R(N-2=tE!; z0>c!qj2HgmyAK`>ECtWqirc%?yd97xCihD4#Yk5y^)0XOe{l>g^FP}X!p@rbqHdz@ zsF8N}{taX%?KWhe^jT<}UWtq92(|QRn-O#!{SuV{^(O0j` z6wD0(*`LNg`l$CuQIrA-fc$=;WR*osNXE~9)4ktjg(a$q%^)QVKM-5SfupDRYFbA; zh&s@1UL2j=V}8csrC0n;F&fA^$I0V`OG*AW%wWFwhbBYXH|EkEH>&h<{izJ>o=bxv-h2i)A1(RJ?r3##3?exH^7^Yu$)sgc0 z?imzMH&`c%5E3#eDM4BMd17zX;W{hae-d=> z-(2}~b%lUI`uSz)e^+uGh9Q7H3~BoYX_4{)dtdrU=&TTwv*?l6k z@h>^(<|@SIvBpbG+61NaG1KXEi)nClALP9SBXg{d8LunxE2Z$CjEi^~Z_O!_h(|}I zmrqn~cE3^06XVJLNaU;09p$CpUp(Bc)XrL)hZVXM7wBn#bK_Z?O5)e`t2`IZ@xV>! z^qLFXI|bK1+KleCY`k#GubhXDjIroOa*nj+3yVGC2&C4NkO41J`wb17x0+=mdc*Ku z5+;<6mw_XJiMP`-Jlo|%cC&Nz2zYrP7ZEXB7&#lBRL%09d!~%Bj`iL&wv%g~f-;a^qsu^^aEdXc3_Qd!!~>P8P4$Gp`PQ{DHrij7=u-64 zRi|1W)fu7inRzLR`&T(!C7-0HXOH4mlsk-GT*#A;Pn&bXEO-X|h7VSOrZ-)iQXh!z zh8pP(%{^ey7EpHkdV$Lq)QM)8fm0ckq#;8Zba$sX7BmWeRb~)!#ie{Gdt%O-_PfHsvrtfE6O?I zG8BJr-Psr#^v&hczzLtN^a-Yqv7mH!AO1d>U3dvJfzS|Evx6xOD?$Ma=~Und420LS zu<#klJLv8f3WHqlrUT)x;d*X;l`*X9x_-XWR{KQ8;*vTUR-P3Dd_E5JYkaWx*6S)| z(r}jS?e7yi&sJ26`&i}nK|dua%MTSa!?IOYYTx=(M|$jZ8)GP`?FV)g#|jF2cVX zQxV%?j!`29s4iWNCxYZ&WbOaa<|5lYxgO5f8k3}rZ(%&x@+}h` zh_Fs@n#2iJ?CSSu>2BiwO8Mn{Ks|taQWz#n--gQ6$6IGmcpr{v<@!yn^Lf(7ytPtw%zfXjKvK-k(0J))*q%z!GKk29@1SH!jT z|Lu%Tx|95;Yd(?}(HeU966_~HXRL*T8?U%CD?fMi(|wCPa+cO(-L$Z0OTE$pj7hlG zyOB`m9%d2|SK!_E zY_Ni3-vd?mW~se(DkF>wNxMJ##M@hD;x_!tdoqT2!A-)9O{X|MGSr1_H)NId7yQ-Z zW9_M+)(JmJ;0A0Tl>Oif2e_w?A_vI>N3!2?nX1Fbng8&H50 zJmb%ks@jlqO6|NVw(mLL52k${^+Ei$encN`DExXCqR0Z6bvW8^cP4jtI3vN?E>XR! zJo|2OO$%u{Tz~a7d$>ZN>fLeSxY_%1=gkhXNKmIjxHIvtZVOaUyVEH3tU@Q6g6h%f zw~DdD@>DeXZg@m;ooUk|N|OzQD824htc)|?IfIsJOsQb7T4T8~QX26#P|36cFE*u- zz%43t#he_jJky$pUdr2z)@du$rfnE1TTd(c$XJ=+S@+Zy4VB6WTl@N|t2uQ%|JW%t zNU}2cEfVrSq-E2cK@9j?0UAEF5{T+2QqRq51$YtSc=CCjJg)+(EI1uJsT;$)hvq57 z#G?K}$+h{D=lj#@jnvn6cnM~GtN9D{^R>VAXTpip&)m^`89Gm8S*Mg3>C{MglOWHI zInI>Wrq(L8zeRqd^kWq^T}^t16<-v2@eae103A|>n+1OJ=2o2ea7nfJT3dNZ;2%!E z^fd6u#;OA0FLP2C0dWFL`^GObFWJs^%o!bB#s;da@vm7^$0dEFoEHl`Ql$B(^uV|q z5ul3$-ck$iE&rLcz0~8sYm!{6e7W+)c%{kRQ7AiL0>wMiw!JX3=`BN719vYna^0JR z$;l1nOE)4QDqwfTxNYJOLL)FK4B>$J(Eqkz0|tn!VbrF)Yq778-Kj{KLc5u5T%=)x8tl__~@2?5F-M6ioCMZl%YbO4_wsTZj2uDXdhN1l?I8wB(X9R z(-WQ0nE^`AETPg)1`@Xi9If7^lz;8^F6x?HtI|S zu43vzy<_#skRks|mc5uhY}! zBfB-hR78+hi_=&&GP5)g$o}T?sR_B*bB$9R)VqJB($7jp{MBPnZX133I&Bf~ejM;Y zJBSW1sUyKFof=<&*MKJJhBvk-K*~r`$9pc-GnxnqZsdDM+c!ET+*)MP1J$SDx(6~Vgny%}&!g6f6Z!MMQJfF-TQe$?lo8-t2>uc( zhKy{TOcV_`OL;H-f>G`M)7Rs4h89&WTJQtC{>;gt{>I9E#TL?NDZVca{G^>|QS-I% zCc9nxkpFe}5t&{0hY`5N%^t6ki}?j{XWr*!hDe;|c$~<#&^A7mu$>f4;4uc_khPKn zmcdrs)v23;1Ar`%rJ{}MLE(DDC#ldUlQC07rK||UvpPv$v&EhyU&kJ zk=d2^Y*d5j7R(dh_^E9H`u2PjT9g|sSO`HI+G(R%)tJ3J-yx51_u}7#nuH!LKhn|3 zv5u%9Y%Y3y_&__9Tk_dLDiloA{oltA9=qRwD0(+lCV91nwJFl+h8l6wdi269TeB?B z`(8*We2qhPBX+X%rtl@pDgf%)^6)7?xU$2lyrg0Oray#X@&H^O34iyf3zwqkUE2jYdJ{=(` zgNQ!x)?ax0GD6M%sg==UW->8f?=dEF^f^`m9gXJexAdhwZz@KE5zxoO>K}S7zzn4% zdky(7ben*~udn(O15U|p(Yos|L~4yF9-T~Kt^^|TAqXCnpeV4}q87t#8p?myD)`yX zDD>tBVKK(ICV7zU2$l}|1o8Cy3n|9XeE!-h zKV4WG%r}6C_-}gqpBjw`;-byb^gjz>K)Hx+Y2Tyv5*SN;itIBeA~=2L7OH4zNfY<6 z&F0M2Xi)*(J`Qt;>Nn-CYLl{YO1oMlovp9*uXJ4WdZ5iTEEYz`0n&j5Gf&lsq8BT? zI?BxnNL0Cqft~elU_WW-g`{Ly0{qzLPx%1C)5cp^Dy7apXTR5-_#mOx$|8S>ZFY^= z^gpo~oy6StLnL?a@jnQW7fQA+RhsKukqfn~Z-Uj|tQTcYM+25c%dhA)HDVKoh+g~q znjVy7N?l1{dr_`zk}lMMQ7B!i9xuvGt>J$)F6h!k=Iq|fFw?^NV`6FGAlOQk)M7yR z_2Zx<`r`&erMrN*U7m(}LMTFOhZ`9gOLFCG#R2yT{lPI7@21`uMRB^gtUPkPf>oE! zl)Z%SL_%ZIFEt2N@_ww1{S@ml0Qj}LhwsS0oEJN0b|Fho)wLl5hR$|E7q!LSCA9D| zPz@WTgyCML;Wyp%%aZ2h3U#~G%yHsH9~QY?VRibfM{E?NWn_aYr`k`OvB;2WLS(0J zs?o>UyewBbV9AI2;(fu$A)QmZThWj{J{8Ve0nH^p%z1K*Musggqdosg{_GjOZu|jr z>X2^7`}!4kLZGy>SDlGn+=Ca(d@Gp}h1l5J-bxia{g{hR(ziDwWi=6eV!aev?9^&@yi7i_$UDT z<`ASu!|(h|{MEX_$A%vMdV!#*s{6K$3|d<#9pQzn%_ke4kIw_-hwKzWDL9tIDez~w z3c~g=eEp><0~sbJsn{&wS)Q^FoA)(YF^|%G+d-z43NqTrHU@2PsNpNyz2vwWr z>K(p{E~#PC*Uyg0Jgvei01$jgv+0K0gxChQN$MS+sBG zFaWNpRp}G7Cfj zeSM*Z^AN_lg@L1RTz&{{+518+tA<3c#*PJ4=Lwukd+uBM#SsHz00*N^!Pt3Nr)(_%j98jjsqsEUmRNy^W*lPKf3ddXi2+Pvp zula7xeE;y@4m3Z(9Ty#(K$P(UxA4(kmml@PXY@ZdSzqTaoQ1B~rFw0>aI_Z;m%1O^ z2)y!~SH%+SU-LnRK9PTZo`eBoM^am{{%gjc2PV;!Y=J1;XC%PCKlq?_SsCqR#w!4# zwF44XqKzACJ!s-B)j+>5j&`T$*D$>5$ns!h9f~ z3DeZjr8T!T93B(Z#{vw&vqJ)4spG5eRB(NcRcyZ#*sYVNo07JK9wY*yWAUb5gIrBh z|BJPN1;c4}H{>YbLOU~FZ&^o(vUx0qH;nRxjV2WcB&Nf zlE^0%znwY35@s=EVAw_(z^?<3LsUiVSNu1{;zJ6G{n1~`2wf|Y1+Utg3>UU>o4;qQ{JbmC zs`rJ!V#;4uqkGUY3P~z062_{ynIXlY=c=1JIJpd|-*J5t0$t%R&Ulj6ryBxb5+__Q z?D?rrWcc&1pQry$x5b0Ro&4det3cX*W^NtE8TNGz_)O=y2Bk?9$)dT=`-3gUCG23f2?hNoa+71?hES02&(_HY@#UmDzv3HLo%J&rJHYab zYP9^*X3}2358)S0X)L}K7+kjh0X8NN$;eFaBwCFN$T}|~7Eyq6-~E?mo1ADZgT(N7 z=bDk@Qa=_t>A=`m)*egO;{s9x0#Ei{)IsM6|bpnzpR|W zb7Tk-_$0`I@sZ0Ckp^Z5=OtC*!WDbnyR+xO$v;zxtp0cU_r3wU;lGg&+ybNFuYO-`OLR7`&0SG#-EFnI?h* zsNxlVfWq}D5tCcTQ=jfsi`jJ9w_nnLw!NB}kf^66=d$etV-6PeEBce+j}jg;JwG>a zo-KgAXL{{Mjn7+1h>T*&Q@$RGC)L-+5>|gX>#Xfr0(88dkXC~Ws5sv)*i)a|to(fL zf)Ly*QV?vT0AMBQ4kl;17?#W&5)q7{-*2tW3f6Bq;)Fxl5$3NtZmgj?}RaCgd`VH;Ogp-^jUvBzGBh+^+H{H<9fC87_=ZF zV7(Y-ga}Q-u-&g#Dyl;|;-L+I10F@~-AvS8?0?5^EzqctKKEJz@w%BY`Jtq?SyE-H zQMurY`bKp7GP;gz)NzSzXCbb&4CpLwdME1Qj0uU)@a&ehUo?4btzt8IQj{^L?thdS zrjk*cR29rJ>}YKzci@DdaQUd@iXpauw5HH zKv)}FZir+=#KefxUiYBn+JEuTZUPSm(+8m(kIp23M~q`rx3&?avjIDm#mpHCQ1;JX zz{*?wq5FU}^KZTUR`L+(<%!Iw z7x&83N0#<~*QW!Sm;q-X5==S|L}I3%z6^nDstX|lY;mvYZ+a5{kOgN^A;xbz%6XbC zb6u=u@@^15&TLZn+y+PWmeXScev>GbqLQ=Vci}lCV<0y}Fh4yFq6_5hBiX-$O)FaB2(DJok%7tE2cNEBq*cWl85RTMKq4IeI@Um^KM)uns9Ze}oYf=Vh=z;D(}$$V6i z)KhuJiaBEDYddhH2rK)8`>PabfMA{XZ-q z)@|FZL9?8lH?Q?~-KVN!rO3b;etcET-tsFBBxG%x@zf32NBnWC;7=}yaTho(5+%C< z7ai~ttH`PaDJEp#LT;}V)CY*-fz^V%GQ}U|Af$6u&{;O!WB5+ngwooByzD2+IW{-3 zn8@CTEef9Dn{eDOFH-TLf&;uIr3(&5k+|(AvqaAVG&#d1I}^^xsj{%3j)4k6O8CPn-yfZ|UWI9zpP{f^e&tu|ZG*C%(qjz}A=FD*jixREXCq8fh?FCL#E$F)9k zn;|zNn6*XtlShJnQhPljO+yY19?WO&k3SOrGP+k&o#vk!?QPgzX<#k*!CC0{OZRF# zG2lfe@{CNgg7Nrmzs$+nU_xB_eXf=B6G<%Cdl;iCudwfp(BA)?is6;SnFz+C8G$^) zw(;nP!g$FqqE5^+W*|y#E|}9R zI$V-qw+fVOoGN^JOLBnJaK+X{-c(xw9 zC|94QuX!|_EkO;u#-)ek{eTQ115WY|$r(SvFcq`&x3_r^WLpq;^~@*p>ScSY~zhY0^B0WnD)e@OmH;9U62=AH~-f%I2apvKJpOvg4Z) z>m?vn`AINiKzu#zikIM&%kI;DuB$kw!HhYUk>m6Tj`k^Wse_QaKC5K5-y1O|1J7dt zoacWdJCxIg8&s2Kx_H&Dno4GeaeYfdrE9511Cg6)wSmq<+U!fm&C<2HoWAi(TH}$b zPX)pIHn&(2GOoi9Jv4-@twHUNkzTdvPwlhxQ~K@(tiPQML)@z#o)p&~e^aB%)nyCDaZ^yx%x|HL}5a^cQ?C26#Zj zOo1$ZnP}WwE8F{YF*=pHABvteHa|{FQk^z}kHPHmmscRlp)y0Maq;5w?1vR>pheXn zM?H?kzk>cw76R~fC_YN7L#&_tu_T78KiSPEi1Gy)VV5BymMnNZ5|<1y`+}Q3mGl{; zy3KY8%LDMGjw$q~KYSQFq7Z%^2luH{qs$2V%sGC7&=@4ZcCVK1{@(c3T=v0E0;w}h z9t9Y@o_BEKIJ!~Nc6MCBT4!L=hustR?X4x*jd&Q;UZWKkza*!C}O!Nt6oQ zJX}!32ge`%I4#;ndXr1f5YhPIDS`W}w;vk~(MaPiEnqevCmn{uoa>DN&2EuV7(nX(-V3c^Y6j7qb+UjD@l>HK1;^l%XG#sVzvd>4@zi`TJY z$uqNtD?L`1tRqZ)^_{?8Ikyj|ty~rzz~(1ug0w$P?%BmqcFQ>e^dW8kS@s)iXD;%7krk|3- z9%&F7ns(+t{1O8I3ieXtYq(g!V|FTkMi3Yd3#}lxqg5co@ zeZBNdv{$2!&{7g4{kGkYKt851X0jD*4h2_3;e~^M8IdU=7!!0hp+QVtiv81rYKmYM zud-Q}2MKVp2b-t?@BzNN=a5d?3Lg{n!0KzCj>8PG$)T%UEiA1 z?h4lX^Yry*`7cnTo*^lXjUEUzw@|=8kU`%T6|~L}!uKN5bl*4Ke!+8Q@J(0994MQW z)6leASl3wvgx2VR;C&GC36glVPjh@e>NCBrWokN0hAL!`ekDIax(N|Hf!Jwgx!qIZ zXg1MYI&=iTR!g>vX4I>N>r|p&ko4nxp4N5USra?!5a@v!XXpv|r5Ao#d!TM8=q)5H z(#EJR9YQy{C)Jjc0$bw4Bm>4S_#K-Y^_bnGKGTET+MUb$*wJPe4|Js)R~;-{8_iAx zzaPi^dn0wY$x;0EL|+F8m;P-DKQ3l`u||6nAUsn5kH3ZH>= zGFH=%af@RG3A8@;TqE-hY7+GMB}gK6wrG9DIE}(3fPtEKHh9DrfCt#nKm{D|)`D?> z4WY`H0L+@szxduWjrs#WNyAMrIAX?y!bgZ7EF2gCR~+K98h1ma6+H@qV0<8J1RW3s zRES~9NI)|N5V~%Ku4IqtL;?^>)#D<;%MMQvcE>*vg{2wQh~;WIWrpX^cdSRhrZd{g z$s-edq!Y38@|KDGvXEtz+%C1;tiH0huv*;Hw$kFJvy zPPHp0TAwM3FVSYKW8(pSQF1m1d^DoMJ_#}2or%a$^KZXP4cOC$_O!{-iBSMYzoSxC zKbLQIJ0XFwxLw!JbvTh)n*|FK#2z2o_srdRQsspmV;aj@qx;+>RGzpLQ>%o&;tpy> zCER4B9)>qSH{v{0XAA4LcIA(%If=3>8hK6XEJ-Z~7#={7OiqK>ez%U>=2$n-`LQ(C z^a4XA!yZw9@*upT;rQ7=X$H9O5a0w6Zg69#Tw&^mznYK83X^F=rHxM=|Fyfk8hm<)hpjAVdV3U^e?N zk0{pz(SW+;2B%q|J`S$>^3T+`4<+blg^ep5zNgv~?K3LrdvUY21M`c;f3CR~0KglO zft-W3KId_7_S<0HFS=5Ciqn!%fE5P!$RQh{>R2N1`2L?PPwq? zovT?*qMDRNL2g-y2b1k9h*IfK(e&E*W8&jig!=q^Q#nMHPs{I|K{$~vLgL6fy+Wbs zcxGHxlCou(&;Jlf%0I!DBl%{R@~Z1dBGLoS1;??n0T+y`BXT zS9I9HBY=a_>vwmAw6vCYKBc@CY=~~p0fCR910EmXPqH)sQJFrG80c}bJhI}&0?I!< zK%nC&!qOPz=SmHmYv4M}?DNK&#Fn2Xlv~esx_?GlvekPgVkYDcpNf2@Z+F;sRchNG z2O3?G?}<-ciskO!^=D$NTgiaEN|VHGV&6{i*68lRZU~r z0Dy0YsvEIynnq};pX%~=(N^pm*4C={eOeFI4BBE+@N}fFB8hXk>jrm0HYO3>!Mi?kLU5^%Y2{R_k8-2iZjggT)>3NPZ!s?PGh3x3#mL zNC!}Gga*VL0qeiHfqA+FLvmi&qYE1I+#@bJJnXfdoHI&kM>R%&7P^^JQ5;W=-N z>=8a|X4|KW-~u@W2Vqd)r|m(2X^DnLi7P6XEyxW8dptiL?oL%jvU(3OKnm%gK(|i{ zIfB4C<;(3MP|eE?Ko%uz6kd-Gbn1U*paFb9+1^=)0t8JAIT<110iLe1-e`vJKVw1= zsGlf3bP(k&zBtY71#y9g%=oTxV%#l6_$a_pAU2>0Y1aTih44QqbHsfj1pd9A3+q3^ zIM=Jo;HYFoQ1C@N=t76gs{?tCXv@+d$tz@V$^4Z&QUir-daL)}g-j+DrbQSvy563V zihgNl(nGW6r$<;<7SevO>%rZ?7yaNH>+lW5nX+FzM1Ci5H2#g3u@k-7*0vaqLS1GVimV0;#uwLQ|`?Ay9z ziuP~$!z;2z(LkxZ?49v_mj=)J!%xZ1zl9v?vX|X$QTf z68SuuxoW@F(1r_>yIil$;$F+Wp9LdGU*Y80E z8uTp#+cRTugWbPkf#ent+4BE>k%Ih=!@3N~H*VF|bqXYo0ah5samKCrGaO8>eh*6j z65Yismp}%R9@dK40?AsoxxO{hLjrcy%NReAYrIsL?%Tp28#qluEB~N;w_&wGy%;Ls zi%2K2xZH)2Y&>L13Xa$t-U)iW8x2uWsTS~UKbiw04q`)71Jj|_R{ z-(yI&@+?b{5MD%uaTqYz%pu8YR=RB{nQ<%agkzw3^sb{_sKq_2i_Br+ylm|lt=;im zk4F*>y(Lt6%i5#nkE@vcF^wDL1o_68dxTUkxSlf`y`_@mgL3JIJF67BlqYe1q7|Q90{D zezIA2K%QZ9cGa5ojM&AR*jsCo$#L&#oeR4$tz_g{ybdD9%pc`xP~@G}&TT|$`;yD9 zs7r-C#(HWUQhTAD+ZIcqD&*0i$HDcDH>>R-( zUXd}?!;!z3pY1;qD3YpClE^(8Oez2qWBajtv^mE_>qq1KkKcr<+E3nizU-*S^lKW7Tc;`T|bo@zr_1!f#Oo+KKlfK%o1L29@<=o8L_{D?At@dC%x(LU`8 zMFo?U&G!HVEce`1CPO-9yTcVW0zU)516qO(ig%01@7`zl|K3snc?;779vGqjf>(|W zKJPwSoCqu&l%j>Ml`h8qkVuxI`EH?^?9*Jlnec}awZoNqAbq$y3!Sv@8l4t}^jAKb zAI=gvq6cvmJw${0GKpTE_0Q%W_RpVf%+xX0yH<$rl4X)e_^zxo*ThoV4>ELsf@+7q z?xywu(Z-SmF&aByihD2mR6Iu5OJLEj6>Uw}k0S0mzTNLvyOb4{Bj{BKW~PEJwxB3R`?J@xU}bj2~5Nt9-Z{ZB!;w6~2(VCc%BWN|NEEfK(_ zd-0u%Ti>PWk;V0q9_K}&`D zC!1S4bEMaoNUL=ucn{4{*qRnYxWp++`O`#sq)9#z6u53+HfqyQ%p*k;)8u*J=J}bM zOj&=Y$SxAkJGkYj!jL;#%kpw07Y$>F!T~IonX?YkUiA+9c-mL({b@tHm2%pqG;EP% zU__!m0JXb9} z&7j+5%D2CE-dR5>#W3XZD52@|E4UJVmfG0`7_nlt3;0e#109b>&<>Z#B%0<|4|Etb zOlrF4bQOVSQ>XIIp?`H$PL$4Q=_d?IX7n+4GOa&c;5;q!Kioo^LSqnRLoc##e(Zl0 zd;X0Bxs+{|5FMNh0A_HF8WzPh#=`Qj)KLW`yl2-u#@!u1?tcEd#!Q}}+=X)Dg}}kq z!>dJHIHj=UbH1AIcui9RiVU)m#ogahz6ySU;R_md#fq7n0r1W)?u_NXzv5UnWShdb zc9fuIL*`Jx03EP=k9;lgOW9?{rCexFNaP1Ynm33F42-6C|k-OU+%@bsgv^l%qcRm4Bu&`Q{B09gKtrl{CBXK*Z_icw8n_x5(`xN>(`g&{_nm^J zzm4HkR8JCJSK1_t;u5#d|I-5j?RS1^098qFC#bcj^2QHSy0 zJn2p1{#6#7m8sH>X@ZgN$2ZyFi2i^4^v_bqZk5r3*@wdWAb^`tW5@R+ zS;CYh+f~{_Y}g0f-|x{UO&xL1-W{I);u*`Ezzou}U9h1Emrm|&y-r&9 z_!gAHk+&1FUK2{Y6+EB#?kwom2qc*g@gLC3Ockg???=D9(S+1345w10Q78ytdh(Q3 zzrd2ndc|NJ-THnblJK>%0%tanw@AAEe1TnrBa=fFmM7utd-oX8tC_u(1TAuHsG*Fx^LCL`7!77 z>bcRRl=tK%X8EQKG88~fYJgEtBb+aPUc5@bD8#B{p(|cW?>N$!#Y$^`XMc z7^SNlxN?>lt>f({H{u-Rzn7g8qkt`-MY8xh`s1*K|~j4ht0^t6zo*`0PDlOk;LZ~l}Ew)MM3VUsvhqJ0Taxe*Z?|WR1nz7 z#R9JG8J9D-i2zPA&}4{vZl;@s|1PA(yc*PtZUGqo%>5r0NY~j3(l9>#^U`9zB&rTk z)0(Na8|TIc;Mu&trIR}KuQ&ss1G1EuaG0r(mGih->CQY|_zxa`Njh2Q@|7<{8U~jK zx5~9B5f2^t^_!3@9?9);c~s!$38-^Dtlfwj9cE2H1<1|l%0kdwqb1Rf zPM@V|&N`+g?V6*5fLU*2Y+$_^Iz_8?(#MZiq*f6Ts(X(Kfv=n62>wT)tk{r|MY?1S z$GS*632OIbNw=#Xqt)rBWL&OA&L`;oRrbH|P8TDQaQS0JRuH~VSh>d%z1`=J)< zBI477Bk^Yw**&PoYmYww00)%iq;>n&MhF_4d5hai!YO|T#g279{qee|EVI?}eZ3kd zz}9f!&;FyJ=y=F!4sS7mxXqMAT1$QZ%$l@f(@&B8k47msd()X}K!o#$+)Ye_*}KBC z{;rye?c4-i^w_^Dma26D>N|3E+OPGh69k+`LlQi9ss>snT87%XNF-XYv?s=X9UKQ3 zJ}*nn7Z|W1e6_t`beta*jkQW8Dnc7&g*%Yl&&KuRky_8-rx1g~YmX0lT^2l02G~tb zTriKi5i4UPGnORM?6m}(mE*BI~NP*s0s1fpuHK zg#)@!BpO2ctuh{lUj#D+eLgaak!sWORGRg#EklNdeMMV4yqH!Z13WMRo{t$L)@Sue z0Nn%~s|uC#lc&3_%{1#%9Z^8nfF2!ADqMbi5RWV-^0O&B7aN4DndKF`-SE%o8 zk1lWZ+sLX#+O)JlVSSZ~bRxtu(JHrq{@84Vose?OkE>LNuJeVhJhjdFkm z1q@SrZTq~83Xp#srlUPZN_#d=j74aZ2tSMA)i*af`N|axUN3Fzz>0_<~?l+_ntxFSY(?D6F zqu7dZuXJ^%P z0hR8u&IdpHoEMq|VaF9ZrWEho>c4&U7D>bSK`!y0fhHb)e z0wQZfcJ|&tcv*i(^FBe9yd-ja&i`ex=bgJu{%ZDA6QHPN`S|!1fHglgdZURmH$%Z6)B^!YtI$E%-MP5#hvYWR*G-!@u4|N55r>gwqnM+e}Werr90 zCu4!eM%RGyv2j270sP^;%Gw3jMH1*x^3reX3mt{CF(g3yg*)Q|L}39LxC8Hk3jX0m z8!OE|Ev9Q)`08+uV3PVxAQ9q?GwObjP(Q`a_c8>6l_F{NeV6tg4 zoU?Yn=&@bV7EIBf2g*jD`D6aRC!iaFfOl-BUIOUC%rhI@t(c-!P5LF@vEU;g6yMxi z%a_(`UGSqKa;kIj84WO^`GHn@L5kWgqYnUnyyRJ?EUxZ7V zkzlCetmm&!WslLT$1qW-VAK^u0Ha$ofEjQjQ|Nfb)1(~rb=LSmM$(0m@zDeZ$iybz& z&92$o%HlX_V)*bj;|B&^g$yQ@W7&5_jrz<@y0M4*!n13JxoRwc6as|Xog1OD8=1nt zw*?bbI;NlvT;-2I*{vizE9N_sn?PJg*{>*3mD+wWpviSojF>&g(a=VIV!tcr;5u!-8sKIm#8>S&hXsV#6dsXOxk6X zVA)9xr26)@RoYg6)`+6z4Ya{`-@m?o_L^?=da|8TwC52erFAX6&S#Jul1QWifHcnS z*R6TP2?6=dJT`#0X|<)jlc1P0Munn&Bk@hX)1K&_e0kCtQ9f%9`;b_e$b<;-VSv@I z`%W0Zgs`r!_Agvcyp_Co)IwGM=3c~gn(oFdX&SIwwk>blKgpUGccfx``rwy4NKQZa zNoDM*aaRKm0*@V$Zn}T`I2!6aS|}L*)$xkSrF!S^nd3TjfL$OWu~|)@_oKeIqafyc z+SjH^C(`bU{im{NjXAoxbHCUJWpUoC23k<*NohWqQfnc9=vk?}hs8ByIpB0yMqkhWO-Cpr*t zJTamkiMLe^YX_hIZ^Q&&&)e0s=Wnd(y~V16m_Nn!9ExWyb(SS2OSMUUs*`lv!7oJr zbW*c~>m_w{*L7sk|JJ?bkoMqO>Vg&pC<=|nZHc&1H>iJytP45Te%&S;eVK6AmHkh6 zYu|sH52ECeYspCgB5S=2Pjo8MK#tY24D0yPf> z=A|q8)sy@1yqJWUNGHsqqTIC-sh(L(!pHZ?H%LZr;KpzW913K6?>@>LkvdlKn6>N( z&M?R9e|qqzUcnfs-_K2ZNV(CFhrp;Q7V#F>8FsPNlZVCg(pnT|5Vu=NcT;o89XnY7 zvdlBTK>6k!XHUeEWqh&})Q`yV&3n`}NT(HSwm0fjLiC&DpF%L@p)~M1EDTxsaBWZY z4?@~4Z+6VBVpW%wZB!J;^Wz5JGL4N52^Gh|DZcS8I7&bPXURYBwC;z50ZZ#{tv3d1 zUIsz}6QC@_`Llnc$Ux*S{k)?e(VnBXN+1kv%hn;7L}H*3y7=NF!2BI;0zhkdl%RkS?XW9zq6bmF|$1 zPU(K{|NY8`Vdma*&pmtZwSMbiVP)JgM5g9}k{UsPy})>TTDmZUIh2@rAnvnR+>GwL zyb_<}mdaD3vB)YT^^@rEyb|pFy+Dy@0r2sTuTTc1UFLH1uC+$~q z#6j7MHemYPUw{z`Sg?!SzE!9mErNKLipj`h266$}%U}1Kq@N4jh!QzRSz8MHn!x|w z&fgg-*YYU7!{MAvNZiH?w||@PzRn$mV2W#M{pnh!L$aOC zJn#NWrbr8$DZMG{nT#QO3VmMg_^QESa6V zgx$M>t`}!vGx3VPwI}ZfW^}eYDgBGmq^fGHJlK{tyqU(;&bChy!%}8xkIE-GWsiL# zc!gu4pGyAoO4i*OJbr{`Gn!uUbvQ$R*oPB! z)>OAIbl3gtz)3fI-m~`geRmtMDgglmiV%#2DnDN)DTf@Y0r3a z3?s_wI44C1N;7Dz&ZyL)v1mjZWh5DSYSk_a>DF$U9miLkR3?8gxilSgag$oFs3kn* z7!sL>q@p}9DWhRz&_F7G82fSmX}^0hR74C&3<;M%`Zb{H4=occQXLm`Daglset9Ii z6yjQcs%7cznUeC4FL^5OEqxyInK%>S^+=J(z-Jue2iKWKoW+a6sOk!4=fsmHO6RJf-H2O=Ax>bShq#m_jg@iVCpFY}urOkMoT8UPPhUPe_ zQe0inA8ry9VL%@Btn^+v#yLy0k6C@L9x{e|bVdp~snvna20#*ly@O{08sf2`3Z~9SIjp< zFsvl5shH)1v&CmdwhD-HfS2sM=J?oCqs+)95GuPRcH@~0byZXTflxixL~E^K`XBB^yl7uwTHcGysDEw(<24LfGEOlOha(tvp~a5U8MoQVa=O&nexSx4GiLLipB*L9uk z7w?rvXv7sdy@fo9iX;7KWe}x}*E7|W5U~675{NcIQDr##`w5Nf#|by6qxb}%0GgmI zN0!KV+EUeO<~p}FH80g{ZsIpWM!%-}=ad8UwjFW29^{6NF`!-bt&-i}s`EYV)YAp5 z0C5lglO8O8`P6~7PgTFkT&~dZl0yZ%dpbkaYMKAollO|6mW8uk3NyKS);$(7e#Ari z#r~r2Tws4KTASJlms(}?fkpmzcOh!9wUIs6b@o-LJ4D)&LOJMp6DD(Hs1M>gE&14$ zU+wn4uHBUbnSjMf+pYwb?lgS5u20~g7lj9Id}q&qxB&oH0+}^+~ zIdWhrPZ^;kBQAg`Qe&twbA09T1!2AGjt&5#la?B?PAJx5zt;;4BlR-kwF}bg-jaQD zqpjMZRn{rV5==INhu>+K-0}&jE|^6p`8?G7dG_p&+&!(49mjqTv5ik$aEboHl!#P@ zzb*Q`!z*!%P%_oY9_&U1fL3IJBZ_B6%QeAloS%h>%4D9|-+&N=?XE&#C-2EO4W%D> zs{-PwY|={``I`_XWhat@uTm4@Q)4-i*c_IqnFfc(^8zQIu<8<;>pGZ&FJC=Sd9qoO zgzFi2LTcBe6Xq!2v~pvn!2f=!B${M7p*62r*;Gf4o|{AD@ERifF?`PEoS1Q7z1oY| zA}G%orNDfKQ9gMV4O3dv6h}|B5qATdXg?yJ>oB8hQXOtgG`Fn-I(8jpzc>N1wE(>ORSj znc~S_weIa{H)t&xC*+mwXxZr{ZxeAW&ucx0rDR|}Kn`MbcO@j=8H2oy(jTXr=m*SU zY`$lEA4R%${4K#M7KUA<2t;)jxUSR@@;Cf@Ug3S~>~#EOlZ z-%U!1jUD0xcR$TJ*TX-pF|Xl=R-Ar4I4N>$h);eRS%|)^5~#$}`X{MA^wd$&!opVI z{e9n-~IDbt=@qO*Gf z)M2RFWYhrClFUQzmu(JT@CBvhy`c9b9z>vVebA^?DKOv0Vob^-?e`hOe8U5u9!!qD z3>J(bcYWAstNvE}WOzv1G*lp`a4PeFrx)H*w%%E??B-HlMFL-@gQGQuAI-01gF>ih z>zQ0z_i*P6#R=JqeSyYZ<*_y|Dr1x$`%AvNjvsAjD0{{pnr6=0GOoB4D#LF$HUB!= z?=?70iXzL?2xxwcnt$8*)N6qWpmjy6-{*?i-Y*pN`uv%tyaFGey=Ga(P{p0mpAXIT zuKKk$Wxv0NA1PYOoTVPrb`6?iPImM>^0V8?C}&h-h87gPl_7S*nv#L%Ypqt+>*3)% z;xWWH===(%RhUJ+rG=Rz#i5vIdW4D#@CA(S?@#}h=Uu2#yg!)+%glUONgI7K3sQYx zlo8kbd-ri&uG1o?yv0y)w|vo>-a@U7FO)9PqPCVDnw^yO|KgV|RDiMSBm#nb1_30; zyF-oGww|~LWrbD%_}TV9hb4s=>&~mA)S{9$bBq`Q^R*sb{dTy_d7ruR^+_w5YrDY;w+(Zw@}w zXGdlig&qc-TTA+`!n%jr>raC@T6vn5I;f%L>HKG9{`ZT|bO*Af>E7=exp3MAsSs_Q zc#&e!;5ue!yy*8_rB z!HDn&NQ}j>S``7H4HZ2TpJ${4N`P;XcpTT4!2a$T3Z&17N}Eic$A_NU7Olxb zq*l*lR&>Zgp$SCl%lwD36uoRi%}-`eAgDA0e{5`DP-tpZDDsjnW9(R#vE-{bK$E7t z@!gayxFv61yZEi>^SD{ZKb!*y)Wl0Y&qY8C#vCcu;JAw zr9GZxR*1f!7pPZ%TV)uzUK`ubR^|l#P)`cU*m+R!MQbn(XA%b+wUHd5>Ai9pgb$jd zrtORK*FFg$Qb62iIVY|3CSeMnCi!wkM{ooIw+@Fo zMuk6bUzm#tA$-}Ud+K`OQgPL3vZr(W^>!jlYsGg`_k~7T9ym5;VJv=;;4gb{j}Bnd z&yvQLvu+5}wNKAyI_oHi4%t84poxxMu-8zd{49AYH1?ttfxgUOM|L~@99<8=uC-gd zzjttH*1 ze#L&zH--xoJ#x>h3q3Ps$BKKbZopGi5kYAvmVUUgX~DeT5eQw&+=>cKN5q>$HLjNc z$pDbSmAz|ael-auOy8p^J^qpz?Tx(@_lh!;KlOW>{pNF9z||H`Bni&p^VLNjvd_8e zL@ZK#F6jEOxgt005i^eoFGo~TM(0rhaHOFqQy~DxNHXN(5Y&Q@rEf*@%FXrmvDN;w zzf|vo^^#1M?=%8j+VrQE1fq8bCYK~SIc2yOdZ-HFaOpy7Oy-wtFAQ6PS#7vXtVN+w z9C7gk8Y*H;0tL0$)2mW7{LMEo>Gl0dERWF2(>;mddvhj_5mr_^mX+oC;fNC6aWp6$ z;OQFSODgX1^ia=pX3jR;%aEP$ zVQ4*oVCXt?h(-yG|5#J{4}F6+r)79O2H+aOLd)~0@~0&<&=PZfPa4z|X7p5ioAef6 z?;&~;2IY3EpuGww+jH{}soP>g`24T71BjDzZ~?_LY*s2@uKKg}cYzORz=At*wUu4P zTh3i!7un@4l%PLBFyO}!x1q2p3%gb6r5n;Ny*aDW1M%4^A9iVGf~ne)Mz{B`p~$M8 zA{1GE!6)J*QQ%wivhP%XCDlJ={o>~2fkJKh~N&N7Ba+`TV#BtV4!mxBU9m&SgiN#gmHji;#li=iuO_7E2LK7#Ew z|I0w|#qIa@!_zUV0@zdPb+IIS{pj^QcfHpcPK_1nWm!^q@W<*|vbNx3O)xR4{Hm^8 zFUz_!aPZ=BQ$u?qPq$roSEE$&#i>;kjmsyX5+kR>xWk70`DH^G$NZw0k&+}X5b?Cs z|8f@F@B~*)u7eAca1mzs=3dzo!<-E7=j%_5>K@-s*n+7RJY?Bj*4rHCoe$ejy%g`! zeh7vTQh>5!-aDF6$rR?SaHk(A;=yyLGgfVoLoVeW81QOwDXRQECs(vW_;Of=^{y-8 zWLWQTxK`cfsk?tzx$G9=lDjvFARL`r^jv|ThOk!$qVJAR z2nNw{AN=lT*GUWU{fd)9Ce+xe)it!vb&~cJn=E0tQJQcmw9rmPIfwsar^`+*sk2`ACa>1}>6f2Y6`g`d9M5M_OWKDBl`>1mqPlwbP9C(Ux z09I+9^kH7@P3v7_GhO5asAnXs^>jSn{)n-RZ&=R6JUX8$gjiJfu<+y7gQ-t)=eQ{4 zycZ1AOOoUK_ay?A!6kDWb^=0!j->=zq~WZQe{Lqf>tBd!KyDVz@_B?XP_gS%7uN=T4BgQ8915E_h4tD|Q4pG01iv-4jv z#|nm1P^I3-uX}ksWE+{rHZ|MqHj!sZ+I*Pm%Tw`CB2nnAHL)@*u_ybb?hvQ$IlI&> zrt&$<3(&0L{H;qx^P(rAy+&^VdKsh#NO8gdsL>2)eDMD9v0?`_D#7;O@BEPNzj_G) zgxrt3QMP3UiAEc9uxU#a=>xfTGxZ2e*)82rd~7@w(73X>b(@H{+oxY#Ha%%`xP*8Q z7!DD%p$(W6?Y#;`e1uC80Xqd}1u{dlT8<741;R2y@&6H06Z@*+x`TRoA%D#3A{YSA zh2?}C+=bViGy>WDpSWg~>Fx@8B7Q#cx3#yIOY+R zuoLxJ4-BzCK8O>^P^xhzzAyfxfvG%tRWL6Bj$;VigjGqIiLf)qL#ur_d$H7)N5=SU z&=0rTenASyQDga>@I{cSo|Q$^o@2ZeT3w<=dxB6((RbOkvN&dz50HB^c}r8u_9fWBZ>U^C)TGErv6M{-kNJ`IA6xbtPK4Rq*9W<<(3g zZw95N?NV@aLnmXE@$bX^+!bb<61@!j(efAE%(zGe;Fjo6*At9r3W+KWt zVg*2xT!PWL;Z&gnDuj{+XB@vdTdE{P4CGTRa_vNSPa<>lSA2CGY^}5p?Nw{>e!LMO z)~u4Hg~;_`|85y$i;AxJ_h6>b$C-N-%J2qBjl2f!JQgbLe7OY;Hj)o6@2S5RzeV|K z>8lQr;P-v{rsibIj`Sgpj<>rZ_PtSt1wF!%7~YaZ!IlmC@~yPNdmhO0%Zr!Di0 z*j<(U0-&+lTXO zPx%@()XOHgv;>O@f%JNa()m^$CK1MA2i*`Y=Wf+o#j_Zpm7s1pzCQ~CYxgL9TsObR z79`<+(l$Wx->p&fU!of8ZY}3Eh}4n?N&0h82Axd=024GE_Po{pIW6uk*us3pA6##i zD#?Ho>vneUl^0-ufMmDGoya`8|9-l!OAY_O8kN35_JB|<6Vbp5Sy6o6 z8S8snnerw#47EG)?~JNR&~9hsMOX^FO%eELn1XU0CN+VE6|E)B>6Tf-$nR)z?(osn z&caC!z05nS9kO%YF|>LX>7SUJhmSF5A9g_E+LM19S$uT4!0I9B9Xp5DFNj{efx6u@ zSVWP!IGLzVS=bV?_ zC;CulEevg)uzavd1_RspAV==RWC%SYH^!B$L_$~5a6CMgZszKHdT&=09wnn8b4rZl zy*yTFt27Js8TdAJX8;iUWR?6%f3-*hH0_WUS4}NH^g<9DSQY)abvwUqq_h&&ek34ZfhK#9;uF$9#FyfdlwTYg3 zrdLrQxc3jwMan$hrVGI#nSW%Lc?PsB26#0LuE2ZMciFOF{Z|a7fUNzbPB;N$^&D+T zk}-RO6AJLm*YnQ96*n&Dpa=)q6!zq=OZ87U!4Mwk0Ak zwYuih`@E#_aXzQvpp*eMIPP1k4K@F-%XrxY74>CW)Z5SQ1(y!T8AmKp@sG(vkEy?7 za7c3it3*ssXE?xXip{svmxpa+5@A&9BA)_Z{~OrCNq%Zid$BbE3gQ1u{vIs=2GLfJ zvRJ@)uX-D8-%Owv+_~TYL7u7*!okAAM=}UHifE8>;QIV1gCLhWhx$Q}>e?w3{ z!|sq`puv}k1>i^Sx49G@f~F7KkUBg!JY;FXJ6FP_ zQgN1iPSCrMk8@}?u1c}eXus#_0y;5MCLEHt7V2ab7amFVA#1QL?K#L4- z^LB7N3Ip^T&Pnj3W&#K0Y$k0Mk-pRN<%Sd`t0x047c4Mfxgd)0;K``_*>I(WqG0Pz zprmD6_;^?7y8U(GB;9Gf5Hd9SvPg7@%h`@QSGsR_#A)HMg2pZ{>bJ(1NOp_=)bhiQ z_j3b^nM9{N+Id5HRrt=A7lL;Q5$hi^HvNjmgA>1ChasO_2XkA<+cYTYynVEPN9BNY z@>&uu#jv4_Lnn4h8muYaxNDWuR)NyNlIOCI7I2OAR40E`;^zo>xU?6ookC=3xt z2d2o$0lA@|Pz<$vww6!xzkD*!(cG7)ny8$fVxKX2f8&)@sE~Ybi(MX3i|fD_dSNC2 zL^DTJhSOJvH9`{nk{y=~3ibe?DcSOsxHYAQ%b2A^<-h4>3e%ofYw`7WccY zIzgiHNYmKol&M*CAun)65_0g|)t0~o;XpTGA0yOa5SHIG}ZfxRNu&*44n6!lsX zdV5cyW9i*0OL1|Rk9i#b@A*TcWG|c5d-3q^!eaA|>z99j4Hn^eeC;T=a8sgl<{wTq z{fs{LIz|80je^m5Goo=YxA6snU+JGxmtf+AErDBomjD>+b0{bxv05TEhGqqiYq*>Y zdJLEB%f%Sm^DXoC=nfS5eE$239cq{s08PZS=O*~zuhxn}TYoYcaZ6_U+%;R!73nOj zoQKjup7b_xoDVw~52Nip*V68euw)y`+;d?z69%{(TJgA;_ILT|d)3&+j;jDrs{21- zdBoJ6{zr4k)RWv#q%AG1Hw+S1VJjq~cy5N4(;V>9oK!ynA#0sfg$BLnjt14_~ut0 z7{P>&%Te>|=d}9SJ!H^wDvZ<)1qgHspQMy5VMy5wuI!%EG<8vFk@CBdw!KI6VOiW+ z)Wp)pBPlDvuTZZP_ljZ2v;WekWN3B$N+cl#8`wN;99;O6usGTLvN$I5n7PTlp_=@W zYWW7gTIc*>o~^sDIUfS`#TnaVqmUbgzX?0XQreGC_54-;LBM?ur|+c`DWX`VPCKq} z=5l$ z^Z-1tGp_l4z0Fv?4OT&M1q{k1Lxt#k5$VVMB&%Gm!3hU==y1_S(kkkVkPfLWQxzS` zLc`^e0Wd&{tTjD%!&ugJW5=1m!Zji~Mw3r90at)&ix9|2?obXE?ANTE?sH5K#CsXOQ{*6}+GbhYnTVOq3$*@F&`CiM@dBvb_3e${3A1hdIcgu? z=at`&-ibP>C@VwhKGxl=I;Ll$I-DR?=v$JZC*FUQC1^CHedij-mkxmg>?O0iXS(-f zHRD@!|1tkjXuj-Z-gKD+qdGc6S&>Je1`Q0F#{ox01C){ zldpMSaZSb4dO?sKD2O#VuWuck z>m2Ws()}oX;G2KMqDS;>ZQ~?V=FGp!{v}~ru-MTIjo=!T=ZOe4Qni$)5}O<{Mj( zFwmQr7qcAo^}|4=*LzuE5+`caQT7gsVE2LfLG+(FRDGK0M9V57$XwCY+tqms?30ym zdXGF?0bO4YTSLkc%er>|lia^N^Pu^A+B^KSA@{!>;mmU<1>EIzA>OqB(KgDg5|pIo zK2jeI&tU|Z(;~+m`1#g=1x%GY3~h}dN{U+zLw{ya2|X&5{i`6NyNYvZ{J`w!iJp5d z?T$advG8Q@R$#Zrj`;o@19BGpo87|3fLr%LXK%5s8n#N|lTZ#+-q{5h<~?+njc>Jd zx`0y|3!xZt0+r(8m)&|2BHyZJB8Vf}-6b;aS?qUo1XzxVON0mTOy@g#-d^Lv#09yyFH zX>m+&VwVn%_Ju56K@)Pb!UQ0--~qmGK;`Z~=HSI3_r*VURtjB;+Da<1<1;DjuLTU- zLpiw`0Z`UI(eB_oMO*HpoM(e-Vbnv zv#PdRI1LzikQ{JS`#i%6m)FHqGeAyw0`>P8^=+^gF>>KaYt<&hV+Os zT#yDVl@jOf+zH<+h)aI}7(-eJFy>y{LM|V9gJIpD1pV)U>wvQ6gXTY@96-j`JxXe& z45z4f_Na2lIb7(gl32h$eG~z)P*wmV93hf@u(Q_VblNIe{CF8PO%tMec)~JeaKzZ~ zkI+z1MvTjbE>Rn138-4+p2hId&Rkm#-@S%o$i#$D>D`T8Mplq#?_GYZ+Ex-8`0s(k z4@(?$L->l*UND=z|xq$)A0ju^hQq7;p z!8suCxjX6)-BI?NTs(JbSjTEy3`l3GRc$7L_7vFmY3>kLuuP}NevrB zRZe}Z+sv=uTvz_!vn}`Ndt*9qk1RQ8&vKO5Kl)^|*B|K;&opG6C8;t5WwMQyG@G7O&i7Qs)@ks=O#5}=nid6KAncR45(mj3RWapX`^j8jXQ zw6?j6wD|^eN`M#u@RJ==>at+K?jbMX`p|viJyPXzZXL_Nmro)%un5lYU_pX`^sE1q zsd?9-<&}VySnhNK`xz4a^C7MOO$>W|J=@bO@sF#cs%efYm;R zjTDHy4+LOS&w$1)Ump?(pjGcg^G%)jgZd<|w5e1H*wzML${7yOIWeT0^F%8iLaAcP zJDx)=vi`x?y|r}-)2@C_9bY_-oEPsTa{3K^Rlgfv<9SyBQkC{+DE#6L?KAv;qtyZr z*Wpq-aqaDRbjc!!prMy%J$aoVR5Hh}L6)K+6Fo#%=qnZ3v(J52*wK>l$B9G>GpAFi}v4?;P**LWCMX zpab-$zoxU6c$an)D;VMlz3L9nLb;^692f^rzkq1x^Z`2-xc_JdtHoD0Jk@?>GoTi{ zRJ}1AN@K+sdm1Xr_5d7Pp4sc!da~Jb;3Q0d;eiVcf~&j=gA&-@)8Wk>{YZi_GWrHE zj#Zy*5hFx4>alE{gwF;~PH6)Fgf z*cm;KQ%42dju73Ws7iD%Zdf3QmuZs6TBzq>k+A6jfsXj0>=j4FBM2{~gJNU6*!@Lm z0ZS%=eZ(sE!=_p(SVfKSM@_whLMTwDj30iwUTi~wW~;*1ho?%vkk6XwF93{XA5aBK z4@75KFb{93b^LTT4(jg0#g2rnlXv50F=~HmZu!Fa!BOrru^?B3f)p|(Gy7N7e~;d+ zRS>)y3v?k^HGywfj(KaQurDoCpVTgzK9yrtm^jj^D!MVVfM(?=$vO})i{j8NEj1Ndg*F4bYIqe$3_$PypSZ! z9r<|&0d$W_$;(@&21Xiha{**typ~tFa3z>u*SbupONx~@l4{4o{LwaT`+H1ojS^un zzSg7a(hYS-SLI3!xEfJEL)BGem<94cR6*RatFhGtyV9`y1P@tmKYjHs5jZnU@phw`7Jcwo z2yZ96{F_Vs;31pQez5q5nd`>g&hLsbWU}csv3Jk{TVgzqN@GqgTI#?0X=gz-)oDlr zqAdQ0HBHuDeO$d$um&NJ^h#X`ELui`a~)P}Iw<1yYcUa}(XUSIL!vJ(x{47mx7|Pe zwHZ1}fB`K=2Ad!2I(iO4)PRsb`MPTN^eW#T z_-X+j4A=p09bnl`1p#1oNXdU+s($M^nw(X=vdmUsfDheu!vNUx6tI5b0eBo9R{vIg zbz&o%y!hVH%V9DcXfn`PIh$ZIq~g)3qTI+lJ58cn(n*_Qou0ntTx4u_=DIEd^^-0u zJE$6Ru+H_qmI1AdA3>}k(sNtX^+Iwxcr!ld>wA}5VYlFI)pFMtG~js3(Gr0mg+fJ0 zfxs=*GFnXF`N`{PP+%txA|em&GvDnyLSd>0nUnXBiRfyj4k{gB4Ad=HuF@~YhHt6? z_Gu23M5?lx%s9R#$y%Sy>`#Ix^xyr{Z!tM7F9k((Mt7 zs}A|m-B-9_CqB=ZJib8?p`nlj@X|5@Ndp`us>~isaYNQQKXt!Me}0$!A@&yl7*T&_ zB(nZY;!fnoy(_ve2UyCe|Aqo?5z{wlfE!{Q4VX(_jg9Mbf=HQ@%22Hpxjg4=@IN480@2d=}-;mn7r0-6bhbaI8*X|csb{<2h;;)Kl zxymJM_af6ji%mB2s>Xea#W*VtJu0-S6;lp2D)(I5?w#3TN$mBx_Axs%*_*vBT~G@B zNvXf2QS11v`KX`5a)>?=8den{g+-x^IN_Q5n^110_!tinf3gj;k`;wABV0{hI(#`& z{!(r;bCm-doNUvBV1V0^JQR@6-T>(+*29co)4ChHB7EK^7egQpvcf-C1F%$fx#tF7 zcU*aIfZC7Al2XWDFyIk=0Hjz^&DFPiK#;QlFv4o`$$|+OlT8b0!Ua11f1G-=2<6EP z-Trj_TlSV$D>*jHIV&0G%y-7t{&?{yHS2env&ptV?=To&Hj|Fr92=Y*C-dDFBau6v4bW1`&>dQri(mz&WpqE+$}we9+kM3Ak=!TR{uo^IoAg7T{|;Xyt1O7ACR zJCKhOfgp3(a%Dix_A1Tj=<0~FUPediatY#MM67%pQeED(RVBIn2i|V)g z$CCJ(94IhbHw&jU9OqCUy2S$$f-n8VJfsfwgfX#bTU#uh(q3V2zk$Y7ca|xZ3;PRi z=Sco56u0~jN6^)alQu)8CC$!?+|p$&?rE3umVLpg^byAPk2DwP)6wqBb*TN9mc(A@wyC8*GWC?lBnX+Smtw_VB>Z%7veSk(Iswwx(PZJhORooC#@ z{bKw|iv&E>f6Qd0=rFGu*S76#3rH0G>P?7oT_{nqT=mCt@s9!w;4oQDlL8P?|NZN# z5YYY?(&lZ_sh_8HEIbLi0JR@><4cLpb8BM$(aPKQ*11{SDOX=T;*Kw~d zH(c;isJFmvJi^GVU(Hl^Qe2HoV91TT`a}8@7N{e#ulAOoyY;)QaaM{KSVGwSn&_S8 zJ`7M|_?b!LB=2nStMvCq7P*vrwLI zgWtY|uYUr0JoR;YgR~Q`6$;Nkws0Bdh5?4l0qMvA>I;g#iVKrH=k2cxTR)(_rvEEX zhx(J+rYJ0hH;`70$A%o-ih`enM<;Gru_XRqw0#r+B&9YcGe&}YMi-cU!+ypE)S>_c zQ^H_<_6Qt%V*tMK01|B3TMz=*MgZ~!1ZevIec=NIq<7eDGPyne!ReEn)yshFL^ru- z42hNAwz=q2{l5p8Pq&SP;~cNP92Jt=$J-uqWMSRS`OCp-avH;3_kA;?JdLek+RO#) zcoCcYdA$6ELny!(67?rQftzV^pG4u|P169CmEWq51K(Z~Wi!;JB0e>4_NtqE)n$?0 z(%$ZsrnMMi1+|`TGq~<3Dk#M6u}d42ev9htnfN5HOwxtOXZk!fb+*QY6_we> z9vZtWoTZ>KJNru8Gnj6E!MX+pvF;%1Z_ zh_3J_hXU4KU!A&+K@*SCY%zxK(4O1^fFS#zFhmPs|05AgoND=W{@Tdls^=EBsYIeE zw`Tb*!AS-yOyYSR9v2n>uoCRw9@S&5O{SS-->+0IYg&k=92g+3JmcC)!Z{u%Szt(Y z2nd&Xmy%!%8h2QdI+5%7S8GvBi zZl|}={OT;9mDb;};*-qi=DBIP@1NO-W;ElAlq(qR2jPeqsddk+w5^N91Kfaox==5X zIar=6j&>pSR>U2O-m*oz&Yl?*QZwsPZi|5-W<1UoiXSBcsU$PB6suJh!7jZQoOJ9^ z9eV0qNWEc~;6esG zTmRexGK?v*o|g-d)(s7I&s2@UfVpOpNo4flwwV*4S^U=+?9MH*$lr+g=~7J!Sc1}G z!VDY;K+7l>YYqj{DZ}?vtqiFz6{an|AHf3G)XQ2xR9HxAabEedO_+Hr6)=tb8(BwB za_y5yTnY{>JM`KMBnp4hI)sSsG3@2@l_vamp4$;TtuWNJC3vwciGr|M!&?i4fSCUJ zA7EZB=!#KAM|#s3k!`H#tB6p_8&JHZH7!Qvb$W&7x1+x0H;u!&E!aDjw{+^VY9i zpV_Dwft_x?*@)RGa7l5%QlrvLXM#Pxp&&YDzm{6N%mevxS8q`Or{bidod1m%o&!ne zW=o?09D`@y5f_1gcr^)wVTFjGu34&gFKI*|w8DZJ|VIgM;1A0#!Hq@I}E3~ zE1U^xsV8qlakjh3*#w32g%NYFho0_kGZvK6o-9)D@n_Megq0uDmm6C>8obxF{dN{I=n0biAheCp3e9`Dic(ej(>_SDDu_T{UJ?o zWM^TDc%@>Ibr{1++bf4&aL_Z=kKe7kFmLmYJAp4beKq}6GAr1E_`Y4AN~|X3oGpM* zfFlb^f7$@vN2534d%oZTa)>K`i05qrp&X(Qm>1!KL-gW#!a93Bw~hW5$v2C-;~u)- zrpaP`Ds&v!`=X|mE|k1vg3PltSG4OD4%}Z0J-SCut>ASgOxBDDt9gZjyypt@*e@0F z!O4J)5u$l;-pSv4J}%;arvtD~)qD3cs-;u=*4{WUWu`u-Z7;6uJO+XHr)=k*_)?(bvyq3*K#wnT=#fieH>i3p}>Z11>E`aF) z&GEqT2lavXo99!rc4fKDuTjGHppZ~L7%bt{>kI}2VYj-E>ceJS8Ayt_poWAV?`<4j ze_{*zed#k3HGOnTutwdoX4?h@#G2pQGUTe)Y#z8{o+pW(ZQWR~a+uvBRNojLtO2+~UL=bEmGYe}G@(-nN=5XFyR zTYv^lc05hnjP_zPSA60zq}V|b{?$t@cdz| zNGKx$XjAUliH$-9_a5)3BtJ+jj#E4LyB43b{zH5PKMNCrecv-dI!PXfCZLbT=})uH2-~`@|JPLm1DlTGhe096{TPD!8p;{ zG5l@A%;4*rqM(mP%7W3qoU1#vY(6e}y%2F(cIL~EyD?kih-3(5GjTMZxM5LdAN1l+ zD0Gic4jk{}_KV1I>Z21J)z(+!oSMXVAjVtGQ*pHyTQmPqCduge0n0r4*)<5 z&58@8BOvG8qDFDd;Q}NYAj~)MCX$Dtr7Ai-MpRUtb2R4koH6(jh0A!ShL&Laoz=`{y(1F;n z%CS+%%wI~dfT+?D1%<(w(9g4~iGgUSS#U~~69W{h`Tzy*Nyj2pMC%7RYDQlirjuWf z8E(l+gYnO0E@PFBM`1|!s+9263rJXl4g=)A4aLfl<#Ls=JL=~68PHjN^|Wy_$XRDb zAPK>ZXjv9Ku2|iI94)FkpzOJYTkf zWgiJBa86EZNSq&XU05bOX_VKp3FwPJj{g(_F@T~wU@RWR{SrilN|Ffn(K-)7_2=@! zK>nBR2P9z9ieNypdy45VnFO`Ykxa-F2>!=VqbM|FX_G+!I{`ok&(d0gl9}FV9pAOv zeQ*zvfQpo;^usTi2B8SSQT;tOkGZ-2H@(jy4Ve5bI{0QQ@x5?|&!NvqUz^w4t=ex# z9cPrTi&Y-gNsSoi#IW@b&+rc(n96!uviq;`Iu11d)=NL1a6PC z=O~ej9%>4rg0&ULabu3APcGy0b+orc?h^b7sv~@#Od$~Flg(>na2!|S^w`%)8jcBA z)^oLb-d3}BS26%R#-ZLXzDyfM4B&{y8+-_ZbAn4;02Ufe#}T{&wyd709L}{vr(}$O zXEJ=K)smtfzwfAVh7uY-d|!=@domc1QV#WyQeSZSv77W~#C;5%$n^Lx3UZlGb zIob9zRbTO+d+|fmQu^&N1r{qI6EsKBgU%7LjZChtq;eCp)9+Xz^>r@Je)IqQ1ofR{ z3^L)m1Zx~WT^e`#!lEW@pEmFLHJQCy3TFx|rjsrl`0S|dC5K3Au%p8QX-Al0?T{NS zIt56kz5j2>ubAw;TMS17YIYM2@9)B)=(yQhA3C6<9k1qbRSoeH>xkFQM>m@!FaQnW z>=_{_z^C6hBs6J-y2S=uWw=9}2NSOH;v=)C?}N4SvPvf1ro-a}9x3?)=PCS?p_%zZ zHRf{h^heTjb$UN*XuojP@{^lvTp9LOsr$%FIZmIvE`_I^Wp4YuBYmAg|Mz}~-rX_3 zS5r`m^?*vfI#nZ}O$`SB+rY>Q4c*Alg#~cdmkgD>rppBuHI$#WaO0UcUY~&U-I)yi zFo%k0hr?*2Y6?Yt#+OlSPgB_p|7(t^tE<u!GO^q=bPA~i!b?gf ztfzCc-zVV}kwWSLn^-81n@{KWtBt%gG|)Aw^K^Q{XegR#qny7TKSN-z7!itzIk~w# zK9Vb(vA44V-MjzeAO4So_zXO=onCcc3K(S!zHZK- ziu4miRZ~(C6zlQ3Sgn@yox9#*0>2s56wn3ty~rJQ`Nb^Bzw7j{30EGQX5nWK&L#Qs z(IJAYOEo_;w%B+m^e$Nl8q?H8Ev3d}>c5c-VY>DGpEm4*7z~K2sm*wOa3URs@PR#- z*$VPMDPMy$p?qVp#plRy{-Z`{$EzT>9}LyPlT&nj&|`K3p(cP5o+ngS;#9~ABAZ&~ z9-R?sRaF1b=kQRHyC_#5@bUW^6W zVePW+^Z(NgbC>^C2hyffR&0|x@7N5+a3Tk36ZDj~%HirgFVw!OOh|uG?n>tZnuXpK zn2`II?kx1CamM~K6*+ABTr~wv0*1a^KMVbT0C-7GV)?S75uo|s#{y-O)Es18aBCR< z8&VnYBlMrX5&9BJs&zL+hMb1i3YAN8bJ;B9Ry7>y@!D)$*i#)~nWy>rd};0tk4^2s zgz?$f%)TyE6p>eS$Ln?)#(iR}7GO%(6;2rwxJG^R&70hWY$ zCREW&N60!6i#8|b&Qdzd-CbU{-!n?w zXTAWdsx<$a6K})Qkde{{X;z`w_(Yr(2<0lgMuQkt%Z|JjpaX(Zm7l%DB?CviiS1GH z(BIpkFU)c%W(axok87#!<=HkCLZ8ZeXt#}8N|)013nM4y&X$lVcx+mV*`q1gy!z|z zuVB5e4a-k7A*VM1^hxgzRM*vQ3hkwulVluQnt&#GDvo`=G)^>EzCDCcKY${9PJw>; z-7xXRl5N7O(=_YP@hz^O_rjR*Vnp7GVHJu?Cn@3C$V%%NqFM<5>s zw6b0ENlLuulsA+1<;oIL8PKyp4m}c367x(19TeXg%t+BYqLJF$6)FjF6q`a9-}2xw z{FK#&FbTDV8zV}S1&)LYJk9sWz~pT+J0)Cv&*v2Ym(HZlBFRZ*eFE}Sg$PX zu}iF>6?idEVchQ!D1rt9JBFL3W5tY?=C`bL4g^I$g8>^#jJg!)WJ>otk&BXb4)h3p zD_l@!5q@JvSzV6k%fwfuvJ=GN$j%Dpj~+x+Kg$}S-0hL1!JVJe|aqRm}Sasl0Q6zNw17g6meE z-22o1Nf{($MNI5Wr`I%amk#ezwMA?z?Q|AJeMd3XQa;r`b=aW8S!?uD#MmZJ6!T0> z{?~4-&`@17Z%h~8{A=$ZO6{PjJKN@i1EI5A@(PV;ua9cmn+~J$WncEU->tMUso!IZ zI_wCxWn1aQ`be=oJYsyFt?Am!9$S6w8$Xi`ziv(fcXdkmRI?^S+wv-fZ3WE5g^6QX@30N}g(8=`Gue;HY4y zho07;;n>x!t8pFoD9F2fY!saMBg5gr7P7u*nQ6O1)i<;k_OS~KvFE0(Y@rwXDho>~ zK0=9((97j@Ml?try4(IK@gZe8UQ~8;UO9OA6r1@>Eax}fH%mk^uDqPk1JjLCer`UkgcCDi47IE@SmGuX4`c+Y)=YrF^Gz zFKEfScNuyeKB(%J_i%nchkg_WQeI- z`{XIkPj6l)WB(>_sXJUk)PHs+nS19D^3gdl9gRgmW4Os!F;BSvVk}4Wc{VJ2t7T?1 zg&~+}P#i<=Qb75Z88eWoNLYD>#67+8jK&O?fzB*eKO*zb;O%n66qW9cQdYytKXZ4) zdYhE2d+PFupZ^yuA_@C|0RQQ@u@_W0k>$_q0%9U?P*8=1?Mil~=AURax4NG_>kW3* zr94--^oM6gJDT@i{C27p@~T>PY~G_&&W5r0S_FD0v_0$5x?aZleF5G3Fxlnr*BM9` zcY22?i#MY3mu!9l^2Y>K69gedM9c~Gh%+Q;Cmsh8NF1pJl>;UJ7|IvCgjNa)_Pq!K ziKFeMVDFx%x;J~WyY<(R*KLv&byLh!VzuPEP)tSb*I?No-E4geVVzxcB&2pcyxHy8 z5^FC_dabE&zg=+vFW`ih5yU#$Cc^GCgE{H)j1l1%7(suKy)Y0(vx?}))LxXopLRxW zKB1f@-T967p3X2Mrj3eVhOvIoy+#8by$S{;O-L*-UqG;g@ z(q*@+fp}E3KY<_B1{_ODD`A^@6(p>FI_tta*dSCW-RG(B1sLb6Z4 zOck7XWw9-Wqp)90)bfswYqVu04iq0|(`eAqW-J7`U>GU%o=Fd0|O?yd_ z6k8r&MTPi7@kFi}xz@^b-(-KSa&4_(xq0!j?h8GalaLh#?xQR?909RF|HPfhM6fkb z)zEWvDnXmPn((y(yOK_CDr(>9rbtWY zhgix0>BM8B0A~#XHs+8Qz8~X-<8KpAeSdFX)d+TGzxv46rF>4uh$ui{QxY zN#ote7@yCuhS%e@z1YqAV|F@j*Rm@h5(n_K_TBm}n`Hy#D=#Q}Wsp3CnU6fZVG6Ly zJRO*H)@C-tWzwH(Xh^_<0NJ!H_X91$Pz)WQ>D6AZw9du0LZ;zVEcZj(E26ZneP{JP zSF}{JET*hHMfpr+>)o}*R-u2vMV#?+fI&H;IbYDgrQ{O^MvG2+uB3b6l#eLU`PiD@ zFnKD8&Ckf>l%hL3EHF;d;#85ryveOwUyOb6d;2a`@}dYOOwz-p_~Ogc+7zqk0M%B+ zvhD&VMvgx!hFgIEc`K8lyVxIWw|$!LXR^>PPd`H&N^hHgj(+#k>vy|ubBScp%;j>1 zW{5!F;u`^G?<#GYGX*vaZ(ke{w_+%6s31K(^L2|#t_T0i!|_05+5D&bRTk>jr@FkWmGyA;bMsUI!w z8!oh-=I2bs{KPuiRHNKA3W>E=ps|FV01VLW*D9Nu0q##h%l5|<#ML8rX;%~7t>r3% z?XKFbV?yOwhzzZaYnKvlNcehc503a@@NEo`Lola81Dus>=*J3sO$96+>Wx+&vRg0i zT{l$ff*uwxMno>Yh-KM)>=qt)ROc}wvYlC;=}CeNS72bZ)h=KNIK;i%HE9<7Z7&E% zBi`rxBsHl>7d88GW?rvs`dT{koh|z=G(|KoBSE;LPoY|%sgJ_KRzPJ6Y68TbO2hty z=GyhPbHVNNZF4hsg&v%|7sl8v4}(8Q#xL2|-@5rmAkC**k&?Z6 z6R-Pm(4GD-@2lq>b~LxMly@$PPq#uie6cQb$7{^2>OEd4ba$f)MR~}_akO4@KKqNV zAc;-47L}G&Fc837r81bAB`6kR(EAkAS7m*LCfhf^NB?TS=WS+Smgz?T*CqyXBCH3{ z|Az)1KoCa%&oohrgTdz^0Ex}LvYV@E@hVI&Q!+bg#bEH~6k#-brPR&oM zB*)AOzs~+yFP7}&aL`?fWb@(Q?o)6SA_DAt-CXsl?&3X5sIfqes=jK*Wp&el@Hn-E z^YsP$2zuC>o4PH#DT~-cb`x`#NY%}Q7QubJnQM0?V;eE|QTXjJ;*W}lF%1^7*z}jG z2I|!96_%DquB6w=(x=b2-~BA9fsLo{F@&~VK-{Oe+->C+To74Z4Kx1>8PmbwGL%09 zF)MS%Gd?&kD~)@JzE0HPXZdFO_y@waGod$ba3my~AtX`aAYUL+jdYtSS?qZj1Vl26 zsj47wKO8pWomPC#dPDcn&Ndjs`*6+#KwEDwopVuJ6TZL;nm`KLM_q&iBum0{GaDyi z$n0)HBMXQAAz73U_6^FC2$HBTK9Us}IgQR+hcqt(A>`h^=#ljE;0n_Z9}<;mQ=m+) zJ|07+i}~%U8+0(7v=>HsMO6;4*<_9?Ov!OooAsW!FdB)<-( zx8GiR^R1N0(UMf%^0UEWlXuC!Tr>zu(}Vaz?|2MQ!(}qob1VsHuCHs%DpbcAAila$ z#NYNT4q+gDm5yKQQ*mI+J3isj$nR%vK>T-X^M%73-#Ed(;{80uGtbH-L&BD6HndlP z;16aQNhf)((_PLc6BCQ?#KZg3H|B}+f_}G!XaGn8%-ceE^3Rwbeu41bA-uN%7p_R)o_OSE8@{GME(aWI8mCc*QStn*O*naOCfVo* z3GaVBfN+&0kqP#&7J;(unhOJArPSN_%Rf;??(4TMxdl1{jzvdR1`%_+e3O5%(}rG3 z=FR;cslAdM`QnfaGMpuCK?gMjXhGN;HrujMcfS^hRaVVM?0L6Z%*KvlEa(|YbCSI8 zDsQrEpI+(}T1viNVFRmn(xC+L3_QP*Hl@lIB>p&Jf-Y@kV_l^4!8|`hk~pkHJj003 z)HsrOz&^Q!36UxaQt21JWH6heQyx5WcOyey8cv zJF#Z-hL+N2nqgo9=^6)GHa9)52%j?gbSo6!abhj1&}0%vN|Qt>Byo{M5UGa$;?*|p z_uQCYBUy+h^{fmOXhoCB`+QYTJuvQv25%FqjKjmHTX@yg(|j8`7*hy3L%lSClO_%V zO(K1DcJR5=f&;J=>lfXIKT-=|GsbnI_#ST?QTcYJJP5Nmf0`nw< z-IQbS-cI>Cgby4g-G;oqb;+hs?U;N_DerBa2#3EX+3{41vf`lHHT)WYqxY1F4kN^A z+P2?o`=OfQA^Y2-@4rUqS22+o7pdP+UVJM}y3G17kWaED=E3OO2X6TRTwn*QK=5q)gm8>hhsbRtL zjgwr-I4T>iY#IpUjD9Q@r~)Tv9Qy&UOzI7ivDGG=SZP|?Xxq6KxYaO0N)qJ(?mLkT z;U`rXCsbLJlOuty6oCIE=3+$z6Z8n6BxcSfRz$r6Ig>>});>SPw2|N)aeWunKvjYCwvc@o2y)B}&-WuW#9e?sZBGiMoe zDBr&pQeBr~!OX~kvbhp$+Kl2Be4;$l2i}+7IYtz*{H*Tw1(xFYAT!xIpicp1jmY$e zmW(uPH3r(=ztP8Ztn7N<=yAzzfK9C`K9JI7(x~!=MeGSxa?Wn8-bbF{Yo2m63O%dU zcn$janx-KM4%D>7iWP=sd9On8`!{KqGhxd|r9F}&+s$WW0hFAnH^=?M%|~1wFYa9% zw*hk5<`e4pe(=V$H+)yIQeVNlG_}>$Jxy}3u0+gbS^;tCrmcNowe-f9M%^$bFQ;Wm> z1>i4!!7hDKfP;+m#8QadO1ll&gV{7XL&EpwMj9+8Mm+_Hxg2ft@=Ajwor|IILC5Ff zbtkB*WlBPJ7eFA#NJ7}xT67bnD#5V$=zN7MjNu~IgzAx*LU zE%Q^p$3cSl8aa1=FzwEaR-0YZ4cFTXRP4p!vk3Gm*|qy`Wr6>U0EHN`L5cM3BRpx3 zagw+CX0Hq6^Vl9ty;;8bQN0my+D35K`cK(&$OIu&elz#iypTd)$&ecj5)nJmHvw=s zw1~gVs(D_qBiH?md}VKDBUdX%p4N=}UQv2|Gjk*f{$@a;O<{zCJWRqT^U1^}MHW}X z3D4G<72?;O=in&`=iDf0aGW1{GU=|+bwfdvCpdt>1mmxT3TSB{4)y0p9n4d(G>tj& za=%_L0w03kX>sbW#VFwKM$bI&hb76c{pWCLE52G*uuB zgp2dx-TvxX6X#Po1Z%})4NL9TrxW@jE-~Kz_oJJhQmLcrQFl!YhLOQy4AX-mru5rx z;RjA77@GG|44sX(rt!z;gv5&_y?mbCfetExdX7$d3hX89bt=|H-%&24y89mFCAq}O z-Ux6%knRPYF=ZwNkq19py(Pyy6pEwnN9EzHp|dZesE$HAbnJj#ycRznxOh!W-ax`= zc|SVXHl`ehSiAFTzR7Ta3y2sTcv>gLIL7VRJKZ@lwqLlwV#q?HTVcjz-D@u~En0Up z*9*no$#mIBixIEtJ36HY5?Czc4~7(?aw7vtGGHI!WFj$h6Io5;&3mtVSTaw+cq zpteU|Y&A|9+gHI!jhvOgF6mZ^2-yEQe1Z-R+(1j-!VNO~o(&B2fR6Wx7S3L3M^eD6 zg$PI=w{s|;CNeyD`pw)hoKpbK#&E<0_aGLU}AZ@IwrpbVZlkOosy z@JdTs05ouzq z*u}3m`(NQgN57K2{w{P9#92q{urOTARIaHNc=7p9my^;YZ>r#iAV#5hYC}&VjpPUnnJL2j|EAF$*Xf8D%1 zLBJ5=^U!qjn4);e#zt};v~bDw775;?M>f$(BX`mLn4CP*HztPPAi;l1c&NzqSrTK& zAxj5N%wFKC>!-bzHkkW+9Dv^QoX{fr4WKIy25`$IPuFW@iZ6YGO@?9Y^?|lZ%_ghH zh9; zw5Q0o5x}y^+U*~uUE;2hG2ZVA9Wy@3=X~`|KJ0>fhVx9P;Q?gL&kA&2q`VU_a(dMG z*8Q+oT48vX@}H1lG58|}RyiA}IXL~9!Z8*KZAi9r0shJPcv95mwj~QGW)A5NSfzcW(X0($1Zka4}`s;*~SLnt8Y~*a4QlH z_NN)aI~KY;ZeMN2gbZXjeIdphZJCbvIvbq5!w^G1^gZ^3<{#ZMl+LoG;E#yYRkX*j zh;Lc!7EX82XFXW*5gVdbv6VBEg6E)$uP| z3#;j8ICYT)XS5naF=7x$AR{0D#VsFL4RJ%IQKtC{IV9E)I@crpegq1be2qMQF0i}T z?F>cD7W1wI5dZQtD!>`6$dc~z)tmlB!Z$9Y>Y^Fk|2)7r@mf#$-k0G@Ds}VWIo~s&T;+wqX&z(%xW3zY78vsg z>^cUMZd_3bqof98hMVTDFY{Rw({N!=lxR1^;S!`Zy{tBR$V|Dn7;r~=vxx2Q^**kz z{rt|kzfsP*%m3y`>RoM&dWnQ4dapk?dL;{vN@>CDS97fVHJI{k&DUZi2sJ%@A^#^H zGGID{^wIHJA2C5gdG&6*MZi|(>D%os!-|3D_LLJ5A`1=A%A84C&7PU$8>6n?+3Qdw zT!`cyrg7RMf6+Z&uzaH~4b*&UdpR%C)ho-8_>n=I`u5pF$>bQ;3YX0B{d8 zr@sCh^gQa#UQA4VFGk8%#_ap)!bxG7R8SmqZ<2ed&n`lH)29OetS8 z+(G)4%8MBd{?emQ&qU15Nng9q=ZgjVm$fT}iKO{5WO!HUFi+2p$jFj7`RweAYm_!d z^8N5L_apYXIDOlgm42nBMc||1>_RKmShf8NiBXKA`yDX~cU_ICUN;3#{P@-jf*7Lm zBw-tbXJ>@zY=XougBrz!uj6^B92a^~QWKl@o4?xXRgsYBy5xjE^W1gp-|6YBHRnz@ zw^pqtcaviDZGMq|O^2Qnil-?7(voci3hx|-dW^`!*?ZWYP+MVhzy52=T>%@sdo{?~ zyp)6(elyERo^%r9xQJ-+$f}H+d^(<{w*T|Fe9DQqJ5GMF#N3*js*kSZb_3@hhLAp~ zFHa_mnbszbjh?FKpH?2%u?a}zgdl@J+QIC<_^$k(v>)F<%M@%pqCDSrqbPf8JppNg zV;A})neqIV5H&bPMM@eAUHsgpF1&TP2-O^b;{?(rUh>$Otd`HRZ4_tIPp#H9T$ehi!1S zV**|(y2y1hrqql!1wU@b2cZ7lk`&{Ey2q_giQ!nJzJ$i68R}*lK3n6=g`To6{ghxd zuJ}`9d9jbNeIxst0_&Ai`+WQQYhQDZ;62_FFIqjgQi%dfhrj#d5NZEKDwyh0%BRLN z%ioB3C?GkEAv(eampdRQ!Q=}%82zXpaH9;Ft{Tmh2(+E0D5`A_s;i>A-DifBy4!V zE_|mHz!A4FSjRR#;9dY7*BD^d4!|#%;>ao1WwBS8 zt1k+u0Q*2|!iIRR9Dji=jBLraKK)~8uUZCxCkWZ0O$zls#=8(Y^ND9b()w2s)*dWT zPqCsdGL!eR3VHlVzLjrs$F#);y4=usXssGmvF_sOR{1V$=f1u`d38rmO-V3E2@gc??Y18VE$Eq9*jsx34WPT3N+Pe+X=6!scWS zKSgx9{EJkX7VUsP!6%u{czJHuH#z&h-?L451P&^YsoGz(MKiZseGe~AS#cN@=oQoJ z;QL385k1^FQRH*yZIFt-IF2;u!1oU>tBXlX-bMs|6OYwYHY=zLYpBUEIb$-SQCTr9b9Kmj@@GuR<6{J8@Dm`7xK3c#U;m#xReQ`z($-=Bu# zi}0tOZCDNX-UWk81)~QF2mAsu*kY54ixkth4Ww8!gSd=8%F&QW7K*3n0z&4I9o6hH z!e)5(tgGNvnk#I=e7XI-S-SzYUYrfOsA$12BR_o)db&_Hr8VE4lY-g*Rx{f#F`B1M zXqV!o;n3r=Y>1Ugz}VXy+rWty)OcOkz!O%!Hh2&Vkk%~!*BoLy&1Hfb=^>&K_AL3+ z+U?>@>4$|#58BAfvmF4ho^36fdFS{~(;Q9QS@*n!{_clrVY%$Xc^V^Q1!L+}g*5;U zd&+V$x;~x0>KR%1+NKAVlb&rNk`LT6yEX{_R!iF)5h!BoAX(865L-{s|g3!4i4V4 zXN6G~Q_meas-H&-9^AO>kNactzn)PLir6fK?kOfrnlC&Snivo4r`oxIJ)15OGH|I| z5gF|KR@l<_7_DS4(IL0`r^g4!Dh#y9Yqes}Cu=wN?3)Z`DtQ-P2|HtQ%dhAp{M2hI zd&K3_BZhS16$*m$gL;Q_P`649B1T(hZ$` zdrY67!(~ zS`c3c!v7I)^4H`uBtVhd0&b0v$K|Q|7lh z*L3270gEoE-?l{Ec0andZC*cIs8v2V6`1w=%4_`#@xCRymqG)7(udE@PlOx3rMxpR z79IV};65D@33eADCB)0b%QeZxNB-RzByIhYOAQV#(R%H$;JS7*T>mb|#t-*pAGccf zS}-ZLx8q);2MBG3Bx*xACRng4ef|JjW|OdYI%>{aF)L_Sxr% zCmegco}a$qcNlgo?$-o-jIQeF&TF%7KCz1#H#)u;%grv!(}O=N+^t(7F*io)QCZRx zkzP+hrxn5%Bf^N;86Y0@PC{bpHTJr@(kMd_{wlC=$6O;n`_fxkldiS2*-8klu@VEg zjraeg*Gt&w+qCWHM+HxwV&-fr*@Po-!3SyraQbd^DCke2P_gk9kcoU9KSyE!>u5;i zd1>y+8C3#upq{NLJ!jQB^ZV6lP~YZqMbmx0zl#W!p$u}IFamJSquD(=tmdw7H;TJb zX+#T2gzQr;wYxseeqzI*cW<9g?Fv-BmGV-5x8mD6_Cwn$_4YQuXTKuK%|)mp*=5ry zcxF%3?Yp5>6bx3VQB3r^3GSrO{8Dz>!SYr%N$TVP!T%&gs&WTf$Ni0*S4Ww`LYf0`^6CpD2 zRSX3^<=0x3LEahsEXy!8pX4e6D03GWiM@@>vDCzC(tS%_no<2vxee^m8Y{iB7~LEPV3$MYl_ZOMtlG8tl0&oE z=M#j2@Mbw#&z-{kuIr@7Z%e_B@z#0K(dWBP+XwE?^S+`6*NIlIL#ksM7)cfJEkQQBgT*?K!@K{4OcMm?|U#nBX&%{cjGhL5WM2BSZ0aOVu5l_U_Hsz(uiO*nE>2GTDV zf1Gxvl7$%rfR0cM%S486#v+I{yOJvp}Tl-a_fd2fl06 zPQOnn%kAUGgff`hp`~% zi9k)tNVdt>!_s4xOhF`Z%-ORTZ2hN~qUt=QD64PwClRb2iWRtB4=vA*TXs+AD}PL6 zHFrzRWc4F_d$am${}u|r^WJz){DG~o9(I11t92+x27V7;RVFBzJez1>z%kHPox9;3nuJ&Al9elhWqtK8%;baMj^& z$M2OV-dL11vu?Xfj#6Ooh`Oi4lGtpkMBH>9F&~fIn4v~Iai9EAQbmP@3x*y8X?>XV z$9X8vQkWI2MndCQ`u8Oply5E=QAH*&kbLBk{RG%ZfG75k0M#QPo%Z)lCr6WR=%uNu zC!yYbZz&si;)DfE1%aDBvjSQzotwD?)%Ae|I%!o565*`3YyDe?Wd=Yhp1pW;C zyD}fCUkT#dJ#S>RTIVw3{1L+RubuI#`Eu%c@XSlvhleDIxc(DUm8}ONyd!Ia$Kcy< z!O$}QZ(3{F?&aK?+7FH>;P*t)xQFSp7vUqNbscf3Lw%NSloY2aghFTj9eg8Z^FEME zcS+O9_eHniucm;36cpfAu^NbLuRN^t)1qJbk`4_7A449dGc-70QHga5Y!Rl7&1h|j zVZUvz?ly+4r89t65tV2P-ATOlL!KB9C+7nv>!U@CL?PzY+q`tD#F%)}j+ogP$z)>m zDM?QOwAd(gMoYF8teKOaICQLWY#S#EybPv7lbjBDPkZ}&b~fu(h|1K!yX0ORlk{aa zIWAH{jTx!!>pd}NrY~;_ns+1_aeSUcjgBsCJD+E5zIe8pyMM$=$?N#I@dIkgF)RBf zVd|pN{{C_HGp))z%sEBN=F`JG$H(?un$M-0*);;baY%24G1LkR8R>C{V{F|_1-4V_ zr)~wkJh6DzppU}w!Nt?EOf1VbnB3 z-JqG&->~QWvrFw*ik9XO>YCOqji>$&cOHEvTW-;Qcg+Dq($zk^j^D%2%ia#qT*|eo z?q&~Ry>d-7^Pcn4DNMdhvSIgu^N|^BQle6(>-opE557lKB zwu8Z~iO5Tv9sW~UaJ3!tkcy^xTA3TcThEzFB;jB^L8-eyHl3mq7rJ+dz8`Jc1y+Iu z2Op6|+a*gc;K)RA)EyPqq}C6fqp5j}Hma8>;;}KicBilBGLD6m@#0kj{*Wha-bV*j zJnY{ZTv8KQ{6uhXg;s|#3K3IH!(1O9z&dn@gO6?XD$F*D%zWN>()2`o#9CKN`5+Ns zKAe!~*-*TQ;jl&8jB5;_df4^!%-31A&M@Lc=r~8qw64&^`p7wV(>Fams915JR}T<$ zHvcCzx&vB9U_5)uL)P{2P+QV(oVDSN3gqgdL&?}FFRnIAG57R$zi?LUIx#b zQAnTwEIqV21$kf!im*$f_ ze~ppAM^nFDKNRqWyZ75aLcU|#1Ui=LMF6n4qS^Zi5*K<~HekZ)VO3%9n5e`_&|w)y zzFLF?Ml#xLAP8qbBOWupdcOskc?_$gQ{E+1!!%|O$F~T;k&R&SNZ=6lRje&oeH$eq z!H*}c`F7QAbhi!qMr7*+3E=?km1}ZDy9|L;=Yv_yGoA!P>kgYn7z`|F@9n7a@qcOlzbF%JcO$aGhD!}i+F&h+>}6b)F;c~W|eaL&5_2{6}depw-+6mf)c z>)147R)*36d7sMkpaV?}08FDb3Q7z{S0qroD{G2y+ru3mB}%2E1Xf5X!lWVY&~I1a z&nV!7%cJ)*U;7W8Lt){~!<24iy?;zMj_5y;Ge)^i${hy(aWzqsrK3_Fjg}H3Gtmp_ zslRwad6$g|67L0}rDrawG#~j)P1cw)W1hZ(tnxelU-P)XBE$Y^>+07o{Pef3R<)c7 znVY>+)LZw|^)=kTocdr;+rAVR@+zfs--SEUz#e8Ak2;K)Z*q#@a&&s2QK|cJ#2A<; zQ0f$4L}M7Vbf!Q!Ve99LVN0qSzIIT>5CJ7f&7;T|6MIF2QM;pZ<&0X#e@QkOOP@5M!I4PommUvpmc zkF+f93Mn926XA`MZdk#wgb8*CSn`|kz97BXY60^o;Qx{I-H%ki@BjC)SN7g=?7cUK z?7fSSviHg;;wY~WB72i;vO-pzBzuO)-ek{g=lgtrKmWk_;oSFqJ+JF}EFaNF&k6FO zmI{vgVuN3^mcFQl87njSbZdNPEy9<-yIiu)PtMQ# z@)N^)CbzV>@Rx@dbLwAnc@X|HBtV5%w*9!K8~%KmZ7HTkV+G;EFK0>G+$HSk!CL>Sxo z*;I_^NNy@N@^ly&0+G$gGt4K6XhDoUDO`9kl3#dLLYYf{}w6np3)~R44tuv zs8EUB@}*2jlo86s$fKXQvWLP&62;2xV{O=W2A=)XwZ6G3*PTT;dF=Ff++66HKgOi8 z9(`WICneTZ-toMJSz#Q@nJ8Q6-hW?t>mHY%MjG%{*AwN$!_k>1xtOpVY7pLot??{E z`seP2)(LVk`dcNxWreSuE7MidpG4!9oa#v!E>?1xK)izndUWDCaoFt-c?Pa|(_ia> zvxvx2*Xf|CDTsb&%D)dM*L49%HovH z`f>j5%PAAi7w%H99Lux9heNOMgvzO~fh)hg84$2e<26e(PkSF@uG`fOExYJ$Z5;Y` zA|fjg-`$nqTIeV&P7^D!G;HYweiCOZzGl`jo5m*NxH}%|w#kGJ5t~ObR~?@;@mXMo zox^ude7A1V)`@&Zn82&SxNZ^?ieC(A40dQDdEm=J2e@sC*8)20f6L=Rh(BZWRGeAe z3D@P9lfX3Ox3ukToTQlZrUq% zSbUgIL;@0Uv){2b5`+J5E$&ge5$RGrW^Q`7yk9?!UU3T3HuH;-xJ=z{fAzV`NX(aW zgG~@YH6SULPAkNy63)w?*j0~)LaA-q$rmU|kpf3JIZ`YSMQ8)wnqn=n*W`=+3Sis% z`axq#v&Z@cA9x2xV`{h584b7XE*ZJ% zV1XiDz)hc#c}@;}@^NAdVZZJ3$BklO$HB_jAmrm#3JtFVA!4c4uyTBZ$;v`l5+i$_DRGOPMA1#_eNyT)7ZNl8xabeu&3^>Yu3`< zA_Yn0cg=F{z6JXV?gUH7#uN2=ffouGAQ{U!lc9(N4;1XUXZHKhdxaN{h+%?IE-*^; zvj`$Izf?Pba4vB^6CX^&-w)Q_WUUsKSBF>jJl78`>fh3LU5WH>*Pg%a_CGq73!}D2 zVfK}?OIlJqq>8QBr1B66e}i(eb;8Zq%&L-F4tsu69PQf-KtO;K7O2_7)JwN7pNG=Ep0WA!@d3O5{jLAe6yFyKpEPU7W0f;xyZn7s zlM$Ub(ydFp_=!JN1p%LCV@J2{%(E#>N>wLEU)-z0vScuA8Y4nYxCpFP!uY2K*zuzvBA$@kosOkvpx?@H zbIp_MA6H)df<2vPSXYy1mVHK@?sp^2rd@UBK`b}E5OeTQx|2bG<^#Q#yI$8P zpZvf3%sbh)fBQG5@L|&x-ZmAgclV>;WC^;G2RoF=FWbcQTU>?K)me~pZx7$_idU-K zuXN%eZxD(LMs+g|&LO!!EA-XPuk7a+vD4fn(0_Grtxc^+%lb0xzoCGWgO@sYq-*a7 z_OV~HjyRm(S&^4>UA=G&^}|(oST&eYigyDQJyqr_bSzvsw{y?40wBkWpbh^6NTNgV z&wZ@^PR>lTmt!N6e2Xx9N~AT^pXyCRyV0LHK}mb-7ruGXBTE~RztICKFZ!h)pSA@F zV3!kcX9NoDV@m(6?_prA)6R3UipCAnUtFUW4=yRRIZ z&GW(J{k*$C116XYVvLT&8d=@v{a^?lU#8dyJ<|Vj%`Uj@{E^`t%P@P=g+$7-)b8zn z8_L(K#y*JnHyHO|bPqYgAEe81M-!+G{*-xnE7*5OLCUK2kIw|0LX{jK#S#z8)D2Ve znY@1kp#3VC9oQyeI|Lx`H;c)D?b?Cn9y3==UD$mMFvN9FZhSx-Cp7#28ga^9l;EDPri?f-pWSN}xjm523`&Qo*h3r3ozy*4FU zz>NpE3Bi`jJwUJLh9d0k-TV=HUIc>$oNPrd;=#u@7-?T$l>LJ^e|VlhiIPKSA_jXZKA zf3_?E6ISIVMtp|>?Y`Woz^UhJJl2?$W$$ZN^E{{rYX&YuHr?m8jXp}k65mXxuQa7l z%BQAC{jzu-f@y^%R6CG-KJP?NNlKFQ^!<2`Q%_%S$@VWu;cG<%>1% zx*f-d^|`HS$LlZ&44TIbUBhi+{<4;|V@z_N-|BF{D2vEElt(KTlEXgl@s&HBaI{O^ zM&{{3tYOrxD%BFf-n-*`PV~51)H@tNU}t%|qBzIcL}rGhQI#xbvzEkpRBq#!nr-x{ z@HDT4pSa_{qd}=<-|7h$*L1#h+Tq0D*bA=;$lDVU)BhI`xj4N0odMwvzNIFJZZQj` zeR|fy%+5<03-6u_@1>Renf>3Isaigxl`nR}l*nVAPHIS}`^76IaNzv7%}~BgljiP_ zqYSQQ-&PhaOd-9X_rA|6A4q4wRYSJ&4D)wb1=gY(!*<9y=j>N3n!~ypc5YLO5R|cr~}xR9aiH zUD{+5_VvtF;u6=_$FFuKY7r9dSN{-OA3IbZ@eZnX^0ox5UW$vnb#^yM;uA{NWyKm1 ziKyVOx{q&KTtA$moVy)FfF~k)%F83z8Re z5(6tf6CWml1?~+Zi*W%?Lo5*pa$UF4MsLQ#34|jI8x8-Uz3RQ%RBx%f{Y(769QMN> z&Jz#lR24s!$1Qe4t0?341shgDT$&$IbQIh%Yu_9lxEiog;sjGdMa}^oaIV;Q07%7D zQR>Gp@b!&tSd?!l#qNF!`0zQNgSRo6u>xa`;|bsQ-E{a3Vd9NY^4lMT7{((6c*rQt zk<2oz=XmB=4ZM9AZe=ha%wIs@t(Ay&z;7Z1uRkT;kn}?yg2Ib0n3T+W&es&z=2T&b zF=Ud^$Vm!Acm!Zm?}~m0g33Eh4g7*6xDY z+)%G92up1djaWoEJkp;&e+rNJAw#3VPsasOK-fqL*ohr+%9q1v!gA~gh?orU4YB@Y z1ULi|fKl$|Fg&pILO2c}!*stuw1&JU>_fJCv{Lu5($KE!FKo+)uu(Fuo~3!0Z;cPk zWj~2)|M>vF?UirLp(>@Q`S^8T)8^4ii?J7tz5GGFLtn1p@4)740uaIhain0aWvfMF zhsF-lZES?=3Rf+4he1LIu`(Yg3ktuS(w#7{mKr|q-}E*5736XxAD`mP6Ot(;ljn2O z>u`Q=nZ)sq{fxG{6lK^wga5f)NiD@FpjD)OmhMZ=yz||Tj&4Nnz(%K(VG@JZzjKZw z_6#D{kGwvrp=M8W5T5>x9XHtXu-efp(R|Vbz399(Io$m2AlLj=1u%#bXZup`E2@(o0r7XoW1gB zk;YsA6upy|;_D{6Lmd6J&Jw1F4+WfZIX@ ze{LEV$=gjEfVyAvPrZVgl#qassOO#U=Rkuw7xE%mIWJD38M!o7q7Q#H0}ulGPoV1@ zlsoXv*axoZ83%w|!09sE{0oo}pF(JYiF8*0LC&{<5l%oPc=F>&GlQVipC{Vr1bQ}^ zPJcxBhj&_m_Lc?7_b;!@$PDzcRY&z%Eox7m;IeSYeKf)KOYYrJ^)I!|pTScW@}i2| z>^Baaq4ohw4lmOh@Ifj)c*Fz)@au}in`*7O#3nYMvEGoLNqArL{^d4|N?`G~ERkV? zbP0Qm;3Xy_u_ZbzFtn1l{L7E@J#B z_2enWqr4&jMq;x%74Fp(P5O>=vX;^^Nf9HGv9_XuhcH)i-;$qO%5#zj*Zr70?1)kF zQljV3#$fzqzTnSZ9Pmm7keY?Wy+%R|k_<}k&)C90V9nm+UU=J)j~Okc`})VH|F0k}hgnzylZfxL4CtDK3ho5u6v41JBn;OJw91 zxy&4??ULSL08j0el1yJ6#RCf%h=d>ov8eFEX<9%zivt2|C_Bw2^i z=b8FvAr4rh^YfSkhp=)`plyR zY~NyCXcZ!HOHytaQeG?CFLq?4c(Vi2TShvwWxldXuJvERoR}fA$sNMih>H!Mi3pA0 zFDZvmwK@MwbZw+%*czwSVQ@DRtKi(qi*4n*B1jsg9S!meTGe|M7}nq3^#jx*B;S>? z&d&0VsTw-%)UsuZs2vKvE%^6|JdvL#gA4oH^Qh3YwM9PVy!}**iTw&KBelmE%vkpL zW|YrwpDXcY8*F`+a>K;py*CGu8V0J~(47|8y)#L)DpMDsSl;!#fn`_BZ4kB672jJ+ zC$xn<5>e4~uy+%F1yE?Y9f0!I0SF!CR}*o6_0Y*Ofr^+47e6KG3BF{*U&Hr9FL!%< zZ(r(WAbTmtxxy^5tvNO)??xla9@S`Z!h@P{7Bv6P61~+YhH`l#V}p!?+p5c}H!JYs z-wm@fOK6fa!({f5i$xnVcqXlHtRlBLDqkfk3`cppfy_NH}~Xe*A^Jpb33v8tb3e~W$6J_zA-X+VCGWy@RQVre1AaX z&MqifR{fTqV;-vPiQU?XaO7&<&koLS?ock@E8W*vof78~!8*5%Imhaw`{Jv8&Fv0-?739)DxU^+~87$@hd($^y+-?tl_n%L- z)6)u!KlucEjA=`Yc7N`=qy>FMuX*J;e9RSkuT#VW2PiLO2cx(uRKK_Bi>(<_)z@~* zj(x;g8<8&K@+#(MO0m%+ZJN)S`cTG3Mf=cjv8 zwjGJL>M6Jg!zy!PV&ncv@8ibc=k}hOBLjNubuhsSX5cuH%qRC#m6tTRJy4{aXEX4> zY$qUj-uwB6kEyziJCE&q7hL}_ zi>V;c>LA~m+_n|4mSa8AGqjOo`IVhmlFc04xIzu_Q+8V>YpYA;T0FnZf2(+Tc&n}d z={)Aa45OCgfS7(|gyQOhh6#UyXZ;M$6yQc}&t%axBd}R?Fb88G9R-M!wC~7o|UEM!Wtli=E-E8N#9`6qLFcaFWT=Y`fbUkhU&tfw zrzhjguh~2GpNDIyh*{#0+HN+QP)|MZ-7TxP8g9;6A(Uq2fg$p#QtNzW+gcbAfAjy| zjyqo1{Cpm2vYaV&4}?I9p-(0N@zqjQZmI>>kx1<_jg>9$Y_E!y8I#%s9l&{j<+WAq z$6U50&#NUWAZN_qC*^d0@76&bArqgrrtt0V*3xfy?a{v2hpZpwSBoB4R(Z)^H|G4? zO@jZt$0zY#xA{($bYA8fY03wx^m<;HxINW+IhTj$o|CXPa>CNxObYUzj`V(?j zh*Z{kZ0c>=E`pmv_@VjZ3 z*K)zW?A_YTzv13v&nKUx?}xNM(smdf(`9byUz0FqNFhOho~8FZJs(D0Fb6;6C@mac zbXAM5E0@#vQjOa@g_RJs%g|<}k|v+p>=#APfe(i1Lpl1j9!XDAbCvk{g8~rKHV6z^eaEpv-ZAxYjpMD0RhIG z|1y+i0)-~J{4=b2k29E<8AB@h&97<` zaq9pNnjw+e(#`n~n#(z({eOy5>YfV3RDUU~*RbApbq$;qIC8U4+_WP8mMySmg{(M% zZB6#8H=0HVfhPQSh*y*^lNsK;?Q#*D#$fy;@|~8uCn7jg^4>Yt=kSht7%1gb=%@N2 z*X$dlT*cLG+8h}8Si-xN?#TK2HCeZ2zQZVYLHw+F&}Xu+(2B#6lM#nl-@t_4JNSl zl}S(U&tTqWJ;X7OU^Fdm(g_+gGSS~?I+0#;r|A!_7C!XRy`;U>?vAkPvsZhF352oX zMzy0EyYD!|9Q(Y|(I<5OQ(HdZ~hn`NdDR~x^2_9jdtxGFA&Qq$NZ>P@(~q?dx{F`a1Qt-{j@;z zh1@~8^$-k|CCir24e?G!IgZ4+-;(%pNVFF0`N>XIANY02!-z8mR+MvGX~(8sKUis| z!7ccHaKirY(G;~z;Z0QS_Q;)oaksN|(`HCjxM5`8ap>Rs5EW3q$(7E%A80wseY{eaMkRAcl(H zJD?^{r?dE8&5wY&^NA=2L~tQ9pe(_InbE(8-IeV;+`9}dA$IUGvzd&}ke2E^YcXt@ zp1v=+dBgATvFZOyoY*tN`5vOsP}^xSqyG9FgGsRu`|>qmMQ)Al4_&A1#1CAG%F5>DgSn2zH9 z_yF2G|Ed)9r97?~vgfQwi+{I;&2WQ2kWGSI`bcRrIcmGm!6@kgK8eoaJ!~237aJR8 zl5O{#oS0yTt-Eq@2VeHnB`^U0KDTM7MibMibH^2&AfEjC4O>q5qP0Z17LBVhCYc#I z;ai0Sz&5C8(ynU|!M{x@@}xY|PNt1x>BlUAm&qpqr5Pu?Q1ksKG#QeIdx95&a9OEa z(R_R&4Ay5#&Chn}`I~m`F%#NV?w+z_;ZvK)j1Ua>+_(FjQKAJ{Pbx5~CVi{EQF>=% z;Tfg!qI9q^iVk7p63PaX?lJFXJXo}O_s7kn)R&T_E~n7L3L7c!|1F4+M7ByA`Amhj z+r>xY&|}>l#jR9bD%-N(nab#U%J#Ja^=5@KPV-Fn;Y7)YCLuyI2@zgr|I^FjVt}FN z1!&0EdC#r{Aj_v-#o1Hh0`9U&fXdEZ@MRdtKkiD5xFF&!$qYRCb6Vi?eNa^HF$&~Ie4^Pvy@CuEzj$ z2;V1}Gkb0qoW7iG%rif=-10hmvop)v=T5JQHK?NH3W>BJSAr(+MV2gp)W-xQlOM+7 z%9*9=wmfeY+5JP$W*;j@if*@wfA6&|RP7yCn1+T-KEnQ2alQ3B$SjIVS4w$!^T=L#au5e$C z$}^@{9V$I!p@`XDWx%4M$7?bect1V&v4vfN24#+6_WAedmSsX0A*6#q7t4YpLN+~o zuFuQ}J}|oL^Vywa90S=hBEVV6hSM`ywSRbcr6bua?LEH zXwW6mzE*znC*NOr$h`WpZ8n96ZDgc`;d+{Hd#wLasrJhxv(Puy#=G_N%f)jgm>_$A z>Nt3Yvt6}S!{edG*|#v`f9Qx;!$x}*uEwGjkA$u({*7oQ4vJX&p;Xey{uy@3StOqG z%7PkgfFg)q$G}L%nl|b%VwILUm&|5I52xDw#si~^4s9t|4;B|MMTlg2w4Q_0^!H{J zn#|mu`dfNl;>HY{u5l?F=b2L7R34bpv-ayxf&fa;Dsg=^MC*)4zm$9}-zIYQ9+vz2 z?8i32FMj{!<^QS$8~pl@W|V-ISg5!8=Xk#BsQvp7CY-#L(p=#`pK&Mv=fb0$wSVhFmMyxP_(P{Z%FC2&sG=>LQmf_4f$eD^ z4Cwl9SwWd^l@9|mC`CSn!MPH-{r=MErrkC3H>sUCIyaU|;(|8>AOIgc5(2h4aCF1* z0X;V6ar+CdPlR~sT#K!AVCl^Jew*8FSa0sa{Q!@y;};Da{)^f(loNx2c%e2=pWKW!UZSFl{*F27ObJ1UoSsM{Fj_=~Y^wmO@cJYe0@|yL zQV`~$f-6Q0Sk72k=|D0XvfroEaEI22-yu@8J}MHjL5g=v!@Bqmab!3^4OWHRE-g50 zIT&0G=0KGa16{AViQn4CJ(N&tEzb)L-q#uWh(npl`=dM>Ri~Af-(_7MZOpnT7p8-E+jzug)KE33O6r?{J;^K3&_8>^4Bto7^UYlKAsz;1du%8f|L;~V%WAN z&DXK}-{VzIYD6XqHN>qTCmQg`s_gd)9P`E6g>kSo47;3`31smxFj#$-OTStVp9jD& zXW^0qXeq7A;VH&{8{$yJfZsDXY%G%Va(w%bLrQ)MCv5PvzdsujmQ^`PE-=zc{tXkr zRRcDa2CiWkz?Jl(33q?nv*F>T2=tGAgtB9_4y>4)_aJp$J!vCdHKwhGn?tjnTu|$h z+D2s)%Q83ro0#hQcI*l z(s4W31%{}I`|%v025FaAObMDS$UVg=W?ZcbCn=G6>s}9W^CxL-`2eyejtjP6*l`q| z3{W2m$zjMd4mM1ts5qD`&yp1HU9AQ=y7rfIP>XnFH~Z-Wi#dz*{R(l{cQx(H?1XE& zY$pC0Kg<519|Pn?sr{*RHw=*|Uqer&g@}FTBm0D&z@YbB)`;E+gYmuhX3C+2=~>#t z&BnKIR4=XVm>vuZfAP&v!F%9Q6*J1roJ74#Z$<)n4hWHSs-(UM3Z#$~Cm2Stfs18-lVWAJ5p?>+l z_GsE132G&+-28cr4`X_%P4nmf+P+-Qd)Ngk(yA3wR`10R7TRoTk_in-6BF>ixDbY? zxff|1kW3Erco?^jn`C8lJkuhOacl1(hDq;W4;oHBD|qcE!?%i8t(4hyWbCl=NmjbF zK-XaMTV0|0<3F$cn%n~e=@qzKV5mu2+dW2G=BM!pN#;J%s$11F zaq$Qw$e;iFhK>UT6}2&d@K4);0TZZndH+iSNG*vc-|17}Wp5EbmGyE3FVD-SM?V?A ztLciDU8acMY{}XdF-foo3GlH?$U4mp0Kc4_VK z^xs5G7_#FBTwkk~@l8<~0L(=Cm+{f@ai=GGgU;{w>eCp&^izC0FMjEN4EMnjLvy>4 zS67?Mn`Tm9p;7gI)0g!_MVpTj#kMmHh``|=0OP)6dJhA`>@5UJrZCj3DmdH?#08w# zkRIm)q(?5#w)PJT!V_WDxoeH>D41iE=y-iDTu`e=9x8vcSn%CX{PkE@2bUrj?PrCN zY)Y8_wR`Mg$QZu#d=9ixh72zPP;ndbP^}9XLP9=f@R&a5Ck>OPD$o?oEBZ{GJv=pW zKwG6nFous~2r_*%!)3(=wu-q}8hvyX6BVv4zgQH1<=RwdEyksPyeRvxCF(|DJI7|~ z+-=nn5@W3-qKxLRv*UWd)0Z$_mfmRhBu7Q2gdcwBdT{r|ku%g#Vv~gTVLlFMWAqXO zq-cGY$526CW;DDz-**WVev>$#r@c+hwDq!ZeL`_vOt{~I+aN{3!!>QU+L|wIXDjpJ z!D>_ToKLd}9g&x|70LU61MIQTOr#pJ9o9rHn ztjj1*exFgJ-`LvB#_RFlMAI~PquI24Q>```r6RnBH<;2Q>RG4gSl<#-vU zdg4N~!+v6``&2-fEuW@YB}ncuv5;eMCuYW-xAnPZlkDm#!Z~S)0`@fNk$bJ_i+jTo zqIwsNn)0R76UlQ=^z}M(%GHrTp5UWGirK@zm1m58zGC?c@fy06 zm~J7C14O02n+Ex(*D$0>o%9pP%t|A%(@y;*7NEQj5v5lg3QDKx@(J3{ZqO(57)@hFiPpU64Fwe;gn5gh7{NfWu2G?fs^?lvN)c08(3N zO0WSAC1BKoT6GP8GV+ii;!DF&;b0H#!iUyMIADPrT-?V10kk0h;ARvc6PJ!1_HGwV zxccn@DD!dA0m2t!0F?v@JHA2$DpF7bB^Ovi3szBmk_h|{YN<#Xbp-OOv5l*0zxgu7 z%V!e`0iFK^mJI5d!%!oMkiI>HIrr-A$N7Vmpg3^SgZcB92imf z+LEQPGM~8Y{mn2 zfmgXZZ_PiIAq;c2*{+WeOJy_cep4S+H`6E%Snp#q;;QLN&n3Xsc9RMl9t-%CV1Nb8 zn(w{zgi0%d26_mbXY+mxcDv#$_U0Pp{hqsCnU#N4CW)I0s;68Ij!fV8y&*6|!amAtK#*QYIUYa`xSGi^GN;&YNUZXF9qDUvBQ#;wM%!@gH_AMd{gCmHpnORopF#M^ z!j6~q0VTMhh$lGnqJ3C`Vh^WCk#+Lzbb9k}`7+<2$X5vWn`LJQhce5Rm5XLyrOq3v zmIt>^=2iaDUUeP)=tY;~NUSE}v>&zz4cff&b``b)fe*U6Zfce>io_ns#t0--jot#} z$)5%9Ku1=q1qFIRGT~-cxsM(xmy$y@c<=waA@0#U_|;?jGZhtQ{POlqF(BpWIbCPSc%LYg9Sj7jp!y7O?A`fE^%Bpib=~Z&z2M`D4=`?6 zFu;t%zc6<|+EMzem$U>Xpaumo`(*Ro)dGZ~^3RG4<_CnZBs zRJgKvcj8f3ylTdo*JPA6m@aVW_aZ)$3dV+kQI!fM6LCvhto?(byeIFcTK_dj465Cj zccC8t+EBNw-jfU2;NfDaT+Pzjyz+#QVcrC<)J2bh_pWN#UzlHqUMy$(mC2_B7rm8X z2Evkf(J9OgXvQawp@ba?7bRtkcZJauiOZ#l!cTv*Z&7SjO{o16(N8V(BqA>+1i72< zme1Td=hynYTTk6LWm%u_un z%yI1NJ5z?--sbj23{bO`Cn!yfHO{+bhBC@ej=!EYN?JZ!QDjuQ>MYetyb-~9MjzoO z!s4Q}re~af=|2p^(2}+Ztvaf(DmgH{dKn#pbJr*+Mqf1&Tb}yUalVLnN8%L`NH{Pu z0E#5^q8h1kmIrnfF`F;iOfJ;dxqs6 zNS?(7>n@PVagJgyJ>XVH0FU?q9AFN$Th;WYFh>SD?+nJChQymGt>eW62D73rYaH-i z3I?EY8mWc@(%m{pF~R5G@uhb+k+>j*76h4LgOmG^k7R_lcGeeoN-VpplkP8#2c3U4 zv&Ed$p3`sJvC30S;C95I_mbi0Br;NOZmB|oOz%gjTmWeXc{f^q=7Vgi7Ab+aT=ck6 zv}>~Wj=g*qJX+koQCziBz5KO5p=RwPC)`RCFb(@!gtY|_f%XfMP<&M(vP29!p_nnP zaE?al_vZ=P*=2LMNKDeOM+*0&=Y9*q2SQk{w!gLuK;9Pr$=V4z{hXF5uC(ERbr%CD zJiLYL2Mb)&c9z4(42I19ns4eN<1n_>+8yteY4Nwfvfg~+8APh$ejkx_vbv2g^5l9b zNt+nTPFFt`-c~;I2^;RC3qIj)7h4bM|A)j()QW77!H~Oak`nzl!?wso+P$iIoQy{E zPRS@zg*8Tl^ph`U51y(FkGakNcV8y%A4fr@f zv=GOo3f7I*@J|0y13BeL#Ko>Eslya4hBH<0`1^(mp z<|>S(a&V%@L+1Z;$kkP%a%rcW5mTIQpNfIuTvacW)aQQNQ_@e#lf826Y{e!QR$t*& zS&Nucdt~A)Yu`5g4I;j*W!|}MLhK9APPNZp2;XCAK7ZU=mOhc_YIo10uyMw@fOY1+ z`&6@kG4`Ps9$4w?Fw(k$9%~_13K4iYdxCNC28Jwu`~)JRX^&h(f>f1zK>A}!JPB}= zzy!Zp^!T1!^#Mc`BocfIwO4n!Z-H%%1mK2af`C0!jQ0J26$RmiBO=rqKF{X3BV@&g z0W>qY)^2|@09(c*NcCSQ0YK8Lfdd=>B|;<9aKLn2FgWys!e_)fA_N?{f7Y(bEw%jB z&`esXwQ#6_CA`3wAC%M3fJeSE4J)~#B*vQ)rF&K^OzMOYax<}q{EQ1Koc=%NB4tAe z*&Aoi{{8yX;JFD!JkCjpmfWAN!g-8RRc!Az;rBvko9QCN$Ff;D1FfosvHn^MbKE&~ z!Vfy_Y8}Rk1~obkvNQ=n*6bd6p!idgE#1I5F@?w8-{;N=C#iypagn7g$sjj}NYIlkIgN37inaL>$-H=F&4sN0 zrekG$*rReHT`^)KrgWDsCr1j1eH{E8`FNw>dADyjtY%4EK4QjPZD)T%aDb&Cs~-S4 zIZ<0U|M_0Z7B?hoQvOpKCoa@J_^(;;z(bDROKzF)9KO0Fj(^T!FHQR_;0@R~pgrvo zyOxhzz@xx2WF1#=a%qIpjG#$@F-^!~WnjTT>*|2dhUNXaE<~B5eiA4k47h25*a&*P zupQ|qSYQnrF@>;*UQYX~I7SE%E4zP-i}`H2Bqq4%r>b)uyXT+&t!m0;)Q!>rcIL4) zWz7+NkBpTB+`+X@ym*ODD^ibnIr{$D7p5bKeu&z zWg^Q!NRE#k(&~JNt%E)a@ff*t->ygU5V54-I9glmi35b+$a3~tmX3?!p3%yFBVoA zS&9w-$uIQUUTEDT@6-X7g0~aDb&3d|%Q>cp3&Lz7{Ids=Q*@U5FM9DUm^Xd(D$pWJ?VRk@?c4C&X4lMC?4p5ouHR)cb}e5>X^EC7{4OlqOqGF zP>J(h^vn5EEs(F6OJ&WIHSO`QeXvFd!X2SkKAAD*?dJ&H6e)sN+lo_v?8kD+i?rtp zhD10|EsasD$h_B|X)C_r0PW9ONUi_v_w#qLVy0h+4L6x7-$Ob<^D;sy??|M5^My<| zWC6C+Bc3;K5Gn#twP<7VwZ#@UuvAU{q<3Tydiq3hwLhK^=m$_!&|8wF?N0j%p4&%u zn$bo4H$ZItjgQ|}&$!A(Bdqf8vebn#E^RHEm6faxHI;LF7+IeDFPzjLv7nSI-C3$Y1v1`HTUn#gz@G3%zGaLs^qDzEtLw+uo zLjU`NobOQQ7u1-sj)5=X-WlyUR zfQ4oC)f^>e@+o-#&6L2Yb6K4Q%CU;@T0yeHlc;ja<-dVNS@%t4a(0omnEfWR`&v&j zHXAXEd5?a{<6KmYxVPq*B0Yq=l$@oLvfM{4%Fc;E*(pV8Pf}78|Fs&PGxp}k zrT6}?4gxC=qA?*37gDJ9_<}mkQ5O zf@IUWmI52X-MPO?>_MuP4Uas&6Q|hWc$Z^VrP{I52_K%dH{8^kAL1lpQgCsHFil3z>11KN~vN8>G>1P zKC%n??>t*fO?6-hEh(-LmK$Y3XfZGXEnmxI*ktc1H_@>a&;L7uu-`Wr$iMKL`VoWK z9-T}(gUA0xwWl8Z*qlh5+*7Q*2)X}JcEk6FTbQ0FFZp+W3Gu&E?Qp{TF}Nokeo&}| z5d0{N6LR_nt$YC%Tb>nuR!vfZ7&)C4RP14UZ*U^gaXnd!VnQBM*^y8ZAp2El+ zS$wbD;rNaZT_^g=VB3lIBV%&Ul_>gb`r78V-^RwWR0ivC9ZIWsctA#!{?-{V$w?=^ zPVF(<3`Jc3RRqt63a;9Z6}G4rjg`V};xv@iR@Ih}W}GZ}9)T2G7SY5q8$oSfvN~RK zC$?>Tyz%xYux*bXHZ1{b2d+)<%`NrsWSyjkPo3JWu73#vlby*!XVr}Lv~?eAGCNui zyGLH>g&07ZH~ukC&-!D#RKLnl)+0hZ<*aaCD!*;UC$Wi|SIET}@^twR{Hb z)L>TneBlZ&4?5R+yi3?XFY$j|q$-JSS1#HRh!JUk4Tvh|mEB;?ZkM|d??)voli$Vt zRo2<@_(rVb4jQ^3EI8m7-bjcmNcb8W@^GOwjmjZhP-~^yxy~Ne;c7E`djC(^m#n9? zv&?KW3H9iSOMO0=j@W8u?^6|u65S^`g>mf)tp#q>yU7;{z7_oaqy%VB=wlN2o(vZ01!cW ze@%S0L|os>fUQb}0W+{l@#|I@em$%SzYR;=d}dOF$xX%(OVsq_uDcdvsg&Km%!7M03N`SAi>rL8w=~u!gJRD&qu5HXH0k(!eB`cqN8L(>ty^n7-$YyZ!N+F zRla26E-<*7KM~Zjh7hurHUe$!l@MM4zH{(CtfyeWKz5!2MCRHP7h5hxXn6@S@9B%f zEIFN97hpbs)WPzrSol)L?XLSD4+WER(dKA4;ua1c6>UBFlo&)ZfDtHsz^}x^R-p_@ zUk{#REajL3?pgGlK+G2`S0}9P$Jd0P65BLV1_MROo9f4=es=m{$F$7XpvNw=5(7gM zrUEwL`br_KSF!Qjw5aJf()$k-SqRNPEgf{>SLkNPzDhOWH54tBV}L)d-qQbQy43xj&pP$4 z>*34Dy%5f~uX@-y?|gOJ*;fR*sI)k-+&vM%jLXYS4jZiLByRC8&#SNl;j$^5luss^ zz1LK+ADaGRvVR<0oVLJ(Kg>8gFmEVlnmlV>sSyFllu*CfM2~d{k}kKmNIelZQL+gtgqIn;pmCm>rJt- z6^nF#frjP}yda5rXZLC`kHuUcn89aYIh-SUE{e|i@BTO|Xq#f}-a+W{b|E$5VbXY^Ia8d-W?-^z5=a@{#|QP#ZhIyXvm(rHf$$IraD9RSirEFpxZsVDBaazCym*hj zTs5~P1y5H}qH4++foY8fxgPYzJF6i0a&z!~iy2u}Gdy zWg!Xdzu%;>VhdR%P~xAr3?JnF_Z~ZO>dF8U^nR|RefhS5h8l*qJJlswV7agOsGk16 zutDWBT$az*j97|$J%iM#YOh^!V`TTjuQ}h1dsJSPKDf`ZnO66x_Hog92(Oa!)sck2 z$voM;(^BG=DT(;ECkPgkJ>OVU>h0mf|JT`9MMe3A-M>SJN=YN2bc0GrBMp+$tw?u+ z!@v*{(nv`SEsfL=0z(Q)2?#@XHx4!AH^008)qkz;dvBhL_ndQa)>&trXFq%ICoUDX zWWRb(7yb6&2|~Y+f}Dssx_sz-Uhmf1!VMCnYi+z@-mI{?wQMfNaiM8S$Qpb#(?G?k zx~9;ys5kG+x?S6k(9&i8{aPOjkbBNf{tNGZ*xep zO+benYWfNPrl*zI@Rv^HXmi405~I58!(1noli?tjzM-b|(Y@nWl2Oej`-UiH7bjIu z43R(0$st%S-g3pKH{&PSy_n@Z^&HzJFPJUkpOIr#?kfYr%U=zT(q_S)3$R3|FP|BP zuF`F}HBH1vs z!gH@%ZcAOSd0hn`Ov>33i8jZ=@>Rxq`xxkpurgD><=tg%MEJhyq4af=!MwM7NjnG#dJS5=04&y0- z%`IG8MtQ86Y@dGHieO7(3%9DYI}Yy)gx>pi#|C_Fw+tvI=%xHvnd2`^yiBtGeU$6I z_)6~j*!vrf>L%3T$BQYI`Ck&r%r^V)Lmy%NkiNqsDbykEJR5mJm~1ZgBgi*{^p!rK zQoVp79;vjNS@-6LzHMHc@4kj+XY!!Eh`6Q}sA=h8Me8Hi*29DI5-zmm+W2o2NtfjW zX}#poyggTp(7fS*ODc-;nY`AA#-bdf@vz_2slqB@4T8(yec2k>YTRVbDjE}+n0-2< zWS>-k+ufapJX}zRt!az_gr1*SkQrcfo(a@83!brW2O`eDa3`wN)Sg7v%dlI(Q$( zLxp-<*l|vqFr_6A@P&cY{Y5RVt4Kg1&Nc=E$GAeiq}Wp7Ig!A$99DB@%f#4&0eCM( zMG5yyxEynm`{K!kV}_~JuNFU2u%B`7S>Ap42ZI7vg$+1VM&u__NFRNkKgh}Fr)h2V zxC<9Afk-X^wO*k;wI)<2jkKZ?2%!~W(@#wJ#m{Q{d;Qzs60#JXgoTp)-N{YKB7{}6_?_w? zYywq1R&U??Q$OSNcYkVx0HAZmvDi2HK#`62JQCA#mh~9u^cT8Y+@AWaSp$DcvnKBr zlJ`s&yk9_u0+{sTfcS>`=IWM1!`~zRimr9DM;DZp@&Q`$PqhC%V@Ac6)Jqvw79^(2>@_Sos@>?w*O(8Nx6m zHYGKv1Ek3`b=f3Ijc%dsU?@$5R{$e(Fd%~{(l(IBYzJ75e{$uVcVly)syf@;Rs3hU z25B18i@f>bAyFG(i&JORKWSk|F=A4IQzM}o#K>-Hkq6Svcpf==;1X$ z8_f>_Msa}oCdT#reJg+M_w|IMFCSjt?XkeD+Yjzujqt>Eb@cj%#5`a{8+`ym7FM~X zlwGGFyWke&1oE$E9TZRXO>T6D;OkYB@=*D;R$}vsPxXWOh zDMan>QG5UBb%7t+B~liG{~Sh=7Yj^&)pm4S>jRfh{NA|4ABXFf+g!evO_XwF_q)^reX4YShU6toA5~ms-&x}QNNC1k2WHcS6o!J1tWpCJiUznQm9iPulI0elHYP%p z>tbBcruvR)bnFn;ahdH+<8{+cB$&d6o3Wvo~@3B5CkDG$&RFw619gda6l$A>d@na~?e zhYmb)iMyIl*mFK5x)+CAo4jiu)mN?AxMxyz<^Sn@G0VBjm{rkdGAY0`anvU2t{~+L zrvCon;gw$Ih2kO^5&(>&F~&-TH?6$A_^jxo^t_ZG20ZK<-N_K$OY4r`?`^`2^rZxb z7c0(l7SQxH$*TZ1Ps8l7_`ghkbdAFqnxZ4}J_i{#O}@gKm!KsWgf^;f(p2r-P=m-c z+Gi3u;;{xJ1b&=48Cb~hN+>CC8!@8x4u0xi}h*$?)eU|tP7c4LV9`-7algvUs-zWc2k;-rEB^0ZIc zz0pvGX!2h9M?Z-&9!3m^kYIzly1NfGM^CM7eM9;z$bacdYh3-UYW4cI<$G~}Yi%mc z6x6-AbGU=_hM6|)>cQ`zKkfImGE<@)D4|n7fS=m#k@M9|-IKihz#ohgbf#99CiS~( zEk_VkhvWPfTUe>vFR+{pszFxgMN4VT8qM{LHB^q*DifHmvAokd`3K{#iZ!&jb23KK zJ<+~+J$)igSy-uC@Y({aAE~PvTH3o1xM*z0L;*}oD**ek!L=xvuiPQf zE~%4~-qesF8!To~khW^HAj92V`Pq3CRydjq@!;mc;>4}gp`tB)O}l#G3BA0h8N={~ z)n1@kVI&Ru{^OR6t`If|Fw}vnu_=6WuQb#LoN-5r+@1mNBb>R~=~{7Qv(Titomxh~ zg9D+3bcJdCYuGb@eK!kHD7^2_JU^V{G1zz|_sKVlx;~xGkvL%E6$=CJNNmb7%3h?y z_HZyvInA_sujwfL-nJ!B#X8GQ-kaV|Tx2gD|OJr6oz1_@GpnJA8X|Ki8 z^#w~u-0_k7GiS!p{@I9&FDD^PXwzClVI22-oA(1lkv%LWpu~41WYA;2 zX ziXg&kW>`!oJ25+?)f3OwOYd89=p{x2QKfQv@+!{)4)RluTZpow#jlJNT-CEh%_XcA zo`2U+pwgV|cUSwTmN>Xv0tkNW_r~(%P859Q8UXKAD%kGwkgFlHn6`Hek0MeU&w!)# zW{;(*CwQCHrGMopir@ex^2c+XEy^$P*xHVqgrOS4)7wlN{_l!*3k@EzeQuNj3epF^YpcC6Q+Khz)9lZ$&Q)n;8A2S(vF5et0+!`h8pGhE#@Oh|Np^E<-z9=00C*q_!yUYY*6YEJR`O6-n0R3?2b@!TaG zCY-QU-r;^yAc!iKIEy*ZTp>S#Z-6At_co2v__G$CUx^A60b~H`n|foS>;O|JiDocO z@#;pf>5zvS;Y8tY;P7*)7_?MAIpdYAt7-z?#d1>-;!we&Ny`GKG+;_oJ2ax&TP3%z zlx7tlwVPq79KiH?2YD))7spqCH{EZ35M$MGvH3bmw}p=Y*8SCeg<+M3Y&Y`V)Y9bG zNkROd+J)c>-1BA?EhTxJRi@0p_QjF@(Ybo`mIS4v{rn)()m2qUHs@&gv0TH7x`&D+ zDHFDyVP`I_`GW-Y*EN|>CIvj!LDLP1ErLHU!%m%y`lRcL;zBO#2;a z_MJkM%wqhpcOFMph`!w)Mj{kE31UWj>i-y5N$G>8gmH&hJ7Fs1R*u(yMah6LbI|;EOSY0S z*Q^ZFv97vzOGChih{ip=1#$+2jAzK=Z#zEDt_3<{C?l^xnpOC+JG(W0d#I~7ETECW z;9a#;x~=YbmIywUJ(aI-Rhrs8PR-~^pRf4TqjI<|-O#)ZDh65Wfx$KscM@mQALjV_ zBdDdwFPAaeXYXa3M@3zUQ;VWZ9aDwRz6_*LfCg|ouLkCoH*X?XDHsPB&V+sXd({8% zRtYJS^vf~KHJS|FI_)Pv>Wc5U*)VY&xBLunLJH~phKntsbYsrDrI!)#qV|^_v`4UL zd&twRojp2*2Y;-sP3fP3mM%-a_x6;1hJIxwSWKE{*!me@j&W%j@E$npPGwxgcyRu; zRxcpjIe-e?e$VeFVX;p+Ql&#*Ld>4Cgmv-AQMB7XRv_O`JgSaQ}r~P)1fk2qGuh;oFAy!RoB$!tInG2jp`y_gB9fE2KLpq<8O; z1CXT!Vc6tj&K2>&$gw(~J?>cn^DTMvIV&U|iOSymJS2Bdg+D@|>EGM{#KD|jNus*m zVu#Of(obeO;(G3{08jo}{Lv6StUsaVfyq>BfMtC-Uqjflk(og0bSFm_s3JjW!Y!*n z+BE!BVsM97t@(%|I4C_FS%{(mk2IxB@1W0-LxGb%!RcE~9`O|$@U(0FD;s2jQ>$iU zY;HpU68z32Oz_rqqoh>O2HF+^zS4ae5=!upe48}$JZE)%I@@|a9&T}7c$-JgUYyc& z*2Uyq-Q)J&v}bKxO#OORCM80fls#2&B>l;ui8AzE#o_OTrcF)Gq}FmOe3PGWV^o7@ z8axBmFGY=_i++L+w{iJgr8;IDot8J`YDrF9Wk#V1_CK*3XKQ$@6$@^u|3RfZx;oc~ zUUm0imq}40wzEB}N?B)Pxz5{XBsiyqAif)eX ztfGQ_<}|YR6-k{rrq0FsXt+wI-wwJ&FxuJAKBfRZ!S!+g@DFx!QG@Rb?}r~_o< zaqG}zjk1jR-FMV=)G_LfK<73S8RHiN_8AcGP)iz;{aJoJpi0{%OkKZGdR-!~&xS&iR~`ZwgnV1!L0OTJFK!CFq5FMS=#~E7DvJ1AGb0Hwk1a8KSA$J8)u!m zT2W8mX+HyX66|Yo9lxdbZ{oVVt$ep5UBRN7D@ln0S^XwL>64crFs{tBxOW1AISO4GS_KCyb=BA{uu za$}oT$@xlPmzjHvCVcXO+OMdu$!Y8%EG(-VMd_NqR?;f?@wA@4#dNeW$wD!0%y$C* z5ZQt%cE%pe>t2m{T?6EiR=LFS$u0`mrYI5u363!&zTqp7 zCykcXdv?~xbas{~Njw}aw-^<26YFVQlEDoSIpAz2uaK$+lnSV{UFw|F6>cGw1`YUX z--K3vFej+x7`H&O`TvHqzP8rMY)P>Q9d;Z=4REHzSY}Y~-VI5*(u2E8bPfaK#Ygr(JJKb0s@%=RYmeMz1+ezY$r z@`0`}u5i=EdnU(sVX)SEpPWoSSiS5pqin*`MF92GmLGx?dDXV$0eRnDc@P+ZKyC`P z4STMOI(Sc7Vg!CdFrD$$QiBoRN((Jt%w>)3^_@vi=A1A(J~7Z}kE>b5-- z{XW?3*W#k{r{fn*H^~shVWn5Q-iHOWvk+`WQE#bDpG(iC7B3BC6a+CnxL)qC=HAo% zRxFrh(Ar+Mgm0{r?i4yY+bJ@ItR1zhm}`QR8g$(?Lp}#8_t(z&&0UE_qR_j3b3$mF z?xQjpw{{M17&4*Bqq6HlxJLOVyJ|_oX+jd1V{IHIIsLN%GS%5HE}Ax5zODpW{t&o6S~FhDbx8gQDOanBxjlTg zHBn8RE8xppzq5OUeNBDq;|Nl-w2mA~6SaYss&CXi}FrTWTrb6{=tI+=e{(u0o literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..1f6bb290 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_baseline_email_24.xml b/app/src/main/res/drawable/ic_baseline_email_24.xml new file mode 100644 index 00000000..2c852177 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_email_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..07d5da9c --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_alter_dialog_setview_bark.xml b/app/src/main/res/layout/activity_alter_dialog_setview_bark.xml new file mode 100644 index 00000000..81120bf3 --- /dev/null +++ b/app/src/main/res/layout/activity_alter_dialog_setview_bark.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +