From d534565deafc72a2e897d66b2e77034a975881bb Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Mon, 20 Oct 2014 01:09:50 +0200 Subject: [PATCH] WeatherInformation: using Android Studio --- Android/WeatherInformation/AndroidManifest.xml | 123 ----- Android/WeatherInformation/app/build.gradle | 28 + .../app/libs/jackson-core-2.3.3.jar | Bin 0 -> 199621 bytes Android/WeatherInformation/app/lint.xml | 3 + .../exampletdd/test/JPOSWeatherParserTest.java | 35 ++ .../test/WeatherInformationActivityUnitTest.java | 44 ++ .../androidTest/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 9397 bytes .../androidTest/res/drawable-ldpi/ic_launcher.png | Bin 0 -> 2729 bytes .../androidTest/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 5237 bytes .../androidTest/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 14383 bytes .../app/src/androidTest/res/values/strings.xml | 6 + .../app/src/main/AndroidManifest.xml | 123 +++++ .../java/de/example/exampletdd/MapActivity.java | 408 +++++++++++++++ .../exampletdd/NotificationIntentService.java | 234 +++++++++ .../de/example/exampletdd/SpecificActivity.java | 37 ++ .../exampletdd/WeatherInformationBootReceiver.java | 57 +++ .../WeatherInformationPreferencesActivity.java | 27 + .../de/example/exampletdd/WeatherTabsActivity.java | 182 +++++++ .../de/example/exampletdd/WidgetIntentService.java | 304 +++++++++++ .../de/example/exampletdd/dummy/DummyContent.java | 55 ++ .../exampletdd/fragment/ErrorDialogFragment.java | 45 ++ .../fragment/ProgressDialogFragment.java | 54 ++ .../fragment/current/CurrentFragment.java | 528 +++++++++++++++++++ .../fragment/map/MapButtonsFragment.java | 31 ++ .../fragment/map/MapProgressFragment.java | 165 ++++++ .../fragment/overview/OverviewAdapter.java | 108 ++++ .../fragment/overview/OverviewEntry.java | 41 ++ .../fragment/overview/OverviewFragment.java | 410 +++++++++++++++ .../WeatherInformationPreferencesFragment.java | 354 +++++++++++++ .../fragment/specific/SpecificFragment.java | 357 +++++++++++++ .../de/example/exampletdd/httpclient/Consts.java | 51 ++ .../example/exampletdd/httpclient/ContentType.java | 248 +++++++++ .../exampletdd/httpclient/CustomHTTPClient.java | 126 +++++ .../example/exampletdd/model/DatabaseQueries.java | 44 ++ .../example/exampletdd/model/WeatherLocation.java | 89 ++++ .../exampletdd/model/WeatherLocationContract.java | 32 ++ .../exampletdd/model/WeatherLocationDbHelper.java | 43 ++ .../exampletdd/model/WeatherLocationDbQueries.java | 176 +++++++ .../exampletdd/model/currentweather/Clouds.java | 22 + .../exampletdd/model/currentweather/Coord.java | 30 ++ .../exampletdd/model/currentweather/Current.java | 139 +++++ .../exampletdd/model/currentweather/Main.java | 73 +++ .../exampletdd/model/currentweather/Rain.java | 23 + .../exampletdd/model/currentweather/Snow.java | 23 + .../exampletdd/model/currentweather/Sys.java | 46 ++ .../exampletdd/model/currentweather/Weather.java | 45 ++ .../exampletdd/model/currentweather/Wind.java | 30 ++ .../exampletdd/model/forecastweather/City.java | 53 ++ .../exampletdd/model/forecastweather/Coord.java | 30 ++ .../exampletdd/model/forecastweather/Forecast.java | 62 +++ .../exampletdd/model/forecastweather/List.java | 93 ++++ .../exampletdd/model/forecastweather/Temp.java | 60 +++ .../exampletdd/model/forecastweather/Weather.java | 45 ++ .../de/example/exampletdd/parser/IJPOSParser.java | 17 + .../exampletdd/parser/JPOSWeatherParser.java | 405 +++++++++++++++ .../de/example/exampletdd/service/IconsList.java | 143 ++++++ .../exampletdd/service/PermanentStorage.java | 140 +++++ .../example/exampletdd/service/ServiceParser.java | 64 +++ .../example/exampletdd/widget/WidgetConfigure.java | 88 ++++ .../exampletdd/widget/WidgetPreferences.java | 172 +++++++ .../example/exampletdd/widget/WidgetProvider.java | 64 +++ .../main/res/anim/weather_map_enter_progress.xml | 8 + .../main/res/anim/weather_map_exit_progress.xml | 8 + .../res/drawable-hdpi/ic_action_import_export.png | Bin 0 -> 457 bytes .../src/main/res/drawable-hdpi/ic_action_map.png | Bin 0 -> 802 bytes .../src/main/res/drawable-hdpi/ic_action_place.png | Bin 0 -> 555 bytes .../main/res/drawable-hdpi/ic_action_refresh.png | Bin 0 -> 663 bytes .../main/res/drawable-hdpi/ic_action_search.png | Bin 0 -> 650 bytes .../main/res/drawable-hdpi/ic_action_settings.png | Bin 0 -> 807 bytes .../app/src/main/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 7658 bytes .../drawable-hdpi/ic_menu_settings_holo_light.png | Bin 0 -> 1227 bytes .../app/src/main/res/drawable-hdpi/thermometer.png | Bin 0 -> 2002 bytes .../src/main/res/drawable-hdpi/weather_clear.png | Bin 0 -> 2832 bytes .../main/res/drawable-hdpi/weather_clear_night.png | Bin 0 -> 4538 bytes .../main/res/drawable-hdpi/weather_few_clouds.png | Bin 0 -> 3208 bytes .../res/drawable-hdpi/weather_few_clouds_night.png | Bin 0 -> 4273 bytes .../app/src/main/res/drawable-hdpi/weather_fog.png | Bin 0 -> 3474 bytes .../main/res/drawable-hdpi/weather_overcast.png | Bin 0 -> 1409 bytes .../res/drawable-hdpi/weather_severe_alert.png | Bin 0 -> 2068 bytes .../src/main/res/drawable-hdpi/weather_showers.png | Bin 0 -> 3060 bytes .../drawable-hdpi/weather_showers_scattered.png | Bin 0 -> 3424 bytes .../src/main/res/drawable-hdpi/weather_snow.png | Bin 0 -> 3814 bytes .../src/main/res/drawable-hdpi/weather_storm.png | Bin 0 -> 2864 bytes .../res/drawable-mdpi/ic_action_import_export.png | Bin 0 -> 325 bytes .../src/main/res/drawable-mdpi/ic_action_map.png | Bin 0 -> 604 bytes .../src/main/res/drawable-mdpi/ic_action_place.png | Bin 0 -> 393 bytes .../main/res/drawable-mdpi/ic_action_refresh.png | Bin 0 -> 508 bytes .../main/res/drawable-mdpi/ic_action_search.png | Bin 0 -> 449 bytes .../main/res/drawable-mdpi/ic_action_settings.png | Bin 0 -> 550 bytes .../app/src/main/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 3777 bytes .../app/src/main/res/drawable-mdpi/thermometer.png | Bin 0 -> 1059 bytes .../src/main/res/drawable-mdpi/weather_clear.png | Bin 0 -> 1690 bytes .../main/res/drawable-mdpi/weather_clear_night.png | Bin 0 -> 2436 bytes .../main/res/drawable-mdpi/weather_few_clouds.png | Bin 0 -> 1927 bytes .../res/drawable-mdpi/weather_few_clouds_night.png | Bin 0 -> 2402 bytes .../app/src/main/res/drawable-mdpi/weather_fog.png | Bin 0 -> 2193 bytes .../main/res/drawable-mdpi/weather_overcast.png | Bin 0 -> 955 bytes .../res/drawable-mdpi/weather_severe_alert.png | Bin 0 -> 1448 bytes .../src/main/res/drawable-mdpi/weather_showers.png | Bin 0 -> 1861 bytes .../drawable-mdpi/weather_showers_scattered.png | Bin 0 -> 2053 bytes .../src/main/res/drawable-mdpi/weather_snow.png | Bin 0 -> 2247 bytes .../src/main/res/drawable-mdpi/weather_storm.png | Bin 0 -> 1921 bytes .../res/drawable-xhdpi/ic_action_import_export.png | Bin 0 -> 580 bytes .../src/main/res/drawable-xhdpi/ic_action_map.png | Bin 0 -> 1022 bytes .../main/res/drawable-xhdpi/ic_action_place.png | Bin 0 -> 698 bytes .../main/res/drawable-xhdpi/ic_action_refresh.png | Bin 0 -> 895 bytes .../main/res/drawable-xhdpi/ic_action_search.png | Bin 0 -> 827 bytes .../main/res/drawable-xhdpi/ic_action_settings.png | Bin 0 -> 1124 bytes .../src/main/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 12516 bytes .../src/main/res/drawable-xhdpi/thermometer.png | Bin 0 -> 2357 bytes .../src/main/res/drawable-xhdpi/weather_clear.png | Bin 0 -> 3443 bytes .../res/drawable-xhdpi/weather_clear_night.png | Bin 0 -> 5860 bytes .../main/res/drawable-xhdpi/weather_few_clouds.png | Bin 0 -> 3868 bytes .../drawable-xhdpi/weather_few_clouds_night.png | Bin 0 -> 5374 bytes .../src/main/res/drawable-xhdpi/weather_fog.png | Bin 0 -> 3031 bytes .../main/res/drawable-xhdpi/weather_overcast.png | Bin 0 -> 1740 bytes .../res/drawable-xhdpi/weather_severe_alert.png | Bin 0 -> 2299 bytes .../main/res/drawable-xhdpi/weather_showers.png | Bin 0 -> 3999 bytes .../drawable-xhdpi/weather_showers_scattered.png | Bin 0 -> 3992 bytes .../src/main/res/drawable-xhdpi/weather_snow.png | Bin 0 -> 4911 bytes .../src/main/res/drawable-xhdpi/weather_storm.png | Bin 0 -> 3396 bytes .../drawable-xxhdpi/ic_action_import_export.png | Bin 0 -> 758 bytes .../src/main/res/drawable-xxhdpi/ic_action_map.png | Bin 0 -> 1529 bytes .../main/res/drawable-xxhdpi/ic_action_place.png | Bin 0 -> 958 bytes .../main/res/drawable-xxhdpi/ic_action_refresh.png | Bin 0 -> 1239 bytes .../main/res/drawable-xxhdpi/ic_action_search.png | Bin 0 -> 1152 bytes .../res/drawable-xxhdpi/ic_action_settings.png | Bin 0 -> 1661 bytes .../src/main/res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 24777 bytes .../src/main/res/drawable-xxhdpi/thermometer.png | Bin 0 -> 3272 bytes .../src/main/res/drawable-xxhdpi/weather_clear.png | Bin 0 -> 3497 bytes .../res/drawable-xxhdpi/weather_clear_night.png | Bin 0 -> 6122 bytes .../res/drawable-xxhdpi/weather_few_clouds.png | Bin 0 -> 3949 bytes .../drawable-xxhdpi/weather_few_clouds_night.png | Bin 0 -> 5732 bytes .../src/main/res/drawable-xxhdpi/weather_fog.png | Bin 0 -> 3554 bytes .../main/res/drawable-xxhdpi/weather_overcast.png | Bin 0 -> 1724 bytes .../res/drawable-xxhdpi/weather_severe_alert.png | Bin 0 -> 2231 bytes .../main/res/drawable-xxhdpi/weather_showers.png | Bin 0 -> 3991 bytes .../drawable-xxhdpi/weather_showers_scattered.png | Bin 0 -> 4381 bytes .../src/main/res/drawable-xxhdpi/weather_snow.png | Bin 0 -> 5016 bytes .../src/main/res/drawable-xxhdpi/weather_storm.png | Bin 0 -> 3473 bytes .../app/src/main/res/layout-large/weather_main.xml | 22 + .../app/src/main/res/layout/appwidget.xml | 95 ++++ .../src/main/res/layout/appwidget_configure.xml | 55 ++ .../app/src/main/res/layout/appwidget_error.xml | 52 ++ .../app/src/main/res/layout/fragment_pager.xml | 14 + .../app/src/main/res/layout/notification.xml | 105 ++++ .../main/res/layout/weather_current_fragment.xml | 562 +++++++++++++++++++++ .../main/res/layout/weather_main_entry_list.xml | 96 ++++ .../app/src/main/res/layout/weather_map.xml | 84 +++ .../src/main/res/layout/weather_map_buttons.xml | 42 ++ .../src/main/res/layout/weather_map_progress.xml | 18 + .../app/src/main/res/layout/weather_specific.xml | 19 + .../main/res/layout/weather_specific_fragment.xml | 496 ++++++++++++++++++ .../app/src/main/res/menu/main.xml | 11 + .../app/src/main/res/menu/weather_main_menu.xml | 30 ++ .../app/src/main/res/values-v11/styles.xml | 11 + .../app/src/main/res/values-v14/dimens.xml | 7 + .../app/src/main/res/values-v14/styles.xml | 12 + .../app/src/main/res/values-w820dp/dimens.xml | 10 + .../app/src/main/res/values/arrays.xml | 71 +++ .../app/src/main/res/values/dimens.xml | 7 + .../app/src/main/res/values/strings.xml | 86 ++++ .../app/src/main/res/values/styles.xml | 24 + .../app/src/main/res/xml/appwidget_preferences.xml | 26 + .../app/src/main/res/xml/appwidget_provider.xml | 13 + .../app/src/main/res/xml/weather_preferences.xml | 66 +++ Android/WeatherInformation/build.gradle | 15 + Android/WeatherInformation/gen/.gitignore | 3 - .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 49896 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + Android/WeatherInformation/gradlew | 164 ++++++ Android/WeatherInformation/gradlew.bat | 90 ++++ Android/WeatherInformation/ic_launcher-web.png | Bin 51394 -> 0 bytes Android/WeatherInformation/import-summary.txt | 83 +++ .../WeatherInformation/libs/android-support-v4.jar | Bin 758727 -> 0 bytes .../WeatherInformation/libs/jackson-core-2.3.3.jar | Bin 199621 -> 0 bytes Android/WeatherInformation/lint.xml | 3 - Android/WeatherInformation/proguard-project.txt | 37 -- Android/WeatherInformation/project.properties | 16 - .../res/anim/weather_map_enter_progress.xml | 8 - .../res/anim/weather_map_exit_progress.xml | 8 - .../res/drawable-hdpi/ic_action_import_export.png | Bin 457 -> 0 bytes .../res/drawable-hdpi/ic_action_map.png | Bin 802 -> 0 bytes .../res/drawable-hdpi/ic_action_place.png | Bin 555 -> 0 bytes .../res/drawable-hdpi/ic_action_refresh.png | Bin 663 -> 0 bytes .../res/drawable-hdpi/ic_action_search.png | Bin 650 -> 0 bytes .../res/drawable-hdpi/ic_action_settings.png | Bin 807 -> 0 bytes .../res/drawable-hdpi/ic_launcher.png | Bin 7658 -> 0 bytes .../drawable-hdpi/ic_menu_settings_holo_light.png | Bin 1227 -> 0 bytes .../res/drawable-hdpi/thermometer.png | Bin 2002 -> 0 bytes .../res/drawable-hdpi/weather_clear.png | Bin 2832 -> 0 bytes .../res/drawable-hdpi/weather_clear_night.png | Bin 4538 -> 0 bytes .../res/drawable-hdpi/weather_few_clouds.png | Bin 3208 -> 0 bytes .../res/drawable-hdpi/weather_few_clouds_night.png | Bin 4273 -> 0 bytes .../res/drawable-hdpi/weather_fog.png | Bin 3474 -> 0 bytes .../res/drawable-hdpi/weather_overcast.png | Bin 1409 -> 0 bytes .../res/drawable-hdpi/weather_severe_alert.png | Bin 2068 -> 0 bytes .../res/drawable-hdpi/weather_showers.png | Bin 3060 -> 0 bytes .../drawable-hdpi/weather_showers_scattered.png | Bin 3424 -> 0 bytes .../res/drawable-hdpi/weather_snow.png | Bin 3814 -> 0 bytes .../res/drawable-hdpi/weather_storm.png | Bin 2864 -> 0 bytes .../res/drawable-mdpi/ic_action_import_export.png | Bin 325 -> 0 bytes .../res/drawable-mdpi/ic_action_map.png | Bin 604 -> 0 bytes .../res/drawable-mdpi/ic_action_place.png | Bin 393 -> 0 bytes .../res/drawable-mdpi/ic_action_refresh.png | Bin 508 -> 0 bytes .../res/drawable-mdpi/ic_action_search.png | Bin 449 -> 0 bytes .../res/drawable-mdpi/ic_action_settings.png | Bin 550 -> 0 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 3777 -> 0 bytes .../res/drawable-mdpi/thermometer.png | Bin 1059 -> 0 bytes .../res/drawable-mdpi/weather_clear.png | Bin 1690 -> 0 bytes .../res/drawable-mdpi/weather_clear_night.png | Bin 2436 -> 0 bytes .../res/drawable-mdpi/weather_few_clouds.png | Bin 1927 -> 0 bytes .../res/drawable-mdpi/weather_few_clouds_night.png | Bin 2402 -> 0 bytes .../res/drawable-mdpi/weather_fog.png | Bin 2193 -> 0 bytes .../res/drawable-mdpi/weather_overcast.png | Bin 955 -> 0 bytes .../res/drawable-mdpi/weather_severe_alert.png | Bin 1448 -> 0 bytes .../res/drawable-mdpi/weather_showers.png | Bin 1861 -> 0 bytes .../drawable-mdpi/weather_showers_scattered.png | Bin 2053 -> 0 bytes .../res/drawable-mdpi/weather_snow.png | Bin 2247 -> 0 bytes .../res/drawable-mdpi/weather_storm.png | Bin 1921 -> 0 bytes .../res/drawable-xhdpi/ic_action_import_export.png | Bin 580 -> 0 bytes .../res/drawable-xhdpi/ic_action_map.png | Bin 1022 -> 0 bytes .../res/drawable-xhdpi/ic_action_place.png | Bin 698 -> 0 bytes .../res/drawable-xhdpi/ic_action_refresh.png | Bin 895 -> 0 bytes .../res/drawable-xhdpi/ic_action_search.png | Bin 827 -> 0 bytes .../res/drawable-xhdpi/ic_action_settings.png | Bin 1124 -> 0 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 12516 -> 0 bytes .../res/drawable-xhdpi/thermometer.png | Bin 2357 -> 0 bytes .../res/drawable-xhdpi/weather_clear.png | Bin 3443 -> 0 bytes .../res/drawable-xhdpi/weather_clear_night.png | Bin 5860 -> 0 bytes .../res/drawable-xhdpi/weather_few_clouds.png | Bin 3868 -> 0 bytes .../drawable-xhdpi/weather_few_clouds_night.png | Bin 5374 -> 0 bytes .../res/drawable-xhdpi/weather_fog.png | Bin 3031 -> 0 bytes .../res/drawable-xhdpi/weather_overcast.png | Bin 1740 -> 0 bytes .../res/drawable-xhdpi/weather_severe_alert.png | Bin 2299 -> 0 bytes .../res/drawable-xhdpi/weather_showers.png | Bin 3999 -> 0 bytes .../drawable-xhdpi/weather_showers_scattered.png | Bin 3992 -> 0 bytes .../res/drawable-xhdpi/weather_snow.png | Bin 4911 -> 0 bytes .../res/drawable-xhdpi/weather_storm.png | Bin 3396 -> 0 bytes .../drawable-xxhdpi/ic_action_import_export.png | Bin 758 -> 0 bytes .../res/drawable-xxhdpi/ic_action_map.png | Bin 1529 -> 0 bytes .../res/drawable-xxhdpi/ic_action_place.png | Bin 958 -> 0 bytes .../res/drawable-xxhdpi/ic_action_refresh.png | Bin 1239 -> 0 bytes .../res/drawable-xxhdpi/ic_action_search.png | Bin 1152 -> 0 bytes .../res/drawable-xxhdpi/ic_action_settings.png | Bin 1661 -> 0 bytes .../res/drawable-xxhdpi/ic_launcher.png | Bin 24777 -> 0 bytes .../res/drawable-xxhdpi/thermometer.png | Bin 3272 -> 0 bytes .../res/drawable-xxhdpi/weather_clear.png | Bin 3497 -> 0 bytes .../res/drawable-xxhdpi/weather_clear_night.png | Bin 6122 -> 0 bytes .../res/drawable-xxhdpi/weather_few_clouds.png | Bin 3949 -> 0 bytes .../drawable-xxhdpi/weather_few_clouds_night.png | Bin 5732 -> 0 bytes .../res/drawable-xxhdpi/weather_fog.png | Bin 3554 -> 0 bytes .../res/drawable-xxhdpi/weather_overcast.png | Bin 1724 -> 0 bytes .../res/drawable-xxhdpi/weather_severe_alert.png | Bin 2231 -> 0 bytes .../res/drawable-xxhdpi/weather_showers.png | Bin 3991 -> 0 bytes .../drawable-xxhdpi/weather_showers_scattered.png | Bin 4381 -> 0 bytes .../res/drawable-xxhdpi/weather_snow.png | Bin 5016 -> 0 bytes .../res/drawable-xxhdpi/weather_storm.png | Bin 3473 -> 0 bytes .../res/layout-large/weather_main.xml | 22 - .../WeatherInformation/res/layout/appwidget.xml | 95 ---- .../res/layout/appwidget_configure.xml | 55 -- .../res/layout/appwidget_error.xml | 52 -- .../res/layout/fragment_pager.xml | 14 - .../WeatherInformation/res/layout/notification.xml | 105 ---- .../res/layout/weather_current_fragment.xml | 562 --------------------- .../res/layout/weather_main_entry_list.xml | 96 ---- .../WeatherInformation/res/layout/weather_map.xml | 84 --- .../res/layout/weather_map_buttons.xml | 42 -- .../res/layout/weather_map_progress.xml | 18 - .../res/layout/weather_specific.xml | 19 - .../res/layout/weather_specific_fragment.xml | 496 ------------------ Android/WeatherInformation/res/menu/main.xml | 11 - .../res/menu/weather_main_menu.xml | 30 -- .../WeatherInformation/res/values-v11/styles.xml | 11 - .../WeatherInformation/res/values-v14/dimens.xml | 7 - .../WeatherInformation/res/values-v14/styles.xml | 12 - .../res/values-w820dp/dimens.xml | 10 - Android/WeatherInformation/res/values/arrays.xml | 71 --- Android/WeatherInformation/res/values/dimens.xml | 7 - Android/WeatherInformation/res/values/strings.xml | 86 ---- Android/WeatherInformation/res/values/styles.xml | 24 - .../res/xml/appwidget_preferences.xml | 26 - .../res/xml/appwidget_provider.xml | 13 - .../res/xml/weather_preferences.xml | 66 --- Android/WeatherInformation/settings.gradle | 1 + .../src/de/example/exampletdd/MapActivity.java | 408 --------------- .../exampletdd/NotificationIntentService.java | 234 --------- .../de/example/exampletdd/SpecificActivity.java | 37 -- .../exampletdd/WeatherInformationBootReceiver.java | 57 --- .../WeatherInformationPreferencesActivity.java | 27 - .../de/example/exampletdd/WeatherTabsActivity.java | 182 ------- .../de/example/exampletdd/WidgetIntentService.java | 304 ----------- .../de/example/exampletdd/dummy/DummyContent.java | 55 -- .../exampletdd/fragment/ErrorDialogFragment.java | 45 -- .../fragment/ProgressDialogFragment.java | 54 -- .../fragment/current/CurrentFragment.java | 528 ------------------- .../fragment/map/MapButtonsFragment.java | 31 -- .../fragment/map/MapProgressFragment.java | 165 ------ .../fragment/overview/OverviewAdapter.java | 108 ---- .../fragment/overview/OverviewEntry.java | 41 -- .../fragment/overview/OverviewFragment.java | 410 --------------- .../WeatherInformationPreferencesFragment.java | 354 ------------- .../fragment/specific/SpecificFragment.java | 357 ------------- .../de/example/exampletdd/httpclient/Consts.java | 51 -- .../example/exampletdd/httpclient/ContentType.java | 248 --------- .../exampletdd/httpclient/CustomHTTPClient.java | 126 ----- .../example/exampletdd/model/DatabaseQueries.java | 44 -- .../example/exampletdd/model/WeatherLocation.java | 89 ---- .../exampletdd/model/WeatherLocationContract.java | 32 -- .../exampletdd/model/WeatherLocationDbHelper.java | 43 -- .../exampletdd/model/WeatherLocationDbQueries.java | 176 ------- .../exampletdd/model/currentweather/Clouds.java | 22 - .../exampletdd/model/currentweather/Coord.java | 30 -- .../exampletdd/model/currentweather/Current.java | 139 ----- .../exampletdd/model/currentweather/Main.java | 73 --- .../exampletdd/model/currentweather/Rain.java | 23 - .../exampletdd/model/currentweather/Snow.java | 23 - .../exampletdd/model/currentweather/Sys.java | 46 -- .../exampletdd/model/currentweather/Weather.java | 45 -- .../exampletdd/model/currentweather/Wind.java | 30 -- .../exampletdd/model/forecastweather/City.java | 53 -- .../exampletdd/model/forecastweather/Coord.java | 30 -- .../exampletdd/model/forecastweather/Forecast.java | 62 --- .../exampletdd/model/forecastweather/List.java | 93 ---- .../exampletdd/model/forecastweather/Temp.java | 60 --- .../exampletdd/model/forecastweather/Weather.java | 45 -- .../de/example/exampletdd/parser/IJPOSParser.java | 17 - .../exampletdd/parser/JPOSWeatherParser.java | 405 --------------- .../de/example/exampletdd/service/IconsList.java | 143 ------ .../exampletdd/service/PermanentStorage.java | 140 ----- .../example/exampletdd/service/ServiceParser.java | 64 --- .../example/exampletdd/widget/WidgetConfigure.java | 88 ---- .../exampletdd/widget/WidgetPreferences.java | 172 ------- .../example/exampletdd/widget/WidgetProvider.java | 64 --- .../WeatherInformation/tests/AndroidManifest.xml | 19 - .../de/example/exampletdd/test/BuildConfig.java | 6 - .../tests/gen/de/example/exampletdd/test/R.java | 19 - .../WeatherInformation/tests/proguard-project.txt | 20 - .../WeatherInformation/tests/project.properties | 14 - .../tests/res/drawable-hdpi/ic_launcher.png | Bin 9397 -> 0 bytes .../tests/res/drawable-ldpi/ic_launcher.png | Bin 2729 -> 0 bytes .../tests/res/drawable-mdpi/ic_launcher.png | Bin 5237 -> 0 bytes .../tests/res/drawable-xhdpi/ic_launcher.png | Bin 14383 -> 0 bytes .../tests/res/values/strings.xml | 6 - .../exampletdd/test/JPOSWeatherParserTest.java | 35 -- .../test/WeatherInformationActivityUnitTest.java | 44 -- 346 files changed, 8721 insertions(+), 8468 deletions(-) delete mode 100644 Android/WeatherInformation/AndroidManifest.xml create mode 100644 Android/WeatherInformation/app/build.gradle create mode 100644 Android/WeatherInformation/app/libs/jackson-core-2.3.3.jar create mode 100644 Android/WeatherInformation/app/lint.xml create mode 100644 Android/WeatherInformation/app/src/androidTest/java/de/example/exampletdd/test/JPOSWeatherParserTest.java create mode 100644 Android/WeatherInformation/app/src/androidTest/java/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java create mode 100644 Android/WeatherInformation/app/src/androidTest/res/drawable-hdpi/ic_launcher.png create mode 100644 Android/WeatherInformation/app/src/androidTest/res/drawable-ldpi/ic_launcher.png create mode 100644 Android/WeatherInformation/app/src/androidTest/res/drawable-mdpi/ic_launcher.png create mode 100644 Android/WeatherInformation/app/src/androidTest/res/drawable-xhdpi/ic_launcher.png create mode 100644 Android/WeatherInformation/app/src/androidTest/res/values/strings.xml create mode 100644 Android/WeatherInformation/app/src/main/AndroidManifest.xml create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/MapActivity.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/NotificationIntentService.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/SpecificActivity.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherInformationBootReceiver.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherInformationPreferencesActivity.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherTabsActivity.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WidgetIntentService.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/dummy/DummyContent.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/ErrorDialogFragment.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/ProgressDialogFragment.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/current/CurrentFragment.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/map/MapButtonsFragment.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/map/MapProgressFragment.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewAdapter.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewEntry.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewFragment.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/specific/SpecificFragment.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/Consts.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/ContentType.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/CustomHTTPClient.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/DatabaseQueries.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocation.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationContract.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbHelper.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbQueries.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Clouds.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Coord.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Current.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Main.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Rain.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Snow.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Sys.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Weather.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Wind.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/City.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Coord.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Forecast.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/List.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Temp.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Weather.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/parser/IJPOSParser.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/parser/JPOSWeatherParser.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/IconsList.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/PermanentStorage.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/ServiceParser.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetConfigure.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetPreferences.java create mode 100644 Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetProvider.java create mode 100644 Android/WeatherInformation/app/src/main/res/anim/weather_map_enter_progress.xml create mode 100644 Android/WeatherInformation/app/src/main/res/anim/weather_map_exit_progress.xml create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_import_export.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_map.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_place.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_refresh.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_search.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_settings.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_launcher.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_menu_settings_holo_light.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/thermometer.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_clear.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_clear_night.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_few_clouds.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_few_clouds_night.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_fog.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_overcast.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_severe_alert.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_showers.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_showers_scattered.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_snow.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_storm.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_import_export.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_map.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_place.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_refresh.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_search.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_settings.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_launcher.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/thermometer.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_clear.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_clear_night.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_few_clouds.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_few_clouds_night.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_fog.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_overcast.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_severe_alert.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_showers.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_showers_scattered.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_snow.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_storm.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_import_export.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_map.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_place.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_refresh.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_search.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_settings.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_launcher.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/thermometer.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_clear.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_clear_night.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_few_clouds.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_few_clouds_night.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_fog.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_overcast.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_severe_alert.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_showers.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_showers_scattered.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_snow.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_storm.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_import_export.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_map.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_place.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_refresh.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_search.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_settings.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_launcher.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/thermometer.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_clear.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_clear_night.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_few_clouds.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_few_clouds_night.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_fog.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_overcast.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_severe_alert.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_showers.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_showers_scattered.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_snow.png create mode 100644 Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_storm.png create mode 100644 Android/WeatherInformation/app/src/main/res/layout-large/weather_main.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/appwidget.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/appwidget_configure.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/appwidget_error.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/fragment_pager.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/notification.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/weather_current_fragment.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/weather_main_entry_list.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/weather_map.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/weather_map_buttons.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/weather_map_progress.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/weather_specific.xml create mode 100644 Android/WeatherInformation/app/src/main/res/layout/weather_specific_fragment.xml create mode 100644 Android/WeatherInformation/app/src/main/res/menu/main.xml create mode 100644 Android/WeatherInformation/app/src/main/res/menu/weather_main_menu.xml create mode 100644 Android/WeatherInformation/app/src/main/res/values-v11/styles.xml create mode 100644 Android/WeatherInformation/app/src/main/res/values-v14/dimens.xml create mode 100644 Android/WeatherInformation/app/src/main/res/values-v14/styles.xml create mode 100644 Android/WeatherInformation/app/src/main/res/values-w820dp/dimens.xml create mode 100644 Android/WeatherInformation/app/src/main/res/values/arrays.xml create mode 100644 Android/WeatherInformation/app/src/main/res/values/dimens.xml create mode 100644 Android/WeatherInformation/app/src/main/res/values/strings.xml create mode 100644 Android/WeatherInformation/app/src/main/res/values/styles.xml create mode 100644 Android/WeatherInformation/app/src/main/res/xml/appwidget_preferences.xml create mode 100644 Android/WeatherInformation/app/src/main/res/xml/appwidget_provider.xml create mode 100644 Android/WeatherInformation/app/src/main/res/xml/weather_preferences.xml create mode 100644 Android/WeatherInformation/build.gradle delete mode 100644 Android/WeatherInformation/gen/.gitignore create mode 100644 Android/WeatherInformation/gradle/wrapper/gradle-wrapper.jar create mode 100644 Android/WeatherInformation/gradle/wrapper/gradle-wrapper.properties create mode 100755 Android/WeatherInformation/gradlew create mode 100644 Android/WeatherInformation/gradlew.bat delete mode 100644 Android/WeatherInformation/ic_launcher-web.png create mode 100644 Android/WeatherInformation/import-summary.txt delete mode 100644 Android/WeatherInformation/libs/android-support-v4.jar delete mode 100644 Android/WeatherInformation/libs/jackson-core-2.3.3.jar delete mode 100644 Android/WeatherInformation/lint.xml delete mode 100644 Android/WeatherInformation/proguard-project.txt delete mode 100644 Android/WeatherInformation/project.properties delete mode 100644 Android/WeatherInformation/res/anim/weather_map_enter_progress.xml delete mode 100644 Android/WeatherInformation/res/anim/weather_map_exit_progress.xml delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/ic_action_import_export.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/ic_action_map.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/ic_action_place.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/ic_action_refresh.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/ic_action_search.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/ic_action_settings.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/ic_launcher.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/ic_menu_settings_holo_light.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/thermometer.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_clear.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_clear_night.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_few_clouds.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_few_clouds_night.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_fog.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_overcast.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_severe_alert.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_showers.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_showers_scattered.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_snow.png delete mode 100644 Android/WeatherInformation/res/drawable-hdpi/weather_storm.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/ic_action_import_export.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/ic_action_map.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/ic_action_place.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/ic_action_refresh.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/ic_action_search.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/ic_action_settings.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/ic_launcher.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/thermometer.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_clear.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_clear_night.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_few_clouds.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_few_clouds_night.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_fog.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_overcast.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_severe_alert.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_showers.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_showers_scattered.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_snow.png delete mode 100644 Android/WeatherInformation/res/drawable-mdpi/weather_storm.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/ic_action_import_export.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/ic_action_map.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/ic_action_place.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/ic_action_refresh.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/ic_action_search.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/ic_action_settings.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/ic_launcher.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/thermometer.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_clear.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_clear_night.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_few_clouds.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_few_clouds_night.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_fog.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_overcast.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_severe_alert.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_showers.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_showers_scattered.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_snow.png delete mode 100644 Android/WeatherInformation/res/drawable-xhdpi/weather_storm.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/ic_action_import_export.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/ic_action_map.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/ic_action_place.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/ic_action_refresh.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/ic_action_search.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/ic_action_settings.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/ic_launcher.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/thermometer.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_clear.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_clear_night.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_few_clouds.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_few_clouds_night.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_fog.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_overcast.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_severe_alert.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_showers.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_showers_scattered.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_snow.png delete mode 100644 Android/WeatherInformation/res/drawable-xxhdpi/weather_storm.png delete mode 100644 Android/WeatherInformation/res/layout-large/weather_main.xml delete mode 100644 Android/WeatherInformation/res/layout/appwidget.xml delete mode 100644 Android/WeatherInformation/res/layout/appwidget_configure.xml delete mode 100644 Android/WeatherInformation/res/layout/appwidget_error.xml delete mode 100644 Android/WeatherInformation/res/layout/fragment_pager.xml delete mode 100644 Android/WeatherInformation/res/layout/notification.xml delete mode 100644 Android/WeatherInformation/res/layout/weather_current_fragment.xml delete mode 100644 Android/WeatherInformation/res/layout/weather_main_entry_list.xml delete mode 100644 Android/WeatherInformation/res/layout/weather_map.xml delete mode 100644 Android/WeatherInformation/res/layout/weather_map_buttons.xml delete mode 100644 Android/WeatherInformation/res/layout/weather_map_progress.xml delete mode 100644 Android/WeatherInformation/res/layout/weather_specific.xml delete mode 100644 Android/WeatherInformation/res/layout/weather_specific_fragment.xml delete mode 100644 Android/WeatherInformation/res/menu/main.xml delete mode 100644 Android/WeatherInformation/res/menu/weather_main_menu.xml delete mode 100644 Android/WeatherInformation/res/values-v11/styles.xml delete mode 100644 Android/WeatherInformation/res/values-v14/dimens.xml delete mode 100644 Android/WeatherInformation/res/values-v14/styles.xml delete mode 100644 Android/WeatherInformation/res/values-w820dp/dimens.xml delete mode 100644 Android/WeatherInformation/res/values/arrays.xml delete mode 100644 Android/WeatherInformation/res/values/dimens.xml delete mode 100644 Android/WeatherInformation/res/values/strings.xml delete mode 100644 Android/WeatherInformation/res/values/styles.xml delete mode 100644 Android/WeatherInformation/res/xml/appwidget_preferences.xml delete mode 100644 Android/WeatherInformation/res/xml/appwidget_provider.xml delete mode 100644 Android/WeatherInformation/res/xml/weather_preferences.xml create mode 100644 Android/WeatherInformation/settings.gradle delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/MapActivity.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/NotificationIntentService.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/SpecificActivity.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationBootReceiver.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/WeatherInformationPreferencesActivity.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/WeatherTabsActivity.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/WidgetIntentService.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/dummy/DummyContent.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/ErrorDialogFragment.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/ProgressDialogFragment.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/current/CurrentFragment.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/map/MapButtonsFragment.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/map/MapProgressFragment.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/overview/OverviewAdapter.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/overview/OverviewEntry.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/overview/OverviewFragment.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/fragment/specific/SpecificFragment.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/httpclient/Consts.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/httpclient/ContentType.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/httpclient/CustomHTTPClient.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/DatabaseQueries.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/WeatherLocation.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/WeatherLocationContract.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/WeatherLocationDbHelper.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/WeatherLocationDbQueries.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Clouds.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Coord.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Current.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Main.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Rain.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Snow.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Sys.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Weather.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/currentweather/Wind.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/forecastweather/City.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/forecastweather/Coord.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/forecastweather/Forecast.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/forecastweather/List.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/forecastweather/Temp.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/model/forecastweather/Weather.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/parser/IJPOSParser.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/parser/JPOSWeatherParser.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/service/IconsList.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/service/PermanentStorage.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/service/ServiceParser.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/widget/WidgetConfigure.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/widget/WidgetPreferences.java delete mode 100644 Android/WeatherInformation/src/de/example/exampletdd/widget/WidgetProvider.java delete mode 100644 Android/WeatherInformation/tests/AndroidManifest.xml delete mode 100644 Android/WeatherInformation/tests/gen/de/example/exampletdd/test/BuildConfig.java delete mode 100644 Android/WeatherInformation/tests/gen/de/example/exampletdd/test/R.java delete mode 100644 Android/WeatherInformation/tests/proguard-project.txt delete mode 100644 Android/WeatherInformation/tests/project.properties delete mode 100644 Android/WeatherInformation/tests/res/drawable-hdpi/ic_launcher.png delete mode 100644 Android/WeatherInformation/tests/res/drawable-ldpi/ic_launcher.png delete mode 100644 Android/WeatherInformation/tests/res/drawable-mdpi/ic_launcher.png delete mode 100644 Android/WeatherInformation/tests/res/drawable-xhdpi/ic_launcher.png delete mode 100644 Android/WeatherInformation/tests/res/values/strings.xml delete mode 100644 Android/WeatherInformation/tests/src/de/example/exampletdd/test/JPOSWeatherParserTest.java delete mode 100644 Android/WeatherInformation/tests/src/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java diff --git a/Android/WeatherInformation/AndroidManifest.xml b/Android/WeatherInformation/AndroidManifest.xml deleted file mode 100644 index 55771d1..0000000 --- a/Android/WeatherInformation/AndroidManifest.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Android/WeatherInformation/app/build.gradle b/Android/WeatherInformation/app/build.gradle new file mode 100644 index 0000000..2f990f1 --- /dev/null +++ b/Android/WeatherInformation/app/build.gradle @@ -0,0 +1,28 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 18 + buildToolsVersion "20.0.0" + + defaultConfig { + applicationId "de.example.exampletdd" + minSdkVersion 18 + targetSdkVersion 18 + + testApplicationId "de.example.exampletdd.test" + testInstrumentationRunner "android.test.InstrumentationTestRunner" + } + + buildTypes { + release { + runProguard false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +dependencies { + compile 'com.android.support:support-v4:+' + compile 'com.google.android.gms:play-services:+' + compile files('libs/jackson-core-2.3.3.jar') +} diff --git a/Android/WeatherInformation/app/libs/jackson-core-2.3.3.jar b/Android/WeatherInformation/app/libs/jackson-core-2.3.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..8312650173455a58e1b614a5fb72f4b8075f25ed GIT binary patch literal 199621 zcmbrm1CXuFvMAWLZQHhO+qP|Ew{6>Y_io#^ZFBc-y#1eZ=iW2_%subjnJ-pFtXTDB zR%BIXR&psw1B0LdKtMnMEXhWS0Q}2?0ssOaE2<($D=8;NFDob~DJH6{LMJQsH30yS zq9W_O!GO@sJm^1n6deLX!gBKz50E1i$P{YkbP1t}fja&m;S}J%%Sr}E1|w^q_|m=I zhQ9$ReI&&Zmlxu?Ktc!wQL~Dd1QD0Sd*f`Z7?cH1R*svHh>ZHEnzp@N7fnw33A z`s9Au>hbjEh)*=@le(KE0l9@9tDW&4{5!V+C3+|T(|?E$5c)gTOPc2z^S>HB*2^cnDWQHp!+U5a}G2nxqU)q5&A)Bxbd7p;_e zvQeZoRJ)W?%EkNx3PfiLS4IkC{(=?)?v@GEtSz@42 zB~=$`CtUk9+8ns|d*{N*Q_|0QnFdJT31Xc5WC^I-3_yhHcFmwEeX55*dxr-p_yF~1H~l)7Aa?Zb0=xi-Iagy?%KGQm4Y@k+>w{| zDoBGv&>Hh_KmY*%@PYyWDEznF1o?-v{*#-4|GWqe@fWZCf&0hvUw~78V?%^L^ZyAb zBPlE@rz|QP&u9Yd2dK577NT5c1o zMRsxO@#;S8xCv$&S1arD_vXu-T^?23Z@|Ac=tocN#^E3GWdQ$mXaBxI@c+6&a`GyF zwn$Y;)_#)#ru$MI;fxfJscg-(&rLIdR3Ne$^aRJP#FT4=DhiC0{ka#vgap?sk;3n1 z*{cV5oP|CyxJR{qt|3Y*3UL%;n>#vSfqU84q{Ko43~)KDmWFL_S&+^~dTrbvdp>V+e+ zW0ufV5Uo|$B{U%K_y}h0_`sCpP_t zz3Y6d+BruROx$P~Ozh~9F_IZIEcJd?&d+03I){)N;NvOMa(C&{sw9&a5wa&qaP?=( zSiNIvAr#wnW3|bsgsAT4V{&tv9+_k9i6eglj;8mGyDGt^M5Qu`#)Yr z^#A)Z4u1%BaI$wWb#k#Zb*7z=h8kc%0GRWYW1MRd<`=A=3nlo$jo#hIlG8fR0=X!1 zagFNu+haI|7n&5$&_g&LlQK~ggWSz+l<@bwql;&&9_nY}J`QLl(u8tVTutqs-+2KY zb&VcP7Hm&dL%-NGlGD$a97t-pX3|t&*EfR4tsrsa5LC%VfBugT;J;2Ce8E&G z_zz7Q$nPW7kwU3qg5JO36@X+F+nD z5$DzN#h1N-y{`# zDdZ8r$Q)R!TmmGH3g7oZnMKe-Au|1iFGGcZu-OHA-XGszS#DCo2I4SQTwdjFnf(K( zu3|wZC=_}j02e7Gv(B;*kRUk{Cm8fR0C%Sbota-Z{$x{vBxYF3aYC z{pTT?1JXUvZX{4Lb9tBuX{fsw(L|yqs}Vr1xlUHE{+_*Z9Zc}!YAWs#={Xky@JNtL zIc`_-cB77pOwT)A44cly&$gavVH6r#J z<9%#leCto#uePXo=6Qp-24|umSmG3A4Ml{4Vk+KpIiU~S{>dGd(nFP%K zTZdFQCTnvYFN>03>Wiq<%4%d?PZol&aC4R_tFD$zovTRTzT<{4zYWXod4^{ldnq@p zQv!?{%%rlGSaL1CYeD>m)8zv>m`ITuV_TmtnA69)G;C?Ld{>(rHU$)$qEKx3jvU-&Ob-pyFnJ@HZ z8EQSgGPeS+{yx4MR*Fm4&$O$5_M*qcuE-}0|FhCn^>X%rbyib-1O*NvhXfx*OCd)5 z(+2#o%L#bAPBU^v31y6?ul|bhr@PUC8OMu|X_y9?h*_7&#UZMs+A)h^>^o+3?e)qt#vAPw~>LdDmTd26D^s zCl2zBs{AO!6sh&hm5$u^hGR^bFPDec26};}w@&bE0IH0=WgVF2s{nY-DJ+*wQ1cht z;Sj>yPtd=vo&H75YiO`PHaYsgUORuc7Lfk++Hp2@aimZqVTq^%sAp8s>>%+SruE=tePOD#VFHEtm#Nk2qUb^OB# zF?PaiBLB10U*o@S(Z7=e@@MwX(*Kr#zr(=&2h4w3NdF^fwEqY6e;7XhBP`heEtdbS z`85AGKaB3*qY^T7Hf3W`Gjy^vv~!^|wlQ>eF42JYL0Mk@&RgHk7&nt(3lubJtPdJH z5e+D|jtL-v9v~vK0HU%OOoSOfFk`>5BM6E7p;4noD`jhp3W$F`*lI+o&|;z85?A-! zw4r9b+>`h6?CbkRk(kTPoV9I(R@n>YWOmbW>N?B$n$7%cCSo)eP$R& zjQc1%A4vEvM~FCxM0)70qJ!&t4{XG}9{}R0KEpBR7)Vj0Lz{;}bI3-&Q~_fl?}`EB zBev@z+Uly_!aVqD4lo0K)B^0Gdh9FSTCsQgzsuihBX27_79*e-`eML+O#CglKJWZ>X_@rXf;@q@zTSCRRAmw6Nh^v*TQG;rA!8 zASF1s)FeoV9W<~Ol*n`~fL?|}kXB`-(!sXS+(Oh^bha0jw1`4Lb4}^WSlU@>qgkA3 zY&Kg>H^wSJ^9xJk7JVdjnM)&jlS7E&?wgpCEa2J0k;e!C3u?{2pt{?zq+Q>WHDIHh z?SZ&72{1dj4h?jJ6}T*)+@(6`vfy0ST1%4>HQYEuYKi+VNYui)yWVHQ>X9q>t}v}3 z%RwM}4FXpYF&d{JUdlZq9EB!mkhG*L9OqFu5}D~TsC1<6!HjgR{V*b|DCu=CO0a;p zk7hDc(x%$-JPzIGbG8*bW*tEKuAK3(-!64vG9>}?Dss)rpumh+-0=>yKte+ve-s#vhpJ7B!wJlaT{B-XT#7K`G>)be~ zKW;}iGoYF4_8x3Bcn%*SjtGt0Hf_`Icy?k-IVj>B&l}z2;FIkU>^!_^>e6^xb7=My zLc`kuk}6Twt9d2EYNW}XpwdX0frfxonrw0l?)`48-bnpX@GPiY>u%)6@+w}aD>eW% zdt`I7ye|?-k1qHeP6G(F0kJ4g7#!;0I$>@4jzYMPX{gv_nLydKp4=U_xOQL+`1L&P zS>%RgUp?7Htj&k~6S<9gxWt(r`;6sXNry5qd$cosjiu>b`YYvNrq3&!I*YQn{QEJAW7Iw$CfbM_Ed)3PcW6i>2}pY{d<3`FZ^IE zrL$EB@E5DMkUK+=tWdcX7t%K~6%1fs9Ic{B^E7jPa(ywroP@jSc?98X`5}6LWE_9= zJ-7XxCY!SN))x__F#2`$85waWnO0Yftbt-YfqBSrJ@*~HN}l~ z-bK>rbMIIk#zu!IJfsIVe^_~lbKE>NgOlZERwuJvOfnIe@Ode$Ns`)b zdzGh$H$D*5%DmG?Yd%vCtwRAnk*xYluY1akLVL((wKJlgqb_{s@r^(SjVEPNgdS;8 zgo;lM6lB2$wNavx49+nDweF>c3~}?c0g)GSuwIc=b2;&`Qaf27wQ~SNB3yqKorlfP z2@GAvob@+nqK=i#K}F!ANEC^%Z4J-wQlxu|lgDCTytrEF{CyXef{fi@o+&AfiAz%s zf17TcMTCKghG$TU!AhEUXwU7$7Q5q#A=sc@dvx9bAE&InQ7Dq>Cr$SP{M}rr-opBEQ1n(s7~4 zfkT`=B`?VpNf{eZNZsj!&@>!d%L1a}=g1_ty-4@NMO9tPotlN`J<=T_Gs4MBt{IOh zXRhCY)+LOQ!;y{55V0=kjwm+cY!F8$RO^QEc`eeJq0ewFjGZ_ zRfQia!yok)@hp7G9^J4aix$n0>g0=rqswNd>nxaKJe(OP(HRL3i$5Mch@$3N z-!$FG4(srRCUb_S#L_eP%=1J*opVTy@yI}F+bF`e(o0Q@f~1^6G}3r*UdI|K52*Fn z-EO9@V)XF!r`uvQi%!?aD2i03u^(~m$HBB64zf9B#~`9RdB(W617{RqCAh3##qG{Ln#YB0im$CxLO9jr zMy2yxG4nduaB*HLOi`0L+DVX&RXg>XVLJozR0fWq93rU#!#n}JMI}g;1@lru99&j3 zXkv-`hmNjZ1j_9}f?|*2Hy!jTLVTngv%FW0?}G7_A>z)M|4Y5=M5dMfdjRSo ze7YHvewZTJS*Z-fWI^_#?CD2#f8bp~;!NK!7HITE8yz9@f^e$o#gxGg;eI+ttg>|> zw*=2VU6txb%G$vj9?xrXYxtwGTi<57n*1`Kw|m6AEtJCi|Z66@CPzn z;DA;`On3+(tNcdP{=t?eesIyG0%G256KeLJJv-HQfU9pT*vys~blaxRkCP!NlWVy- zMyfi@0@NJCLfJ;toWpbiz%>J+O9PfGk<=Efua{AC^4DezCs8Wafi`8!uxb=`dpbpq z65+o*z%wPE@-Hg854w7d z%QTq1cq%KWDyoRf*RHXabzk$dOZ4fAADL5YOg*0R)y-LHjPcQmQ#`ipqD>=*oL|R}^SaAP*GMp;4=3wh$h^rk0Kl7p~ z#;y;t8!CBH)RAPrKYgBFlWW`K>O^HN-c}5O6<$ev|917y*{QUxcPP)J+NW~;O_2xBp9w5 z?#Ak$3W!<-CxBl(?wmaA@_%~ev5hfE#YnytBcume&*;QakP!+6X67EumcC+%K#k+c zpX9bhqi@P~MVE3F#e|_?%2^2ewI<9cc|rwnhvmcg!T#BC)+Q)`w9H2i2aV>6Em-@cMtKM8n38#pYokMx77cD z(+in?UfUz<(LOmgDQbr_Wz(sGWS(VQl9>d3I@P2y6(y4zbq=T^9!(01Hib-4f~s&? ziBXp-WiGr}=_1voQz}zRyTp=(LQ~cWO=|aeFyWFT?c|W+bXStax7FB9P#AHruuXv` zW^#FRXVHUp+T_jgszLH}gSWiC^P>L)xsHXL_W(8BdHveB=)66{AH>-iD_v!8Ys0hfZw@8eJ3WDL3!Q_UgA{%bBt-*uO#z%Q>%^yno#2F`R$( z&HwJ0(*F+}Q|JHiOjWm)vD8t%brszTEC3!0A|z`hsSF?@7{#g@9vVcBCLuBn7860y zbac^xqZ)kAWxk{MUJL5j+)PSmn&WcLoxgK8oYg;Cna$pvX1aU5`TS0|oZY|QPuq3@ zqYI5jb!9df{&4dJxOX(cPe;!VZ&~Hby9m((0n{E?uccPbr^> z@sby{1-;A)Ms%v4HfG3Z{Xrs{MQN!eGcWb=qz+Vfu4z+F17WE#sj#^g!6h8nbC zK#7%@M|W=c_KbER#U*Nf-f zk-NFaMXyhCd7cN1u&q;QsqBu;fXzPhvO}MJEA3T}J3^40isQtX&-T zThqw`Zx=jsDfE?OqLj6i({4^z7l9x<3D4DJR;MmEr*=4;vY*r@1ok!*UJ?EN`%j;v z-3#>*V%H4gsZ+fFo^H^gd02{s`QlF9~pWY zYSH~G3ek6!I`9wJ_d^3araYx}7rO5sZUykK4)`#6i?zVrXQ#K3E1w?;85^rB#HBYR z+FrpV_zO2|mLrF6S_ZvyL4*PeRzY^}BK(Ca;HAK1Vt{=4#=oOYQ)$HSLm(U`d#6eI z;PDN9q2~1Hx_m+evTYuDA)OKQc_Gy!5oCje*zV@lcMQMHVyp$zt_E#?j?>|o>@lEs zoyFc3kh^<$l=w<`K+o_`m4ZxtCkG#4yDXj#g!0_%(YDkJn2R3N7@(Po)JJlbOBmv! zsxXS-5mnQbEm~dL16P+?a3odX<2(a9BoIxzV)WivGNkE(|5p1=_NKViQX@PE}kbAJnp(f)hg zBWCYpYv`hEY+-6^_)pCv8_ftcAb=urI+|WiK;Z%2;@H2!mtufOf2ZqbWW+|DrTS!r zhSw(?0SUo1Y#hn{=*6E4u!1r2!x#qQP{*e-&d9@`AKI{0!%n)Vv9f(e^+H$i6nlW8 z1-*=vvT`MZYz6acMlDA+-P&4ZBnI7`IfY6y4@;ZcHmBS_hvC=uEnJBOJ|YBQr-H;8 z;T6_9EwBjwU#fOV<63)D#(#xD|E_BPH{|{mffcngwl}e~Gyf;KDJt5^iwX!| zLW?KOunIuQ+{sZ3Xi}gcigZp55E_E8dnown3PR*-rOe$7eDA>?b3_McXLna|PFqQ4 zQh|H|crOn*+tWAhY`=crp5g-_d)$Wo0EN#rRuobgNCeN(I57&%`?*InGE60mJ}3>J zVZEhqerC9~cS0Se7skP^&-}z_`E9-=Ko7{p_v3`eIQ&TMHio4iN@ zrsh=>LsLd(H#3KHcfVDehIN$mSvlflmq(3%R!1B5>yl}*GY?P}kXlfQZDr_9a*Z`rr=@pltt z%w)Dv>~L|cB!OaiR=$U+EokxaYg=2^s+aKi*Q7vP)5R{1Zb*KEz8Zn!LlA5mU+QVU zu5=N(Ot<9x<`y& zzYi{NQm|(px`XGSC)|-MKSUQuB&Qh=VT56%Po0?v?TL%VW?_z~7YNb`jV5<)YXVZ1M2#4PMC4>xL6PSL4B zJC|Su>#(u3U1PvRT4{zUv$Uv9S};bdyL4sf&TG}~+ptVuRhHJZ*ict(#wK*j*_+C` z+n(TQC~JHD5Ohn9ekpp!=~2Sbg`~ILBh}`I7`qDosf0pc67fr(7nuD zM+?oBEBzAZpx>BO5!Wv<#9VfB9(S;_kS5bKp}+n3V;3|wR@PW+DmPuMXI`>Yd(pMH z7xQhi$qKuhbHnCGmY7JDq$*H9wQyedfXh6R$|=KE?aMLaY=LU&N^BcJtYW!N=3&Tt zm6jVuz)Uj3`$E76V&S~dt4P094v?(Ey31MDFou-6EQ%A`OEEWrHk!0#DSMZ2$(j(e zc3q!|br5P{ZXd9cB~t&0V2!1wFj5nXFtoA9fC^JobHEUWQj(y?7VD?<|y9N z66dYR#|KA&IRFs8b<=_o+-|0&viE0d34Qojpn{E{$o{Y=Wz62@BDw7vziwsN+=n!9 zXxop39BXabs%K&57u>z#dk4PrkwE~IfP<36x(6wAoR?e>hKRBYAQaqiOgxCN3F;Q! zV=hiBX2dCIn(UfP_-2TG{~|}YtKJ6QJBNqx1KXwDOHb1P;Xpwk;iNj|%dblO<)WD> z2g5sDAhEXuugQz6{lPnkL4~5hMrm&Dv@Cs3eY>(*qTy>z=33`J(20U@FClAjd z+15TZY_xlOpH(awK{& zuRo3T(nakYdAqX)*(x}QExh9XHF-(R@CE;t<0pD>JO7B)ox3v1t;O<2U$H>uW$pe( zR@ky?z`d?6xlT9=rbXkk)cp% zv07H^ve>R%(W(}$w~7)#Vo{yfYIbwJE>yK<@7kQM8Gg@k-kqee*E5UAyPNEI-FCnI zrg`0RzU8&g{k1z72h=zI78w0_r4U5Ewr`bfKMLB;5RNC`Yz#_wkeMV&nnXpmEQ7{e zVb~ZlE-52t<^+{gA|q$&lo>sV;lr7PI#r-H!iA~6QGjx4et51^+jxlSVaB%NT(-Qm z5FcaRZqq#IVsmiP($Nl=b={6PJ28T0XW1gm-g;ty-THV4MrOXbk9D=DMV>^*{WG7} z&Sb$hT)kd+#QCZoCClkv=W72%mdUPl(1~X@_Vf^R>%ho~kiWB|HPjlf_IaXwqd*V2 zB2JP&sYd3fOe^F1%#e9FAkLT|KiCz=4|GTEc*!65gF4tojlv`HYX!mWi-U4xT_#)8 zoxV)r$sOt1bo(16TQ8KD^oNw4TX3iQs9O(~n03vAp&qD7RT(~FBeNR?=yirptjJa! zD{$KP&P;wga!9`YaGQ5gOnRext4;a(2jiXnaOwv!Ogkpw1ZnJ>gfe)7@NIWl^yY^( zZa-n|%^y&6Be~mORBN}#!E6pj>+Vsm3DwXR`@P`iCuZ8Q`h#jF0%GD_r?w?GR^W1?;1IMd0ll03)b`Z#~r9zq~GCv4vSsI*g1_e(oGTVC8TcP-m94*~E)-x9R~T*ix!|cD;SQ zbD&JDL|vPIv3`7C(GS-GZ>SY*rmG!X+0{n6=lHwaSgx#Xw@%xo%CjzoaaypYu9SHW zolJ$b{GIn=!lV#3w7VyBS=iT?CX7sOo9bPD#T^tl&|y%`z214XFEt>J%t4f?c&;`O z>jw7%s<{Jv39OBO@6}7gHV7wNyPLYY6n?auJV03|kakl=zMXKc$_s%iQLsha8%pqf zE7yUbUD{n4sko0-!l|m?B5H8CF7dLnLch6T?3nP=q8`fz#&auptCa-P*j_+`#7zX( z`SBe*e85`eVh{!atqj02_LANO0w(m3F_DYFuz3`oAl`_P*l6Ch(gXmO+`44-7Pd~P zUXA8LEPl;~#5roUt`!#6Mlo3TY8WELGArAVE9pf~zJ<(I>4Hfxg(t9I7h)z-^t{kI zsoblT{kMBO{WBXxKw@P2Gx0!5!0aUqvRsw7g8HAT(6*Er)k1T+x*<4Ll)GyMOglvx zaaoH49^P_2mLpR64FnjN%Kp3B7lXQqet|VF&}-cZ)2Dfq|o>I(xS2Eb_hE$CoIEPEK9-?7F(IPFc$?4BQwC)C#|8b2if{ zN?`p|?{2~v*;w`^3XT_|>_kp!r^Me239i8qNl6S)Lh_}1m)yqO=o*FuF|>lY zJ;UH@vCdCe3#sR|614R^caE1@66+WhNvPpNC%X2Sw|Y<6tw5a@r=X0 zVdVH6ExHnnoS&DBZt%>d_Je)Nq7PQtwD10UKo`0#=4 z38@E3S3%C)e~+@e`PC)gBj^h0lsfb5{A{SQ{3Whqmy~wbu(>c-py6X%_OW2@+97v--j23b#-av75U?` zZs)Y8LlVP<8&063cic>Tg?mMJAVPMYp?;2~>UX{#VY~cdi}mF{+4I9DEQx9072@*S z)R!4ACc5{XI(^f^fuZn1$t9G0bOJ~BAu;n5?z(ht)bAue@PdZaT|jfg$p6H5_LSfL zgjB=wDDG$wKlu0tY<0_gJ#|>|lKPBk!@$ zp2C^FB>M4*9n%=K`!zYT@biwvxmR-!wdjVk9T8$e(WX&7puc90c4ckEfKQ8o&Vfkpk;nGg{wmo@P!)AOiEkBr0}Mr0MG9FWZ|V&dHrQ}%HnoS5Iz?BUUkTugZ48i|&6gsHwP9>wF_ zWMrqKc_7AEBk+)iU;Auoy>9%*f7`G8=Qf4TRxLgojGN1nMqPVB6_xphuO!? z@f}@Hr?_Rcb)d8-H;7FfF`ix@Y8J21IQvJ&U%7$Nf@FR++jzE&2U20Gxp6S?X)8|+ zoypH54^v@Yl`A z)2Ga&TDpd}M!};`Z&d#vfzwTjmPA}=p-M8LD0sGV71~T^O2Fc5k&B08Sv6Fy}(}z&R}rM53K@*iQm(QpvY`nKE^Mi+s z_~{zIEaBi#scme)Z)k6XA0r>vnYVjs20aD2Bu*v{PF50>VRA6NBp6~$N=U{bdasSp zuWG2&oTY;u1b9Dyd~b0E@DhmdBJ~(~_pzlE)=u&9-FrFb+PC>oh2@d5A1^;?{jI`X zYglBHK$JT#E<~f~r6b(Okn4;_wxo8)RagNw+})NyIO5T*GVcWA5o*X=P|K0}7c9#R zw;^3}-?BmAY@c}ngjwI|K6JpHD1cQLoYcOwgYeNW5sJeQ0}KP96y`PwpDk zz1-!_yizYJMq8lX&cWOBkIDnwzfOUT*$bDTj+Rc}I-M-9AYF_K@R2Vh305Gf8{5Yt6j zM{TYhXCRWfPn3K?PGSZi<9I2yA~TMfWF0Y04xP$}xiCuDs10gvJWb3zAn;Z~_41)} z$ctU^!Ui}3S@jK9v4U^Ugf*=3j2d?A&)P!Ih%KL>k$h3`7Jt_)b_cX%?rOQhNL5nd z2Z2hgXnJ6eE%3#I1d)z}{4wSEiCKzH4;h5Rip-hX{wRA~*Nz?ls5KWB!dHRR!y#ag zK7&&FU|jo9o}a#3GM+3KU3bNNjIQsU4k8L;`(pV-h!*gG+n}KyuN(@5KJwLaT=(<4 z%9iQJ49|XC172t?jMm!6h#Dr@3E~HRz4EzLfobP^3xW<#DD6=urU2ZWcf=)3js7J1Xa=sThZ;{^euU>|5Sg|og zO@ei4rID}SD>HN-E$%4O95vXT_;ap0rPiKRnY$tb2WlgPv&L$zLv{6;8>%ok3v@RR zuHU&nCWdN7#k$;(eS!UK%~lIR?&%1+I?IpQ@3fJxjELR%=Xd*Wr|YAT>pw$q^HbUP z;ok$AT&rYV)%ZkzFYt}w2AA-r6gg1cHqU!5j_AXXrb>rEO7$!& z1AbE?g;~4Km&KofVgZL%!S`Ec>NJdWJ8e-rtuo>bxiX)-LbrUNewi6H z2^CG-5x=9^-fI=RCXGs}sBuu2AZn~|flaOhP;Yod;1Gis7FK$JSZ!u6s}d`qqk2<$ z0%^bn+7ObVZ4l8EF|0nsD-fp@jp|^25f1W;HqR6aj_&CPJ@>kxhv$v0E=oiz5|+ni6*@73C)(X^I>4HGrn$!fRdxaW_5X8%q8{*|^84!M9uyl`wu z&}|#GWFgW?3|s6z6`vU`5xywkwF+ZdgLpp962G&UFd>MPlyi-O*E;j#`H`i5hdrrs z{l`;RvIM?U2&#lPM1l_FMoY==$W3d{1wpoJoJR6+COVoravmBK@KI<@Guj&V=1^w= z9B3gheXN@mRm$0RSa}&2Fp z+5;)=8re(b@@LAHh5}nJlSo7t#u}e^E&}n3ARXAJmL&aE%&?7**ovElZ3dQMT2phvRiai1cgooE4T^hGp&gFSm zo~+na18pd{O-ltUZLmih>ihvUXlWbQ`YE?gjkaIeN*UzFUyc+B4Fn^Cq%WxA85R>qb%vCmB4cc_!nQhqnY&K)+=iHEK zTDF<+zT<+0M>1rYQXLcFCM8}pIkefQhu+Hg(RlT@ z)O6boKDwZ!%pfK~h^IG)`DjW*@oy3i+VUi)=6Klhq>0m|0l&coF+-X_qCX(4nV)jD)t1uI{*4dBQC*@agrKT z0DyPFf6e3kJ!$+`XUkvBB>&YI@_)5<{G%!3uRM;pshz2lp^N38e5!}Bsl#7i{uvT3 zNtBfbVnhhreW;*@qIwGyD*{(!up3Yv1m!0p9057jTaAp8w(g8de5>L~@L7;0$RwsRuC_0n#$uKudU`-m-%bHj>hr0PnIvEZs6 z8D)1Wc1Gnk#Px#v3S8igJ8S2B8c49IsI>-GM@=3g>$Q{48ukEUHkFc8AYFsA|NE&Ev7G7V z+W(3pTl|n8)Gvdn6`@QYh~X$<2<4aMhNuCd6k|-v6%OTQvFI3iWC`DzwM6l_RzYS7 zRR;q<^VBZkPPWD{(rvsiNxa=40GoO!Cb&AD%3#?|++2rgHy8k8wp%=p6oB!5@& zo-q@j-!DiEf84&^a-Mac?I8cX+S|(q9xu`YO~eOB5L_Kn9O45o+JHfD%E|`H2KGDh zCzaz9Qr0DtT>U9BnJH!&Mw)51*-yeln8Pxr!sxv5AB=u<#4{EX80H^BBOpbjhN1$! zT2v>~DrEK+W{R{l7NUR)KW$mtuv!5`-Eq1SDmAmRUP=Q@N|kmcsx`A@yBy7nQrj(6 z?QBq9_Bw-72#Z_bGMAaL z3Ja89Pb%uvCND#IMLNn+&+Q~!g66z#Y^lI5QlLF;0pVNQPoG0u(w3Mn!`#xDsqm5; zcD0V^X>{(3WCR>Y^i@L{}7M(9xPbB}-8*YAH&iKJ$=X zFsfg(T34;GWU3`~64OB6Wnr(J&}uCjTG~iXC$~pNvBND?%xtRJM*aTKV{yv|F{Ki7Qf7r&PCmCB?jL z2f4k09;1ltRnD2Bt$9hUo;i|rky*>Nd;$|Qz<2QOWFsk%rl{-wvjDlMmfC_l+tBsK zT7Ez^Kh@n6yK}ICtEJzhc&X4<(xM$v#Evg^JREOp#!j}XSsasQPu9W z&)V@+L!ck@i<}%)rJgDVI)|jzOM;TbeK1c6HgdZQC~gWuvRQ zY}>YN+qP}HtGDOg*_hoMv2!Oj@>}MYjL3}l;P;&8C^D4_4i*JYYHHk()uM3L?$OTF z1H}8Gqo_ECPgpZqYzu6SZ4Ycm)@2Q41#d6q^4hDHE)cdK6j@tJh2E1hpNdrNpZ@6Q zgt{t#ys9uY?}l~z0ViPX0I=SMi@Z#lFEpFiVV{z@(V z-rVQ*y*eR@MsoXlVI6xx35^$c=JG)O1{!Ftim*@!g*rlS z7#WTLB|VSOuLfWEeu9wPTS-RJFil~0CQyjT{Rq!ynby96R2$eqx8NN_FeoM9%80*3 ztnqo-Ott(`_^s&}@dychqiWi){DbE&}^@?>8)YbI1b{h`Oc2WS*Z#lNs^Bua&s z;ZMbPTSso67N&=V?4CnTje+Q13zLb3=-xBwudz6~Yo4=68pimDZs-jbD%@Hhh*L_@ z=Cn;Z#t;_glB_`nc@Tpd^PE}>xx0`$fQri&XQ(kmgK&&IsS`5W6+_-#Ts?&}7TDLp z;mUp0)X3}fNG4A%$zTp2+dr~B`-eCIO0qAi;I9%Y{;y%n|N9jDH{*f-M^FPe{iiHJ z6WRy&IQfsjCJV`A;@gi@5lb|v@Y+2fU=)-e_sN`&SB5+@Vh3XjYZ&olB;(L0Fu_hD zRKR4uuic;B zx4yfjgx~MOslZu6v2DnGqxNtIhznn(A%7O`BskD~t_CO;{n{Nud8h~g7s zLjNVD{(U8m%+E0LLr9!36-f!$IbWCqJ)W3E4Mz?qReYGUX)TTk3V(z%3H2JDs=J6msRU^f0-8JjL~ zzTIA1o<`RtNBq>rB|w~JTT`Nv)jF<6sgV3Ulg&EbuUXut2!OuOj8mN`l_`G7X1!WA z7;V=iR0zAhCZCPtYPEDdBEM0l6pQQIBvm*~zj07dZU1)PF22dyAz65hb3Iq4QJ4)@ zJ$yGJP7EOgfDew6G?~MV#!(XXtgZDo6d4K|7UvKJ$xlNjT55V95PAN+Lpe*253^!$ z^?V%>BJ$khFjO`>peL`W0VW)<_8v4)aX}!gWU@A^EWHUrROoA3HXG*R{TT@7C>EVo z^$xYIb_jiT*12}4RW?~UDxy1CxD0`N7#%Ezx+*9wEVta2luo?H(HSktiiCiS5v8zV zvd<(%6?uUb4j((z(Tz-iTEcWbytBRYk;lPm2#a)!MKt+^f4GrlHsQmgp4h1W2w9L) zW^BN@M2N*$xcvz}WS^b1MWx52uYZf*a;S?J#-7Rk32otvT-b_I(jasF?gem3P1mW0 zi{b8ztk9+?wqas9dw|Cg(HGus>u3%l5z)tWZ$EOq7tCmK`(hn0AWN!O9EG^V)^K}4 z$V>__1LbPC7|~d1&$fsWjV3SLcb!zLk1S;p2c#J#SE={5ubU#0 zV|GY{!UNArg5ZD<0Zf~=abd660}FM5J@QQ`k!+x`gao|XU1AL#wZewf#fbGs95@Uv zSVBy6c?xmrV^n0LPU3d;8Dvy6t?S-MrP=$E=5O#1gju?&3-`$JS4rNPwE!$i;ne{^ zZ7J$@Hnw)?9>LJJPdDpp+YPKH?fu#zk!FWw)QsUFOrJXfH(k_V?BhsVeZ0CaR9wsz=?3950Tdb5{ z!(H$iPul5tSU3nJFT>!v)13n($b_lJ?Kf(s_!6bzCa$7L%Z}(T7i~D+Twqr2r-@12 zc$~;t`PNv_V84}(sFj&{_x%*2UaKTZ{cz^2;y`fpsut;uBjsP-2E~_9VMcjdekd&Q zUMZ`>vf(UHk&ZPfmNJ5i?T)&_9il{sxORyCfV^uHN6s!lTfFB*S-@MkC)PgzJ$XYo zwVkZk7|enb^Pz5j@O>tU^x zbQaAhEcg(@kNs=al+k)0B2L16P0n9rUeB1DoK7HuvW02_R9YE>I1I_3O+O6J-9wiY z>nKuqMc4uN>DrN1Gj}enUt9@xEX7;AsIS$X(KF>)yU6BJEpLDvbZP3sxBUaByJ|7o zB~hLO_6nmzt#s4$Nv%V#w00h!+ZSKs;!Vh&ig~050ndgP-iCHP%H1qQ9TD@Jv2rB(*g80?@3sPb7C8b_v# zy`Q9BFwU9T6tXo3p9$@5xt6&zNewYl4VIj|uF6-lif(Ns?wIJaZsA;K&0lvw1q>0k ze+$k4^4G{uj+{m%F?2M>AU?istoz^dmWANlh{$x+vno@1X zTZpl7LtNm`-4D9a6GQMkpE=y?lS-M3YCD~yAape~fKAgDoeci(-%9WKbX))yVbFRZ znuhI@Z7Fr;N1O4Xj1yBb8@;uSooU?D$hed`2wm;O+4hi?f^N5+a>5qYj(~-vc+RN+h*08C81O0L?DDFPc0jSmr=r1#5BaRoKErST9 z#$LG8OihhF>C9ou#OX~N5#0oIOmgOQ4iVqiYttLY#$qwwbbB=*e9ZP=}Afg50{ zpJbs*O~;H$bddS#me6h1D3tPj(}fWz_ST3(6l1n99MH0SVG9~~Rasj=fL*8 z5u0{hDw;i(dCN=uu?-ol4LW^3xN4RRB0V8IP6H2k6IopVW18L=9=S7)wT&iv;=;U< z@IPR!?)C0?+?f35eLPdw+ie!YoBD?@nQI*RTkdV$n6K*|1e=ib;R8ZRJba%7t*?i` z6svf20tYWbSGjW;CR_ZhO#1z*_JsThU0hp!G?=wx;Tps9o)d@2g zYF}q1qNLrZmSv)Eqz&%nP3J{mhlzEJ=heL&^WwP`6wPH0?t^Czj#vFelWHv%24TT_ zSH~J>I#-O5`cjp-Z}h2J$x7>!Eu}{krrNsQdnMMNaKshZcm6du;fyiboPD6`ieNA1MXmoXu-*M9^B$cE%1F+uN@& zs%l!2INm*V#IJtzjYsaEX{>B{tCbi|0UVn+?w&S&ICT{M_jYQolp4rmmaM)Zd1%^r zB$w>YG+^cnOx}&zGcmnuSaxT|=%JB`#3v$gd^T;|d+O*Ef&6y=)Py8zrSp{0P$!`PU2&7F4&RP+6J%W25K}Fs7T<}gcfgIv+oMl zeE!qSr+)bU*E602b; zgjQy6ixa}EEz4aRZ!?jV#y0Aa^YFmZXzZQ+2t@vfGiA(y3=qXxVH442KEza8GIvE| z_BpCVgjLDO>)7*3KIZ^5PV;*aPn2>RuXq{nf{jvb#kg@H1YerxBMAX(A{dG?8;W`x zOP!s#!ghebjD=pM`gFykAy5jAqgvnilm6jyG#|k80Huzqg+?2F}a&nqdh}jy(S-gqFJ?CSE7_= zbrI!QT)Se+mY?H-@i&$<+t&$8m6GbWvqnd(QAo&ciho2@d`bC@u*8mUoGfvIi8{<= zv}eNESE4SWkr(sG7F$hgpF-c)rPK+nzw=w7T%GKKm}0KjV&O`PWsLtfB#pOx@>M;C zP6H-ax-PR`c8nBaiL-3ZK^pHglV^y@18oV_u1N6%-U-#LNx(n{W$4=5pry)RY4n3{ z%qk6DEeT$&2A6)VW0wBt@dWN#W!Jc)7cK|oZCXzzIReTq{$Mz3X`SxzAL3D=*Vs3T z$M=`n^1-gKPYLV?o*tLUiQ7hvw%?4+xu@%)cJ+8I&FvP|+VR9$!xuhDUVpr7L!I~x z4%^_%Srp4=Of&qYj2KwB>e{AKO>I_Wm~R`EvZsUoWOU)6O*PWHx@cc#lAmvZHcQm6 z_<$4kYjX{G_Sh5V9G`bQyGqQH+hoCA9!nm1cJkfEEk>W>UcCo9Dc*N2=D3fi4?fy^ z_b>$zqysiWshD?tO5xXxiSha|Y9N_+t!G;&JO>}`J{74S?Vxo{FYC4;>=X<`%aBK5 zRys8Ds@xd&{t zVVX80(7Pf>EPExDM>5Iq;U{0D-<8QYRCr-rEH&1P@G!^x}req z$Uy7;&wpsiw+6$l(U5_FFlheIe#`&ID3&b1cL2$W5S z!}SQ+O|634Yas|jLL6w6;3GimS;xxsit1ik-koLlWcEz!5&~~lxi90xV2O0nO!Q12 z!(`ubkssbSbi-(@JAGWU|8c!%w|?KB&h`Rv#;Uy@iGfVR}dj{0;gWJWfiYbeQ?$=2RCV zx#)V!FlD$3>lhu?0$Hhu;#gtGRA|y7wR@^MjrV+2UqeV)O=Sm{9!v-`y~@eSIGTycxDsd4pIqXZC`dh6v`7qg z=%LnAsj!cY)q87dWuQu0n!L4%Yth+JSSoeAR*pJz_H~IYVk9ji3A%H#(!%JZ9mt~D z^n^{MMX3O_7sI$4);Sq3hdveZ-|*X60&qJx(fF7EsA(KpTUK_X!ZRm}Rw^`h8|j`;on~~i(jhTY zlq2LUgl3$XwJ8xl%I?n`$5Ql-3$%T+wAjw2@080$tnWvL%Oqj+Y5u*A=6zLQb?eX>_X;UK;p zDieL%UoHN!r!-i@H)cK72q^|X?tMqVzbtmw$JO@ceKHIrzXzi27!R#yjPt9>>sRZ` zW9b-~Q|kxGmV%9f2kkNCxhKEFlInUj3qD1+Lsfa}j!VQ7aXwxew{^+Gt80mK(XY`A zuM4?UDXv+y#am4_rP<8C1lc}gTSA1I;7J2X6UDPf@CN}eQ4xh@6s#P0v~Uz;CM`L0 zRbIN&o#2bM)8aLZcFF;I6Mu7w@X)PAX#gBgTcEk6dUW;M3!Ffjdk3q5Ok>BBs2c#Sa7p)GRZifteZZ{+TB5(1oZ|M70 zxCy}*5G#CU#D88Cr$*$H!bF0 zDhM|gTR&&pgAE)IdyBsL-S>e*?vjJMksGem^$XNSc%n~h?p9$ns+iEVp6aU(VEH6G zxYlOa4s!?l**<~sXD?33WVy|U75+KB?|EvGZuhru{QLi!p#9f#jOE|cGesjOXS09h zpz)K^piF2Xf1VDK>N%RluH;?zs}Wpu&P%8@A&|8@6-G5xO2bK2u5H?>+wOpUDDO?t zlsNRT#{3fo-)C|sH$Nw7eqvnkJ83#M+!zgtMCV%v$MX`vm=vq8VwS>HjVfMPo1xYu z5XD*$$IkX+smm87NQLG%V#>dfAR5<<2njGLM{gPxmG;xMhBH1|;mLZq0GeTl?L_Aa z)yhb6;^e&j$Koz8aQhXZi&0V=&n44<35S!;|CBx=x;R)oCEBEKy!-O8#B-+37%wtu zY-u{O#}54>iN)6pidCa93pqiV+~pLp(dwR$uS>Cigg3&~`hfG&WQ`kz5sP)hMzdsg z$5DjB|1Dx4>7$p=1R&`00w8Vw7^iaGX0)-qNmlrC+p@%wN4 z9ug{h*guH)tM}cwc1h_(f1W2Dk-^6%LpG3u|tIm^hY?| zWGf}AYaubrxc55G9_Ea`b^7;uf*Imn3Wbe@8X5}?SV0FPA@sw88Y+pGmh7 z8@6gwXSA57rP%A3m*<^>6mhLu0a*2brCapfGqtC!nzvGZHYr(EmDX}rw`_K`=*!e{ zCpW7X=G3re*ni+c4(@KRRSPXdkrDIXM&^g7+=cvFsNt1|z;kK=kPa}H+ z0(Z=Vx850`WJ9|c`4MfsJq@U0XrC@He;P%)6wxi)X^VNPFj zEcli#RClJij#`EG0{qCy+xRS_NN&!008wLAtJc_D1bG1@a&@M)QU0)0)42H7 zk8rGk>2$>~@_Z2y0G}1iM)<&7=Wd*4PHsAAaqjy4pjv!lL1F__XfIX1%CS=Frg_e~ zjMIRFI~~EJVHSP0%Zg)?kKQ%K|GEgHewPze@pB&EOp!4_4ZLL+MYfchGs*-eh6UMzxL-6O91WEs4a>|pDx5WD-r~a+)KZP6Sv;G19aX{B zDyF?j`mo44_Ph2Jmb2S6;|pNw)H&?M&NIB*x{Xn%Bo%$))O@pKErsWm55hfEyy_$BB3iDCkF(gPvRC9_gfer>UHiJ zD}W&!+9TT(u~#PkHyF9^=iu4F#*R?fIOLfhoFh*tRn|Rz#?hP{Cr+BrPXdzXGg(7! z_Af4kBI83;W6>_ib8@f3s~`TX?^1$o&qudsc1~vpM1^Q*Z#ip-YmtP=g9@C|r)Yj7 ztlMzJcVOK};Lrf5B)$hkvrFSok%Z%1!Jpc2S286bwJR ztslV)zatp^3Qc=WQUpXuU^mozbFhdi8+hK?k~U|PzahuDvYzEe$J-<8{KIU$Yj=Z4 zcLK52XlI;15;28qZ!(SYPjg%Bhi;pXy5HYT{pTqgIZv@+k$23z21LS+1A2aX5O&_= zLd{j5A_1jl&ZTIJ?-JBcNs-gn*m$Fo)J6c!b+_}s5o zYH*|6*RkY{&LAc{kayV~K_Sx1GwTH#-ujcY#vCqXTalv$hI;eKkPGMU)(OpgZknNy z-hMQVbMd|MGo0@1e16Wp8USG^LJ5ylg}|Mlk)qLBVhs?7dQ*q6W#}Ftzp9CH2`C~T zekl%Pok~z2WD!nqv9zGUB$Il*&mOV;=J=?&?REoK569C#ce;kvld`^QNr}5WS{Wo&Az0OWh z`(hrlm}<=xb5-e+?_=K-tE@MJiAz>TcdDGhxNVL7D$gVw38pG-aVvJ9xbG}Gk6tL8 zBo%+bi8VZf&9$oX{0+Nv>T8`WJ!|2ztM!Ukb}h3L3ddw+sAD!^qbQa_UDY1d;Feit zP`oIAlup}qKco0ym{XV|)*;d)7{_|NB1V zfocoq+Ipnl;rh+`7w>igQHPf_|3ozCkW#D(L98d4!amR_a0!gb zpB3|p#%DB+KhZdi6fUftbeMwacvxY8LR{omTxoB=Kis=dU@U-^NI_DtAQetwb|@C< z&552<>`VlQx&-=<>$@oZ`{O<2(Zx?g0ve_HB8>pU0 z8{$BE>Jz4f*zbQ>J1-3G%!T|-3vm9gO)mecclukF{yX{FKmYW9)}76oR))CC$T_8h zG*p+Fahx;xSuMw;d~bA&#rH}(%;QbrZYJdVhKB6fq~Ly zK?p2^Qn%-TdQtXPLAnlrA-k>uHO}90$LV@V|Dz{qxcVy!sIQ9|U2$ z&V|+m7Vj`|cAN$c_5mh)w|9siKAWI_g51Mi=zV)60Jn>qy_RnrzJ7ZlfBKlbcwzu> z4uMQxrtFxFooT;%vgy@-F!m4YLd|T^pAcPOAx;?=grYYPf6$iX2Zbo(OjuHu?xW$1 zEI3fZAA+&(3{&&gVeuKFYLdaDTBV5&nqp=OE7V5Hp|7z9$YHL*1x%x@(LxAk(w;M^ zng94GRMN7Gk<1{s0jU%o>@*h1G-azZ!7Am;{;ugMfe%>W7XS_E9WW=WI9FCRpb;}} z`2BW&*cn#o$amUs=!9p%7;@w_dvOE(1KRVaBER2n+jwOGIyM0o<-c#Gc2X*i-H@cD=^dx;LM}#=d}|Nqa7hgBE;JlJNPIOFC~YDDn^=BkHcuKoK&iM4b+d3 zennWb1R53B@RX?7x~ipwT-Y$qPpCLwE-@10EP-%Ym-K%q>Di99swGs6U%=&@KNsTU z9!Pu!D{8U`Z3&TW5E3x5PlP0bZ>0$s8`Z`*XD=|$I=XAxuzd|-O$%5_aAb^6^zx9| zMb@WbbrVkuzwDb&Y)ZSU?$kgg(J_;YJfDpVIzd7_LJr2qN#B=^1ABSR0#h%8B#+!~H_77pBM6&f!B zm~o;L4?ciq*fbYFgux==dU;4<|QGk$*l^iUvNW zxK?JgB>U@~1AKQ&Da$YBk^&{k3VE!AG=i9= zcctzknkG;699<}JMdKMp%inPU_1b7(XTmHI&BInyXo_a(#_ZPDBqj8=+)6D7bh;^+ zw-MIPo)MpcE+k4OLfvX==*yCY$Su1v?Y`Y6K%Fo#Yk6A?M(g3yfUWcvb|D z7;_jU@OoL)JI>HrK|oc=`IvPF>cz6yQYt9%{hXEaa!gnBrY>b`OV?^2-Ay?9@zZ9m z#5~c{sB1p)bU(M@N<2j(syquLZjLGSr_b&ZmDNCWC>z9vrYb~Ru-p=}S0k=m*60I4 z28nHp_f;JD-8hML22x;b)5k8t?`i6Ad8p&*EG)uo!F8wyTqVsd7B;6z{b9GL8z4}u z(6mr(FtlK2>eYRIF$}&F+nC7Aqw;RnmBV_qDtUR_D=TUpsu^=*mlvEecQ={fb!Fa7 zq3(lw#P<)O)>*oMFsC^y(?qi0efL+Y80=Sw;?-XRT?0 zJVsV!XVVGeAw)PJZqW?LG);x>86)5Pk`ZkqBtY6{U~6<-i=BLy}i)wb#wNo~3qQo66ZxAk@$R5hl; zC_`|%?4~iaATNvZWlXni(cvqxpL|#qu~at#^?4!8;-49>_-C;GQQ1h~)Qq<22WwsV$w*!ioY)+FY#%<7AW+^tSjUqGZW_Gh%`p8zI`8vkO zJ5lvxo$9KS3fEmt)&2afk5+o5)dCyDH6mEA!58l8@QNKymgDYl)Mx+Hys&9m zP~OPEj$iFh)Av%(_Of``*mh;g94sV@&Pio^UOzXz>+ooQbl~vlFzLVRn@Y&!T~$_` zGXdCPkE)rd3bblyzP^fM6m&P&>PwnyIpz*;2aHvX{oJb0ZLP1*AKk&{%oEYhv=%eg zAkJHrukfeKACT><)>hIN?4t3z#}1EXnYsf;as&-b6ci32CL_pgam~auqT+x(4babH z)Dr=qHR;<{MLiBTh~39-u%V}oeP&Mzbj<;c^}-*jRy;NzyopVHFF`t#_r=4 zwyfcaxu*OjCio|_H}dN?0C&fo(V770&J)3BYVU*7C-5@8kI2r}fSjPRuO4yc*ayEX z`VNBt3?Z z04Gct9ZOrc{;K`<#W^ttSWX>wrx!N_f{2z3ip~R!a6$67?lFLflnH>2n=dd*Wwr)>4B2+-bRI~4;pw#?tqowS{%HuCh`l_mJGg$J2&WBiz=47s^1%R6yJfs zB70^YjAXm<%NH~2iceRo%keImPVfUGEw~A`iuJ1l$?aj;<|Lv!ZPE-f&j>kd+_& zbB;4Ada#_rVS=4uf9VLK@pq=CdWa9SH=5GbP+VUIk!e(9CWqb~?G@TQx?hTBg|9zH7uT?7NRlbWA2(Wh!pqBXT- zG7}&@A!KLquRyZfEKb5}TEx6!@NnpQ(QF}Te%ZLr@VYj`+T@9wI@O$O7!G|0JE(Qf-3M`Rd9u?<{ z(-{Pz*r7BG3Z4K}xTuiD9>j^OPotjSF{0G|KxVcP;D5;9_(uu%-Xi6`7W53U>K=n2 zres<6U@C!Q^MGT8+kZ1@8v65^33`?QVh<fHFI>wNdXR8G9jGEP7(;vRg77gzkrgS^DWo}*`^Yk5e;+l^d#T=Kp+15+$B=X9Z zK9IR3l6EkyDj(rvnuhO8ik0qTqL+X?wb5U*a$IyDDm!q}H;xeu1hbh@IRAq6dEv}5 zAMRq3p;yvPr0^_OJ3)w?@=arersWwOV7J_{!)Pzma!MtwpBk{qG*0#$A$ArZPeZSy zM0f%)mP(Q-mOiO6r9BX%bBlr5>##KX{DnBF)7tl2pT#GdQ4hx}6cr=u6Dn+`s@*p>8@}k*57UhYsL?qf68 z`o%fP6IlO9iYGA_FW5zN>7lVN!vsLGC^K$ztbF(#P|W%J#?5?W+ioZ_;}MJa_dwl# z>YTYI;1@<0WGlOBpR`ZTvf{nLe{`e``@T~N{@VPq{@uazUjp-g1qJ^D^DISxmHppk zg#WBNlhv(kbv4kxcdByk8~LySQX}@I@`+Kohw{=^mIuMyBT^KuS7g&@j@Qbb+8UBU5yFEX0y3+jk5t%E-t(B&QTdg;k~H zqQyUwAgc7i5X*<(P^HUFUX@{%qPKk_5MmRkA)UusD9;~y?XWs6mYY5W5%@FbN=Y21 zXCdQJ{l;Dx8%*St=_ih(~g7ti~3* zu<#GZlC;aNjHQ=CJ|)$w@20YX(WK-smY`EIf#=MKavQnPIEZV;#25xIXbUwc?in8l|?qC$k-W1*Jtw;F!~21`E6)x2A656udkC2 zE_uPSHQTq-p?E{?cgXU^tLBOA^yk2^H0pApt9bcUcuWu+nhGf}6Fu7?8ajLhA#?DM ziY1$9@uhNH{k)vSM^)Kl(1zD(0vV2#fWcl&qpawdxa$1<)6*uskBKjnZ2{Hyy)B3A z@kEE{6%%C~dgE2vPR(T`(M|6&lsQ;;i_=g|+YtVNFEEcdVw+kUS*h={1J;gu!!Z^{ z&OG$44wF#*9@(XGEj%nD_P_*2TitgwLCQo~;pK=N)+vQ1xirraG;m6ScDg`THVF0H zwtowgpOuvpsYNO{`rLMA>=YVV9{s_b6L7)B@})YE1#=s9vxRA|1H^M#A1BwY9vcJ!LOFyvtEhs|aK!tkdzz98e#6pypr0=zyGYXg?N9`Uj2Xh+s z;CCZ+%pP*OZwxjaU6yObals>L^ivVnu#}JV?B7jd!x^{7?)SRrO{v$wxcCnc!()kn z-vUY$%=5+ykx~ciiq*>3vrvN#9-*32FYri@K1RF%$R(uk;R*JL4@pno=Zcu_fOLlv zmmR9sy`hNnAD^GA4QFN*As%AUE?Z}mr}k{Pa`8LSsg9V0`S?BqTb2pbCsp#)J2+aW zD{YemT3;(?36a3yuMd|$@Uno3?2sc$bOS|Txf%M4x#;`th_i(Qc5&*&TMzN0vE2;JYsLeVC%$?_J(jmh}~PTEq$h;fokUFI>u zLvmdm@5!9JDa=Ccsh(6BH!X6NO&WV`2(>mC^ru@e!3QZ8wy7}_ki#9n)@fazV04RP za*D5n-LX|(b;Hk{lWyrI$6f6}wf4L=1MJE@XVbdZykr zQu0*;ya+3=SJ1en8~H>$^RD_mq~&@=JROb=2U@Ix)9CZ^pKSFDOify=L$4iLTCH|N zHrZC)@a<1^H*qa_8BqHzJ0rwlEBx3lg)TdMG4*{A)!z7Jy#3mvx^G~17<=4WLL*tx z4~5!=vh!;PFk#*df;O2>udHG81T}5AFBLrsJ2FANd%+Ey4PU{vik;lf4kJ;C)Fen2y}YWfqxQ)ZBhqN}q=4jhCOS${|m zl;}0G%z9OqXmtogTYRH=PD^ZNkGUl{gWgaO_TD76a)%7qzJ;>2u{7L^j8|-*`Oqc_ zzrPu&QKq(em1Uq)!aS9}#+Dx5T>vD>pLkTD@%MLd{x>?^8}4pYZ)5$RU+{amU1NU+ zn7(ie-w@%%T~Pi6hi85vKeNwJ)-50feUfXVF+k9ep-ywG@%(60UqD$7+DWR{w?+#gs8v#o&46kzM|B zzTPo`QtzWfgnY`3fCybxbQ3#ci|wext;(k)9rcDOa5|W1hT*CBD#15R*!&H=75w0-Rc!Z1`E> zM_nq#xt{D=xgSS(CGsj?eQ)F2k2P5iZ9t^wH(S8Gq+4w0R$p3Z{nc{n2=Tq>-Ci`6?H*ZVQU|By9z#nZ) z_$@h3qtmHQb_C@>8WDpHR(0OY6%i%+(v%LSDx5OS2TS7P4DlW~QL)AdcQZ$*bJXTr3>lw4ly*u;&MuU5mtQ)BS7>m0*0TD7vz(%Q!;gzjw_4^{UPNb zBuu2gkXPoRFkBW9Nxf65C5~+)-Y%GdwJM4xwh$4f9$8gb)Q$CSk@;P?bfBBq?jyvS z*F-XsPmD=45=$bQ4{DqMMIw9@^TQZfILrrf2%WfQVL+iY9P5C(&F$Dv^h;`z4;i~w zNuE)*(*{)Ux&}7Nwn=xEL(imO8}REvdGeNHg@U0!DXI9&ne+ptSQq~SMa-%F4v)GP z@J-dhp|S~YxhSnYzUpY5txi`hJ7%|!9kL)TT`6LqK;v6lOjnI|;c@ApaXOgeztHi_ zRYX|{=bhVXFER@HG_cRwW?M9Ra?8>WSSKfBfpP?8`+nj(;(3C~d_#D>X zixHT^ogO`dHC6RteBvn&_A$s{lV_@{@)1>^7mP@LUYQ>~`j}BvygnVE-PC#JJ5Hv& zt*rgWp~0H)jyC((Gk5jB)dw;Ed)lPp;$&uICj$7J`+NN7>d9nf9RP|D+BXD7icP-e zz4rOAdfu9t?~}GwX429E(8>}f_gp;ffNdjf$#0qw$lZ)IenVs9gI@xDgl4>rRZZ%j zd*oMH&M!WxT%m*ly}pnRgu_q+ZK&c<>qt&SM~d5s5ZxtpmtE_{(rt8EcJ{F6jA)JR(<#d=J9j-KSA+Vi zXLl=`J!H`-X0U~_O4Ie=xAAfkc-)BCE-E!^>;g`%`it<^2txXIpt1ax6BTC2?qf;G z<`PYmQ32OMUZVTVgiKmhrSoGx~1An4| zh&;X0=YyNIv^~>S(E8*=k&2T?mKKmoeGX)E@_0STbAw7~m8+;ITtcXbPnY6LY%}Cb zJRS}D`8)q4(>x(`43kCgQ`ac5hF`Yr3*8`Be{jeD0m*$q?r?*f_CJ`&HYQ9&He1E? z9)aTL3&G?YZVT+~1?v95#dn=={iY*mlkEB`^?+a@@R>zrpnRifn;kg&0n%0n_xnWo z+ejL>1Y}UvfsY}K`#+%}FWHayN z-SH80R$H0P|L2VW!T!u{H6MXo_`IKeBCc5HUJKnf$bS^Dp`I5J)_=Jv&tH|me}%t) zEnunt{hzD~urd4JMjvWA&MJSERBjnZSEQxaL}Zli?HpoZTQE(4QBVM{D2Nfdgd?u%vL_e17BVZI$9-U&HYXPe{`ac9S;*8r*k zz7}S=%`59)Z>t)ZKvg4Fh*^{#N}^JO>hLD|RsF#1uMQ_aGDU1}o)7r9W_OI(5$inT zrjgkZ>peA%t5ffg5eSkklRcugN6A)Xc>8Y>QE*9fj9;z7qfut-KC47=51mo2qa?_< zv2s(_hTZ~2DGr&!r%@OhJ`+S!hbFHGQlVtJ25u^G^ij)V;YSkp;~o52xA3E(XroIW z3iI{U>yzm5@TNmvw99>medv=WFcv~vHW+B}RuQ;VRq2*E5>ZDSQnCaS& zXcTiYDa2Q?v8U(`Se=SRS3d87i>)#uZcTu_XbZkAujZEDE9yHaM_XnJRN=NC%;xTx zFD%4F#`kTDC(k>Czgluc{cs&}Xp8}7*I5%?hihnuhsL+5k5T`_k6%5(Rb|rc)N;O- zmvzm}Zk!#%&VFsny=H5?I1WS6%v^24@>!#&-XbZKDt$E4poMSrf=k{S%|Ca6y*OBI z%b!}a^Rpk{d$Anl8L*w~y_DD-G5n%E$^Rbe;Vk_gK7Fn&_Ii%P?;`f(%PYWU6KM82 zK@aC(*qxZhX8?CxEYd{JD=9}#yrEu0aNtd053{S{tT|4n)*5}25i`3c_e!Hs)io)< zFR&!e+Ev|paqP2)nv-sUH?v^dR&XQv&QVWjKbH~hb3$XQ_HaT|d!0Zt9Ac`=Hc+8-eeWZ2nHQ;EP$1*2}lRF757)xnd7Tl$}#5bpSnJ zk7c`q+U~znz7mq|5C+l4Y_Vt)y2ZOCJBGLeGaU)P%I}dP&MLB($8Y&EbG`L5uJ)Un z?XYLN9%LqVNbO>Bg79F_UKH8+tFm#=DnWBuMzB;Q91JtAi=~^46`&(C(+(o(p0bcjwA81l!Uo7pDUhGO|ev2%qL`s{3k-0 zTbde5vnPaUFISZeJ9pq4B14&d>kN)vgcf8Alr2c)oAGS7_=(1wSz1zkZ`4ncL1m1oa( zL$Tm4#tF^b+JpliJpxJ{zo>V{K19s5= z4nhC(1or>XL;WWNNf`gDhbl9_VH>~?54x+Na98!?kedaq_pC`WE^3lW)PlYZG!zpuHnTu4e#Z~&$X*P9 zBaa_TdFvHOsF|!Sm`b8Ht1`yotiyP-lC&vkCt+LIN^+CuMskz?LV}mal>nz8mJmBf zmLNB0mM}9E>qM|k_x;Zj(yTHK{KIW3{yz?8|1Tw!Gqf}@au%{PHZl5F3A{EB#%f5ZWc=W?M{YMHt!Q z2C7t&xLxJ)B$Te;^I+w)Y0#Q&s?8#9tul&^h$5;g%Ifn73)6+}?5QhE6&hxm?kzQo z1wp=&U$wx!uRr&Gk||Up3tQnhJkE;N?=_4@#~fWbGKb^&X&U0;87}f9NH9VXxALhb3uDEnqa4rD3pAxQ#-J*;*F*;rqjO& z>pC*gCSrJ{^ZzDwAZ33s?FM)YfHFoI;Wcx@9sv;dEI`UJ|KJ+rZIzH6g3t~S2JlFt9e z6*kqsg>>&kA1e$m?%{;VIPDF0?d7^(=45^ZK&bB9<_Z3M6F;(1FtBeVybgCj_1L5o zbpj-Z?IicF))k3KwiEWxDU|d-Zk+#%yOF%3iL`4#{$&$C+(9vpfFI|7_^JWu z702SaQqjNGWQ9{|fvMNE-(V`NR9O zAKv`O{qTResG?-zXklP&;b~xKZSvD6_`kt)Ch-%pKRJ9M-+ht@e*yt@TTSw1wA1SX z#RUZgq4z_UxTFIDGQkWpI@6>~|a|Nd?x^6naLm6KBAmn?zIbr2_xX9$C+$Y618cu!#PI zk-&sZH*TWyI@=O$6OLNPh&A!^#BwCsBrS?oUyo<4Z6|ipcu?#+_|U>a+}Cywt+lk( zh|p-%Y{UIQbDTphj65Ds@7BVcJV?0!rlbXrXyE*ctRi1~URvfA1J|<4YVJQvdQ(hA z6FV3>^T&Dzz4!_Cwsq5bh+~=ki~``$sWb(8c<#e~Ov#AB*|F9FdhBO-%j` z+M*T5WPuo5q)KmLbR`Njq7 zkZ|p^&SWsYGa9>Ivo?on1Lnr~a*W4?%Rs8a)mo;ks_-_dS?bKtv3cryKSA4tRuzdH zhlis5Wj%wv*YP)s|Nalmoq5GvY+Z_Ubfha@nVF)BXt%zeHkE#r)_@Aijm9Nzw`-Ep zO0ZEybR3`ca=dBFVRa}>ttW-^J{Qap9{t^IFnbZeUSmynpT+hKH@<|J*;{|kDlp21 z_U4v|vkqLh9Rt%4#T@{=0HQ4UMViasAHzIV_YL5Gwpe82?s>;#>z^&KnWcg}vd-+s z|Hg9Y9+;@~TipCkXLp5Cs?X8=0%boK#ebIz9DV8mws3S-(Q?87*(9nyXMp`LW!i2V zA8(6{A*4RXCyg0>rfIg6!oxp>`#V<%L7$(ZD*o)B|NngtivQgA_(xG?fB4FOsrHIG za*O=PJb}smfPj?bWo6#xD_~Ypbf(eq*39L7AdOgf-dN-EW)`KH=@bBd8E{{}{F3fm zHP_Im6#vqfzD%b(-DGj``TG8a-Q`&4ZSl5ddfkM+N6JSJ$m>Eo(Qu!PMtP@}8X$<3 zldkD!Um^6C^NU$CFfS+MLiV)hMdZa**z5?yI3_9%x-Qv7H$d0bruFJ=M)35a79`;& z>Pc8l&ck7tlz0d)4L&^*Q@LguC}7^w)}Sp{Pu7b&4rCUsD2nj0aBV(5fo7V&#Df*F zKC>q@_rbV?d82?+s!6D`W63^~wsy)3uH2^ZiO5jwLTJ?+%`u{wFT|aZ zgdtMgWnB@@xtb7m&@#9D9OILy{jz;$!O7ZpF8th8Om!+Zuf5~ZvYRnvXkb(u9x-B^ zv-G7jSA@PQVIoP7MZ&5ao-dBLI~@L+wSIaK9NEv7o~Zx6ezQ1(9Z(ItV4#k!uJXJ^ zpy&R(lR93hqsHvm60`OkfmvfM_Y_GzC!^ZFu?ya#>@B7=G=13`}$E_K|elM9JcYw6xR@KqZOs)Ke%p z1_*VON=1(dl`*{r!)~Wi0d&&wq#UoAGpC-v*+;lvUoS6wzpw|kz%lJP0FH{g#gtcRLL2X0qsQ_^(5ReE-L5Ab95tRx`hFmoBrr=G5(@_}6cB%JyzJbUfylp@VYEa;>0o1{;N+sR zJF+BWpsiN<(p*synMAi)obc$35g$a~UAOCzEXd4Axi@7AWvS60WT%;KQ;Hfio-wtS zgqQ6XoC1$^5*PcC8aYbiWMr*YIoa(tSr9P>a%74&vrJ}OBUvXL8up94Dd!AQY4lrpUPFR?$0DN6S4%^3f+A$*OD`o#kAH>D01gZDIqcSfd zUv9KK#CK)X0nN2cnfOH}9#GfWTUS2?|$V?Qo6i3M8 zsZ%VwCQvHTax65K=(k^F(HS!i-Bh()Ah%lESvraO)~ILad6eoKr(L|CVy?!QdoW$O zNFZ<~ zI1F=HafBy%1}&30rj$n%WeL*SX&|^cKNgC)Ho5FK#XOuY$AfVh-DD2TG5m(& zOdt>21uv(OLE$RYu2G#Nu}}xAn6=LrbD^ z0bs{-T3uDHX|#>0W`)B5yGQSBUWzIL&RF)O?j&WEsJDI?;VJ!AS4|Fbg6A31mJ`DxB2wi6(XBp#_)))10&FPrMFMOj<9`Bf2g4(pM^P7K zUq#VY0hTKNCOkyadTr9w>+tFTn9LrInbptgoCi^gAwcG)in-3pjm4VtH zzRzdx^+Doc^C~X@w35%}t(KZ|4`{VV$@fhc_R*PyCy!RkqurT;Qh^ccm5MUaD8&Gcpj*6Q2BH73%#gR8og3lKh5__S{{R|H9ZTP_f*e#-1 zMfUQZn{-cx83K!-5{Fk1sMWK}C(PAa(GOQ2yD?4}KMYn@ib{K*ueu%&V;MkAZ;!R~ zAytQ@AzRKxxo8P22=ECqeP>ZFdzAE2=6j=nqoC{)8Gxtec6n<128-k9rOhDknK@g0 zorzklfj&Y)RUp9yTn19swZAm|2gF-aH`l?}J4V#IFZ_+<peFma-@)Z<)Jggs!Tg1|d-(qydwn5;_Jjf5np%;=}yYXJUh5 zqSPun20BI>I{)wZ;CTOZe~>{#eUJocXzPDUpFWi3SP?(a_UGsQ-^6M0e}s$U|7Y+s zG;lJZ1N!HBKVSUyL#+S#`tSArrvUZ89F_jL-hUa-+c^sUto|=bmaV4Yg=L1~%cu3c zdcPWvW9Fu4re@3~DYOX)Yh$e;yTsX0-?mlc+s<8F@;bP|(dyEMk?11?o z!6eH*@w695QCFJSa3nSA;gHx-Tw-g9wubIu{ppWgWzt~k;SiIqE;m(ZEX8XZS~dOQ zu_IE=ZiO}vS?CGYZ9oI!Tt= zvCLGI&VpSjKuc~erc$yhdDe0=;E#duOK2_|!g(8b8nxYGq#)dm6m=G>qo*+i2kX)qWK#^0-eyf8 zUUr$s6Oi44lOnvsqo%;HZ?VdO8P2C=rd>G>L7kG%1S5jXPQ;0GPWery8S}bwD$R}F z9~Rk<8Oc*P_9l-iLv%**!;+XK4=tht&>NU@_FXriDPLCUOEhkNqD(VTi|?_s2Q;Qb z4zYX<1T?KjGCuNh7H>@~84ENQ^W=dcQS*&hh>QF(o8Y*5Zs2y%1}$OmWi?tJDX*h! z39YF2stoUP$|v7`cRPkBvvK*Qi3&D3IXt>g#SA=V<`xGSXP#sjSJ<~9bfk|Uk@c38 zuNC}>G)n~fgsUA4SN%mP(@2Jqe(thbivboiOjz0kCL5S1@nM|`A7(<+r-MbJ$xN!bL>r@^L>TMQ`z|)!bc96H@n`C7f?OxF%QbT)m@{YI{ymg6 zMd9;GtXevh*=#dweKc;a&G`o~Ooz)jy7U;VLr$KWrTsu}$`KZHvzTV-^opt0g=@M< z=1!8jlWBV5Xehj{-({}4TKDa2DN`qi&K;9SEr!C9fjG&rYIpeilz^v-cP!d!cP`$6 z#Zp6TcQhb7s&_cvYC{UZDz6U0LodWKY@W!SCHsG0{R8kS+Wa#qeS-v0_)=E*`r;yT z_fdtKBU(Hr#KBg^by4^RW>7u^hio<#7y=+r7^G(%TO>H0)`O=-EGSVVJls|=NRQ}? z_fzkAYKf*Xs|+DPP&lU{x#b;Qh_jc?nwcY8iqQr%^sSgT{t&)#CVEB$^HR_V|28`P znHg13EvJml$kz!pQ8fjxZk4W+s;Z?0ciyV~1$~SL>Jka9cv&B@}J zS1)eP&CAZfi4E}-8+s79cV}5J%LBEpani?hF9(t4uQE=R#QCaly_?{{I zl%Q>q+I=3P(HO(1fh0}8%zm!Uy--on2Kl0sd~>B_gs{%V>0pY_jT-qfvOkYDx4`fm zHcolmg7wzSFV|q61b#WteGXu3R`OSbv5%!P>@N-zG0uIRUvj65?*{qe_}OE(J@q2r z_(_!T8?vf5Zye7ngVA%At>&CHsWoX62oDBl=}{JGTRo_rD9uLMAIW}WmC|IWRr$(V z)t`_`l@T@D9&5UX8Qy6L? zU{{*_V_Hi$l-)nDcDuOew*5o}{yAP{dI5;1x`INxw3sA)h@Ebu>VZhuFZ_G#;tB@L zhTu5v&|vWSg0T-@5RdmQI4s{Jp49=NK>?xuN|4)9EZd>x zW8IJ4vd=A(GA!_we7Vmjfo2~&{vGm(ZV%u!Mggz^NV|P>ABKw1AZ^A`^jC*@C?{<8kE9DU1NaDg{)xa(I72S|^ zeyg_~;=b!HOp`2KVfF8+Vz<^fX!m%4dqkmwA4v}bYYfZ4SvkOM489WBFMYRmmQ_yQ zJvx*{d3dan_=v0zvq+NU%nDnKUJ_Ztb5*5~V)luu2@1LHNH&;qBI{-^uw?*v_%%|+ zU`KQ8i)*@v&IoTLXkz=Sq0+y_2E-a}_J~XJBL?T2ziUSn=}Vo!Xg=8?$&4{qYde0f zzT=@jjR(+7TiVAmx8?%Z`o;TwUfRag0^^%_Lm?7ZSg>hWNJ)Ofq zFHv;age)_?a~NmgkgBjBC1lNaSPn*TS8e6{AZ%_RH!+8|$iv5nFnUow#&|wi#)oL9ATjZfeDy>t_xOo+1)w zi1?-^@_6o-EKVpt6h$ymuF4 z{-sHIdi%q?{>*2YBKikFZ$>mGyk3X#)CZ%S6F{1 z2x~HXT>l3MZT?+BKs1E5v|bWmS`vE<{|N|f0|T`NoW%`{nHobiEqHAsgO!F0>Pt^o zAfGmdoUK9IlIS+w$xu0j5(hHDV@2!K*E1X{K050e{qQ`!6Af(N?#g4Nt>BvYVb7!33FSU1}=U@ zkjJL2Az1p!H2N8t#%8Q3^#4q9j7(iZFnJ~La+?^+Y2}4v%j{wla7*pB5*C*nB^-$qbO{IQm26X?K8rn5KIt~rt*l`!dL{O1F(2AMd4+ybJ%He3Ay9WM;}S)!fg4p01kbWXAXZEuBaW zjA&tw_>=&l4$)jt#62{q6wVmHpOId=(2rr7V{uG0#XT|ENWuu>nR=4uQ6qdz|DZ5@ zMM-sM&~&Fwvn$O#0|+*DFyn;f&w$FC5=%s%GYetLi;z9`FxA;R2^Fqud_1(6lJ-W- zlxw|L><#H(Zpu3~S(^C<&6I1g-$;E+{WoVh&1T<8+M5I!<*67&wXwX~G2j(JyT zv*v&W_k*{8@BHcQa=&BdLh<9giW4+EpKfZK23nEmHs$w1sGtT8zzygSQCao&@5W34 zMRW;iXfkCF2jPaok+X*mp6qs8rO*W%o~LtoW~%AuxERz>Fs|w*=D_d)8h)oC_N?UH zytCvk92`i^LgO}zE&w+-i%Q=1EZ`S*HcFN49GgCn*K(Dn5>eO0D@E*!7LX*!+?nvg z&8;hD>vf1XWzi`C+XkcTje|!Ut?SEcl`s_&%B|H)b1Uun)usXjo}l4du&kWl=mZLN zj9~)^&%>(y=%9dxPcqSw;76w(!c`3l8hS#&Of}^(Wi{muY|4vBa}nB9 zS23VoMAZ}cg}z-*jg8KQOtUJQXV*=Ie4N3ZhRQ>dF3JI{!D&|LzL17X20I1Im8#m; z(bLzCHfg+L1u}@0T1|3*;VYvtp68Xy=UM^W*h}bhOTx3NL;<{&oYtt%(TlPKL#5`U z+Jg3M!$<**>zZNo;r{91QWq+n=wQk;HRi6&ElWgBsv`b3XIrc7)na#rfty!^#$IeS zO7=(~!i(TV+ZSg=TP21|+uJT%lHh7I(h9`~8NtHrKfmbw8FU*P6`_GU;8R2?)2ztd z!k$yR^WwgI%QJ9%n}=;ISKaTvqJTtMs^|VAXlRvfSK}n@n`iRq0Iy0V6m+HlE1|$f zv0cKz2#p(h#Uye? z2Jg}W7Ac}6Rc8a0j#)`2L&?H~6)){s00xQsduRnL0f7$wi*W{mQbo=jpGhSZ?OBI* zO$C%rFrKAdIu>@Ct-1~%1<_@S4pWnP^6wudF|a*|@aHS#)AGTjseggja7&;{9=D@$ z-{aP=Tw2)jRwF$fNR%_I&0!HKO1S9HKXfYK%)!7nBK!I0E|uC*O7#?+DtCbKA)B_h<{S~X~dv!$sGLHHC3K}T_F$Ol?e#`|= zm4YZFAyqf7o{`!q)lDW1GgjL~*dK~cGzL30nKkgklwYy3(=H~AfE}JBYNdFU-6~b3 z35^6kgANd%9Fkh3y$MvXaYm91U)+)PR9cZ@A-<3>lZo@93txvrQS%44DXa^_35i5G zdYW4yv&$_{#Uw1T|#u{^+c` z3;Bx&o+F4_oITqjOx`6)-&G?8Urd2KD^=24($^~QI?~pHEhx=)>oOP%BP-B=YAE~+ z6s1iSbb~;NMsaxNkE*`NVBw~D+AmODo#U_Hs{27**54D2mrOT!u_`?&mg<`-l*^1( z5|x=-63eI%j?LAy)u}JO>P+L(WU9{jE0L(}%jU8OeU9ciuQC?J=v+VkVW>=ND-yQPn(Zfn9@M>|orlRdEfkE|;uhwJYc_4**`bAplw1w`1O z0y_y>1`Z_n=fv_Xy^Ep!_$}51l@nCz5JBI_G{Q}~Bc@W;uvyhiO{%m_AHa?8mKgbx zg}Gq>w0b2?xpVdG>&Z! zZJ5;5-MLpapg6yFV#P1_ah(C>oU7+gZW*Vu7-Muo8wa;|A6mXK8}XD>ebD>9wOR7g zMrPecPRXfpCruqg!37WK|RcVc+j8^5WnWV^~&h(b)rvr;B#yKZWu_E5q z0j3u-k~TI&56nQ)Wwxmu^LQstD(qOcFdqu4RP1 zDkE7{uY{tIQwKC+W^J8@N1vvSKFzwM%KxIj)E=ixd^`GpM0}O3Iudp-^q(~-s&;+60HmM6L+rkZd@TW%LLeJ9NHgzYY~kYouG#U@{e*_lnX_;wTq zS6bp+>$O_l9#Uakyki&S5A*=5lGIH+-cV{<#(V;;FP19V1~E3X<7u94mFamIPa1)s zuhqk=mseTdE<}geUHBk;iXLkt4dce3H>q#O2ajwj zVhzcX*amXcmQPVt^X&0ss1I)F3LK*KFmb`!a=4`7#ZZtgY5(lS*|w;|s;yQja0@wl z?IX;<4QAi94Nf=cAoraSuvjXWXW*rLmcK5Z4$&$6CETm0j{kC9>z^?)2ct;$Y%Yq- z*Wr~4@A~DluFI5VQ!kau!gd>ruC9uL=3xb$1x=+TOS}F|wKEA_ho&X@IQJo;Wy@Bt z#lQWQorkZT+x(+G6QMji8GPXt+;+l1z>ZJbzr(O@&b3^l({8bIr#U zi`co6kNQgS7w$8TQ4O~5$X1xaDDjnp* z!rdk{y<~iv3+oH=Lv)`AuZj1QjoPx1Q69-X4l^N^ouX&apX6<*f2Kua2mkOOW3M_q zKaxK}^%kkm7zv5zlOeQsEwt3Ae$YN)h<~8Md&Xwq4WRR##9Jv&zKx)bV&8%`O4k1U(~#wXd8PVz#|mYMDp@0sLUzs?svkPJocqv2Cc2O9xIx;) zMJ!B@34Ux6YN#q%#C`C<2xhiu;U}4eEDN1KhcSsb4W(9GzFfu|DhLJ9D-M!r7pgUJ z#NT%ymx?XThcnUe92|TtFXs8Erq)2``2e6uDURt_bx_g9mFk`4PS>?P6A+!EK8x=V z_j{a)7J<9E+Z?4q`TVnMykku7-H%tX7)n@i>}pw2CIRk_Mx_;)pByD-`>psyToogW zNJ1I~?^-gCw=tJ%8?_JH8oE7d+`6+(2pi1%UhLd2VPiCa?vCpV_KOKW8dvMIl*e-& z{z~e$!CY@{ov**Lz(;04Z)Kg0`8^Z!D`mMG<|gb}?v}R2;?bAr_GJ%f&bRFD4V)MC zN^cj*+G$TIYi76hv4hAvgbw>t{Gum;!#;sNbNE(pXV|Aj1Wz_xWIwyQFE5UiOPR?B`DE zqxX3sYk4uz{-&&`$gH@mbr5yoGRB3%gZH_;APM2oto7VYOM*x-rq<9gD$O$>_t@*l z@W#0Ce3^;d4#GwvVbKF9f6)H``t;S)PYI6Y{RKunn3f*@=)e@@ryXZ zot_sL81^0uU}nZn>-;iW6(q<3aLV%Cq!mbk zAsKa2#v^9M_3u0@7pMp{!GHJi|f zv_b$R@!vx?PFK%2hz~~@D#RbE5?<)hTHu3wi(P|RLxwhr0M)1dioO7n;%Ocl%?gB8 z9UaV1Kkb#?f-LL{608D7(gI=RLaCbc|M9O%UyU)n2>M03OC@csm_;8UaN4(OtXh$7 zoODb>G-mIY)PX#BYlvrLF4|{*i|3dxJ?6FA-$eRfb*c6}&ONsK(CcHDn00kl4&@gFfm^>gE=%<5#?n+)sadri z%v($erwd#i)EA{IOMC08&_ZCQ=<9H*)XAzN+FKJU$beXkL}<%fEYYv;|R; z#Tz_AUk*`LqH)Fxxupx@G~FG+k5^$_SMiLSUUVNnZ5r!fFoNN?AfF=Mive^+C$fh} zTqQEZflwDDUxxo^xnoKr z5ndkr-Alv8LafSK19jn26qI$sjGB)9IIK`Qh5CRCZy$rZQ~rCIGnsz zQN7(@I*?J&K$WH}8OR&W&dsc&o&wamqa_Mx*T~rMPFKIErK@{&X>2ChSX_HJ9beMf?S4o8}1v?4aM?6|Ew6Uog;0>f$1Z#D7<0v znD4tI9w8n&8ree?j~H~)3?o<2>ISmr@27K(*P&INfd-`%U@scq0a%L`V}bVi;?I|G zqaeP5iyxi!y-E#{T&yDUB-&$!Xz`ZfotKr-=HF||HWZq#ISZL@m7Kba9JC|ZZ-uwn@~#*BYVaVa+33Z5 zs;+G3NesX_@U&16;G?E$$S6cpj^@Oe>_kRCwQ9L*ip=o^F6%6k<%VPL7 zWm#dh3Fj1M$!>;*%Z?k8B4A!jnQ6WVZWCCi4KFR8SJf6!mmFZ+Y{?A6l3RETGCny0 zYTz=;1BH*#@i2D<#ea+v*GEMVt0ur(>rc^%dVD)1-*+WHabW;q7s9#?Sm}Y)^l&sg zqz36W94Il}LW-GySg3f)xLiWvnO$OTBP}uljKYEwpyWb=z;V?}ppG;TPEkrUgn;PB zNUZ;NL^4puP>!t_e2-s>Yj2Bg`=GLF%JOmpctIayI>#cc4P zQtv8cD{mP{*^HmSvyxyW_@)`1%Y>hk3!&Cn!iO2FZD{2J8n?l3ewDKel>%+W|%2%+_kgiXsYe!FZ#9A6UB{o+hLE!3(xYGxkWUyOBJbI z9PVbWV)3pGilzRk%&xS|k6!XR)IRj!`sg!m3~m6O7aZv|K5sL9uFrupXT{K=Mby3p zltYVUI$||IAq!7zS`Pn&EdF6(^bO(tF4nF&>bD4TRo%4Y|HtvwOP(&K*CHo-!uUf;*m`M(9a+wee^2PK7oOA@SXv4nFxEG?)6$6i zAfJEvhZ6aLUohww2J^#Ae(*Pr(-L3rP|xqD52@RGzX8)PJoZdK5VVI{1F&z`y&F4-BIWQBvQqh+j~5V+gn>k3gNMR$dOF zv$z&x^_n-mmWAzWD{xc{%d=%ZaV2vfo}XudAD~+WT@@k@y{4S<)(X)PYGu`6B0te= zfH3CE*=fzHV9lPVg+1NN$XRpg8i`>zdc;5rRa z2A0M{7M_Db7?UecaiVTBNi3Ca+fUFjj$l^@;CCo_U#Ml&5AxcGm?Aw)b+rLrL z)Wskvj3d{5v-^<9E{d+gcX;8JOBu)eQ>Q2Xgsoq=?G@9LpRXA|1F(k%@u`R*K`GA(x*98_tW;Zhc%->{fD=aTDG5s#cLaTQNF$CuIs zbSeUEG9g+mCbgHC$WyZP*DXhxPEHwsnTK2@sSfBUUTRB}9m;M5)s4fxjX4Z@Ax85i zZHC&2{q=@E*#~2QNkwuj0dY_yOfe3i(+(8TMD#tkYeA46WcLT$hH^+wy`3u{*sb`x4(idNb6}Byi&JVsyNX3c(r21U6vL@8o z0w^k_eXasGjqHg(y9q**gs&TajKe0w4g7jjl?c$w2+`Nxw)O~Q1WYk0;v9y8|Zhqt(6geC`Hl-tw zD!7SN#F8e)dVWYho;Ems-h^JX9ouOFrR*)aPJA6;qA0sgwjGnR$SPl~oz~qLD?L6P zr+URxrxrkl?ghTfwr_G3EHZE}z5t}RI)Iy{tOmTeWdekOjj@{+VK9zU)rs2YIghus zkk>7b*R6opOCi@so@NUKW`3(q@;s1bzH63b3vHf^hDI|Nrkz);S^ebNfI|Jpap9`47E(}V=GtF>WJ!0=l#}gQZD!Sl3Bx4e^y=; zubk|Ligl8KVC7!ky1Du~AIuReq{j>HYfS?+Z{XO%s-Zv5 zL6IqsGJ})M$7TRF$0Xz=xUTusE1v6D?s_!SI4r;5a6}mJa!h)Wif!-)W7nh2KK@3Y z_2v1Y=7`#X`~hcRpx;7oS1m{R1mjNs0GB}Lwg8P8A%nPw21Pfb7s@BVCB>qq-@u3J zA^V-=46Qi#c4i&+yX!miHxL=}EIr^pv<107C?q=~$fO`ZqeAZ-xjrtWxe&kzEM1=e z7g{#yE_#&pI>j9^Cf4r(1-Kty?oW$L4F-owRkBh8@&r@7qXfjnKm|te8JWOas)z(J z_$bDzVtVd^5YhB{xEk_loZoskkTP%4?Krr_Vikq?6tTf2Rf8yaJ0PgmIjbNC0Z6&f z2T#i8O}O=P3vPGd&(c-#8X;z<2AWYSvEE4l4bXizV!Ij+iXT`0}jXp_IoL(=J2 z=%LnO8vD%BpjI%)_tZk(Zp#b+I!)BemL}TD7Z4v}`h+LpJP4#TsaBC&Y(}lFe{rLk z_=^# zCJ8}IDv=S~Zv)2S3aQc&L?qu0nhi+_NkAqK#+?;};%N&A|GPcO=4IjY>3fC8#dPCy z)7^cuv9kSkDfO!kbLS=q=+?#eBN}P@w;lVQ-CpJp{BO4GThx#2#O`htX}z7}5x3X7 zm#DwAwO>Gd-6MlLW}AGRd%3&0B(G?`-~0i1jQ4tPcXl7I@j$+pK_0g^vafKj;XuCU zL7cC0pkI-x-f$>3gUUS|rv+ZP|D@h&6F_ zO8v=*H3{}C3sw2{2by5rk^UQ5b$BZr_FX`BV)n1^p+E!Iw!n`BNuC9o)HUXJ3M2{g zP~QmZZXi%Sp8^;9#N;H3_`vyv#g@mKjS^{*?@Z(w{VY41ysSO7fwtC z*~%aR5IT4BR6;9gWLn@!E%0&-(h}_7Lmf3w}HLkX$bb+=&f+qNa!Z~3T zrY>{CwEG7A?5!*874`;pEB-_tet_PnVm_wHYum z^GO5wri2(O;D^)Sqg*NB!U818*YfEX zr*eZIEDFf0N1uX?HuD4L%)M9O1y%5Q%f(_LL-H+1#G95#9fi5F!V(AoJJct`5u&wY zWX<=GN}@$`-HilH*2!7qB1il)%?Ux=lV&|*F`*iEx;ukOpgKC+ahE*Mah8%T0Gf`e z8kkMfq7Nx71`8+egR16|z(;sTu_|)FHT&ImnmRKvbIK`Zgq+DUW&u9t|Jz<3ijR{n5INo5%4wDgR-M%b_dIyVr_l0O<&Y2K^+<-{f2 zWK>pCBlz-A)Y9NLLIfAV@V2M$L1dV7Hhz!8MwqY_bQ2u#I*Ef;4-Y&9JQ zS~0cR3T`!~8IqN8BgUA6ARsam=mE9SRMb?&34E>o3owM`wt|D2W}MDlOeW5yLarar4e;nQSQiItFzW14AwMQq#I10!-(^m=DV>bbTHf$g%Ju2BWs0hl-xCjd|g|IU=}HbI5&-L zp$fA`W(5Q`6Z-XbZN|&|;+cSV3FxVolT+|Z*qOY;P9d=EiH0myAVlHtG*}AlsVbYHWbmk_ z|A(`8{?0Vo5_K!KZQFJ#wr$(4*tU&|ZL4D2#uukzJGt4r`<#2a$GCglI2KfSLv2T*79Xx+ z7(XMQUU<59Rgjt&n#|rlnT8ul#XKhgj?@;)mV+BU;+tFKqkI*yA<1B`a+Ya6);Wd~ zMJJQAvUYa&>IM99$W32j~@ea;r5@UmpeC3JSX9bE$&)F4MS4bhw^unxLOA z2@R(rm%Jzy;g{@7(;lB24fk<&CM!^SXS$*R7OK+N;}Fqm(5lY0gAK?wh9_+$99ncn zM5%u`OW$Vf_i{}=5XBC%d9b_f$J2%=o25X4-_>Qu4RG>LcrOtm_la`Q389P6rz;VS zaO)f=nc%j*_}d{Dn<90PCPyTRZ+#-!8(6r{uJojIG538U_3X&VDdcC6T4dQjMoUw% z$e%%Kf5}gu4!@*to)!)(kW1JkF!NPAMYwD(g7qgRxq@4xnI9fQ?W4YCIkL(H~^Qxg}=Po>~ijXQt81Y=ZsT*zu=EA*$ zgS%E$jZ>QNynXepq!@|ymUYErvA2>sllD?2%blfCja^JTUtm?`7>bz$e_QK?kcdXY>FOnYeCX(hiVQSIX0 zw*68v2HpJdg6-VQHM}A${(k)ykoBy*r$y4zPqqJ0DgK(c77vQ#8r!gYj|&!+p@-Wt zdNZll->)#z2L<}39v;sAfQ|+diYLSghE!wObqu6n-jxg-z`7O;L@@0|3M^$dh}pFO z=asz%z-mx%rUH#X$(i(uL-J<=5s*B)gL?<=dNJ?*3d*@+y0<-kgX-oviMr$!ar`L= za}sk;Z_^F=jO#<#m6t0DK5rb)|4ndA;>4+KUe*WI&Rn)M=vIL24)#Fwm7eVkwkT(V z0!!=lhpHvv3?<(sWjncK3z+Gc1Y}b&;x>!Mbyn#Mwz!&=*%#x|()lyi5 zXjQ6(@j;S#-ORyDG`(WXHmv6YSYif~==aqf6_zTh=5G-+rNHL`P02As59D36GSVa` zqg%u0aKtaz?ic-yYMV_kN`A1zqqIBJq0=rOlFGl`2hQQ~TtO@SVr13ZL!dj#6k+n@W?Ae;;FikM$>3&i^`UxFpVxH?jFj3$c&d5@P zd-6d^b#VVPm3q@|Z;yA9ElFi={OUNr3N0_J|JVumL)4)+ZM2Lb=~pc#I>wJ_qR*ex z+SaD+&5x?g0QpgM_QMF?(4SBQc_Cg>>7PxCg=^NOx4XFk3yoR;c>s#pdO~Gq{4%}~ z$J;u?z(?{#fjLk#vl0GpAz+Kbo%r4xUL2GjL{(uAWa`&SYMw*|Hjt1<7S*M_#$6d2 zpQ(&*BbrqICRXLqg*mKnEPW&%&-C&7oCgT<>TC?z`HL)!1< z@F0Mn8R%aT(7%Zac~}8cD%$=q`G`3An7VcN7z5-wzqHL2jr{`{dBc`0I2~Ire`z_+{ zEjO!ZKYw;^nc7!3XT@UVRX20!1%@^T>pLuav^-Y4Uw6)4djZyl8>xCae@DM> zi}>1;_goS7Y}H|Pj+rAo&%*FH;zaMdt%ms2K|m1t^B4kO1zX}WdFR5wPaH!J9239U zq|Nlbd{LxLOfRix(F^W#^>hO!u%O^}=x8stf8FO6SIy(rqb*Z0|UmV5jdqe9S^=6q9r)D#^mXp#JM{K+0 z@=dOpU2}5YfYJ_l{f4??iLMK>)qJd~A1DQ|2ptoKWZ+oYiQ~A=H!LWS8!aaXA00;r zXo$r8(V;9iGu4HZ*4n3QFdRb(wx+Pw-TUoRB29Gpej3{uucdqdleloAD(3Y31lkop4C11JEZydd^_rO}Y7LUR>M#WCsz zSgO*-o-iTOVryR+tA+g5yZXN`=E7-MBQNIWw3#mf_uxQ%;Pp`7j0!0Q#8a{g zv|Y)?XDdbCzo(U`j|DyNd^fbeFfHYTTG50NLV|{^5JpCh_lDmoXQz zw}&v4h=BeGZk%!m^xO9vO_aUslnrLt$LdfkN8oNKBGdU@XsQ>z$? zWV92fmmhh}-oq=trOj1-a-~j5uH}rvR@JrZ37~%TSMt39Kd1ISj3QSk=9{ZN56CAX z_!~!KWFC&qKv+t~XMX?igO7QJ86Re7MD?apMNl@f-k$XY0#B?wNbfz+kW@9gnMhkO4~^1FSWqBZDdxp`+%kHYH>64q*gqKl*1TooF^EajY59m zK2yJk>{=CFV_-H4^9fP#<07Um-(V;E|CAdPtFI|5t7CrU*l<9l z327D?I$G*B5GvNU08=yhi-4?#ibi5HjDgXUJ{dU`mf2qHX%nok{BfyZS+Zj(mLoD& z?3i4fcF8*3ne{8UkZIm&ha!&W4&Xn?zRS7u>AAajIw*zEX8>LeYsKRXU?lL&b|`2C z_2H!2CFAd*HGtTO=CnA$VC+2>a9v;@R^~<(k3V!T&YCgp#cSD#N_!>f#0l-v2R|+gol?_H-cd4S-zvMLfHObz)#Z z6gvOAq{LNn38Gj;j6DhM0(RO$XZbL_rg$DUH^D(h`gNqJiN4e<5$dZ5HA~96;%7;* z$(N&+t7P_r5>38nv!$-2R0O_coGjzHPvS{>s+3g6jzP=`l_uT_1#EOt0e`3>lB^U9 zkt=s$7@MtBW_&ScP<4#^{QzvtWx>)NEVD+SmW~-E3{AymmSpUBxvwRwAP@a7ccl)( z7nY91Ylvo%z)5x1B}6BYWJlF`7OFiM^doB;wTJ<5qZd)pyc2Bz^-#B+zDH#INxVz> zgofLJ@VGASTtu^Y<}{9d*+OIg+0yW`)(C-17`yjH=g^4N)*p>lf$)(&u9C8w>|9uY zw*}giy~dPg@d0Y)lFQSkz^YoG`dl~o%(V$|4aQ|h`LBaRCp zn}k*9A`ckpXa*8pQskH}wERkD^V-s246z)N>Eeo8F7no7$nC^e~>M%JVv~s#kT)f+dUW(kjwRwDF0+Uf|~e^g_z`^X~!!v zeNmuN~4>;eb3_finNGoKDyKtSG7*bb>A43VRZ#A)$(bZsYO6m{>CzM-J>5SnViJWWgjgA12_8tfIHV!+qZAjdLQ z9o+i`sOMK(T?%EWc?2_n%M(YDXucy7qmilejwOX`icAGe<&1PrA~_9FhV|#+!xnfa zoU(@(`VoU=n2>nk0;jDY)w;z<6nR0r4$I`QWX#HOCkV^{pT9siZO!)EXjPv?(gMkF$C@gjXHOIGV}r`}Qn_Q7+=fS(_k z5zIkcQ1*U?Dvn^(J;P4~Wk^C7$MTCKig_aeOJ%M)p94!}?-d=uWr{+4;$?*sW#rrC zcV)UFnwB*WW*(SFkX4Scvu-m94@;?B$@E^0sjNT94FZ56$WH^QREPy7<4I#N92p7l z_4%t(w!xC&aE`W{%@uQp78>JvZCF9nsX7P+UiYvOZ9T&AnnsAEoDnruP!WC2Q?B#7 zuIag3XLV9hYV1b~8vLK%Xa>uTk9BXEJR+hHXn$LAM*Xd;^)|uJ3T-RJKv?qgH?vcU z@c0If9oen!wvP2l^)SGO~)fHbC8%V)Lvrlstmb@ zqSLpRX|pu>D`Eb_9CjZgd$=}PzGqH(58vh8ZdDp?kBFKO@&t93Y&YHC4hXpL`Xh*s zt7DI0@m&(D6;}r3CED64`x3zC|LMDnHa~X5@Q=nqI5veL>^J_A707^x0{ga*Kk zG+U)kote&{b@eeStseC_3^+x1buZikKLHC{70y?vh0w5HImfY3&ZJ_!BIKCHb>f3e zNKe)@5}s$a4k7MXILs8umKbou6^>`+I{d`}T=~%ovVbOHcs-aS&Uurk2yj5Ytx52u17tFlZVj^5-mYFjPV-@Y5}+Q2073+zV&8)EWjAFl(heH0VDo4u)8)yC0$sgGCG zG0Ejivv*fL(Fz}=f&iXkzV4;!Lwj#M+Y2CNKt!%hPJ3tv@@2v0P``aMOlU;HTa!}${mfhmrZugr8C4Us@G>u zG{agQy`21svG*ku^GAU7mWKZ_;3 zmyi;|?gi%8A56<7F;4zWFLLt1xs-hMKBOCe>}s%ni#`v{}x_8 zA%`S#$}5M?7|ja*64W@JNhZoT7VcM<;5#Mrj`)0}f#o&4ecJyCi(mglBJ`-j@;!E>==pk?;P)r;P8NU& z&6jp2HkA!jvZr0C3V%`DjKw?WKp4R8Ee8W-_7;xByp= z4mps8Rx;_JK-MPX20UiS-o<86wP$oGSC0kW+cYv$BWi0_S68p)3Y?g!?V5a8V8G1Z z7x|CEoWLD7DWlG+RV3cb)h8+^rh#%Rj~MMtKGHL}&(o~~mzqh%@~Kx=t#22!Yn4zW zazlnI9^Z}6bIABDKb)WITD~3R{Ou;1mBC-W&}`I_mzJ^DbW=^$8HqC#BfMPIRxeAg= zI1{Pu+#N~90#s44teJ*W*gccLWGcmik?ty%El{w#%sVliqT)d(2th$R@#wRHqw+n{ zXrM3>#aUU1qRX9lvOHHf$mKG^SZNG@$E`PH4Qv}n!Niwm?IN`s(yPm!^8ovjn*Cr? ztwLWB3VR@iei(nQB)q+wUB!-}hpeXciGRtGF>mmZsM3`9WbsJmNLUjc4f zM17R%SVtJD|2m1!)W+7$4XvTF_!ISeHabSJTzV$uRb*rugOr06SAy?~vxP&G-ADgo z;dB6hvevFaE?}}p1jEAC=Jh?{u?4^JOUGxaYdG)@Pjt#^NsYnc_oq=TZ1CA#GM1xg zV)=WcZ>;oF@6b!>C)Q~A<37EKm$kfC$IJWIlU(XG@=r^=T`l53_U5&B%$D*)c-E&Z zE#(colU#ujOnXM`P+<;LGqo3Fqd?T-*POtb~@@)sja&S&n&If(HJg$dX*N(Hcfz0T@W ze4=3pC}7~D^n@kc!|(kxa7U1x@RFdt+7pTT6J&-~ACyE_3V(k6hdcYo5W?JT?$%lX z{zcr*f|iikTSGv4_GL!17o(}?0Nfi7@nFgC+97%E2lyFCXRpan6_u<(jDJ{?BOYx+ae{IKjEJH=Sxt7r0rO6v=yiR_+5QE@ zrU4yggMm3r$`TUi<8F#=*f8+D`G`rh@h3H@!-Y@BGtozH$9FKjXmVua$P~!R0VZg9 zV8iXr2lh00-}CP3c$Yb)FXA>#Ts`inqv$dDvb5Q7$SeW*#pErq(~KA=UeKsKo(6B@ zw%z%i1x5p`ty#8ROrb&!pACywS^`+=mCf)8-pc9~i$`>v6BQKAZhw{)Kde#Gn_?>F zA4Tc%q?o(TJ!go_x4Ikc6aXrJ-aD-b31@}h5>*U-jPaUCam8tjIn)(KJB}_6C_WJs z&T#E(^(PqJ|MO67JZ$@JzmLrE8?yKR%>??N9qK<5!GCC0?95#({*wx%Y%9N@@SP4W zSL;&2g2Sd$jz`)3Mn&`rBij8Q(NTv)Gq|Mp+$4|*;b{^$DkX_xzhNWs5KWX$&JJLt|q57 zhiooVww^KGm+VR~vb9(>->N4njj;=6(n+&{#(p`0k3!8$Md+4|32I#lYOfqMz%cT% zWU$q1POlq#miO>t@rS6M{s3r?1Qy)Pb+%xSAp)GTdp-cD#LEnm1Y4|K(wSv=ic<^| zoL+tau~B!2M3H1|GepwbD=Zc-@wz!GOwFmecWYSd_$;8%HNbF+)1zTUAT?^L1xB0oFmiwrdrkh7eeHJugu~9>!@I9|9@4L z`!}5D@2~x1)=J6L(BywTi(*v%mzZpfeB-b(ul;2iLMQ2NBq~3pecXVQ$u4_HnlJ(~_UxpC8v) z70@*XOtBLh$o+`K6oU`Rj(#T7W!FIK3vk07oyVHOz; zJPlgr@N|CG_TN5Xi&awZafP02Wh&ocV5&7e(F1f2@CI0wH$c;!X|fGRE4aL?o7MNW zOLQw1B#U%@Wfcu%wz1a%ls{EFkwi?-87XPrOt-JC7p0_xC29Iht*$~UM%s~Pt;Qvo z%JA*ma_!sbN`=x)Z7EhnzAHyW}%6wOd83F zg0oQ906HS&9fU(dlcDjHspo|@`*4@a=3nQQHl7uS<*9we5(Hr~6)D=z6OY&AWlQ^? z?&yB%U#P86i1OSYQLCysyTzzg>me0J!n9z+(HHJvtO_MtSTZ+}l*=^80R2TE8D*v} z&?`tdK_K!2CSEYkWo>*hVfmdW>A7j|0bfgMPcAL*vn|sh*RY{?u|?vyKo#0&+_fJx z$fZ3?00wt4>{X-8*u;G$nBh^_`UlB&1d$|WJqG+&*(%l)_eSr_qPBQRk(6Sd}FvdxQNywkf5NV$JG1AtN zb_Z#61U(D(ijw}pRdI$unpEEFOn$bGHUQe!7^I6F?EM^Si=Md=?Tx_y@v$?U#`k-q zFJt!(H$P3m<+L`OkZiMVF@X3ZK;lGmciVG0439#f7uaV8idkOPSAusLL;@^}Rf-MVm^_2eJ0D!4L1v5cDh!Ikaiz>L4v6ZpjEb1; zF5w8%pYuFRMx9A6;+$Y&tkT~QFfqZa$WG@H@=+sGwsVd$jd;b7|gA6IUOnvae0 z3fh;hAKys**hE;sdcYA#^;!zXF&U@p`J``+!;0XS!C8f+ zi|H9bbw{LV3bU(iYa&%hjdXcOwbt7RtL##dC7#V+a@%$8dVXa!eG~)6;CP znU5Uj89x0-uP+~C^j<68J;5Id$eRJOi7wI&nu%{@rwK*siFAoJ4+c0b(hUPa{O8FH zy7=c}J%Lv3Sl7Ei?V5jwe+OUO7%)6~)Db}Na)v`3{)K_YS8|Z}T~z9IC7h5uz4Zay z0+P`6+j>W!mFxtWQuc|QoY{<&%ciKfO#OG2z!}&-oQzAE;2#k>-XwnLO-CB<=^N3Z>-MDa z{-kyeI?Cj6aaF~-8XB|hdsc8hPYroE(ihHCO?wc&yN4{#d%(r3$S0bfk5Rt_?A17_ ztg*&#rY2h%KM{nHhe3y*dm*l}6w0aKp(cGL7+9Q_svy^;%2KjSjny(CM1d zlFKPQ-e`C*M~2}9h4_0TV11SNTVgn6J7!>-g0Y+H@Lcwo#e^Go_h>^I3KW0^vuUvL z*md?9s~?GykFc>=GM2VWR@pY_bWR=czL?P>uZ=39@=>DZIjb|3iHvT0GL%XfFa0*}=1GqDB8@h=IgRn~ zp5a7?%)10Fe(7002$#emoa$*XKAS0Rh0!Tp@)LaHxG@P6Nwc!N=2a}~x%rZWX?d(! zY~c^_>}-1(Ms=VJ?c1RSEn2;-V^FaL8l1& zOqdHAiJ#!X-wWDD;MX6=Aw z`&lc|)uXjR?m_OV87#yl2M2`gUDXZsDZ8dtZnf#&g}?Va@6(bd>aTb#l(w!fy3*tT z&BI@8{1ACZzovRS&7nauJr!z-x>RpyzWE)pQxXv+>}ZTVl}pt*p)*%%__p;2%VKmq z>xnEX6)!1CP9B>?B{e<|&0J5v3M21--QNmRKJ%dicxi5dVGa?z-w9r-;${PW5(WM& zg!tM;xDbWi%X3G}6BsF#*wuH3%>!V5#!!@f!Ra&z)x*|UD*%-01pD})*MkkRYX~W& zYJQ9B1UijTkGg5igm`-JQ}K832Z0?c4A*kfo2r@04d}s*YlSH1jqnOOY;$PBJ(lacI8X0)x@2(j z3-H2t^1b|d{7L)-{UoOyhF&$T>l{0L!G*!PfkmrgeJA$Omtc;I z{}$lr{V^Xk<=V;jO~Y3&SKV2IZV22>7Q!R=t~0FBi-*Sm17cbaex6d?BycPF(12@v z?v|A20MvZ2anUmX&mofRgP4h-UQT~V?LBO@sm;JGbb_)o(6hcST4tP!WL$K}l(Tl%*26spDe-Qfxq@_;8H9G$lC13PpW7At zHG!YF-&ZdGzf`%f{*SI*Lt__HCsAi(!~gg8O_a4?5I_vwu}#F@Om2x!O;wV58HXrK z^#uG7f|jFhPsRkWrs2;HuZ6HgsCRYn2ZWT}sOBY(W^?G*-zgXJ~ThzU;RJ%PlNM9bxb19uy&v#Df^^uYY(9v==& z9>qk<#@G2-^OAqql9~MXfEkZQdChu7JLdIG>=J>lU&i!p(7MxJ`6kiurWn@rJ(5Vh z+zs=#2F z+OQ?1$QMz<8IMhNeg~Ov!MP$3(6Npn*?-M|PVObwQrkM>8^29QeG z(S6vkJI!Im4i_CQ-e33*P8Ah{&+#zZ#CBFr>1cZg(IYi-UpPkfGw#&K^t0~lkpqfR zihOdC@fxCS@*h#o#UH!aE%YY`i+KlZZGcT$%NQXWWIqoqG8{CQxzM*4tuT&9ee!^0 zpn=&{t>c|ID!cD6{*lnJEG#oUf7ek+|E1{S-zRjE^8dwBTbycbgR71<@?~86>*8Tm z&Zd;qcEL_Kvu0&Dt4R*JC~h^&b(OcvwA=D;up3rw?aJBtbX(*8YDow??`xpYMpIL= zI51>i7;!UNJsEK^fxG0#56FnXcy~xBAR!_D=k!%ZIZ>5naz<7}^^ zKcCBS3?OY-J5YOK-VGo;`I1a@qH2*?RKci?N(V*hNyH38-akr%6cizE^H+iJ#1LWH z^r4mcQ;X`j>%v)-T1m|(l&VHY(HYY+-W_!jLjBm4xr8rWDn^o*K8zHS#_kMuuuVP@&&lce^an@bMnwkCXd#b z!1Sxsd6AqHq%eq#{8fwJN?{6NPm{RewNy%82GTM=NSYwuh z;ZxJaQJ&2i!}e5bq+ZXBu0a!>)X<=^es4W|=yDAUym4rRuSGZ;3+P09HX4R4oOfoe zjfxoBYhqkjcL~UxPORHY`Hf)Prmwq5*33asHRdE2GIo%#N`P;XyfLkFAr=HMyY1xC zr#62~PqF~3{;uV;#nsbl9vLl5MVVIO_5fl|-8L&8oj|G;7#qqvMBe&An3rq;!F+bj zvU03aosFJV^bc7!x>_YY=$JIxBj?zZJ%1ZrQF58jm1g&dPsJUXzNt3n6o*HrN6ADD82}?!qnD+L0z~_ zDZz^h`s?p|BbYOpA3u^U)ak0%Ro0XthXjsVhA6VMYM^$Y=}$+3(b%6%n#`7u+;qW; z{vwvFr8D!?pjWF$h^xR9QyH?OdX#Wvu~TFs9@3)J23ier<}T->0m^TfK+HTfUdA^0RWU(p_%|<~cJGiw0thzTY3xg;1oQ2LSDxyo?V!Sw9eo0e@`U0|JI*tuF%erDKp~sQkZl7STKNBS< zTxtlr^ezw3Fd+-{*=?u28%&+g(>^xv*XC^b-v01ix{dH%juQCu#kTG1d2K?6bl<3r zBixON!0cR4<7oyVE7BK;MygSHD>X?1(ufhUy22kvXGL8^TJ%M((Q1^gk;V;Ol%^9K z3GgsQIpFgVP&Q9FYp0%!Ae`OS)^F zT00*%xTtYAh<^%=OrSaURPzdZKwR1wte>*!7Vrw_uVjJi-=@t*QZS~_stnf~iBMwzcp&T5LBZvek+sQH31?I60kaWUp9j}Qo;YV; zdqC|_03a4g9omrctEEo#htQGNyMogso{8ARu~FVt`&HrluE@HC`YRW4hw8-wAXT6U z3F?58y>K;n|NH~gwG`6Yfn^QqmvgO;{7KXAC;Mz~1t^Ex<;S>mc3y-0 z)b8IQeE${vm3#ejv7aKrSDaJXJ7ys?n-#^k8sk&E|4ZaK59$jB;8z_&u=C^c7r?g_ z7`yLF?0E<33j**(`mW!6-O1q(q2u057b|w{hw@3#|0VtW1^MNNcA3O+k(rosjo;r% zZ}|4DyRvTkY^I)~YUEgR-=Rk7klfYXAlsA*Qj6^l65b&>x}80|YDlRiItZbBU!kHi z9W}#os<4#6A^M~)64e`^`Pk<2?UQaZtoSv8&3|HQMX}0sMDK_Ma^u5mRG(C&T|eAeoamAvN&rcblnC zOV+b#eo%7+)Sxl#w(Rw*5oytCY{XPra*r>Xl*o`PdDEx|{zLMHEU!d|hBnkYnc+Qo z@a6pJ;o;*6?(efYDFm!Wr_pGz6$lrs)Z1*Jmv<&Wx#p||=^m+IL5+n;E}Q2;B;R*0 z72fxek84^! zkMAvP3uZc0XNJoM!la>6=;9UyiLDryrnw|X(UW04Cye$0(amq}-6h^ADukEZ{(RbC zP&Y{7W%hD7BJ#}=@o-Jw&Fn+UZUA@-Br;A6O)0*_O0gFvJ_1X#fJ@#aidsqbf)|)y z7kiX<}NTgk>_%D0uoIlNT7OnQwxohRq?|KYrnHQ;~=9cVd+OU$k!jeahh9 zG?~7Cp_H?|-FJWKThAwIXZ$S#`_D1gY7HnCl_jjtPZ_gqlUv}VcyS3}!+z%eqy%Hgt4R!_+O%$OV*ks@iE*81l9kik%hJ z7xjGABVdv}Z)W6Bh=S9WPSf2_Jx^a>Z&y!#ckgrJ@F3{{>U?EF>e#H_ns8hAlfrSK zQ}~=qT|)y?^k6zAa`ft)+H5+2fLNL(hZG3?z9oE{0re$^nDtIIBp+G06%PkKI|VO} z3IMsNZ)2!7@2KiQdz&iU2HIa+s|QzzYi!Ogu3o?ckgG!{_8)-%F9U&mZ{?fkR4pHE zxL=glJXR07O7FS7IoN-W1+h9dSM!gqyskmcU5wLkI?=jDf|NE7{eR$Z#^@FI@>xCS zhkB(X>SAA_6w#G;wiUZcK2(Saj%Th9icS43;r1#Ni{D=DvRYcBi#k(hV}~lzi&w;f z7p2o5?HI*~&H$Fj{pK7It)8$Xp5$_({v0pU-(FNw*6nOcxJLdP&RP`|9ZYmDCt^3A931+{}|7XMbW9w8hTv7(RQlG6T8l#XS73yF5;a85LEQEQwUa|;nNW5O8kY)T@@-Y1^t^rA%7{%uy? z!pv~a@=V^IU29P5=&Z?uIW1jmv-z+*cDNqQ7$$6u?+;gxg)E)3^ne~54C|)6BeKYp zY}Bzgx+L74xSwke}}2)mf2TP5&!fvncFx)j@mhfQ@Xf z89953Xp)yR^x2vG4%oxr*hzFh&P7wPs$mUMWVGhjG43 zYClE*gS;^(`b}08$T*L&JmZs#DIy*Q0ERoWUSNcocIAfTT_fHvu?{^suS9V0>r5i-iN!!2nlD=z9MgtF$w!Aq)}4nhzsuUK6ma9 z$vhSF7=x5DPF;c%cW8N^qUnVj7GBzP zR+FCBw!#XMi|FEb)s+hlo@xQk!EtAA0eG{E}k6#~ZLmehE!+-2Qx8tFR#?nI&56=BRS z*Sa_5oOfY7Ug=OIt3|%SbUe-7bAn_z$PLjYBXs?9f6MT?qbtHCo7zOtE8V$<@x47+ zHso2CFxSgiESSNBs+$eUM6%~oujZ4D4TsfTH7@T@C7G&qK z2+C0iLXq7y;yDoUO7DnDxZBNBR&Jg&=W9bRg2dmr=J9sUT=Ao&bA9X4u2f*!epKp| zPzEE}zz;K{B8Qqy2yp_XJb!1)8|T>~jNCo`wp{;Zgd#7l4^yg+ByF~OpT zKIL2g>hW2hiPa4H<5!_xSS8F zIfJUCzS=7;a}ZLzFAvq`;dh7_7SpZr!vvjI?pvJ zm&1gak+Qlc?94aj0>^Uv4+K*Q2G&q01-yxR3633!kM0_PuZ)_oG0d6&s{yK01>Kp#K`P!V4~9DmB137UGs?g(+)u;8T*nyn#^%JKBOn29QUJ1 znTBsQ6xZgrI0)=wOw&C%>J1$Iu`?G)PI?sOhus_k6ZlHn>6P7j2gF%@NP3#%lhdV+ z;0d+P07H0|1KZ_5GpB#;%~E%){nLYYwcWv+3yN=8)(yK|-;N{AXT-%bXsaZ&9R|f8 zqSIt4k6%R0v4rA5_WslIh4yS!6h(ct`Kr$lZLx&vVm`1WhsrYOzAoO8RKx_vdtsPK z{e+C=iFnYlqAGI(3eWz-SZS~!I%v=y)TqN;=&LpIt}5J?`R^VzP-1`SJ(R%0)R+a^ zXKdTL)z61Fb*3Cfj14*fldepVE=tjP$HbO36ApIHk$~;(rYRzm{C1u zBiMaygS%=Onv#KeDY#=nnL1G}i5K*=>X<^6}%%FXI=o8EuIZA=C841d^s>Lg`eRc=!z~OADYM`?QQHdVk0-3f@bEIKttyvq}s*L^9~fMCnF}s zqRYvo%Y+M0W8`OxPk$r4HVQYl?4H0G<2;7_C&!Ctq2)^0QGo&&=v82x!_GRFi z8s9wqXUN7i>!pG93kYx2+nVI1x%|oq`YmJb2#q_CJtNrmzyxQc`e2AYq!&9@jQ#{_ z7d6W@PDa#<36Nfz=yUhtK3qGdy%fxLqT0J+$2G-Th32g5FI;w2t>vBoytNa(uq$zpNn)EKrDZe>9t#=BaU@36 zs8hL#VR3YyXkyF~bLtWo1db^#Hz`8aA*>D=ieokEt{4|e>!^u$6yT5gbU%qwI7TsK zPomMgniS?`@pF*Oh`16_eB%&RBdP8*Qtf1F1haU_m=0CKi&Krt7;!AdD6l3GjA@FB zbmyXkgw@cVWZdGIsnZ`Dis4q%^7DA`HM)rdJENzG5GM(>btp&pVN#TS|F^ba#1y1L zGQa3tK7L~@_(lUQMYqQh8&9Rh70ZI9ax?TYf&%j75>Ml);&pzRi52!4D|*+;lwbGD znp1i!+kNoVQ8`E^bk$x^9<7A(%L%#;@mnU$%I8hZ*ADM*i zF|evhi>hWtkAN!Xt95?V*dCO$WDjGVLvteo1gYEZ%c+#<1|Lf1?DeAz-tbzgok`H; zccO!LP&+i2T8;ZmtGp8=oChB2@3rq zX+?S@6-iV!qkK6d*bMqm8IENs1okm>9qP0VdPkB6l*Qs>ZbQFRil%5X?D66kO|q(u z7iuqaT%psy!j#4^Tzr*X2xuN3oLS1tu<$PtY-A<$jqrQfBaPH|4dgAJd|PLuMXp=% zCxyvFhgOl@aCe8;+OT@1@?jr$0z$!55viK$E4LMEk;lKibpFcJls?b(k$bh!F~={& zalJ8B6F5H=o**76?!LSMFs&+Wffz$&VD-3CI#cO%&i~mBXjE4e;Qa0cq@(|<*X6%a z*L*)sWKEsSO-=qW{AOtTAAR^3Rc(13bJXnS6k`#ko$oI*S8+hFL^%C0ZI~huVx&5WjMRoQ{cYKQkoIhZ%+knYq}-K-q~J@0 z++h|PvJ)9e0N=)n1a?O2-OSM8Vx4jg*Om(Gy$l^ol6EWgirCI(MTwfV_6Mo*^vM(* ziVOy_g*)Z#rEjxqvA3cyXQSCpL)662Yi`&FH&au;sjs5a$dG;v{Ta($N?dpla5OP)uk03Jd9WCnL< zKUz8HsWocn$+g4vnAv-^X)5)*Vxu7eF=0Y=O4Y6n;4Z_?Gh8ET*~Y4dtV5@oIZHHWFAe^a!{%&F)g7@c$8EoIQj#0S1Sl*`q_ga% zGsa*_-L6(qJk)}-P6Q`KFc~sABhqBDg-RpnU9!R@+_7rYF;i)LkoW3jNN4Sh1mMBr zSsBguxQ}FE$3vVknH>fOH`>bkUcaz$$qV!M)46fCbADbYDJ|Lc(QnI|wLT!B(bsy6uT>oE^Y4sBEaU%ZSf5;BXj$INPEZcNCRk3x07^i+qP}n zwrx8d+qP}nNyQx-9ou#?IcH|pnmZrPxp&=vpuW6S_3r({vv-@`+;`i++zPY}ebIra zaaKi#i2u#aPOgFkHDGhy2I{mRR0V02d0?6DvQXkFg7N|sk;#_nXP@V$3Ih82C*X?y zz>mPe`$DyX`i<}fj?ThC*Et=AEyu2K%tbhb^0NuUcH~hDvW<7mfj}>FdKm=yT;V*z z@dgd(Ra*9m(ByFtUwjE9^}AdWKAb>QM3JxtszvjWE=lB9#dD(t9qr9ty#;klre$tdIttSp*!QZn*K7k=JDzv=Lu9B%=73DJIVpk z=LKCOh9|Rz{}KQKioMVE9}lw9pCvZ@BxebJgd~mhj<_1Lw@|zzD!dA>4W9={dt1~< zHz62x%UVKn1c}+NhZ-K*Wo|C9?tI@j@ z%FVJB=QhZpgw96Ka}$_k_V{>Pyuq9O)xeJ|<4FdyA`1}=k|)~to^VN4S(F!baU!g^ zF^SBLYU)B(B&cV3ib^!c+q_ZnFAUry)PPB?ecc4}`Zi_TD56bs5B_8zj0Pb7u*--2 zZmcsxo(?FBbU^<2LtNW*RAUJ5BPm_IJIOD#c#E2eWq=Pj1oo zw(|md;xkdDw~$@`{{0@d4|2OQIc7GOz-Y&HFHc=w_XYkx#1{}rTi)QGm=VN(8Jnj6 zZ~aa=S6d@fr~g#Z{#RgH-P%EU6!i;DS2C4mqtOU6x>y4PxY1*k(I6TY&hJ-3!XXNB zKLXX{JOILGT%u9fBCB|Sh51w_NnbXgS<<33m(q<;GRiWYEQgPb*7q;TLhy&>d(ma{ zsmyjxDT+g1PiG=NqAYcs`*kj_H{Q1AX3vUU-xHTVn9oS0)`M09iub`yKB{-a3>5wo zc1K)l(+Yt)$>Xknh&=e=P5c2bNm$(E53}J@G<@vQA95|Po`{OwNR6XFs&>c;BYBe8 zY?ze!xJa#iPCMAx36E;9J{wsrS&)^lHY%}Na^IMFEf15}3gU1Lh(4w@8|R zs5=1)+*7bysQ2>)T$tBjPe9IQqifscOcJP!_FjZXscQdD)fRQW3yE>EDq1x8;_S(d zf95(eCI(T71xcb*Re*?C{{{CdBE%w?g^)cN67MoD=3GX0FFZEYE6w_@0TW|7|CTGb z-F(zO7u(os$iyFHxH7dqg=`Vg$2^h&uN?9{z<&(e3V7yno+p1C1p|BBv7jEoY;0-aS#107{#;%J ziRfsvWl2W1%_uNzC5esrfpSb^HXD&79IU?{tD%1_8Vca5Y|GPzAbE_2Bz*=$bK3Ru z--u-pH8$&O3k;1vOCM#ivp856w>R=@b@k<8^M=c&Jd#rsAYd$4jM;)`jfK%W5APf^ z`w(Cz^d+qDW8eXcD9V~uJoYiLc_YZc)Yjc|5`$S1X5Ao_>?N_qi_Mv1<&5?umpN50 z$u5pKWuR6?y~Ki3bc|OkXjV*VFBgIuklhDRsJryV z{i1||hrolG^;IHk=h(yV7P+URE|5H#gakxZL}ZP3L`*Jv3MOXeah;PXVtuD9MPIu`%qY#dpVL=yR-6xaX*jSy7ZB(t zpMSGCu$V^FkD1IgMp9vv!=>MKv8|pP*Vw6lFFO+IT-|dVH)zM1jDOZ}U5*1cy8vmm z|FTsFS}z4|J_NNeb+*ivgatiSf^c{2#x_$a!kBEY++A?09)#+2hu5l44C#XUNd!pQ z6b-XV4&#v}mW7|1N1Qbc-+AtN1hn)~LNCbbAYjSJa>?kE%G{N_%lGXvq1oQ*hZ$Qp2d$^NYC(}v&;tlAQ=F2Lx|4# z{ozL==8qmmP_Y%vF2aFNaMCpws^@fhxWM=IxQhUX@DYSDBJ2@dC5||vd@{-$zC#0c zgLCX5z3Lpd4m%goYzT$!gK)h%gn>EJ@~0 zagxr8-Y{c1PpOYNrQ1IueQ8kZn{);pSwLj~uv4Z$rG2_Z6^oSKi7HJ<1lev&Fyp$Y zOIgpAToOP;ai~wcAPYk?l6Z-hm2qg5-Vty%Cwc`k$srayChw20O;M$x*$t@a9jBMG99?>pvLSD(x<~~q^zrY-X&xy4i@~%d(U52JQW>{BZu2@|PRSTEOIZ)${ zAkDXs$|p7{=OL&OVJR@0wZkPIQ6T)qq9)IIe-S~<hdVjM% z_2M^-ex}<8=P`Kyk(%)fh3f`5`DW$Z94CL#mFSyy^o%-rM``&9()JyMoTzt9LUsj%~k}pWRHxGm0bYW88x}v`Do_ zYqp~l+;gSiG=Zfv!mlnU|1CYEWRjceu0qvicAX7`fLlmm8f1-Z0QLV2_5V!u|BUtj z%=Pb)@Bb3${~B9-Mb7zTp4_4L!Td=1`iKF1xqH39rw)OyhWu%W`^=iRSA4U5D#3gz zhJP_FHju$^6#7|mT7|%;S`g|lr^an6qGvf?x72BYv|Szf40IMIqyA1*Mw!%^*t;I~ zXi73702G2@$rK}v6v4Xci-eMklvEVTknt2NG*w`N%o1vI($t|6*0nh%t^J1#%jWNx z8Pxj;Q`B^()YF$iG(pjJMI*}Req#|xt)3qq2Is+`tckib5^=XvZWyhpa=d#SmUp8R zcLVG#yduZ6*yL;DoU9E|zjWkbB(RU8;LZwrl<_f#s4`;$-BDz^kx6|CT#nqv>0%}9{Pov&90{2v8TWmj_jSi{uJhIFH1G3O z#EiZ#hydqEcKN8>3A=Qo?wwsik9Lhy#)ssxdN#$N zZQ>?fn7c#-x9K(AT9>xmCUMxa6w|>l+(q+5i@Thxtmdn%?0fw}#C!c@#CwBwBp<_z+t0N=>uM6+ci14{73C@4wxdy8@QGaNM}c)gq(1$WaxTDi0k1GF5Noo+RqK z%7wb406-8`zJjB8&k{9E6-SY=aL<}5SMjzQcV>-|YRAF~GGzU1Ww{m|;St#KF`_rX zq?z8+m4y$Z=?C=qG-5!3Vq;e*5nt4Ks;Fh6s+`4X1?}jT46RgJ#$p;zT4@1gFQVl!(=;B zm}4UH=G{7C?7}`|P=^;iYVLtM=Mm--8ztP(TWiApEayDmfQswLOg8OcRNqJ3+9`fT zI}|S7RC}Rh`7gw}VJ<}W#KDj@knSP>ZwPH-b<&XRNpg4jK>`cm!62;Dla$Wk;QdP{ zH2sb!dgkG9OnBFdNXZEV|LE&FEy~W#fLjO_#1lTs<_Rq?SVq zwEEcN=sO(Mw<5@}LM ziAI^k!$gOW5)C@d#e@^uH5^=tk+-(z5$RS2W-ugQQrw6y4N3XJgTeTA%*a;mqbg;*0yGt8lO}0!MW<5E?j!W8w zg>8sUq-M!%sh4!&f$ z!*%{9Ibl?+#{xQ#>v43mxs!=D0km3;O4vb6flFGUheL=5mUhPwOwp%GHNN(f6i}=k zBU-GH9ZD2>HLt5K?rLu^y?nM+6TDKgPsH`qMG7=ay}mjUV&)|S(@bEYM^2TptevK` zo%8;Mo~XLE{b#CFk6#rs*pGkjs6r{}*gBV~>i!yd)-33ql#j(fcMud4- z3=fW;&>LK!GoP78`@$CCnN(+C9>PZ7!@}rAH$!J7kZi@;Z4TUb1dZMU<@S-!MhUM* znmZ!viSdsx_^VUCf^0_PE5FfhM!Gv<{~Nk|38&sT1=zInO!J7xI@F?&C(vKy6$wEY zuG~iE!qdBA)s4O0tRrWPOgh4Kh*+`%{|vOTpB! z&it`BWu-50`$`_argsUg@i;ErZZgI-Zl`w5l*PX>A}4R7F7Q|>sz>eoN4T}d%;n7X zyVn1&H8GU9f`n%eHvDQ2TiuqwnOVRJUVV(*=Y%!&9TkrZwhyzxW7kjPks~NeUspQ6XAW6;o%pdeD4;#q^Hf7(YSse4seWD9XQu! z3CR@aYiq-eVA_7U22^YSsK? zq^WYKJy?$7WtX#Y8p#~y8tB#*7ZP9{;4t|@2^O-jbk=+89`;MN1b zk8rs^dr?_wRCpJjX`y2azd0-BsyC`eoDc<5Eaq_46PU&&z36qB>QL0=he|q`b)7O=pGBqt zd5%`{2QYQDCFXw`DxGuRZ3<*)N>(0WeL&UMaJz{^GG^A!O* zvdd5M)<@w=Aai35y{890?-Mm(Lk|aeUEtKqC<$bwjDYqm!1pJ6T}cDSKj`ql0hAfw zywT_|M+0e4Vu_<(`C?VfzBzcR{gE|zVjrR(hUzp&6U7*&abBG~#&k0mdfTYX z`7hA;K%A;*nII2j>bjEC7XSIDIMdY`LDUC=*`T4(ccED3hvyJcIg8wnFD@s$)yZCK zZ1hlZziQRWjklfQ=J5YE9h)wEza$KCxsE5mjqk14Pq(jFT*Vbc6P!ChGTTO=xJ}@G zbVX^=;sNZc0h}${m(D05+tztXcGbGdXf`XoCWdP4vdkeXwv+`cy;2jocz~43%r!l5 znzrPGN1ZD6nJV_3DvFfOGzeW)PPr;waalWKQ#xa{YIB`Gpb^}W#p*>gBVv*~+9jKI zh3LKs4v2H&QebF)@aT#15mbDK>bpdIf~-fTaB+fk(5Z3osQgz0JZBU8No0BMdp^-O z756-JN6f|kZP%n8x_z$BH)O6KFo14NX%Fwzy8@*_?R+5`028lf^2yIs+LY~22@_Ik0b4d=37IWs5w}%>%FYx~uaam?O>_VV^{lfk)!*V`4Z`@-jd-w@=5JnqQ@z=#L3J6h21r*a&|Vd+=PuYLFK)?>o0YuO@j&8z z0DVz7x~)hd-WnJ%jSrdpo0@tbJ;(M(W|1B~P#Li88||mV ztkgvf4h1(G?vXf1pc_%(NC{vuhgnne9*#e+tT52P9~00K{}MUD=DQ6?DH~MH#O8|C z2KmX_;ljtvLT@*jZ~8*08YuhMmo&crWbGOlat5OL?=UzMGQ`a+ns@xlKDo^(a_Ds! z*&l9a2l0lM_>)Jplx`wN(DN^ZQ7zSV#@chmsJ5i5l-@Yt>hgn`hUT^l`Sp}$kSXK9 zpIezTAXgOLO5PYS!+fN=H1zj+?{%%Neqmw}J?2(N@IW2VX3Bv9f*0~E>JZk*XU2}< z_4{-8feNL(2?GvshOm}Tb&9mJZHNi8s)DO?i|u@X|Kp(n_sl)0{KV^o|I2vYe}nb< z@vxLl&23HXT>jI>`pMX-JN;Bb|5wB=CfQbbK?7yQQTCWh6JuS>E62BeG{qD%i;lHnzV62VYmM#yspbeZVuUG&9FyqnCeo({l`2{8_@7FF;2%8GF{FfNdSxa%(3Y zt&(F#aLLr4E%du7gwqL2XW{hnoGhx{VkigmR(0kpqlEG(HuCp;YnPwJ2a8ETNKzwi zCbJ!nom=2Rd1L<-oAxgth0o~3@)Z}!zMwmG7PFC)WGq&35A#4$o@_DZ)-n+E2cFU; zk*aqojETt?M`A|8fCsWt9!0UkP}GNQWB{NOr)R?SJ5tR(jOqHRdNaRQK=zlI(a@Ero?QQdkPz{lr|~5 zG0rX>^|C6=a4P($h?+XbQ&o!xR2EMI7HJfrUaN~Ek$v;AURfb!M`uGc-lP3T^xYCJ zO|Oj8`49)Px6KQmoE*IqlzPOiB+QP+j^=x?KZU;3BX#l*dOD15br2Urmcu_9oUTh) z5<*4M7bestjdKVB5`UK~$ ziE6?ePXE)4cF*-4HTo$Jh5wh0@c+J=rflkDX=r2V^}m0~|4U?0({w;lMd7tibzwR+ zX%zN15J)v4BczI?h)n#&mHwNMB)q(V`IH2ijJd!Z45F6c3R}9OMBmQ9@(@HNPzu$q zL`{>f#IGay?NG_;G)+2U&vPq>VGD-xL*n`T`HJ^=^ZlwP>G|9D62t$#p5Fgdqbi>m z{~Y)xzv&m~36ueEZ9)|+kWN$#R4w#P5wrifW6V&V-5fE0k<${jdZ*4K=xiL2 zB@VO!LKbkiu>>EI6Fntn*r8Puu&|(%pcX-$cNE&p39xBR&^lTTWi9Dj7T3HO&0L>I ze!I6bS;n$A_ezaUx7s!Gjg1W&#pyJO&U>ZpDpNitrRB2F@YTRSS=>&Y5x2}MWmOMwjei#ldXLz+kXEB$`qgXaxSftXP0>1Rhb%6`}ZOFEx}X!Z0(4q zt(8}f7SQ=5!=q>IxjaIXwccB-cpjP(ey=(;tO?axfiXaY>U=orhRSZ(+aGA*R9+!3 zUE*rIq0ns^FPbAomRTq%oVMn&-!P%N84aMC9>D=^D{n__t7ymNR+$>1LFIM~i`42^ z58+1Htk|R5tl7ic{Nb6PKJNp8!dH4o2=PR3QLP_X!9P`6j9RJ1aJvJ?BuU_`kY_o3 zC{c|_6TZ&|@Yrec*PNjDXgXr(wzp2B~h}ZMKnc$UK{#G4y4sHS-x&u^w?4D7|F>_th9Thk=889-G~)# zn+0pu=AE<%?!@p8FvD1vVBzE;LYSCCOu*4b%y8$dyQoOgM~@gAm`!mln}&J+3v(}Y zV894F>HNUBgz*+XqDXK2Jg;xid6>|2X^ZGcD~fm+TVQENH$d|>CVPB+0JGR12eqdE zf%`Z<$iCfl$(|K_t=o9`QtKaoIcARA$F)le%)sjMo9F{CGIp@3V9NV*iSYbpw8!41Y8oNz+= z;4n-&_+&&|V7XEiK_mDv(#9bUTo24Q#@*Jm`aEai;YCsL{pHRP1IIv{7YZo$Nga;h z&Q9>3T+ii5B^`g!R&m&Erxp6O%~D;K9)u{{1+5L1Z6r00v&P=oW%OO64X+s7Q5UVM z8X1>YYKlglC~ecyr5i!@N>)DagFh_Yje06YGcvAx!;UJ{8bUA94wi5)`N+M)!SK1j z{8PtfgV@3HhI!57HV2x^m_3Y zT>X#IsQ%(DyDLsv>>m$5U}z2^`6a~(M<22x4V3xjOP3;#N^6uTBdz;yu8lXWiHAE~ zd^lYHZFVd_bO1~l*KptGjkoxaeSW^I5No=_f}EHd88h)jK{%8QYDzhxsu_x(2Wpdk zEt~Ah$A2y33K-f!g8!*G5%G`IK{pYeV0)Fi7M~C;G?&$OW+H~LkzPUXA z1-BFOOUrR84h;vLiQ<5ekUW@&#)LwEiDolAK8fiw5St=x3nFEb3lB0MtjvdlcHiQc z{%{drcEWi2N$IA-FW4`d1NvFR7Y4dXWWHiw2H*4tLgaoqnb-Ko-D(?WI)9u}03ZEu zqNQN_=x;|w3CXY;V=+Pow%orDhYOm-b@_5p`7FvbT9`v@loH_vMiUfd)fwHgg7b`= z_E}Yd>kXE~_9jy<*HZ_@nlzLi@aFfLUE&3OmIi~Fc6lsPt(w_c(=B$>RoUI7u2m_$;HJ#UVq_pYOWjb0jiILb% zK1)S3n%w%F10gAq6J=7PwdrvM^`oYt+p^TMPGJd)*+!hSHSN|qhBMVfwQ0vstiX}= zDr*aKvj?Lqssh#~9sHIi*LWi6WPm;Jg)A2AmX?s$gD+f7bRu+03}v{eFI@wEg)LUrVA=9v|C%U71j$;#|+ozO(rsUaZvg zl=%gv+O5VwY3T|D$`p@uUyWtd;CHx1%S|WB8Cz=NaB6~WmCer`FZDSUh$eZyv!oIO zZEGr6S#2wk*2c|Mu5MHnylLK4QGi$qc4Lh+xR1lo&e-04*U-YLanT|b1J;=ElOJUuD@&)d}H)_Sz3Y5~BO zv;(9g^xU4|H4@M5vU`Cw^en|)uN*WwpLFL&gPkbqXPC!#80DHM3FFn07)jp#nPB^b zMQH7Qd@LPqn5zplfUhW@CfrWfL9yTTX{u*4ltGu=L%^;$H>wZvlh;EhO7RkkXAUqX zT^=c-OuJG?gkT>blC~Qqro@{d7n51*X=4v*oyJO9?166Q zpQMwFb1o4N`oZUTfv zwjR*Tj_%7%UZZ~8j-z<8IrfRtmisq2 zx6W_Mo&pE_xB=`=C5thoquum_-Ifs*cyRYJH&|}@8c=Wa{f+kMkvE8pa0Z&r&U&&< zJ10fMr)pBdC%7C+ayiyJkHP!s1?cjTHhbWH_#G;LU{k$Vc*tMlLQ>M)fQ#5-F5aww zO*#Q8N&BSXKT-xB%LXdHe0gH85r=p-9!s(uZmjhN3VMea!vAfP9yj*&G5#I4j-lVr z@AtxV@9ZLuQLmS_Vj~h6PEZ-WF-_B=_!jP@MX=Wi`~ws*aUgr)3(o~zBc{QqIa1a| zd~r}t@j}cm5UzC1<4d~__e^w}b32x}Q0wP*HV%uPz=~eARjrRs))Va;JH-3YVw_ah zzHbOB8!L@BjxPz>d{?zDMmj?z^+siND{M1FMBljLG4K_>a%`>h&3OI}dt?bJev5Yg zKwiDxrdhONuv^yriAlGE%NOT2T{c4hQtO!~@2@|fC5dQWnCR5KlIiypW@)>;g44-g2-{&9*y8>#996oX>F+zw=+7D!p z+CoofrfCHc%#LXf#00wNAMEQt(V|8`H7rs;o2=9S1GMsgw?6-Smg3KA zn&bb}qIxvE9g>$&zjI8Qw$0Z1&4!59w&GKc&5$7ozzz^)gopxuGr%(#NT+VeHrB7n zJ`*CMDk@U9s1CQhuBzktN~>=mM!bGp?0jlt8v^k z5Je;$hpd*0EPAY#%G3~9FQ&l#K;imuk8ZfY-|Mwt;k6r}6-npo)EMXeU|}6$L4JaV zrUT}S+4V#b$)J|dwaV{XYV8c^@IZ@e=d`QF1F&eD76Ys%X_#0rsMN^N3MC&RgfUcj7+J?m)WV-g_|0?YcBcWwa3#^(>TVc7&?RKBjVtps(VCp@cLf4$rpv(= zD_>TKaLmg0s@|S2@bc~k6WD9>!r~OLj0geCUb2@UNwH$AfjejnhEoWlqhQvHQa={e8)Nz64w(~)KVsQew?xVa&2xw#yDVO+1J!jPp%*r9e&h+QLd{?Qd>YXYDPJ zm(8@(Vue4dEzC<)tG7KQLY|BWawEIwawJ&cLnh7xvNwq5EZW%-Z~+-yxy@wRFqPU_ z)O3sV6n{PI7S12?Df(1k*7r|E7&cK9Z!_oD=9;G>5VV0rn$s+aCc48%H@~@hA`EZo%?3)XOah=%BL&}*E zOia2#ZY5|AA1O&yQU9rIVy{3ug|zWAoWzh+_|6TIecgg3{sWq5V`cS7TcpvWx^W+Q z1F103=SXIBA&8go+~?ijWN?uV$#*&s70KieU_EK zRUeMf`wMEftOyGl@+qo)Qkd~MO8io~z0YQ`H~F2k=n3x2bm7$cDTlA=kb_%g<@7xz z!!v~s{nmz7&AB_V%Z^XSCr#myANKY*PbjzV4(0Aswanm79j;&pWy;5PI-T~9xv9cc|SHO{Xgep0@Ci;$nfi(3%O^ znMhb??4M#C(;hjyB$VBm`NO67Nn{iQDaZ4l^HZ$Us|nw8a*VdO(j99FlmVrLT08Sk zv=GYRH7tQLkN$0Tg|_VpZFQSlw!OJeI;8sS?AAPDM6WAL838z>q&XM#G4wiKMC(qo4Zyt^TwantHPL+qsj*C@h z1akShOAN&M<;r8&GzjwqJ){?;Uz%vlBsY~UOi+g zA;X{@#n2F+=!T*iVdy7OJ)%^Uti8s%Ci zz19e8mO!~%{@xjf|l2AaQe z+^|&OyJe_x_2<0ZsNg$!Rz1KowiP`vKy6jBq4C42uPivY=Y)#1_Kq* z&iX`{(WXPc{xH;2YU`LYi0dYwyEW}e8ck__p-uUy{fXmRT+`OAyqRdqohkv;MnB%e zoXfYXNH6}JwiFjX@F_Z=Vsg^V{U++3d!uIV)}b()H5{``f2EjC=B@6>t{1Qy=30xw z>kx&9#Ba{H-+bcoTeX`GHWWL`+N#cNt3);i=?5t)u#56rWBmsG4aQhG99bUTDq87pSGbYAk!?5KA-h$&kv$~)Tu|lWex20}Bn5Q*_TKZ{?LNcn z{=DhzKGSmw4|lxl=WKH}U>Ic}U`THxqqdhixhF2Y`tn@izjERIW=0eo(wA-&hZrKP90 zn8p+2D*Xu%(2Uk?wnDEp;JMo4Uu=+vV1JaFkNydN{azT^jst#B?+_Wz*_yqOzJ6W> zJTS(@Z< zx~FfI_E3S3K1bmp_~2_w%ORLG5m+jl3sC&^^8>-GC1MeJ#4VQb3~0(%Np3 z2pV>%G`IW4)HEf9$U0p=%8Kt_75xQ#uo?oHIsEB`=Led(nS1H7sAuc?Mxl28&hbT9 zBr9JHDb|j%`VBN_T~i4kWPn5#eW$?v8{k@Q8EHFLkXrF(Qe^t|pG1`d-c&8lMDF^C zs!cD)usRcp{`vaR2NP#v$S#(BliC$*h%itdJ4Sn;YMwkY%)v*O>5yg_G3-50c1^htw~w$KmF+Y;i~*vq;gwUQoXBden~Che7~LU3#WFEC)e$4a>69XwuJov-byEm zW2KSWnPcm+Hzm`aHLbjG@OQBRm$;3HHKcfjGsw`=lgdE{(-0~3`$9q{U!lC{d03Uo*@1+V&t-?3-St9hIsQM~3Vhx1) zs@)^@nc8Iw4p+S+Q%@=QLog&d%g=En*StKddvwT6?CAJghxVHi>_eL5Q+t4%iVqN$ z-B0xuq=%ZfTR)M;*ryxe3fxn12yU?m+Clb;g?eV;(y*P#ny;ymOG|CDi0NC+)uL)M!3N0(B&3$X3dec%}l-*S+C~LI@s}Z`7y?F&=tr<*24g-!x1e#U1 zxz%+@x&Otfe8hb!>cmoHjov$%Ba4k}#0+Onu~K*|U7fg6zd^6fsIFP}?HVWvY5 z@F_fmUAD&+j@;5R(q_Ryw>v6-d``=gLb(xlr2U0j#E6d`SnuCJvdGxW0Hix#_!wgxCL1%o`ROVRTLFV2i zi04R-#8W1R!IR8=@M8Qj_-BWL9?wzW!CRP@)8IBl{wa-=@=QZR0)^tOV$vBI-Wv#` zQfo#d+B{gWaYg-os-Jtcabv`$JyQoP>Q7J5^2p)K@J77p%;k({@@AYK9TxI2Q@zQG zpX3Figu+6;r8W7{pWBO&aU1b)4-9#g-Hntrm?io}>yEG~#O(q*Wte#;)0Jb-?s+Dr z@IhK97(Zmbba{HtIXu)jb1duNl4}}~od2R+BhcmD*uN4x1Jh%x0?7!3i6VrH+t_Vy z#J0pXK=kPxEu_wwuVW#*rvQXX7^hehUv%x3UkQLXr@IM!S-IGc34-jua59T!SvtrW zPZz`1Uyj_skz9u+S(ZI7h@CVi$VgubdiC5l+eNR>G#zcyMNe;)jHYpPLSn+KFu1|u zzqXW*Jo;R)-`xHisqM|#@&?iGd1&y%)qVD?v z@zUTr^!Hx|ig?@LR?w8!mZ*4ROwH9m`v#GZGwnySW9R9=-6qLh79hGO7sEXnQsG^Mwb;|sR9K2J>9%5W_uZ+CWjvXATK9<4 z4$S4EYWY(!wv8O*{nJ2l_8}XZ+|8Kabj%_0-`#*4T)8Rtwb^G5%I|Qc?mBEc(8od+ zzs%4UHXqG6rdBpfusk$yR#cB%Av{Nhh7M&n#zgt_LnoZ|=ygFe9Nx=7xh>Y!&9D8L zzjy6V`39};ctIy_KBmmmHy472z?MGTHg==x?9h76(!V=!Cu2>!M9j69XUOCoVd=MF zr156*eEF3&V=J^_Xs$JYrs6A^DLlRWB6DZWiaoLy?w$;|j1_UYsY6*$S7C6GuYOd7 zG4wbTaO^*mC3ny35{(8hTgn&#HKJ8gRz}_%r_--(IQe$En9nfF9Fp{U za$(-4(N5r%pplur7@X25*D)`Q?Oj10^rAs|Iz@shieiX7+buL5D~Qq@Lqbsuva5o+ zH?K$H4Er-kh5UE7?mV6I_=dvuy}2DIwKxY)m>+y^+Ru0BL3?7xyqqvZ?c`22Ke=eQ zHYx)3R_Rbm$H{xjjk|H3apF?KcGRJ5=pS8zxpf$zhgs2V|_O5z6#3iae854{-gF_Tq;d^_Cp>2=xz z?((S8>mQ)Fq(gl$9y-RiK(AV!2`9_nC|3wm+;Kz_!tui@=927X_0Dc>$zY=?O_lmHLO@&5NS&a^ z^EDJj8w#Rr`$C-{QI@=Ph1`ymTd@4LBK~ZIGS3FITT!kq_{WOey>i+P$hLqS7k;*R zw&n$pY-xBWJlNW>w1V`@qtA{kYh@&3WYz5gBvr`A1lcQ}o}V+u6DuCv2EnH8&dp{1v8fSl{SU_8!MW0? zTlekmBpusU$H|JZvXXRc+qP|V(y?vZwr$(C-EnUAcj{E#bE@vX`%idlzH`no#(bXN zqhfU)SpQ{i#isn<6eO`aEK9B9SVi6664+*zq+; z{~$iUXWu*;I=}a^U3ta?y`qli%P@w~&$irSAI|70Dr9wDv6#W0??=a`yiu`(Lg;$f z9cPw4{{!{@F8kJ#1pn<@Ki>blsr~YjYbgammlt`~ zG0SUG`?c}W+UM=%9)g$N`gnL(@+Y*T1xMK(%fdlA3b**ZIY-skBRVG_Tc=M5UkXch zH#TtW$ExG@f~N*def(iXQleVJI`D3DyuH4U=Euu@`5xqse?#?mIRvkv4ANXP&gjM? z<$%fuknf;TA;GT(_pyLDrM@10PK_B^~R;1jGj}lHY3rzQ<%x)NtQM}=?#9eFI5<&hwVnc5xJJ? zxph)qN;aC_cwban8+#{cE|jh8SOGNYFE-n9C*oW3#~FjtD^uy_Lfzw6%X3M-a1bbN zLa~fz%?Yt48aaDkrooE7l2nx*xCKoFGyEnD1APVQZcSWrl&JDEswLz71Uk$FhitwI zIiPy&TBQBtyWFALf%W#cRrquMNT-Wzkpq|MZtHq1Qzd=GM;J$Ii@~2iXL5E*eTg+u zmpja`m9F)`mJ(Q->@L7to8pWjAU>QA4PEOFUuWT$f}+<%36iuri`5pk3CE<(^fS|ahg2}-3X_>KB`P_?-coy*7zw9^{I=}8vk^aJM-u4LZ%gXe zCD5nC(A#Os(XPUp;}hnF|or^5v;=!l5>^k z&Kx^vwE{1pJxD|4esRGqPP)Hv_6hw6ad^e{=tD)esYK`(6m?YEV1uGw6dn0&395k7 zGst5JQL?0xA_Ik1Yw=IL*-lcOr|`lO%}Y|a#@x-*%ZVrh?v7H-lJ>wv&%cKHZWXh{ zY|!Dh`%QYf@d;6O*Dhu>G0k=updR1`g&U%%c*;9h{sS`kb4pKKF*CmUqA6SGik`1$ zy|f>XUszr(n$Lfdl1%jnE6Bcdu|Z#=pa1WWLiYc`9{jKIi-?i6(SI1gVpg`6|63Y6 z=7Oq(_hF5b%$AX;Zw5hS8t)b>oa za(oRbgdk4Tg$LYq$5jk_T)xznc98V|BClOtU4?JH4DyuIa8y;s$u4_9u0zQwCB zmMQg?K&7fliKb#aBrM9O_%`EtKL^<~HTd}DOR>*TrA|`rE>>TWy_U#?meCC(voRw4 zaO?ba#fR9;%qI>BMoEE+67=QU}rVdzRT81UpE0x)7cX z?T@oeYv#f7k04GE_tJLW@bppTLC|1rVmU1oUZe~F=U=$tK=s(jbVLJtsjq$tnZlx{ z`7Mj)(sd5+6|fGak&dRs73QnTGg_37V10=lYB8^{m!w*(fh0Ux4n)RZW6a$Nj7)1T zFu-&^!x|{V;hE9X)eZ`Qzz;%RssXDySq@=@mmjie#RJA2&B>L< zr^*par;d05{u70Ke0EK7whT1zU6-{O>JCLmmflh-a8n8b-0@WT3Uev5ir%I1)cFqn z>2X>zs}ApYSv+H7%jTLu_9D=vvj_YhJ9wlOoEC>rf5{*p`sf&^^(Zr4*dGEym9DXz z1wE_zID?XGDTpa!5|(l%@FX}x{SN-1XvQ(_AWrbq^4@yp8`hUr@T{J1o82h*yC0sPzV3`3f5u&zUjlx(?)!uNtLiygYN@?l$VM4PY{x*9xzLEfk5B zs!@Xd5>(O3!Rac!kOUh#@?TwVXZq;71@+I5vyeizkko_`la86#$jB3GQar36I<`m? zv0mIEyq2<}x&7Yr+j3$OkNeHwvPCg@3go~b8KS^3n*F3hO}GSE@#e2vr)`6i_=$~< z`4UG-G@E`oe?V0nA?JdU%+BoQ#A%-_=loDj@%Vm;SWTgUsUXYqbek6CIAG3Whi@bH zd&9$BBF2*WMSsBxP-+ha?%EWq-%&qxiNc2dpY50iji-iqvqq$KG&#STd-D+OXyfcbpI=}q~{e;zX1v&SHekz3h@6OHt zAMW;l2IBv9ZvK~2^8XAbQ9e$GV-i_HCPjne zQA(q>2eZ;9)}NXm>~fg7w@O`|NpNO(pEz>G?f-Qknr)8rmM~tG25}cIIdabZ&i>>p zyu4DQ6HP#8sQj7v&pmSMRrBiO^!HUKejl4S3*)vt`pAD= z(C)i%e4QG)8upQYa;=w~@m-F_hs*#!8c28KGB;gEK1LxXN*}Y3gmTzaL^l40+5S?n z29->$6*=ChowhbBVMQKI<+`1=s??Rwms5cSuWp-~gCn)!?j%fjgf*kU6VPF5NS|=d z&uIZNc9%0Y5gU{;02p9uI*f3a60tC=020yi+2Zj5m_brYaf*G<4{V(h>66K)^?-&jx$33G*@DRR&TWyeW3%xmoP!?i zn9VN(Lq(9FGjAW}4Vj#iYR?BKJWUB3U#V*~f4IjqcKh%(FMXbn2RB#|PiPEJ3^&sFKiYy?n z_kGy@=IM#c<1z`lzDTLZ+)tj~%hg0X_2}n~Ixc!wezyYO5>X6<${u>poa#oTGlI+2bj}iJgbL0 z5tga`m(?kny*%_Sz7n~JAZJc}P@XVb22)SV^Xa?d!AmKq31ZKq*vdWJ?$9`N3`V~M z*FyR-*TdIs7Q(MKnbYm()FYk;UXRAHu#g5HIvm34_El> zDbMa8mG2ZhFt)`%Ih;t*&HL9b$f_jTjdnZ6=ev6AyGH9UxyFZ(n!hyAJ(;~`gth&O zT!bXmi-WeBqz7R${;bo(FH9!}ST|~jjLW;hl?axE?IHMcBib+l&sCM#dE~ecOiv>F z?~E>!yK$Xw*uR@R?oXPKp|v@t+&P6$rfHT@KB4Egoxs7Ws#?lQ4_O~0m$?54PTvym zj{e!kAK2qUFTmC@ORE3TMZikWHiGWBNL{<}_v2^ACpl|pfHZBDvM$A7dt%-;G}B$p zKP4G^nNX^P^Q!ExES;{9j5+oi3wMaNwKkey2hipu(GbnCn6m8@%;me$#ICZ;(^3CB zK;S)0$>QB<5zXzy>*{T-YnZhL30IZxs`%+piK+{wvy4i;s+e3MA$?g|+8#S}o-+wg}*lQXGd$;&p+w>`2Bg*^RFSQC4#3NSzG{MX|#QvhuK$X9<+f%xCu zm2CgR9^*fH#sB-VbWl)2``j?L=*z>UlVw9jTFpliwB?Hrtmh@xA|h)b3S7FEn=KUc zbc@;T{Odh)6V}TS>K#oV-fOA=Au@;!X@d8FXpeW}qD>%02|>$rur9`Zl-h9f;WvhIfzSlsKyPS}7ZrUFJjGh7O+ zMhW9p4*Hj;m>U{RJkR_&GBOEu*LGHBg{kc%N{{0w_u?p!#l(d|#0w>Rd8FvA5p5#e3?534Ym zX3`a8_sXzBCSe;r{bdHo`yCb_!Q3z|?Rw+lW#enfMsKoE1HqTIaVeSweuD|YxGpg- zzq;X}v+~ge2RJ8s%a+)Dpi68}KpyT&ot2wsOCHzYNF$_6OC#{ff(;E}o(@CFaMd=*z)Iu*R`YNaL(i-icDXs(pK|YJH^3 z`IZsdFDbb6HR>z86#?xK7hk6FBuPJ6boe5 z75LQiTjxyUE@_8<0Imrf+CZ1$y*N;UK85~QqNyl`}p%4Oq0ddp1Dh~ctAse#44*TNz8dzRREKf9xkp1)c z(U#r;GFr_k%lwtI z>oHue6#N!j@bY|JQ}U`)(#bcEM=GgRibBGT{esqMTw|c^uVl}izx|yn-aCCq<5_}e z-oP{|ctbd86Wlh_cKfh-Vqv@ zQ)Y^nI+#0HNRm2YZLKLO|K($%?QnJ*G^?UImAdTPY7z^q~ z)6BdxrDk0~LbWF}$a4dPc6$-f{2IbH>bXtv9OIG$s_1)+89_0)Z5s&RLu2gHCL+nu zJ%t;bJ4BY<;Q@3Q;;WX0G0#oUwymCV%M^oN!W4p8&12~kQLpGHX|Y^(H;~JHN`e#l z+y>87vCDNxi?Z?5GWd=pJ%66Ltj4~mh=)5<(5K>2rJ&W62OrFHxX>2eHF{9Va9s- z&jcIMvpmrG>t=KKZ|!pbKd$osbb+#Z1{QiIM#@I^4rVsi|7&y>5j!T``xT+}xwGge zRO1TPqcQ(ykgXSGchFRyzdN|rUSU);w1Bk$iEwO;f3FwvIw!nHow$}ab-d*u>uw@_ za_DFc^yf#TK2i-!7rR?fc2a{e) zil9{QwK_VbCj3ga<~e4|vVJ5g+{7IMMsSDcp906r)^>p{p?WvwU2FT31&b^tByir1 z4CjZpa}5|{ttaeJ3m2VvcM5$L30xE%i-(=^C#GOhe*Vq=SjJer5Cz3(*t3FifoKCo zlmr2Mw{u|h=+yu{ur#<)|2U`iWBN4Wof##Cx>fUvm7P|JxYtkT_JQi(e2XsdcPbu2 zj2T~$HFwf;r%I+DOIkzKs|9A%3K0ZB_rihglxkMAD& ze?EXK!!B|pY2EGg6Hl|#s6P-5#8VhMx= z;Wr%$cKV`ztp2yu577UhVEJDbNPayBBg6md^JVqy9saj4ZNbw;H(u!F)8x=9ZGv2l z9|J0lw-`Fj{~NzzY9JC(@((fI@2s>VKYFUesL*JrAMKqXV5K6+sI$Q*{W9Mt@6O-v zxu!te+#X=yw_ch5yqW_3xc+-R3TnEW90who7#&W$pLCP9eG8X&r1&6xgMQ+t-Oin) zIu-h30o$V5KcHV^iX_qOjDs1WN$V7v4P|GAjadW|iZgYVuNXk82vofkELGh>qIqr! z4P$QRm56pEbL|PIV*%tq(S=wWv;w z*=*b4eifo%Z7al=+YeX!y8wZDVE+b!T@)(nK*zchA?AhV`qTiJ^iB41Z$pK2jTBdZ z8~6Cch347zDnijRmG@MGi0g3Px@UOU5WYU<@2qXFEXUyA*U3d#$wk=ZCe6>Zm{WE) zT$mP57qFUdF=4;$Zb~njk^LD5J;4$F%m}r=K9>COm zMa0x053cH8()8?`u)*I2d3#?W{k~@VZNEoh+&`tcHZee8ed!de(_9l3_P*}WP0U$B zyc6x0HA{?snnXPkJ&z}UB;7}hkC4)>CEam{oBVn2Z~+q~>L{8dKo0!kOcZkDr@gw{ z#*7Nd^a>QlfQuutd))l&XgS`CK0#PX0(Bsy^h`-^77#AIIM9s|LvkGO0*9#}$A}St z@mq!tF?-Q{_YN)^3>^7W#18mOQ9%cwecK?~Z9Y;w`+R{&`{6v-wwZO-Kwql;)fr8^ zzJVG9U}Dyu>(~tfu!oq!{*?m|=`u`mnYAB1u%0=79nZ0k7V8a6@F=vah!<3rKH3Eb zjN;X%LtN7amD>)BXEOf{O9?DzGHl@Gw-V4w=_(-RkmsGGL7y((6Li;`XM=cq@FoB5 zvV!ty@53ihoIQGuO|e~S1qHCMN||r9C60=|3vHpV*A>gIEZ|TiEJhusDubn?Q$4n^ zhGwbITve^^*KtvIpj4H`G>1V`6c(8^k6b-elEC!GNrQ;wUZ=%Tl5Jn!n%6`vy{3mp zd;OcEE0EDuvjc}(?7uqjaX7Hx%iHmXNOHY_E@$pX&nyvLOF82-O7>;TkC&%FU4bz{ z-!(*7k{k_nH9VL`aOK8unhSA1QlZN(VUuOc?+HstqEr@8KdIG|08lIoPnaz7Q3i5E zlEyld)myyBhr{jbq=$$Cv9oBVa8GGq7=0<-+zuqafHfsK0mS676iQ9gOa~uEY}u2s z2~NI7bnrPuH*6`{0Hc}`ga)>SnKc%_4bA)+LQTV~5m~mtw}%7pz(29f;T(ygs5HUw zlCYl!AQ6sCBSX$|QH_ci2vbH8G9}5a(8V&;k4V9OK{~=R8XEi0Whfu{L z{jyJ1ByV$c4G6jY3#Br47m6{V4azdNR@aT8&SO6fhu+nNOAybo* zM}M1yX9@T*QK%W?D?{;$Q*QI?L0ww7baT}Yt+OOxLiQx)YOnEM2~2=`Y0~qVam(#q(spH~6^Y{f& zMAT_>!K;={5f0tIoZn5W3n zNoL5Bax)qCULJb^GH|-&Mk^t2{FCH$k<6nyI&a14J;5XsXbKZGt!i@ zDsicKzu}fMsXgz9*Q zz9M8)CvIM5Q7TSTXdIAw?kx74A3G8!LB6CcovJOb8JDDVgqYg*?&Rcqcu4Exu=ryR zta+c4d_+wDPj@%vvji?KSlC;HkW`qu+M$6fi)Cn*U{R)+rI;-jczZR~tQyd8J}`m| zW4-ryi`vFvWbME`>3C$HQ_Pwu#bqSIK2E|gsxDjGKK}Y1Y74-Pg8d4`+Fl2+ zLVo2u;<4Ysb;^@uX@apyPlz-ORjw(_2hUeOt}}(fN{y|zotS~3^f@zz*;X(1`!H{|c}R=U62Bq;CI_f=+Ca&7ES_ zR8PFTn!d1JO?iw0h}lOmP=n#w-cdV%pP1kZ`~yczf=xWzXn0_|tqX&|cqSkxILkCn z_Bm*YjVCa2%>!P3l9HlDjsti`?)&E=hODHsR%eo-*Xk^BMq96WYtU$5?rk=J=Dt7M zNA}rce1!Te0~1ff-}82epAP1u6uWO*pM`FaR|NiM2m#g?HabczQ(jSA zUR;r^q%E(cK0YNzrnEo{JnY=BzLofUPObsf?!Rv8B@fOHTbGXfJcO|4hCyX;oNS_R z^+Gn7p&!Pn@g@kd*6V}(lIw4Xt+Pv$^rq;2h%%sGEAf$5v3itCIKXDmMh!!T^7acY zV+BJ=tX4}u5o_pn*y$O9D)bFePE=Bl=9UcA)%A_(AxD`+>f@w>cou0910hLYaUdFe zdg&Hd!22wAt7ZghkRHj@R1GhfXlN9@fd~kvY%#65?hXu(uw2hP#IoqGzWin@SID(N zRv6-08;t$|enhydAh=sa$(kTPtM|J25|E ztP#sSPIed?2Vp#zmiu$fI%YD3Gd{_v<)xk0M<>DcAA+(;Zz%;n>|tbT?@F-445<2y@r1@NU`)tEc0RBHWKKCkJ%P;0coS-dT%sL* zPQJ8hPiiX|4`DQ8V-nQnrFBwwdN-w;{bO*IX~93m40|Q%^#E5WtZ-iFYe{d`2cR{R znQEf7LK)Y>^}cPBTYI@4#N->=mdrT~Fz_si%Y?4xeI7=6T}3znOi1NJk&0ct!mA`m zRf6FI7iyv?$$MpROnE$t>8V}ICP{Wyaw}zqKzro5Wzx1XqGmK9?>%|N=ZNm)zF!g& z&5Ks|5}PLscO1=B)jw~!NFJ*U4G))-pUkdf3~l$j+X8#zl?lyqrT0$(3P%F{Vms4o znk~k53Z?;0;ViohVNH!JEEtmN3n-NO@C^p`y>IMzmnqm|$dTmxE2Hx%@laVl1n)YT zw=q)T1Zw1}CZ)!!CQByu)6x4+4s0+H%C-TqgXwMq1?1P<7H5<&>`@)YECC#WY*V~N zu=&DUiUG>YBkuNZdgRZ{lOiOri7>|>Mq@wVL_d%-Tvrq+rjlp0CJDSQOrZlH3Pn8m z)#QNzbDx2-{*yu6(!mBqbc@rP=%#EAL-sz?U6isml&i?0K6AQj?a1FrSXImzuuQ3~ z?@_7J%-(a=SQ8osj1m^&B@`!1sR788PYrvKPYchA)j2KwOo@g?-Vch^V~#vf3*&oI zesestzdlwQIPB(wqZZ9zn70;JazxxY_d=yoo`(OJ;c0VT*_I`js-j|ZUtSNEj+x4r za~_&h7XaP2sc}!Ap#nEx8c1^)Z*66h2jh_SPa;D_du-D6GtyR9Dx8$}uSLE|lpk!D zaMYLkrj)R+LRM4lTq^11yQePZ=1NovoAjrKI6}F$P82-%oARAgS*8D26FCo>lTE5fB$JXNUR@Q-j*sIePS8IO7C}tj+@Kjo_nf)(?#WZxu$5?!0}eUxWAmt^uFWl+VM~4NL)q=% z3;n}NMS`&-5z@Rle?2iYuN=Sz+ilQ;HK2aS>9lXU@aXjciHxYa`mHp8NrF6xiKo}tLIl1 zWk_Uqhh`SpnV#+~T_-FWcT#KVy0O(GT(#V%*M8nme-mZp8Cx2QOG`}=u%iOA3)Vaj zzQ_YVLzK@)g8IDA2qHolQhw+%5wRuDSoZ3RRi$4ZOA=AAyVL}AoKaevLZi`>^Q1M4 zNFF7p&-Ur4;r%G;KTXXoO=VE_(qBZ}5?#e@F89^r%1C4^FG&?Tm#oK82puhzAgQ7@ zPDrQ`32%Y658AT*P}NYEGmxWn&)UmX9_NmX?OWpDMrf@jZm4FvT)8lcGzOb(qG_ps zMGHH27l^hI824Z!xeJL$SDJ%e^qDv(UP@zbx>qU2IUAe}}wY$mYtzz-~ zOzuYx>c{}i z4f&vyX5C_91$#tScdmf_>Rwh9V9FX(P@eC6SU#GH@*}%y0aVs|o~()6Ahytz8qJU< z`BykQ=xX7)bMqz9pw+F-XbU}Qus|s$%`jI&;Lh=szJlTy7lREv)j0XYx5%O?gY6n0 zANw;u*xz2Tk18;vWhG4&lz9;?P9t| z`gZetNe#a>VDS1%PwjNBhvOsh7=iNXeL!eB){yfT)1D`ar=5;gAUJB!_Hv|u#Wq;2 zG&LlOATN3aBYH@2ATI0iU$x_)6|8X7n5Z}+|L5NhU6Qu&^_P9qO@fIt6O#}u(l7%A zoJg@Bc`lurenhPWbLU#%@L^`{)GX$APc8nrqj#oe6z?c!6o$oV*;E(n$;lE0i77MR zRfItiv4`qjQu|4>seJiF{sgA{^em*Xbo@=*t3d?(SmfWulFUScM2~-B7tk=3W#3w* z!>^-GOIG80IS>e=2)O3>fRu_8#w%Vf4i(%GD6aqNv4&~ki(+4O;8TsK2xhr}(#_kd zz^t!0;at(U54l3;fuLz-)(S8J?P9PF&S?+G7p@$^89WHggd-B{vYmlv!BtoW91B}G zKtH&qzgRO?oE>)I4ov)xIBm}Y`3rRPD}&nkKr|LivFDX;9_yGeO_135n$0g!P;@5( z0!DUc_>aA04wVd<>!?V-c=Ov+VU*OgVsB>mJq!nlU2hu)=8T_@NF()Hp|)#l6M03| zO{DVhxj{`}*k{4fYtbvd-WF1mH2B9?sK5F(NY@@nczxUSwh3~(I|O~54fnn~NWh1x zsO&MEBd^$Z(glEdfue;haPhIaRTB<)AlYqt$N!;Jg5{+>fK@#}RXk$te3>T(0P=kl z(UBC4-(*tKI8|$ZVv(>)H@b(icx?Uj&>^JzT}esm2bFc9Zi%l9Oo z&J;u(L#h~#B#kHVV(?Y{5$a<3yX)*U$YOGzQCFZ%v^7yF+imf8#FMS7TKr9UKe^{8Wl12=3sAh zlsU_5RILu*B*~?erdWU&fek^v4fYWU;lUEQ=hD6(P~YH~6{1Xf8wOGv`!nv=>*Gt59mOYd!tU(V;Molp}g9X(1 z3Kl@R7mE?nU_kRn6NZAImg?=Tpt#DcamaTze@Ia|5_wS=SBl75bCE5h)g^;W3I{A_ zt|9fvAX%(5&dAe!FHVL{Kj-!+x;g&~jzW0gK@8QhDKp!tE~IPEbi!^wcxXVw z)(*&L3*jC{6GL3d?_&pFJK$s}V9mgH30oi{PvOSAfFuCNIFGavIPA;NUkxCiq_C%h zi+3qr5=--s=V$dv($*=a3UHry!4*8It>kH&zQ(#N2XSsqJw)Hp&^x-~HRb+(fM5UC zAw~XDoJA`d@W5|#wtgtby^4SB>KMh@B|9~y!etIgZ6*0(Jzv~F+goWD;g#%4{4GK@)=htFZ18xYo^>h8BSTJ^#DRbETA5_Z0J|TDgMfwp>{F-E)Xchx1yKFZR zuCksq&cRpx2D=_N^-pr`)ZV!Z-WXZI8!Y;W9q$1jYxD(*1p?-?q)sb3IQH3+@ouwZ zQ3+!9p^}NrhN0z&)^4%q#4<4@wc3yI5wix=Zfx!ZL?qBL?Sv5g_s4aJB_u^t^vSW? zDaqnfr~Wx@jJYzHX$cg!RuM(t5=gDEbsy7B)ym^8bFV!i50@)5jjRC;M-l%v#nnV1 zr5{6D))-A;MG!6bQRweMU~6_TO)?vi>REJEBM;OEbay})p20I7qrccSF&(}t)2u-?c24FuE^F|=V+42V{NY`BFqH>*?W8rKmztg_Wl zW2*}@go9Zkn=rGYYcL>qY6m1}nuE%%qZ4^Tl-WewHVl^T9!qkrxvsp@2jB~Hi%w*G zrS8Xyc&ZLUCXPg3fur68M!!YYrWhaVro9QQen-`04XsYO-Fy7;E}Fh_c%ft26OskM zj8^}_c(F70A%Fj{6!FM%$R-~-Q>@?79QAZhG0fAUdp~s1#g4JTl`d-fu-;@#u}M3z zV$9j-H7#n4jRb53qR#`@lUirZD{_?+=^xN{;we(Q#476fs(rYDBuO&f%&A~vD)P6_{|H@sNDOAVd{$CoxOKjSUO78TcxRX zdyI8~md7vNkl7G2-5#>$^4~ETA+a*Ic)2^A!hWUcW3ouJ{N*ng66`%0Hpe94bID@Z zbk9WQW0l&KPZZ3W01V)g=IRKt0j>~_+&H-$2EwyR?X2m ztTM>=1T)yzNG96qF?NutezHH@}%Xa%?dmnL@i|BsG1;%X|-ToBme#cCIcX;@L ziT_&{^z#(-GddR-dnXHDt9QbYC@(MYbu0rMHB`lyIg)Te;qOYjNMBNjRx4pya6nb(v{iWV=7c5EF$q4&81%rJZ80K z6;qkT2RrgnUJ)EmMsoCy^s;V6#*VXfbz)@9Gj%>P@e301YzUH92$D95;7??dIH(!K zzIfVET1ee`CaAsmp5zj^9;v<%A8@ z^{O|?Ip`OemMHaEo=*(eNqf!+YM`k)CGYU!-(~~QM8mhy1n-q$ACCL|mqSR|ND>OS z_~@gng)yx%uBZb7m$*H_A}8-nxxQcFx%=^yI5dE`n3QF9G4|gpWdXenqXW%+Eof&6W42lLKmysy{=U(Lrw)7gOhxPNxzPw$ zwH9a_YW6++0}Rjd_0X#Lwd=q3Aa7+hs2ocau~Fk4JhW;F?i3Mm0Clc~l|CFfwWQPN$>133lRv6vk$ZO2+=g-F^b!sv6cU+gpi zby1Co2s_7lWS0W9+3l1$O*A!2)`l6pe?cQV!W3e47~CZZZwa0FdR;QL8N7;G*3VUC zqX{9K4Wi=))~$CYRE4f-CmZDQr+^atAcc~yv+jj}R1pI^>1>XB9A>(sN8#~YNHIx> z1GN;lHn!9ojthIb3;oOO8DpWkq0GgVHVLYEQL@$Pqijiei?jBnJo!#6V0cR;iAhu= z>XHMNmjFk2XH31nGdU~pecNh%kq!EgAP#Y}&yOpKnEk=@+sRDM9}`#6E)*{Ux^i8X zD3)9-e~-$fnCZ4I`&HwE%q7{qkqR| z(Pjuc1sZ3vL0@a+`ggvFib&I%2-RyO|DbR7*Vl$Ks>x3T_cKD?I(q;(d0k54M_h zp7H3Zbav4XEZQqP|8`OR-qtt}k)O{Jm2(LLH;Ov0I7jzN@FG!Iq5nw*DJljM>ZI;x zETtwdPNkGX?Ppn_GA;|*HC!M&UHDZaD}~J05Y((Kg_@=q)vR$r)>zyzz{aY@mFqqr zVxIUUj!)F71R0vOz?Z9lPaD9gNM5`$TXs0?eaZmjok$2cwFOGkMGu^s0;TXt%jWsr zYTfHKvm+BE=5Gp#IdD>5XToeW9*HI5p_E-4zpH`G{k((Fx$-TMUgBvM8jVJY=?xe@ z%{n~AEV?xq-~i38NMvU1t(WDdOV@H#w29QGSr%e8g2bxVp}Up?8}N^tB8ANHPm%{r zF(BsR(1ld?ipet^mIMIkASbUQSSwlm-3}^n`gtl*rJ~-v#N00TANC7Oa4Iym;p!nF z=IDhb3&pY)3_2MBWT%$2Dl+}lP6zL?)_y(!7Di$+h3{33vwOwq%sK;5ac3IaxmRLs+x1>t3 zQB{<#PyV!GwXXglI7PXalMx8S5$we2l{;m^E6R*SX@E{JXT~V5;1JP@3|l~NmevYs zIHk5!p5hI1$Iw=o8fZH;j~g!{rpog{CPU2_W{`1&C<-dvV+0vV7U?@tk80mbd|WuR zGjd5Dbn(;`ykKaQmKpe;@i062jjVyck_Y?%qD@CdQF=a-4OCb3Z+kS}jw`qwmKyt_-3lw~xb!`%hzogrnx>5TJLVr^tXX30IxofHhPygsezFRG35s!t_zsZCR};?X7g+Vdutq6(|i~m=l|b!m+r{tDf$OVl?)*%#SO(|7FPV zkHpiA1cv_|HDx$yM@gqg_bV5y*d|-n3w7ZX1XX;M%jbnSHvg}N{~fAqp$qlmH+kI? z;+yn4g|*^mz}mu;UD6AorCisb^aJi2-#f-s@z$Q(17v&dhkw(2){So~ZdS3!b-+v5 z2s>i67<9bWD1Cko+~r4Im`gC1|2rx(eh0CO_iuluRBTcZ9D|+%o4#kxu>A z308E`PkP|iM()nco@0{f^27<6q0XN@>2RhXpi=}s?(Ia~%w&-@=TjC+a{zbmu+nT3 zscu$HJE^k^Ztu7dW}~RHuoKYiDN)L>p;@SMHuIRBxDhsuGN?4WIF(JzeOGL`_MrPG@w1Pu-~#G3Y&E>h@JhFub`)9 zp*J>5NiKT$t8*45wE7LafloCDesE|8ggcfCSHrWQllL0pq4xY@5?Ff5Y53N=Xm|mXoN4+9lRNa?Mos3@{UA@6PJ!gVRY(HQ%#CzwB z%JK_PNzfL9B9dORgZe|xC=>VFRVrYJ6H{dZ7Kv!-BSWT3{u+`5j*WpW7s(`s|9o{< z!izuR;a+S$CXhl3GV3KCn?UhZKI@Y6@Wd7=`XwA#xQ#R;p@LeJY=Q*3Iad!|>1(_J z)&^@gMi^o!WLm=pSS@k{?4-EJc>9qjraWrV0gm>Er&CWA{Tq39G)PePZa}h53Gyqdfu_YMWUDk+>vuC{RP@WSw3)F z8!Q-Q+Yo@O5gf{G(0dJOa^)2Rju*~~W@n5dYk!_sh3C!E#AvU09-F@BH-67ioPOL@T{W_VzIrE`g zzjC&>`4{d>;`dBX0$i2&PIQsa!oZV-aKb1f93>oGw3s1QYH>8D$N?h!?Y~+M3BNeJ zf*^vB5U3AK_3k*pmed5M9Xrx!w#Q7D6#wT#Qx$Pmm^^G=lZwT#X z_wk{gFp8$$b=X-1!Z0kt`KQ8OL;xRUxO*stNYBuFCT3rfTIh7Cb0CK?%EY*n8e+HV zhF#+EzK6X>k2p!DnQ{yNY=@;ic;wSJQLTj>IDm`hSCafsa zydcB_DYwQTU3;1cn&v*sH|)U1Sz9wz6QNA~OY)X{2DXSyyA333a>)&DhE?p^z&8sE zFQV+XIf=PA!AySm(>ITY1qy?3ex&xdTg-e6!)U!|s5cYTQ?m3DdBI}8UseyyQ%jSI zmFflwdXf$7Ak}X&+4<^wHr?RX51JyQYi(kA(k|KN^Ys|fAQHxN(w8Z91SBEseU62s71wC_Is2{Obk%px>_ur7s{1A@0?3NU24X+BiU733vs;n4R#3P&khwTe zxUNZ^wnc$9Bu?AHz^=5hH925c-q880)Fu`{b)KC9?0} z)IPHBRp27WWmi=tk$)wQF#q;B{pxR-)qvKG*^Toj%^3IfDcEaWEvgF3K`ysB0+Pl% zPRorX%&PBzrc2A{g*+mZJKBu+V}*QyIL$W#$A+(hh-4Hkt83peRC+%6h>CDs+17+r zhjnSmcgNl`Fk>T_P2|rz77j_7LdL&ugpp&0p$J2PF-S{Jvo)9F`yy0L! z#Et2G=LGK?Gv|Hx9llYR@Kb%Re8)7u9c$G38_rXQF!StxO3YDAHe&!hYShKQV1b

oIRXg0D$P_00x0Btz(L*YS^_7sf&ye%##5 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 + + \ No newline at end of file diff --git a/Android/WeatherInformation/app/src/androidTest/java/de/example/exampletdd/test/JPOSWeatherParserTest.java b/Android/WeatherInformation/app/src/androidTest/java/de/example/exampletdd/test/JPOSWeatherParserTest.java new file mode 100644 index 0000000..42e89eb --- /dev/null +++ b/Android/WeatherInformation/app/src/androidTest/java/de/example/exampletdd/test/JPOSWeatherParserTest.java @@ -0,0 +1,35 @@ +package de.example.exampletdd.test; + +import junit.framework.TestCase; + +import org.json.JSONException; + +import de.example.exampletdd.model.WeatherData; +import de.example.exampletdd.parser.JPOSWeatherParser; + +public class JPOSWeatherParserTest extends TestCase { + private JPOSWeatherParser jposWeatherParser; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + this.jposWeatherParser = new JPOSWeatherParser(); + } + + public void testRetrieveWeatherFromJPOS() throws JSONException { + // Arrange + final String jsonData = "{\"coord\":{\"lon\":139,\"lat\":35}}"; + final double longitude = 139; + final double latitude = 35; + final WeatherData.Coord coord = new WeatherData.Coord(longitude, latitude); + final WeatherData expectedWeather = new WeatherData.Builder().setCoord(coord).build(); + + // Act + final WeatherData finalWeather = this.jposWeatherParser.retrieveWeatherFromJPOS(jsonData); + + // Assert + assertEquals(expectedWeather.toString(), finalWeather.toString()); + } + +} diff --git a/Android/WeatherInformation/app/src/androidTest/java/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java b/Android/WeatherInformation/app/src/androidTest/java/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java new file mode 100644 index 0000000..90c0d07 --- /dev/null +++ b/Android/WeatherInformation/app/src/androidTest/java/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java @@ -0,0 +1,44 @@ +package de.example.exampletdd.test; + +import android.content.Intent; +import android.test.ActivityUnitTestCase; +import android.widget.Button; +import de.example.exampletdd.WeatherInformationActivity; + +public class WeatherInformationActivityUnitTest extends + ActivityUnitTestCase { + + private WeatherInformationActivity activity; + + public WeatherInformationActivityUnitTest() { + super(WeatherInformationActivity.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + final Intent intent = new Intent(this.getInstrumentation().getTargetContext(), + WeatherInformationActivity.class); + this.startActivity(intent, null, null); + this.activity = this.getActivity(); + } + + public void testIntentTriggerViaOnClick() { + final int buttonweather = de.example.exampletdd.R.id.buttonweather; + final Button view = (Button) this.activity.findViewById(buttonweather); + assertNotNull("Button Weather not allowed to be null", view); + + view.performClick(); + + // TouchUtils cannot be used, only allowed in + // InstrumentationTestCase or ActivityInstrumentationTestCase2 + + // Check the intent which was started + final Intent triggeredIntent = this.getStartedActivityIntent(); + assertNotNull("Intent was null", triggeredIntent); + final String data = triggeredIntent.getDataString(); + + assertEquals("Incorrect data passed via the intent", + "http://gumartinm.name", data); + } +} diff --git a/Android/WeatherInformation/app/src/androidTest/res/drawable-hdpi/ic_launcher.png b/Android/WeatherInformation/app/src/androidTest/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..96a442e5b8e9394ccf50bab9988cb2316026245d GIT binary patch literal 9397 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/androidTest/res/drawable-mdpi/ic_launcher.png b/Android/WeatherInformation/app/src/androidTest/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..359047dfa4ed206e41e2354f9c6b307e713efe32 GIT binary patch literal 5237 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/androidTest/res/drawable-xhdpi/ic_launcher.png b/Android/WeatherInformation/app/src/androidTest/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..71c6d760f05183ef8a47c614d8d13380c8528499 GIT binary patch literal 14383 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/androidTest/res/values/strings.xml b/Android/WeatherInformation/app/src/androidTest/res/values/strings.xml new file mode 100644 index 0000000..00a3f66 --- /dev/null +++ b/Android/WeatherInformation/app/src/androidTest/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + Weather Information Test + + diff --git a/Android/WeatherInformation/app/src/main/AndroidManifest.xml b/Android/WeatherInformation/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..55771d1 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/AndroidManifest.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/MapActivity.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/MapActivity.java new file mode 100644 index 0000000..01a3c41 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/MapActivity.java @@ -0,0 +1,408 @@ +package de.example.exampletdd; + +import android.app.ActionBar; +import android.content.Context; +import android.location.Criteria; +import android.location.Geocoder; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener; +import com.google.android.gms.maps.MapFragment; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.MarkerOptions; + +import de.example.exampletdd.fragment.map.MapButtonsFragment; +import de.example.exampletdd.fragment.map.MapProgressFragment; +import de.example.exampletdd.model.DatabaseQueries; +import de.example.exampletdd.model.WeatherLocation; + +public class MapActivity extends FragmentActivity implements + LocationListener, + MapProgressFragment.TaskCallbacks { + private static final String PROGRESS_FRAGMENT_TAG = "PROGRESS_FRAGMENT"; + private static final String BUTTONS_FRAGMENT_TAG = "BUTTONS_FRAGMENT"; + private WeatherLocation mRestoreUI; + + // Google Play Services Map + private GoogleMap mMap; + // TODO: read and store from different threads? Hopefully always from UI thread. + private Marker mMarker; + + private LocationManager mLocationManager; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.setContentView(R.layout.weather_map); + + // Acquire a reference to the system Location Manager + this.mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); + + // Google Play Services Map + final MapFragment mapFragment = (MapFragment) this.getFragmentManager() + .findFragmentById(R.id.weather_map_fragment_map); + this.mMap = mapFragment.getMap(); + this.mMap.setMyLocationEnabled(false); + this.mMap.getUiSettings().setMyLocationButtonEnabled(false); + this.mMap.getUiSettings().setZoomControlsEnabled(true); + this.mMap.getUiSettings().setCompassEnabled(true); + this.mMap.setOnMapLongClickListener(new MapActivityOnMapLongClickListener(this)); + } + + @Override + protected void onRestoreInstanceState(final Bundle savedInstanceState) { + // Instead of restoring the state during onCreate() you may choose to + // implement onRestoreInstanceState(), which the system calls after the + // onStart() method. The system calls onRestoreInstanceState() only if + // there is a saved state to restore, so you do not need to check whether + // the Bundle is null: + super.onRestoreInstanceState(savedInstanceState); + + // Restore UI state + this.mRestoreUI = (WeatherLocation) savedInstanceState.getSerializable("WeatherLocation"); + } + + @Override + public void onResume() { + super.onResume(); + + final ActionBar actionBar = this.getActionBar(); + // TODO: string resource + actionBar.setTitle("Mark your location"); + + WeatherLocation weatherLocation; + if (this.mRestoreUI != null) { + // Restore UI state + weatherLocation = this.mRestoreUI; + // just once + this.mRestoreUI = null; + } else if (this.mMarker != null ) { + final TextView city = (TextView) this.findViewById(R.id.weather_map_city); + final TextView country = (TextView) this.findViewById(R.id.weather_map_country); + final String cityString = city.getText().toString(); + final String countryString = country.getText().toString(); + + final LatLng point = this.mMarker.getPosition(); + double latitude = point.latitude; + double longitude = point.longitude; + + weatherLocation = new WeatherLocation() + .setCity(cityString) + .setCountry(countryString) + .setLatitude(latitude) + .setLongitude(longitude); + } else { + final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext()); + weatherLocation = query.queryDataBase(); + } + + if (weatherLocation != null) { + this.updateUI(weatherLocation); + } + } + + /** + * I am not using fragment transactions in the right way. But I do not know other way for doing what I am doing. + * + * {@link http://stackoverflow.com/questions/16265733/failure-delivering-result-onactivityforresult} + */ + @Override + public void onPostResume() { + super.onPostResume(); + + final FragmentManager fm = getSupportFragmentManager(); + final Fragment progressFragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG); + if (progressFragment == null) { + this.addButtonsFragment(); + } else { + this.removeProgressFragment(); + final Bundle bundle = progressFragment.getArguments(); + double latitude = bundle.getDouble("latitude"); + double longitude = bundle.getDouble("longitude"); + this.addProgressFragment(latitude, longitude); + } + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + // Save UI state + // Save Google Maps Marker + if (this.mMarker != null) { + final TextView city = (TextView) this.findViewById(R.id.weather_map_city); + final TextView country = (TextView) this.findViewById(R.id.weather_map_country); + final String cityString = city.getText().toString(); + final String countryString = country.getText().toString(); + + final LatLng point = this.mMarker.getPosition(); + double latitude = point.latitude; + double longitude = point.longitude; + + final WeatherLocation location = new WeatherLocation() + .setCity(cityString) + .setCountry(countryString) + .setLatitude(latitude) + .setLongitude(longitude); + savedInstanceState.putSerializable("WeatherLocation", location); + } + + super.onSaveInstanceState(savedInstanceState); + } + + @Override + public void onPause() { + super.onPause(); + + this.mLocationManager.removeUpdates(this); + } + + public void onClickSaveLocation(final View v) { + if (this.mMarker != null) { + final LatLng position = this.mMarker.getPosition(); + + final TextView city = (TextView) this.findViewById(R.id.weather_map_city); + final TextView country = (TextView) this.findViewById(R.id.weather_map_country); + final String cityString = city.getText().toString(); + final String countryString = country.getText().toString(); + + final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext()); + final WeatherLocation weatherLocation = query.queryDataBase(); + if (weatherLocation != null) { + weatherLocation + .setCity(cityString) + .setCountry(countryString) + .setLatitude(position.latitude) + .setLongitude(position.longitude) + .setLastCurrentUIUpdate(null) + .setLastForecastUIUpdate(null); + query.updateDataBase(weatherLocation); + } else { + final WeatherLocation location = new WeatherLocation() + .setCity(cityString) + .setCountry(countryString) + .setIsSelected(true) + .setLatitude(position.latitude) + .setLongitude(position.longitude); + query.insertIntoDataBase(location); + } + } + } + + public void onClickGetLocation(final View v) { + // TODO: Somehow I should show a progress dialog. + // If Google Play Services is available + if (this.mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + // TODO: Hopefully there will be results even if location did not change... + final Criteria criteria = new Criteria(); + criteria.setAccuracy(Criteria.ACCURACY_FINE); + criteria.setAltitudeRequired(false); + criteria.setBearingAccuracy(Criteria.NO_REQUIREMENT); + criteria.setBearingRequired(false); + criteria.setCostAllowed(false); + criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH); + criteria.setPowerRequirement(Criteria.POWER_MEDIUM); + criteria.setSpeedAccuracy(Criteria.NO_REQUIREMENT); + criteria.setSpeedRequired(false); + criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH); + + this.mLocationManager.requestSingleUpdate(criteria, this, null); + } else { + // TODO: string resource + Toast.makeText(this, "You do not have enabled location.", Toast.LENGTH_LONG).show(); + } + // Trying to use the synchronous calls. Problems: mGoogleApiClient read/store from different threads. + // new GetLocationTask(this).execute(); + } + + private void updateUI(final WeatherLocation weatherLocation) { + + final TextView city = (TextView) this.findViewById(R.id.weather_map_city); + final TextView country = (TextView) this.findViewById(R.id.weather_map_country); + city.setText(weatherLocation.getCity()); + country.setText(weatherLocation.getCountry()); + + final LatLng point = new LatLng(weatherLocation.getLatitude(), weatherLocation.getLongitude()); + if (this.mMarker != null) { + // Just one marker on map + this.mMarker.remove(); + } + this.mMarker = this.mMap.addMarker(new MarkerOptions().position(point).draggable(true)); + this.mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(point, 5)); + this.mMap.animateCamera(CameraUpdateFactory.zoomIn()); + this.mMap.animateCamera(CameraUpdateFactory.zoomTo(8), 2000, null); + } + + private class MapActivityOnMapLongClickListener implements OnMapLongClickListener { + // Store the context passed to the AsyncTask when the system instantiates it. + private final Context localContext; + + private MapActivityOnMapLongClickListener(final Context context) { + this.localContext = context; + } + + @Override + public void onMapLongClick(final LatLng point) { + final MapActivity activity = (MapActivity) this.localContext; + activity.getAddressAndUpdateUI(point.latitude, point.longitude); + } + + } + + /** + * Getting the address of the current location, using reverse geocoding only works if + * a geocoding service is available. + * + */ + private void getAddressAndUpdateUI(final double latitude, final double longitude) { + // In Gingerbread and later, use Geocoder.isPresent() to see if a geocoder is available. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && Geocoder.isPresent()) { + this.removeButtonsFragment(); + this.removeProgressFragment(); + this.addProgressFragment(latitude, longitude); + } else { + this.removeProgressFragment(); + this.addButtonsFragment(); + // No geocoder is present. Issue an error message. + // TODO: string resource + Toast.makeText(this, "Cannot get address. No geocoder available.", Toast.LENGTH_LONG).show(); + + // Default values + final String city = this.getString(R.string.city_not_found); + final String country = this.getString(R.string.country_not_found); + final WeatherLocation weatherLocation = new WeatherLocation() + .setLatitude(latitude) + .setLongitude(longitude) + .setCity(city) + .setCountry(country); + + updateUI(weatherLocation); + } + } + + /***************************************************************************************************** + * + * MapProgressFragment.TaskCallbacks + * + *****************************************************************************************************/ + @Override + public void onPostExecute(WeatherLocation weatherLocation) { + + this.updateUI(weatherLocation); + this.removeProgressFragment(); + + this.addButtonsFragment(); + } + + /***************************************************************************************************** + * + * MapProgressFragment + * I am not using fragment transactions in the right way. But I do not know other way for doing what I am doing. + * Android sucks. + * + * "Avoid performing transactions inside asynchronous callback methods." :( + * see: http://stackoverflow.com/questions/16265733/failure-delivering-result-onactivityforresult + * see: http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html + * How do you do what I am doing in a different way without using fragments? + *****************************************************************************************************/ + + private void addProgressFragment(final double latitude, final double longitude) { + final Fragment progressFragment = new MapProgressFragment(); + progressFragment.setRetainInstance(true); + final Bundle args = new Bundle(); + args.putDouble("latitude", latitude); + args.putDouble("longitude", longitude); + progressFragment.setArguments(args); + + final FragmentManager fm = this.getSupportFragmentManager(); + final FragmentTransaction fragmentTransaction = fm.beginTransaction(); + fragmentTransaction.setCustomAnimations(R.anim.weather_map_enter_progress, R.anim.weather_map_exit_progress); + fragmentTransaction.add(R.id.weather_map_buttons_container, progressFragment, PROGRESS_FRAGMENT_TAG).commit(); + fm.executePendingTransactions(); + } + + private void removeProgressFragment() { + final FragmentManager fm = this.getSupportFragmentManager(); + final Fragment progressFragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG); + if (progressFragment != null) { + final FragmentTransaction fragmentTransaction = fm.beginTransaction(); + fragmentTransaction.remove(progressFragment).commit(); + fm.executePendingTransactions(); + } + } + + private void addButtonsFragment() { + final FragmentManager fm = this.getSupportFragmentManager(); + Fragment buttonsFragment = fm.findFragmentByTag(BUTTONS_FRAGMENT_TAG); + if (buttonsFragment == null) { + buttonsFragment = new MapButtonsFragment(); + buttonsFragment.setRetainInstance(true); + final FragmentTransaction fragmentTransaction = fm.beginTransaction(); + fragmentTransaction.setCustomAnimations(R.anim.weather_map_enter_progress, R.anim.weather_map_exit_progress); + fragmentTransaction.add(R.id.weather_map_buttons_container, buttonsFragment, BUTTONS_FRAGMENT_TAG).commit(); + fm.executePendingTransactions(); + } + + if (this.mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { + final Button getLocationButton = (Button) this.findViewById(R.id.weather_map_button_getlocation); + getLocationButton.setEnabled(true); + } + } + + private void removeButtonsFragment() { + final FragmentManager fm = this.getSupportFragmentManager(); + final Fragment buttonsFragment = fm.findFragmentByTag(BUTTONS_FRAGMENT_TAG); + if (buttonsFragment != null) { + final FragmentTransaction fragmentTransaction = fm.beginTransaction(); + fragmentTransaction.remove(buttonsFragment).commit(); + fm.executePendingTransactions(); + } + } + + /***************************************************************************************************** + * + * android.location.LocationListener + * + *****************************************************************************************************/ + + @Override + public void onLocationChanged(final Location location) { + // It was called from onClickGetLocation (UI thread) This method will run in the same thread (the UI thread) + // so, I do no think there should be any problem. + + // Display the current location in the UI + // TODO: May location not be null? + this.getAddressAndUpdateUI(location.getLatitude(), location.getLongitude()); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + // TODO Auto-generated method stub + + } + + @Override + public void onProviderEnabled(String provider) { + // TODO Auto-generated method stub + + } + + @Override + public void onProviderDisabled(String provider) { + // TODO Auto-generated method stub + + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/NotificationIntentService.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/NotificationIntentService.java new file mode 100644 index 0000000..596b43f --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/NotificationIntentService.java @@ -0,0 +1,234 @@ +package de.example.exampletdd; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Calendar; +import java.util.Locale; + +import org.apache.http.client.ClientProtocolException; + +import android.app.IntentService; +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.http.AndroidHttpClient; +import android.preference.PreferenceManager; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; +import android.support.v4.app.TaskStackBuilder; +import android.util.Log; +import android.widget.RemoteViews; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.httpclient.CustomHTTPClient; +import de.example.exampletdd.model.DatabaseQueries; +import de.example.exampletdd.model.WeatherLocation; +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.parser.JPOSWeatherParser; +import de.example.exampletdd.service.IconsList; +import de.example.exampletdd.service.ServiceParser; + +public class NotificationIntentService extends IntentService { + private static final String TAG = "NotificationIntentService"; + + + public NotificationIntentService() { + super("NIS-Thread"); + } + + @Override + protected void onHandleIntent(final Intent intent) { + final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext()); + final WeatherLocation weatherLocation = query.queryDataBase(); + + if (weatherLocation != null) { + final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser()); + final CustomHTTPClient HTTPClient = new CustomHTTPClient( + AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")); + + Current current = null; + try { + current = this.doInBackgroundThrowable(weatherLocation, HTTPClient, weatherService); + + } catch (final JsonParseException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final ClientProtocolException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final MalformedURLException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final URISyntaxException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final IOException e) { + // logger infrastructure swallows UnknownHostException :/ + Log.e(TAG, "doInBackground exception: " + e.getMessage(), e); + } finally { + HTTPClient.close(); + } + + if (current != null) { + this.showNotification(current, weatherLocation); + } + } + } + + private Current doInBackgroundThrowable(final WeatherLocation weatherLocation, + final CustomHTTPClient HTTPClient, final ServiceParser weatherService) + throws ClientProtocolException, MalformedURLException, URISyntaxException, + JsonParseException, IOException { + + final String APIVersion = this.getResources().getString(R.string.api_version); + + final String urlAPI = this.getResources().getString(R.string.uri_api_weather_today); + final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion, + weatherLocation.getLatitude(), weatherLocation.getLongitude()); + final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis()); + final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache)); + final Current current = weatherService.retrieveCurrentFromJPOS(jsonData); + // TODO: what is this for? I guess I could skip it :/ + final Calendar now = Calendar.getInstance(); + current.setDate(now.getTime()); + + return current; + } + + private interface UnitsConversor { + + public double doConversion(final double value); + } + + private void showNotification(final Current current, final WeatherLocation weatherLocation) { + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getApplicationContext()); + + // TODO: repeating the same code in Overview, Specific and Current!!! + // 1. Update units of measurement. + // 1.1 Temperature + String tempSymbol; + UnitsConversor tempUnitsConversor; + String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key); + String unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature); + if (unitsPreferenceValue.equals(values[0])) { + tempSymbol = values[0]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value - 273.15; + } + + }; + } else if (unitsPreferenceValue.equals(values[1])) { + tempSymbol = values[1]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return (value * 1.8) - 459.67; + } + + }; + } else { + tempSymbol = values[2]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value; + } + + }; + } + + + // 2. Formatters + final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); + tempFormatter.applyPattern("#####.#####"); + + + // 3. Prepare data for RemoteViews. + String tempMax = ""; + if (current.getMain().getTemp_max() != null) { + double conversion = (Double) current.getMain().getTemp_max(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMax = tempFormatter.format(conversion) + tempSymbol; + } + String tempMin = ""; + if (current.getMain().getTemp_min() != null) { + double conversion = (Double) current.getMain().getTemp_min(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMin = tempFormatter.format(conversion) + tempSymbol; + } + Bitmap picture; + if ((current.getWeather().size() > 0) + && (current.getWeather().get(0).getIcon() != null) + && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) { + final String icon = current.getWeather().get(0).getIcon(); + picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) + .getResourceDrawable()); + } else { + picture = BitmapFactory.decodeResource(this.getResources(), + R.drawable.weather_severe_alert); + } + final String city = weatherLocation.getCity(); + final String country = weatherLocation.getCountry(); + + // 4. Insert data in RemoteViews. + final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.notification); + remoteView.setImageViewBitmap(R.id.weather_notification_image, picture); + remoteView.setTextViewText(R.id.weather_notification_temperature_max, tempMax); + remoteView.setTextViewText(R.id.weather_notification_temperature_min, tempMin); + remoteView.setTextViewText(R.id.weather_notification_city, city); + remoteView.setTextViewText(R.id.weather_notification_country, country); + + // 5. Activity launcher. + final Intent resultIntent = new Intent(this.getApplicationContext(), WeatherTabsActivity.class); + // The PendingIntent to launch our activity if the user selects this notification +// final PendingIntent contentIntent = PendingIntent.getActivity( +// this.getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); + // The stack builder object will contain an artificial back stack for the started Activity. + // This ensures that navigating backward from the Activity leads out of + // your application to the Home screen. + final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext()); + // Adds the back stack for the Intent (but not the Intent itself) + stackBuilder.addParentStack(WeatherTabsActivity.class); + // Adds the Intent that starts the Activity to the top of the stack + stackBuilder.addNextIntent(resultIntent); + final PendingIntent resultPendingIntent = + stackBuilder.getPendingIntent( + 0, + PendingIntent.FLAG_UPDATE_CURRENT + ); + + final NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(this.getApplicationContext()); + + + // 6. Create notification. + final NotificationCompat.Builder notificationBuilder = + new NotificationCompat.Builder(this.getApplicationContext()) + .setContent(remoteView) + .setSmallIcon(R.drawable.ic_launcher) + .setAutoCancel(true) + .setLocalOnly(true) + .setWhen(System.currentTimeMillis()) + .setContentIntent(resultPendingIntent) + .setPriority(NotificationCompat.PRIORITY_DEFAULT); + + final Notification notification = notificationBuilder.build(); + notification.flags |= Notification.FLAG_AUTO_CANCEL; + + // Send the notification. + // Sets an ID for the notification, so it can be updated (just in case) + int notifyID = 1; + notificationManager.notify(notifyID, notification); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/SpecificActivity.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/SpecificActivity.java new file mode 100644 index 0000000..3cb5da4 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/SpecificActivity.java @@ -0,0 +1,37 @@ +package de.example.exampletdd; + +import android.app.ActionBar; +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; +import de.example.exampletdd.model.DatabaseQueries; +import de.example.exampletdd.model.WeatherLocation; + +public class SpecificActivity extends FragmentActivity { + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.setContentView(R.layout.weather_specific); + + final ActionBar actionBar = this.getActionBar(); + + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE); + actionBar.setDisplayHomeAsUpEnabled(true); + + } + + @Override + public void onResume() { + super.onResume(); + + // 1. Update title. + final DatabaseQueries query = new DatabaseQueries(this); + final WeatherLocation weatherLocation = query.queryDataBase(); + if (weatherLocation != null) { + final ActionBar actionBar = this.getActionBar(); + // TODO: I18N and comma :/ + actionBar.setTitle(weatherLocation.getCity() + "," + weatherLocation.getCountry()); + } + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherInformationBootReceiver.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherInformationBootReceiver.java new file mode 100644 index 0000000..05b751d --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherInformationBootReceiver.java @@ -0,0 +1,57 @@ +package de.example.exampletdd; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.SystemClock; +import android.preference.PreferenceManager; + +public class WeatherInformationBootReceiver extends BroadcastReceiver { + + @Override + public void onReceive(final Context context, final Intent intent) { + + if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { + + // Update Time Rate + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(context); + final String keyPreference = context + .getString(R.string.weather_preferences_update_time_rate_key); + final String updateTimeRate = sharedPreferences.getString(keyPreference, ""); + long chosenInterval = 0; + if (updateTimeRate.equals("900")) { + chosenInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES; + } else if (updateTimeRate.equals("1800")) { + chosenInterval = AlarmManager.INTERVAL_HALF_HOUR; + } else if (updateTimeRate.equals("3600")) { + chosenInterval = AlarmManager.INTERVAL_HOUR; + } else if (updateTimeRate.equals("43200")) { + chosenInterval = AlarmManager.INTERVAL_HALF_DAY; + } else if (updateTimeRate.equals("86400")) { + chosenInterval = AlarmManager.INTERVAL_DAY; + } + + if (chosenInterval != 0) { + final AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + // TODO: better use some string instead of .class? In case I change the service class + // this could be a problem (I guess) + final Intent serviceIntent = new Intent(context, NotificationIntentService.class); + final PendingIntent alarmIntent = PendingIntent.getService( + context, + 0, + serviceIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + alarmMgr.setInexactRepeating( + AlarmManager.ELAPSED_REALTIME, + SystemClock.elapsedRealtime() + chosenInterval, + chosenInterval, + alarmIntent); + } + } + } + +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherInformationPreferencesActivity.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherInformationPreferencesActivity.java new file mode 100644 index 0000000..1e9b0d4 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherInformationPreferencesActivity.java @@ -0,0 +1,27 @@ +package de.example.exampletdd; + +import android.app.ActionBar; +import android.app.Activity; +import android.os.Bundle; +import de.example.exampletdd.fragment.preferences.WeatherInformationPreferencesFragment; + +public class WeatherInformationPreferencesActivity extends Activity { + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + this.getFragmentManager() + .beginTransaction() + .replace(android.R.id.content, + new WeatherInformationPreferencesFragment()).commit(); + } + + @Override + public void onResume() { + super.onResume(); + + final ActionBar actionBar = this.getActionBar(); + actionBar.setTitle(this.getString(R.string.weather_preferences_action_settings)); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherTabsActivity.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherTabsActivity.java new file mode 100644 index 0000000..168ab2e --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WeatherTabsActivity.java @@ -0,0 +1,182 @@ +package de.example.exampletdd; + +import android.app.ActionBar; +import android.app.ActionBar.Tab; +import android.app.FragmentTransaction; +import android.content.ComponentName; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.view.Menu; +import android.view.MenuItem; +import de.example.exampletdd.fragment.current.CurrentFragment; +import de.example.exampletdd.fragment.overview.OverviewFragment; +import de.example.exampletdd.model.DatabaseQueries; +import de.example.exampletdd.model.WeatherLocation; + +public class WeatherTabsActivity extends FragmentActivity { + private static final int NUM_ITEMS = 2; + private ViewPager mPager; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.setContentView(R.layout.fragment_pager); + + this.mPager = (ViewPager)this.findViewById(R.id.pager); + this.mPager.setAdapter(new TabsAdapter(this.getSupportFragmentManager())); + + + this.mPager.setOnPageChangeListener( + new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(final int position) { + WeatherTabsActivity.this.getActionBar().setSelectedNavigationItem(position); + } + }); + + + final ActionBar actionBar = this.getActionBar(); + + PreferenceManager.setDefaultValues(this, R.xml.weather_preferences, false); + + // Specify that tabs should be displayed in the action bar. + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE); + actionBar.setDisplayHomeAsUpEnabled(true); + + // Create a tab listener that is called when the user changes tabs. + final ActionBar.TabListener tabListener = new ActionBar.TabListener() { + + @Override + public void onTabSelected(final Tab tab, final FragmentTransaction ft) { + WeatherTabsActivity.this.mPager.setCurrentItem(tab.getPosition()); + + } + + @Override + public void onTabUnselected(final Tab tab, final FragmentTransaction ft) { + + } + + @Override + public void onTabReselected(final Tab tab, final FragmentTransaction ft) { + + } + + }; + + actionBar.addTab(actionBar.newTab().setText("CURRENTLY").setTabListener(tabListener)); + actionBar.addTab(actionBar.newTab().setText("FORECAST").setTabListener(tabListener)); + } + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + + this.getMenuInflater().inflate(R.menu.weather_main_menu, menu); + + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + super.onOptionsItemSelected(item); + + Intent intent; + final int itemId = item.getItemId(); + if (itemId == R.id.weather_menu_settings) { + intent = new Intent("de.example.exampletdd.WEATHERINFO") + .setComponent(new ComponentName("de.example.exampletdd", + "de.example.exampletdd.WeatherInformationPreferencesActivity")); + this.startActivity(intent); + return true; + } else if (itemId == R.id.weather_menu_map) { + intent = new Intent("de.example.exampletdd.WEATHERINFO"). + setComponent(new ComponentName("de.example.exampletdd", + "de.example.exampletdd.MapActivity")); + this.startActivity(intent); + return true; + } else { + } + + // TODO: calling again super method? + return super.onOptionsItemSelected(item); + } + + @Override + protected void onRestoreInstanceState(final Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + } + + + @Override + public void onResume() { + super.onResume(); + + final ActionBar actionBar = this.getActionBar(); + + // 1. Update title. + final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext()); + final WeatherLocation weatherLocation = query.queryDataBase(); + if (weatherLocation != null) { + // TODO: I18N and comma :/ + actionBar.setTitle(weatherLocation.getCity() + "," + weatherLocation.getCountry()); + } else { + // TODO: static resource + actionBar.setTitle("no chosen location"); + } + + // 2. Update forecast tab text. + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this); + final String keyPreference = this.getString(R.string.weather_preferences_day_forecast_key); + final String value = sharedPreferences.getString(keyPreference, ""); + String humanValue = ""; + if (value.equals("5")) { + humanValue = "5 DAY FORECAST"; + } else if (value.equals("10")) { + humanValue = "10 DAY FORECAST"; + } else if (value.equals("14")) { + humanValue = "14 DAY FORECAST"; + } + actionBar.getTabAt(1).setText(humanValue); + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + super.onSaveInstanceState(savedInstanceState); + } + + private class TabsAdapter extends FragmentPagerAdapter { + public TabsAdapter(final FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return NUM_ITEMS; + } + + @Override + public Fragment getItem(final int position) { + if (position == 0) { + // TODO: new instance every time I click on tab? + return new CurrentFragment(); + } else { + // TODO: new instance every time I click on tab? + final Fragment fragment = new OverviewFragment(); + return fragment; + } + + } + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WidgetIntentService.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WidgetIntentService.java new file mode 100644 index 0000000..ed38545 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/WidgetIntentService.java @@ -0,0 +1,304 @@ +package de.example.exampletdd; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Calendar; +import java.util.Locale; + +import org.apache.http.client.ClientProtocolException; + +import android.app.IntentService; +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.net.http.AndroidHttpClient; +import android.preference.PreferenceManager; +import android.support.v4.app.TaskStackBuilder; +import android.util.Log; +import android.widget.RemoteViews; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.httpclient.CustomHTTPClient; +import de.example.exampletdd.model.DatabaseQueries; +import de.example.exampletdd.model.WeatherLocation; +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.parser.JPOSWeatherParser; +import de.example.exampletdd.service.IconsList; +import de.example.exampletdd.service.PermanentStorage; +import de.example.exampletdd.service.ServiceParser; +import de.example.exampletdd.widget.WidgetConfigure; + +public class WidgetIntentService extends IntentService { + private static final String TAG = "WidgetIntentService"; + + + public WidgetIntentService() { + super("WIS-Thread"); + } + + @Override + protected void onHandleIntent(final Intent intent) { + Log.i(TAG, "onHandleIntent"); + final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + final boolean isUpdateByApp = intent.getBooleanExtra("updateByApp", false); + + if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { + // Nothing to do. Something went wrong. Show error. + return; + } + + + final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext()); + final WeatherLocation weatherLocation = query.queryDataBase(); + + if (weatherLocation == null) { + // Nothing to do. Show error. + final RemoteViews view = this.makeErrorView(appWidgetId); + this.updateWidget(view, appWidgetId); + return; + } + + if (isUpdateByApp) { + this.updateByApp(weatherLocation, appWidgetId); + } else { + this.updateByTimeout(weatherLocation, appWidgetId); + } + + } + + private void updateByApp(final WeatherLocation weatherLocation, final int appWidgetId) { + final PermanentStorage store = new PermanentStorage(this.getApplicationContext()); + final Current current = store.getCurrent(); + + this.updateWidget(current, weatherLocation, appWidgetId); + } + + private void updateByTimeout(final WeatherLocation weatherLocation, final int appWidgetId) { + + final Current current = this.getRemoteCurrent(weatherLocation); + + this.updateWidget(current, weatherLocation, appWidgetId); + } + + private void updateWidget(final Current current, final WeatherLocation weatherLocation, final int appWidgetId) { + + if (current != null) { + final RemoteViews view = this.makeView(current, weatherLocation, appWidgetId); + this.updateWidget(view, appWidgetId); + } else { + // Show error. + final RemoteViews view = this.makeErrorView(appWidgetId); + this.updateWidget(view, appWidgetId); + } + } + + + + private Current getRemoteCurrent(final WeatherLocation weatherLocation) { + + final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser()); + final CustomHTTPClient HTTPClient = new CustomHTTPClient( + AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")); + + try { + return this.getRemoteCurrentThrowable(weatherLocation, HTTPClient, weatherService); + + } catch (final JsonParseException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final ClientProtocolException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final MalformedURLException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final URISyntaxException e) { + Log.e(TAG, "doInBackground exception: ", e); + } catch (final IOException e) { + // logger infrastructure swallows UnknownHostException :/ + Log.e(TAG, "doInBackground exception: " + e.getMessage(), e); + } finally { + HTTPClient.close(); + } + + return null; + } + + private Current getRemoteCurrentThrowable(final WeatherLocation weatherLocation, + final CustomHTTPClient HTTPClient, final ServiceParser weatherService) + throws ClientProtocolException, MalformedURLException, URISyntaxException, + JsonParseException, IOException { + + final String APIVersion = this.getResources().getString(R.string.api_version); + + final String urlAPI = this.getResources().getString(R.string.uri_api_weather_today); + final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion, + weatherLocation.getLatitude(), weatherLocation.getLongitude()); + final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis()); + final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache)); + final Current current = weatherService.retrieveCurrentFromJPOS(jsonData); + // TODO: what is this for? I guess I could skip it :/ + final Calendar now = Calendar.getInstance(); + current.setDate(now.getTime()); + + return current; + } + + private interface UnitsConversor { + + public double doConversion(final double value); + } + + private RemoteViews makeView(final Current current, final WeatherLocation weatherLocation, final int appWidgetId) { + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getApplicationContext()); + + // TODO: repeating the same code in Overview, Specific and Current!!! + // 1. Update units of measurement. + // 1.1 Temperature + String tempSymbol; + UnitsConversor tempUnitsConversor; + String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key); + String unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature); + if (unitsPreferenceValue.equals(values[0])) { + tempSymbol = values[0]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value - 273.15; + } + + }; + } else if (unitsPreferenceValue.equals(values[1])) { + tempSymbol = values[1]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return (value * 1.8) - 459.67; + } + + }; + } else { + tempSymbol = values[2]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value; + } + + }; + } + + + // 2. Formatters + final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); + tempFormatter.applyPattern("#####.#####"); + + + // 3. Prepare data for RemoteViews. + String tempMax = ""; + if (current.getMain().getTemp_max() != null) { + double conversion = (Double) current.getMain().getTemp_max(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMax = tempFormatter.format(conversion) + tempSymbol; + } + String tempMin = ""; + if (current.getMain().getTemp_min() != null) { + double conversion = (Double) current.getMain().getTemp_min(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMin = tempFormatter.format(conversion) + tempSymbol; + } + Bitmap picture; + if ((current.getWeather().size() > 0) + && (current.getWeather().get(0).getIcon() != null) + && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) { + final String icon = current.getWeather().get(0).getIcon(); + picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) + .getResourceDrawable()); + } else { + picture = BitmapFactory.decodeResource(this.getResources(), + R.drawable.weather_severe_alert); + } + final String city = weatherLocation.getCity(); + final String country = weatherLocation.getCountry(); + + // 4. Insert data in RemoteViews. + final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.appwidget); + remoteView.setImageViewBitmap(R.id.weather_appwidget_image, picture); + remoteView.setTextViewText(R.id.weather_appwidget_temperature_max, tempMax); + remoteView.setTextViewText(R.id.weather_appwidget_temperature_min, tempMin); + remoteView.setTextViewText(R.id.weather_appwidget_city, city); + remoteView.setTextViewText(R.id.weather_appwidget_country, country); + + // 5. Activity launcher. + final Intent resultIntent = new Intent(this.getApplicationContext(), WidgetConfigure.class); + resultIntent.putExtra("actionFromUser", true); + resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + // From: http://stackoverflow.com/questions/4011178/multiple-instances-of-widget-only-updating-last-widget + final Uri data = Uri.withAppendedPath(Uri.parse("PAIN" + "://widget/id/") ,String.valueOf(appWidgetId)); + resultIntent.setData(data); + + final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext()); + // Adds the back stack for the Intent (but not the Intent itself) + stackBuilder.addParentStack(WidgetConfigure.class); + // Adds the Intent that starts the Activity to the top of the stack + stackBuilder.addNextIntent(resultIntent); + final PendingIntent resultPendingIntent = + stackBuilder.getPendingIntent( + 0, + PendingIntent.FLAG_UPDATE_CURRENT + ); + remoteView.setOnClickPendingIntent(R.id.weather_appwidget, resultPendingIntent); + + return remoteView; + } + + private RemoteViews makeErrorView(final int appWidgetId) { + final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.appwidget_error); + + // 5. Activity launcher. + final Intent resultIntent = new Intent(this.getApplicationContext(), WidgetConfigure.class); + resultIntent.putExtra("actionFromUser", true); + resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + // From: http://stackoverflow.com/questions/4011178/multiple-instances-of-widget-only-updating-last-widget + final Uri data = Uri.withAppendedPath(Uri.parse("PAIN" + "://widget/id/") ,String.valueOf(appWidgetId)); + resultIntent.setData(data); + + final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext()); + // Adds the back stack for the Intent (but not the Intent itself) + stackBuilder.addParentStack(WidgetConfigure.class); + // Adds the Intent that starts the Activity to the top of the stack + stackBuilder.addNextIntent(resultIntent); + final PendingIntent resultPendingIntent = + stackBuilder.getPendingIntent( + 0, + PendingIntent.FLAG_UPDATE_CURRENT + ); + remoteView.setOnClickPendingIntent(R.id.weather_appwidget_error, resultPendingIntent); + + return remoteView; + } + + private void updateWidget(final RemoteViews remoteView, final int appWidgetId) { + + final AppWidgetManager manager = AppWidgetManager.getInstance(this.getApplicationContext()); + manager.updateAppWidget(appWidgetId, remoteView); + } + +// private void updateWidgets(final RemoteViews remoteView) { +// +// final ComponentName widgets = new ComponentName(this.getApplicationContext(), WidgetProvider.class); +// final AppWidgetManager manager = AppWidgetManager.getInstance(this.getApplicationContext()); +// manager.updateAppWidget(widgets, remoteView); +// } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/dummy/DummyContent.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/dummy/DummyContent.java new file mode 100644 index 0000000..6c09241 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/dummy/DummyContent.java @@ -0,0 +1,55 @@ +package de.example.exampletdd.dummy; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Helper class for providing sample content for user interfaces created by + * Android template wizards. + *

+ * TODO: Replace all uses of this class before publishing your app. + */ +public class DummyContent { + + /** + * An array of sample (dummy) items. + */ + public static List ITEMS = new ArrayList(); + + /** + * A map of sample (dummy) items, by ID. + */ + public static Map ITEM_MAP = new HashMap(); + + static { + // Add 3 sample items. + addItem(new DummyItem("1", "Item 1")); + addItem(new DummyItem("2", "Item 2")); + addItem(new DummyItem("3", "Item 3")); + } + + private static void addItem(DummyItem item) { + ITEMS.add(item); + ITEM_MAP.put(item.id, item); + } + + /** + * A dummy item representing a piece of content. + */ + public static class DummyItem { + public String id; + public String content; + + public DummyItem(String id, String content) { + this.id = id; + this.content = content; + } + + @Override + public String toString() { + return content; + } + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/ErrorDialogFragment.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/ErrorDialogFragment.java new file mode 100644 index 0000000..5d00707 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/ErrorDialogFragment.java @@ -0,0 +1,45 @@ +package de.example.exampletdd.fragment; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; + +public class ErrorDialogFragment extends DialogFragment { + + public static ErrorDialogFragment newInstance(final int title) { + final ErrorDialogFragment frag = new ErrorDialogFragment(); + final Bundle args = new Bundle(); + + args.putInt("title", title); + frag.setArguments(args); + + return frag; + } + + @Override + public Dialog onCreateDialog(final Bundle savedInstanceState) { + final int title = this.getArguments().getInt("title"); + + return new AlertDialog.Builder(this.getActivity()) + .setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(title) + .setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, + final int whichButton) { + + } + }).create(); + } + + @Override + public void onDestroyView() { + if (getDialog() != null && getRetainInstance()) { + getDialog().setDismissMessage(null); + } + super.onDestroyView(); + } +} \ No newline at end of file diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/ProgressDialogFragment.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/ProgressDialogFragment.java new file mode 100644 index 0000000..7ff9960 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/ProgressDialogFragment.java @@ -0,0 +1,54 @@ +package de.example.exampletdd.fragment; + +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.view.KeyEvent; + +public class ProgressDialogFragment extends DialogFragment { + + public static ProgressDialogFragment newInstance(final int title) { + return newInstance(title, null); + } + + public static ProgressDialogFragment newInstance(final int title, + final String message) { + final ProgressDialogFragment frag = new ProgressDialogFragment(); + final Bundle args = new Bundle(); + + args.putInt("title", title); + args.putString("message", message); + frag.setArguments(args); + return frag; + } + + @Override + public Dialog onCreateDialog(final Bundle savedInstanceState) { + final int title = this.getArguments().getInt("title"); + final String message = this.getArguments().getString("message"); + + final ProgressDialog dialog = new ProgressDialog(this.getActivity()); + dialog.setIcon(android.R.drawable.ic_dialog_info); + if (title != 0) { + dialog.setTitle(title); + } + if (message != null) { + dialog.setMessage(message); + } + dialog.setCancelable(false); + this.setCancelable(false); + dialog.setIndeterminate(true); + dialog.setOnKeyListener(new DialogInterface.OnKeyListener() { + + @Override + public final boolean onKey(final DialogInterface dialog, + final int keyCode, final KeyEvent event) { + return false; + } + }); + + return dialog; + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/current/CurrentFragment.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/current/CurrentFragment.java new file mode 100644 index 0000000..13f9a77 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/current/CurrentFragment.java @@ -0,0 +1,528 @@ +package de.example.exampletdd.fragment.current; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +import org.apache.http.client.ClientProtocolException; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.http.AndroidHttpClient; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.R; +import de.example.exampletdd.WidgetIntentService; +import de.example.exampletdd.httpclient.CustomHTTPClient; +import de.example.exampletdd.model.DatabaseQueries; +import de.example.exampletdd.model.WeatherLocation; +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.parser.JPOSWeatherParser; +import de.example.exampletdd.service.IconsList; +import de.example.exampletdd.service.PermanentStorage; +import de.example.exampletdd.service.ServiceParser; + +public class CurrentFragment extends Fragment { + private static final String TAG = "CurrentFragment"; + private BroadcastReceiver mReceiver; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + // Inflate the layout for this fragment + return inflater.inflate(R.layout.weather_current_fragment, container, false); + } + + @Override + public void onActivityCreated(final Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (savedInstanceState != null) { + // Restore UI state + final Current current = (Current) savedInstanceState.getSerializable("Current"); + + // TODO: Could it be better to store in global forecast data even if it is null value? + // So, perhaps do not check for null value and always store in global variable. + if (current != null) { + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + store.saveCurrent(current); + } + } + + this.setHasOptionsMenu(false); + + this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE); + this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.VISIBLE); + this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE); + } + + @Override + public void onResume() { + super.onResume(); + + + this.mReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(final Context context, final Intent intent) { + final String action = intent.getAction(); + if (action.equals("de.example.exampletdd.UPDATECURRENT")) { + final Current currentRemote = (Current) intent.getSerializableExtra("current"); + + if (currentRemote != null) { + + // 1. Check conditions. They must be the same as the ones that triggered the AsyncTask. + final DatabaseQueries query = new DatabaseQueries(context.getApplicationContext()); + final WeatherLocation weatherLocation = query.queryDataBase(); + final PermanentStorage store = new PermanentStorage(context.getApplicationContext()); + final Current current = store.getCurrent(); + + if (current == null || !CurrentFragment.this.isDataFresh(weatherLocation.getLastCurrentUIUpdate())) { + // 2. Update UI. + CurrentFragment.this.updateUI(currentRemote); + + // 3. Update Data. + store.saveCurrent(currentRemote); + weatherLocation.setLastCurrentUIUpdate(new Date()); + query.updateDataBase(weatherLocation); + } + + } else { + // Empty UI and show error message + CurrentFragment.this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE); + CurrentFragment.this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.GONE); + CurrentFragment.this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.VISIBLE); + } + } + } + }; + + // Register receiver + final IntentFilter filter = new IntentFilter(); + filter.addAction("de.example.exampletdd.UPDATECURRENT"); + LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext()) + .registerReceiver(this.mReceiver, filter); + + // Empty UI + this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE); + + final DatabaseQueries query = new DatabaseQueries(this.getActivity().getApplicationContext()); + final WeatherLocation weatherLocation = query.queryDataBase(); + if (weatherLocation == null) { + // Nothing to do. + // Show error message + final ProgressBar progress = (ProgressBar) getActivity().findViewById(R.id.weather_current_progressbar); + progress.setVisibility(View.GONE); + final TextView errorMessage = (TextView) getActivity().findViewById(R.id.weather_current_error_message); + errorMessage.setVisibility(View.VISIBLE); + return; + } + + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + final Current current = store.getCurrent(); + + if (current != null && this.isDataFresh(weatherLocation.getLastCurrentUIUpdate())) { + this.updateUI(current); + } else { + // Load remote data (aynchronous) + // Gets the data from the web. + this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.VISIBLE); + this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE); + final CurrentTask task = new CurrentTask( + this.getActivity().getApplicationContext(), + new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")), + new ServiceParser(new JPOSWeatherParser())); + + task.execute(weatherLocation.getLatitude(), weatherLocation.getLongitude()); + // TODO: make sure UI thread keeps running in parallel after that. I guess. + } + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + + // Save UI state + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + final Current current = store.getCurrent(); + + // TODO: Could it be better to save current data even if it is null value? + // So, perhaps do not check for null value. + if (current != null) { + savedInstanceState.putSerializable("Current", current); + } + + super.onSaveInstanceState(savedInstanceState); + } + + @Override + public void onPause() { + LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext()).unregisterReceiver(this.mReceiver); + + super.onPause(); + } + + private interface UnitsConversor { + + public double doConversion(final double value); + } + + private void updateUI(final Current current) { + + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getActivity().getApplicationContext()); + + // TODO: repeating the same code in Overview, Specific and Current!!! + // 1. Update units of measurement. + // 1.1 Temperature + String tempSymbol; + UnitsConversor tempUnitsConversor; + String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key); + String unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature); + if (unitsPreferenceValue.equals(values[0])) { + tempSymbol = values[0]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value - 273.15; + } + + }; + } else if (unitsPreferenceValue.equals(values[1])) { + tempSymbol = values[1]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return (value * 1.8) - 459.67; + } + + }; + } else { + tempSymbol = values[2]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value; + } + + }; + } + + // 1.2 Wind + String windSymbol; + UnitsConversor windUnitsConversor; + keyPreference = this.getResources().getString(R.string.weather_preferences_wind_key); + unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + values = this.getResources().getStringArray(R.array.weather_preferences_wind); + if (unitsPreferenceValue.equals(values[0])) { + windSymbol = values[0]; + windUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(double value) { + return value; + } + }; + } else { + windSymbol = values[1]; + windUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(double value) { + return value * 2.237; + } + }; + } + + // 1.3 Pressure + String pressureSymbol; + UnitsConversor pressureUnitsConversor; + keyPreference = this.getResources().getString(R.string.weather_preferences_pressure_key); + unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + values = this.getResources().getStringArray(R.array.weather_preferences_pressure); + if (unitsPreferenceValue.equals(values[0])) { + pressureSymbol = values[0]; + pressureUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(double value) { + return value; + } + }; + } else { + pressureSymbol = values[1]; + pressureUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(double value) { + return value / 113.25d; + } + }; + } + + + // 2. Formatters + final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); + tempFormatter.applyPattern("#####.#####"); + final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.US); + + + // 3. Prepare data for UI. + String tempMax = ""; + if (current.getMain().getTemp_max() != null) { + double conversion = (Double) current.getMain().getTemp_max(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMax = tempFormatter.format(conversion) + tempSymbol; + } + String tempMin = ""; + if (current.getMain().getTemp_min() != null) { + double conversion = (Double) current.getMain().getTemp_min(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMin = tempFormatter.format(conversion) + tempSymbol; + } + Bitmap picture; + if ((current.getWeather().size() > 0) + && (current.getWeather().get(0).getIcon() != null) + && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) { + final String icon = current.getWeather().get(0).getIcon(); + picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) + .getResourceDrawable()); + } else { + picture = BitmapFactory.decodeResource(this.getResources(), + R.drawable.weather_severe_alert); + } + + // TODO: static resource + String description = "no description available"; + if (current.getWeather().size() > 0) { + description = current.getWeather().get(0).getDescription(); + } + + // TODO: units!!!! + String humidityValue = ""; + if ((current.getMain() != null) + && (current.getMain().getHumidity() != null)) { + final double conversion = (Double) current.getMain().getHumidity(); + humidityValue = tempFormatter.format(conversion); + } + String pressureValue = ""; + if ((current.getMain() != null) + && (current.getMain().getPressure() != null)) { + double conversion = (Double) current.getMain().getPressure(); + conversion = pressureUnitsConversor.doConversion(conversion); + pressureValue = tempFormatter.format(conversion); + } + String windValue = ""; + if ((current.getWind() != null) + && (current.getWind().getSpeed() != null)) { + double conversion = (Double) current.getWind().getSpeed(); + conversion = windUnitsConversor.doConversion(conversion); + windValue = tempFormatter.format(conversion); + } + String rainValue = ""; + if ((current.getRain() != null) + && (current.getRain().get3h() != null)) { + final double conversion = (Double) current.getRain().get3h(); + rainValue = tempFormatter.format(conversion); + } + String cloudsValue = ""; + if ((current.getClouds() != null) + && (current.getClouds().getAll() != null)) { + final double conversion = (Double) current.getClouds().getAll(); + cloudsValue = tempFormatter.format(conversion); + } + String snowValue = ""; + if ((current.getSnow() != null) + && (current.getSnow().get3h() != null)) { + final double conversion = (Double) current.getSnow().get3h(); + snowValue = tempFormatter.format(conversion); + } + String feelsLike = ""; + if (current.getMain().getTemp() != null) { + double conversion = (Double) current.getMain().getTemp(); + conversion = tempUnitsConversor.doConversion(conversion); + feelsLike = tempFormatter.format(conversion); + } + String sunRiseTime = ""; + if (current.getSys().getSunrise() != null) { + final long unixTime = (Long) current.getSys().getSunrise(); + final Date unixDate = new Date(unixTime * 1000L); + sunRiseTime = dateFormat.format(unixDate); + } + String sunSetTime = ""; + if (current.getSys().getSunset() != null) { + final long unixTime = (Long) current.getSys().getSunset(); + final Date unixDate = new Date(unixTime * 1000L); + sunSetTime = dateFormat.format(unixDate); + } + + + // 4. Update UI. + final TextView tempMaxView = (TextView) getActivity().findViewById(R.id.weather_current_temp_max); + tempMaxView.setText(tempMax); + final TextView tempMinView = (TextView) getActivity().findViewById(R.id.weather_current_temp_min); + tempMinView.setText(tempMin); + final ImageView pictureView = (ImageView) getActivity().findViewById(R.id.weather_current_picture); + pictureView.setImageBitmap(picture); + + final TextView descriptionView = (TextView) getActivity().findViewById(R.id.weather_current_description); + descriptionView.setText(description); + + ((TextView) getActivity().findViewById(R.id.weather_current_humidity_value)).setText(humidityValue); + ((TextView) getActivity().findViewById(R.id.weather_current_humidity_units)).setText( + this.getActivity().getApplicationContext().getString(R.string.text_units_percent)); + + ((TextView) getActivity().findViewById(R.id.weather_current_pressure_value)).setText(pressureValue); + ((TextView) getActivity().findViewById(R.id.weather_current_pressure_units)).setText(pressureSymbol); + + ((TextView) getActivity().findViewById(R.id.weather_current_wind_value)).setText(windValue); + ((TextView) getActivity().findViewById(R.id.weather_current_wind_units)).setText(windSymbol); + + ((TextView) getActivity().findViewById(R.id.weather_current_rain_value)).setText(rainValue); + ((TextView) getActivity().findViewById(R.id.weather_current_rain_units)).setText( + this.getActivity().getApplicationContext().getString(R.string.text_units_mm3h)); + + ((TextView) getActivity().findViewById(R.id.weather_current_clouds_value)).setText(cloudsValue); + ((TextView) getActivity().findViewById(R.id.weather_current_clouds_units)).setText( + this.getActivity().getApplicationContext().getString(R.string.text_units_percent)); + + ((TextView) getActivity().findViewById(R.id.weather_current_snow_value)).setText(snowValue); + ((TextView) getActivity().findViewById(R.id.weather_current_snow_units)).setText( + this.getActivity().getApplicationContext().getString(R.string.text_units_mm3h)); + + ((TextView) getActivity().findViewById(R.id.weather_current_feelslike_value)).setText(feelsLike); + ((TextView) getActivity().findViewById(R.id.weather_current_feelslike_units)).setText(tempSymbol); + + ((TextView) getActivity().findViewById(R.id.weather_current_sunrise_value)).setText(sunRiseTime); + + ((TextView) getActivity().findViewById(R.id.weather_current_sunset_value)).setText(sunSetTime); + + this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.VISIBLE); + this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.GONE); + this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE); + } + + private boolean isDataFresh(final Date lastUpdate) { + if (lastUpdate == null) { + return false; + } + + final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences( + this.getActivity().getApplicationContext()); + final String keyPreference = this.getString(R.string.weather_preferences_refresh_interval_key); + final String refresh = sharedPreferences.getString( + keyPreference, + this.getResources().getStringArray(R.array.weather_preferences_refresh_interval)[0]); + final Date currentTime = new Date(); + if (((currentTime.getTime() - lastUpdate.getTime())) < Long.valueOf(refresh)) { + return true; + } + + return false; + } + + // TODO: How could I show just one progress dialog when I have two fragments in tabs + // activity doing the same in background? + // I mean, if OverviewTask shows one progress dialog and CurrentTask does the same I will have + // have two progress dialogs... How may I solve this problem? I HATE ANDROID. + private class CurrentTask extends AsyncTask { + // Store the context passed to the AsyncTask when the system instantiates it. + private final Context localContext; + final CustomHTTPClient HTTPClient; + final ServiceParser weatherService; + + public CurrentTask(final Context context, final CustomHTTPClient HTTPClient, + final ServiceParser weatherService) { + this.localContext = context; + this.HTTPClient = HTTPClient; + this.weatherService = weatherService; + } + + @Override + protected Current doInBackground(final Object... params) { + final double latitude = (Double) params[0]; + final double longitude = (Double) params[1]; + + Current current = null; + try { + current = this.doInBackgroundThrowable(latitude, longitude); + } catch (final JsonParseException e) { + Log.e(TAG, "CurrentTask doInBackground exception: ", e); + } catch (final ClientProtocolException e) { + Log.e(TAG, "CurrentTask doInBackground exception: ", e); + } catch (final MalformedURLException e) { + Log.e(TAG, "CurrentTask doInBackground exception: ", e); + } catch (final URISyntaxException e) { + Log.e(TAG, "CurrentTask doInBackground exception: ", e); + } catch (final IOException e) { + // logger infrastructure swallows UnknownHostException :/ + Log.e(TAG, "CurrentTask doInBackground exception: " + e.getMessage(), e); + } finally { + HTTPClient.close(); + } + + return current; + } + + private Current doInBackgroundThrowable(final double latitude, final double longitude) + throws URISyntaxException, ClientProtocolException, JsonParseException, IOException { + + final String APIVersion = localContext.getResources().getString(R.string.api_version); + final String urlAPI = localContext.getResources().getString(R.string.uri_api_weather_today); + final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion, latitude, longitude); + final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis()); + final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache)); + final Current current = weatherService.retrieveCurrentFromJPOS(jsonData); + // TODO: what is this for? I guess I could skip it :/ + final Calendar now = Calendar.getInstance(); + current.setDate(now.getTime()); + + return current; + } + + @Override + protected void onPostExecute(final Current current) { + // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method? + // I hope so, otherwise I must catch(Throwable) in doInBackground method :( + + // Call updateUI on the UI thread. + final Intent currentData = new Intent("de.example.exampletdd.UPDATECURRENT"); + currentData.putExtra("current", current); + LocalBroadcastManager.getInstance(this.localContext).sendBroadcastSync(currentData); + } + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/map/MapButtonsFragment.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/map/MapButtonsFragment.java new file mode 100644 index 0000000..a063eb5 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/map/MapButtonsFragment.java @@ -0,0 +1,31 @@ +package de.example.exampletdd.fragment.map; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import de.example.exampletdd.R; + +public class MapButtonsFragment extends Fragment { + + @Override + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, + final Bundle savedInstanceState) { + + // Inflate the layout for this fragment + return inflater.inflate(R.layout.weather_map_buttons, container, false); + } + + /** + * This method will only be called once when the retained + * Fragment is first created. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Retain this fragment across configuration changes. + this.setRetainInstance(true); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/map/MapProgressFragment.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/map/MapProgressFragment.java new file mode 100644 index 0000000..aa4b6e4 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/map/MapProgressFragment.java @@ -0,0 +1,165 @@ +package de.example.exampletdd.fragment.map; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +import android.app.Activity; +import android.content.Context; +import android.location.Address; +import android.location.Geocoder; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import de.example.exampletdd.R; +import de.example.exampletdd.model.WeatherLocation; + +/** + * {@link http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html} + * + */ +public class MapProgressFragment extends Fragment { + + /** + * + * Callback interface through which the fragment will report the + * task's progress and results back to the Activity. + */ + public static interface TaskCallbacks { + void onPostExecute(final WeatherLocation weatherLocation); + } + + private TaskCallbacks mCallbacks; + + @Override + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, + final Bundle savedInstanceState) { + + // Inflate the layout for this fragment + return inflater.inflate(R.layout.weather_map_progress, container, false); + } + + /** + * This method will only be called once when the retained + * Fragment is first created. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Retain this fragment across configuration changes. + this.setRetainInstance(true); + + final Bundle bundle = this.getArguments(); + double latitude = bundle.getDouble("latitude"); + double longitude = bundle.getDouble("longitude"); + + // Create and execute the background task. + new GetAddressTask(this.getActivity().getApplicationContext()).execute(latitude, longitude); + } + + /** + * Hold a reference to the parent Activity so we can report the + * task's current progress and results. The Android framework + * will pass us a reference to the newly created Activity after + * each configuration change. + */ + @Override + public void onAttach(final Activity activity) { + super.onAttach(activity); + mCallbacks = (TaskCallbacks) activity; + } + + /** + * Set the callback to null so we don't accidentally leak the + * Activity instance. + */ +// @Override +// public void onDetach() { +// super.onDetach(); +// mCallbacks = null; +// } + + /** + * I am not using onDetach because there are problems when my activity goes to background. + * + * {@link http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html} + */ + @Override + public void onPause() { + super.onPause(); + mCallbacks = null; + } + + private class GetAddressTask extends AsyncTask { + private static final String TAG = "GetAddressTask"; + // Store the context passed to the AsyncTask when the system instantiates it. + private final Context localContext; + + private GetAddressTask(final Context context) { + this.localContext = context; + } + + @Override + protected WeatherLocation doInBackground(final Object... params) { + final double latitude = (Double) params[0]; + final double longitude = (Double) params[1]; + + WeatherLocation weatherLocation = this.doDefaultLocation(latitude, longitude); + try { + weatherLocation = this.getLocation(latitude, longitude); + } catch (final Throwable e) { // Hopefully nothing goes wrong because of catching Throwable. + Log.e(TAG, "GetAddressTask doInBackground exception: ", e); + } + + return weatherLocation; + } + + @Override + protected void onPostExecute(final WeatherLocation weatherLocation) { + // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method? + // I hope so, otherwise I must catch(Throwable) in doInBackground method :( + + // Call updateUI on the UI thread. + if (mCallbacks != null) { + mCallbacks.onPostExecute(weatherLocation); + } + } + + private WeatherLocation getLocation(final double latitude, final double longitude) throws IOException { + // TODO: i18n Locale.getDefault() + final Geocoder geocoder = new Geocoder(this.localContext, Locale.US); + final List

addresses = geocoder.getFromLocation(latitude, longitude, 1); + + // Default values + WeatherLocation weatherLocation = this.doDefaultLocation(latitude, longitude); + + if (addresses != null && addresses.size() > 0) { + if (addresses.get(0).getLocality() != null) { + weatherLocation.setCity(addresses.get(0).getLocality()); + } + if(addresses.get(0).getCountryName() != null) { + weatherLocation.setCountry(addresses.get(0).getCountryName()); + } + } + + return weatherLocation; + } + + private WeatherLocation doDefaultLocation(final double latitude, final double longitude) { + // Default values + String city = this.localContext.getString(R.string.city_not_found); + String country = this.localContext.getString(R.string.country_not_found); + + return new WeatherLocation() + .setLatitude(latitude) + .setLongitude(longitude) + .setCity(city) + .setCountry(country); + } + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewAdapter.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewAdapter.java new file mode 100644 index 0000000..13641b6 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewAdapter.java @@ -0,0 +1,108 @@ +package de.example.exampletdd.fragment.overview; + +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 de.example.exampletdd.R; + +public class OverviewAdapter extends ArrayAdapter { + private final int resource; + + public OverviewAdapter(final Context context, final int resource) { + super(context, 0); + + this.resource = resource; + } + + @Override + public View getView(final int position, final View convertView, + final ViewGroup parent) { + + // We need to get the best view (re-used if possible) and then + // retrieve its corresponding ViewHolder, which optimizes lookup + // efficiency + final View view = this.getWorkingView(convertView); + final ViewHolder viewHolder = this.getViewHolder(view); + final OverviewEntry entry = this.getItem(position); + + + // Setting date + viewHolder.dateNameView.setText(entry.getDateName()); + viewHolder.dateNumberView.setText(entry.getDateNumber()); + + // Setting temperature max/min + viewHolder.temperatureMaxView.setText(entry.getMaxTemp()); + viewHolder.temperatureMinView.setText(entry.getMinTemp()); + + // Set image view + viewHolder.pictureView.setImageBitmap(entry.getPicture()); + + + return view; + } + + private View getWorkingView(final View convertView) { + // The workingView is basically just the convertView re-used if possible + // or inflated new if not possible + View workingView = null; + + if(null == convertView) { + final Context context = this.getContext(); + final LayoutInflater inflater = (LayoutInflater)context.getSystemService + (Context.LAYOUT_INFLATER_SERVICE); + + workingView = inflater.inflate(this.resource, null); + } else { + workingView = convertView; + } + + return workingView; + } + + private ViewHolder getViewHolder(final View workingView) { + // The viewHolder allows us to avoid re-looking up view references + // Since views are recycled, these references will never change + final Object tag = workingView.getTag(); + ViewHolder viewHolder = null; + + + if((null == tag) || !(tag instanceof ViewHolder)) { + viewHolder = new ViewHolder(); + + viewHolder.dateNameView = (TextView) workingView + .findViewById(R.id.weather_main_entry_date_name); + viewHolder.dateNumberView = (TextView) workingView + .findViewById(R.id.weather_main_entry_date_number); + viewHolder.temperatureMaxView = (TextView) workingView + .findViewById(R.id.weather_main_entry_temperature_max); + viewHolder.temperatureMinView = (TextView) workingView + .findViewById(R.id.weather_main_entry_temperature_min); + viewHolder.pictureView = (ImageView) workingView + .findViewById(R.id.weather_main_entry_image); + + workingView.setTag(viewHolder); + + } else { + viewHolder = (ViewHolder) tag; + } + + return viewHolder; + } + + /** + * ViewHolder allows us to avoid re-looking up view references + * Since views are recycled, these references will never change + */ + private static class ViewHolder { + public TextView dateNameView; + public TextView dateNumberView; + public TextView temperatureMaxView; + public TextView temperatureMinView; + public ImageView pictureView; + } + +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewEntry.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewEntry.java new file mode 100644 index 0000000..16135f9 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewEntry.java @@ -0,0 +1,41 @@ +package de.example.exampletdd.fragment.overview; + +import android.graphics.Bitmap; + +public class OverviewEntry { + private final String dateName; + private final String dateNumber; + private final String maxTemp; + private final String minTemp; + private final Bitmap picture; + + public OverviewEntry(final String dateName, final String dateNumber, + final String maxTemp, final String minTemp, + final Bitmap picture) { + this.dateName = dateName; + this.dateNumber = dateNumber; + this.maxTemp = maxTemp; + this.minTemp = minTemp; + this.picture = picture; + } + + public String getDateName() { + return this.dateName; + } + + public String getDateNumber() { + return this.dateNumber; + } + + public String getMaxTemp() { + return this.maxTemp; + } + + public String getMinTemp() { + return this.minTemp; + } + + public Bitmap getPicture() { + return this.picture; + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewFragment.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewFragment.java new file mode 100644 index 0000000..682e5bd --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewFragment.java @@ -0,0 +1,410 @@ +package de.example.exampletdd.fragment.overview; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import org.apache.http.client.ClientProtocolException; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.http.AndroidHttpClient; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.ListFragment; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; +import android.view.View; +import android.widget.ListView; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.R; +import de.example.exampletdd.fragment.specific.SpecificFragment; +import de.example.exampletdd.httpclient.CustomHTTPClient; +import de.example.exampletdd.model.DatabaseQueries; +import de.example.exampletdd.model.WeatherLocation; +import de.example.exampletdd.model.forecastweather.Forecast; +import de.example.exampletdd.parser.JPOSWeatherParser; +import de.example.exampletdd.service.IconsList; +import de.example.exampletdd.service.PermanentStorage; +import de.example.exampletdd.service.ServiceParser; + +public class OverviewFragment extends ListFragment { + private static final String TAG = "OverviewFragment"; + private BroadcastReceiver mReceiver; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public void onActivityCreated(final Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + final ListView listWeatherView = this.getListView(); + listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE); + + if (savedInstanceState != null) { + // Restore UI state + final Forecast forecast = (Forecast) savedInstanceState.getSerializable("Forecast"); + + // TODO: Could it be better to store in global forecast data even if it is null value? + // So, perhaps do not check for null value and always store in global variable. + if (forecast != null) { + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + store.saveForecast(forecast); + } + } + + this.setHasOptionsMenu(false); + + this.setEmptyText(this.getString(R.string.text_field_remote_error)); + this.setListShownNoAnimation(false); + } + + @Override + public void onResume() { + super.onResume(); + + this.mReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(final Context context, final Intent intent) { + final String action = intent.getAction(); + if (action.equals("de.example.exampletdd.UPDATEFORECAST")) { + final Forecast forecastRemote = (Forecast) intent.getSerializableExtra("forecast"); + + if (forecastRemote != null) { + + // 1. Check conditions. They must be the same as the ones that triggered the AsyncTask. + final DatabaseQueries query = new DatabaseQueries(context.getApplicationContext()); + final WeatherLocation weatherLocation = query.queryDataBase(); + final PermanentStorage store = new PermanentStorage(context.getApplicationContext()); + final Forecast forecast = store.getForecast(); + + if (forecast == null || !OverviewFragment.this.isDataFresh(weatherLocation.getLastForecastUIUpdate())) { + // 2. Update UI. + OverviewFragment.this.updateUI(forecastRemote); + + // 3. Update Data. + store.saveForecast(forecastRemote); + weatherLocation.setLastForecastUIUpdate(new Date()); + query.updateDataBase(weatherLocation); + + // 4. Show list. + OverviewFragment.this.setListShownNoAnimation(true); + } + + } else { + // Empty list and show error message (see setEmptyText in onCreate) + OverviewFragment.this.setListAdapter(null); + OverviewFragment.this.setListShownNoAnimation(true); + } + } + } + }; + + // Register receiver + final IntentFilter filter = new IntentFilter(); + filter.addAction("de.example.exampletdd.UPDATEFORECAST"); + LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext()) + .registerReceiver(this.mReceiver, filter); + + final DatabaseQueries query = new DatabaseQueries(this.getActivity().getApplicationContext()); + final WeatherLocation weatherLocation = query.queryDataBase(); + if (weatherLocation == null) { + // Nothing to do. + // Empty list and show error message (see setEmptyText in onCreate) + this.setListAdapter(null); + this.setListShownNoAnimation(true); + return; + } + + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + final Forecast forecast = store.getForecast(); + + // TODO: store forecast data in permanent storage and check here if there is data in permanent storage + if (forecast != null && this.isDataFresh(weatherLocation.getLastForecastUIUpdate())) { + this.updateUI(forecast); + } else { + // Load remote data (aynchronous) + // Gets the data from the web. + this.setListShownNoAnimation(false); + final OverviewTask task = new OverviewTask( + this.getActivity().getApplicationContext(), + new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")), + new ServiceParser(new JPOSWeatherParser())); + + task.execute(weatherLocation.getLatitude(), weatherLocation.getLongitude()); + // TODO: make sure thread UI keeps running in parallel after that. I guess. + } + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + + // Save UI state + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + final Forecast forecast = store.getForecast(); + + // TODO: Could it be better to save forecast data even if it is null value? + // So, perhaps do not check for null value. + if (forecast != null) { + savedInstanceState.putSerializable("Forecast", forecast); + } + + super.onSaveInstanceState(savedInstanceState); + } + + @Override + public void onPause() { + LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext()).unregisterReceiver(this.mReceiver); + + super.onPause(); + } + + @Override + public void onListItemClick(final ListView l, final View v, final int position, final long id) { + final SpecificFragment fragment = (SpecificFragment) this + .getFragmentManager().findFragmentById(R.id.weather_specific_fragment); + if (fragment == null) { + // handset layout + final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO") + .setComponent(new ComponentName("de.example.exampletdd", + "de.example.exampletdd.SpecificActivity")); + intent.putExtra("CHOSEN_DAY", (int) id); + OverviewFragment.this.getActivity().startActivity(intent); + } else { + // tablet layout + fragment.updateUIByChosenDay((int) id); + } + } + + private interface UnitsConversor { + + public double doConversion(final double value); + } + + private void updateUI(final Forecast forecastWeatherData) { + + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getActivity().getApplicationContext()); + + // TODO: repeating the same code in Overview, Specific and Current!!! + // 1. Update units of measurement. + String symbol; + UnitsConversor unitsConversor; + String keyPreference = this.getResources().getString( + R.string.weather_preferences_temperature_key); + final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature); + if (unitsPreferenceValue.equals(values[0])) { + symbol = values[0]; + unitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value - 273.15; + } + + }; + } else if (unitsPreferenceValue.equals(values[1])) { + symbol = values[1]; + unitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return (value * 1.8) - 459.67; + } + + }; + } else { + symbol = values[2]; + unitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value; + } + + }; + } + + + // 2. Update number day forecast. + keyPreference = this.getResources().getString(R.string.weather_preferences_day_forecast_key); + final String dayForecast = sharedPreferences.getString(keyPreference, "5"); + final int mDayForecast = Integer.valueOf(dayForecast); + + + // 3. Formatters + final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); + tempFormatter.applyPattern("#####.##"); + final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.US); + final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d", Locale.US); + + + // 4. Prepare data for UI. + final List entries = new ArrayList(); + final OverviewAdapter adapter = new OverviewAdapter(this.getActivity(), + R.layout.weather_main_entry_list); + final Calendar calendar = Calendar.getInstance(); + int count = mDayForecast; + for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData + .getList()) { + + Bitmap picture; + + if ((forecast.getWeather().size() > 0) && + (forecast.getWeather().get(0).getIcon() != null) && + (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) { + final String icon = forecast.getWeather().get(0).getIcon(); + picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) + .getResourceDrawable()); + } else { + picture = BitmapFactory.decodeResource(this.getResources(), + R.drawable.weather_severe_alert); + } + + final Long forecastUNIXDate = (Long) forecast.getDt(); + calendar.setTimeInMillis(forecastUNIXDate * 1000L); + final Date dayTime = calendar.getTime(); + final String dayTextName = dayNameFormatter.format(dayTime); + final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime); + + Double maxTemp = null; + if (forecast.getTemp().getMax() != null) { + maxTemp = (Double) forecast.getTemp().getMax(); + maxTemp = unitsConversor.doConversion(maxTemp); + } + + Double minTemp = null; + if (forecast.getTemp().getMin() != null) { + minTemp = (Double) forecast.getTemp().getMin(); + minTemp = unitsConversor.doConversion(minTemp); + } + + if ((maxTemp != null) && (minTemp != null)) { + entries.add(new OverviewEntry(dayTextName, monthAndDayNumberText, + tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol, + picture)); + } + + count = count - 1; + if (count == 0) { + break; + } + } + + + // 5. Update UI. + adapter.addAll(entries); + this.setListAdapter(adapter); + } + + private boolean isDataFresh(final Date lastUpdate) { + if (lastUpdate == null) { + return false; + } + + final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences( + this.getActivity().getApplicationContext()); + final String keyPreference = this.getString(R.string.weather_preferences_refresh_interval_key); + final String refresh = sharedPreferences.getString( + keyPreference, + this.getResources().getStringArray(R.array.weather_preferences_refresh_interval)[0]); + final Date currentTime = new Date(); + if (((currentTime.getTime() - lastUpdate.getTime())) < Long.valueOf(refresh)) { + return true; + } + + return false; + } + + // TODO: How could I show just one progress dialog when I have two fragments in tabs + // activity doing the same in background? + // I mean, if OverviewTask shows one progress dialog and CurrentTask does the same I will have + // have two progress dialogs... How may I solve this problem? I HATE ANDROID. + private class OverviewTask extends AsyncTask { + // Store the context passed to the AsyncTask when the system instantiates it. + private final Context localContext; + private final CustomHTTPClient HTTPClient; + private final ServiceParser weatherService; + + public OverviewTask(final Context context, final CustomHTTPClient HTTPClient, + final ServiceParser weatherService) { + this.localContext = context; + this.HTTPClient = HTTPClient; + this.weatherService = weatherService; + } + + @Override + protected Forecast doInBackground(final Object... params) { + final double latitude = (Double) params[0]; + final double longitude = (Double) params[1]; + + Forecast forecast = null; + + try { + forecast = this.doInBackgroundThrowable(latitude, longitude); + } catch (final JsonParseException e) { + Log.e(TAG, "OverviewTask doInBackground exception: ", e); + } catch (final ClientProtocolException e) { + Log.e(TAG, "OverviewTask doInBackground exception: ", e); + } catch (final MalformedURLException e) { + Log.e(TAG, "OverviewTask doInBackground exception: ", e); + } catch (final URISyntaxException e) { + Log.e(TAG, "OverviewTask doInBackground exception: ", e); + } catch (final IOException e) { + // logger infrastructure swallows UnknownHostException :/ + Log.e(TAG, "OverviewTask doInBackground exception: " + e.getMessage(), e); + } finally { + HTTPClient.close(); + } + + return forecast; + } + + private Forecast doInBackgroundThrowable(final double latitude, final double longitude) + throws URISyntaxException, ClientProtocolException, JsonParseException, IOException { + + final String APIVersion = localContext.getResources().getString(R.string.api_version); + final String urlAPI = localContext.getResources().getString(R.string.uri_api_weather_forecast); + // TODO: number as resource + final String url = weatherService.createURIAPIForecast(urlAPI, APIVersion, latitude, longitude, "14"); + final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis()); + final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache)); + + return weatherService.retrieveForecastFromJPOS(jsonData); + } + + @Override + protected void onPostExecute(final Forecast forecast) { + // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method? + // I hope so, otherwise I must catch(Throwable) in doInBackground method :( + + // Call updateUI on the UI thread. + final Intent forecastData = new Intent("de.example.exampletdd.UPDATEFORECAST"); + forecastData.putExtra("forecast", forecast); + LocalBroadcastManager.getInstance(this.localContext).sendBroadcastSync(forecastData); + } + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java new file mode 100644 index 0000000..ba19c5e --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java @@ -0,0 +1,354 @@ +package de.example.exampletdd.fragment.preferences; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.os.SystemClock; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.preference.SwitchPreference; +import de.example.exampletdd.R; +import de.example.exampletdd.NotificationIntentService; + +public class WeatherInformationPreferencesFragment extends PreferenceFragment + implements OnSharedPreferenceChangeListener { + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + this.addPreferencesFromResource(R.xml.weather_preferences); + + + // Temperature units + String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature); + String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value); + String keyPreference = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_temperature_key); + Preference connectionPref = this.findPreference(keyPreference); + String value = this.getPreferenceManager().getSharedPreferences() + .getString(keyPreference, ""); + String humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } + connectionPref.setSummary(humanValue); + + // Wind + values = this.getResources().getStringArray(R.array.weather_preferences_wind); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_wind_human_value); + keyPreference = this.getString(R.string.weather_preferences_wind_key); + connectionPref = this.findPreference(keyPreference); + value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, ""); + humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } + connectionPref.setSummary(humanValue); + + // Pressure + values = this.getResources().getStringArray(R.array.weather_preferences_pressure); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_pressure_human_value); + keyPreference = this.getString(R.string.weather_preferences_pressure_key); + connectionPref = this.findPreference(keyPreference); + value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, ""); + humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } + connectionPref.setSummary(humanValue); + + // Forecast days number + values = this.getResources().getStringArray(R.array.weather_preferences_day_forecast); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_day_forecast_human_value); + keyPreference = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_day_forecast_key); + connectionPref = this.findPreference(keyPreference); + value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, ""); + humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } + connectionPref.setSummary(humanValue); + + // Refresh interval + values = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval_human_value); + keyPreference = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_refresh_interval_key); + connectionPref = this.findPreference(keyPreference); + value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, ""); + humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } else if (value.equals(values[3])) { + humanValue = humanValues[3]; + } else if (value.equals(values[4])) { + humanValue = humanValues[4]; + } else if (value.equals(values[5])) { + humanValue = humanValues[5]; + } else if (value.equals(values[6])) { + humanValue = humanValues[6]; + } + connectionPref.setSummary(humanValue); + + // Update Time Rate + values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate_human_value); + keyPreference = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_update_time_rate_key); + connectionPref = this.findPreference(keyPreference); + value = this.getPreferenceManager().getSharedPreferences() + .getString(keyPreference, ""); + humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } else if (value.equals(values[3])) { + humanValue = humanValues[3]; + } else if (value.equals(values[4])) { + humanValue = humanValues[4]; + } + connectionPref.setSummary(humanValue); + } + + @Override + public void onResume() { + super.onResume(); + this.getPreferenceManager().getSharedPreferences() + .registerOnSharedPreferenceChangeListener(this); + + } + + @Override + public void onPause() { + super.onPause(); + this.getPreferenceManager().getSharedPreferences() + .unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onSharedPreferenceChanged( + final SharedPreferences sharedPreferences, final String key) { + + // Temperature units + String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature); + String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value); + String keyValue = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_temperature_key); + if (key.equals(keyValue)) { + final Preference connectionPref = this.findPreference(key); + final String value = sharedPreferences.getString(key, ""); + String humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } + + connectionPref.setSummary(humanValue); + return; + } + + // Wind + values = this.getResources().getStringArray(R.array.weather_preferences_wind); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_wind_human_value); + keyValue = this.getString(R.string.weather_preferences_wind_key); + if (key.equals(keyValue)) { + final Preference connectionPref = this.findPreference(key); + final String value = sharedPreferences.getString(key, ""); + String humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } + + connectionPref.setSummary(humanValue); + return; + } + + // Pressure + values = this.getResources().getStringArray(R.array.weather_preferences_pressure); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_pressure_human_value); + keyValue = this.getString(R.string.weather_preferences_pressure_key); + if (key.equals(keyValue)) { + final Preference connectionPref = this.findPreference(key); + final String value = sharedPreferences.getString(key, ""); + String humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } + + connectionPref.setSummary(humanValue); + return; + } + + // Forecast days number + values = this.getResources().getStringArray(R.array.weather_preferences_day_forecast); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_day_forecast_human_value); + keyValue = this.getActivity().getString( + R.string.weather_preferences_day_forecast_key); + if (key.equals(keyValue)) { + final Preference connectionPref = this.findPreference(key); + final String value = sharedPreferences.getString(key, ""); + String humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } + connectionPref.setSummary(humanValue); + return; + } + + // Refresh interval + values = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval_human_value); + keyValue = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_refresh_interval_key); + if (key.equals(keyValue)) { + final Preference connectionPref = this.findPreference(key); + final String value = sharedPreferences.getString(key, ""); + String humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } else if (value.equals(values[3])) { + humanValue = humanValues[3]; + } else if (value.equals(values[4])) { + humanValue = humanValues[4]; + } else if (value.equals(values[5])) { + humanValue = humanValues[5]; + } else if (value.equals(values[6])) { + humanValue = humanValues[6]; + } + connectionPref.setSummary(humanValue); + return; + } + + // Notification switch + keyValue = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_notifications_switch_key); + if (key.equals(keyValue)) { + final SwitchPreference preference = (SwitchPreference)this.findPreference(key); + if (preference.isChecked()) + { + keyValue = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_update_time_rate_key); + final String value = sharedPreferences.getString(keyValue, ""); + this.updateNotification(value); + } else { + this.cancelNotification(); + } + } + // Update Time Rate + values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate); + humanValues = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate_human_value); + keyValue = this.getActivity().getApplicationContext().getString( + R.string.weather_preferences_update_time_rate_key); + if (key.equals(keyValue)) { + final Preference connectionPref = this.findPreference(key); + final String value = sharedPreferences.getString(key, ""); + String humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } else if (value.equals(values[3])) { + humanValue = humanValues[3]; + } else if (value.equals(values[4])) { + humanValue = humanValues[4]; + } + + this.updateNotification(value); + connectionPref.setSummary(humanValue); + return; + } + } + + private void updateNotification(final String updateTimeRate) { + final String[] values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate); + long chosenInterval = 0; + if (updateTimeRate.equals(values[0])) { + chosenInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES; + } else if (updateTimeRate.equals(values[1])) { + chosenInterval = AlarmManager.INTERVAL_HALF_HOUR; + } else if (updateTimeRate.equals(values[2])) { + chosenInterval = AlarmManager.INTERVAL_HOUR; + } else if (updateTimeRate.equals(values[3])) { + chosenInterval = AlarmManager.INTERVAL_HALF_DAY; + } else if (updateTimeRate.equals(values[4])) { + chosenInterval = AlarmManager.INTERVAL_DAY; + } + + final AlarmManager alarmMgr = + (AlarmManager) this.getActivity().getApplicationContext().getSystemService(Context.ALARM_SERVICE); + // TODO: better use some string instead of .class? In case I change the service class + // this could be a problem (I guess) + final Intent serviceIntent = + new Intent(this.getActivity().getApplicationContext(), NotificationIntentService.class); + final PendingIntent alarmIntent = + PendingIntent.getService( + this.getActivity().getApplicationContext(), + 0, + serviceIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + if (chosenInterval != 0) { + alarmMgr.setInexactRepeating( + AlarmManager.ELAPSED_REALTIME, + SystemClock.elapsedRealtime(), + chosenInterval, + alarmIntent); + } + } + + private void cancelNotification() { + final AlarmManager alarmMgr = + (AlarmManager) this.getActivity().getApplicationContext().getSystemService(Context.ALARM_SERVICE); + final Intent serviceIntent = + new Intent(this.getActivity().getApplicationContext(), NotificationIntentService.class); + final PendingIntent alarmIntent = + PendingIntent.getService( + this.getActivity().getApplicationContext(), + 0, + serviceIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + alarmMgr.cancel(alarmIntent); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/specific/SpecificFragment.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/specific/SpecificFragment.java new file mode 100644 index 0000000..e355c71 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/fragment/specific/SpecificFragment.java @@ -0,0 +1,357 @@ +package de.example.exampletdd.fragment.specific; + +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import de.example.exampletdd.R; +import de.example.exampletdd.model.forecastweather.Forecast; +import de.example.exampletdd.service.IconsList; +import de.example.exampletdd.service.PermanentStorage; + + +public class SpecificFragment extends Fragment { + private int mChosenDay; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final Bundle extras = this.getActivity().getIntent().getExtras(); + + if (extras != null) { + // handset layout + this.mChosenDay = extras.getInt("CHOSEN_DAY", 0); + } else { + // tablet layout + // Always 0 when tablet layout (by default shows the first day) + this.mChosenDay = 0; + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + // Inflate the layout for this fragment + return inflater.inflate(R.layout.weather_specific_fragment, container, false); + } + + @Override + public void onActivityCreated(final Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (savedInstanceState != null) { + // Restore UI state + final Forecast forecast = (Forecast) savedInstanceState.getSerializable("Forecast"); + + // TODO: Could it be better to store in global data forecast even if it is null value? + // So, perhaps do not check for null value and always store in global variable. + if (forecast != null) { + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + store.saveForecast(forecast); + } + + this.mChosenDay = savedInstanceState.getInt("mChosenDay"); + } + + this.setHasOptionsMenu(false); + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + + // Save UI state + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + final Forecast forecast = store.getForecast(); + + // TODO: Could it be better to save forecast data even if it is null value? + // So, perhaps do not check for null value. + if (forecast != null) { + savedInstanceState.putSerializable("Forecast", forecast); + } + + savedInstanceState.putInt("mChosenDay", this.mChosenDay); + + super.onSaveInstanceState(savedInstanceState); + } + + /** + * This method is used by tablet layout. + * + * @param chosenDay + */ + public void updateUIByChosenDay(final int chosenDay) { + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + final Forecast forecast = store.getForecast(); + + if (forecast != null) { + this.updateUI(forecast, chosenDay); + } + } + + private interface UnitsConversor { + + public double doConversion(final double value); + } + + private void updateUI(final Forecast forecastWeatherData, final int chosenDay) { + + final SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this.getActivity()); + + // TODO: repeating the same code in Overview, Specific and Current!!! + // 1. Update units of measurement. + // 1.1 Temperature + String tempSymbol; + UnitsConversor tempUnitsConversor; + String keyPreference = this.getResources().getString( + R.string.weather_preferences_temperature_key); + String unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature); + if (unitsPreferenceValue.equals(values[0])) { + tempSymbol = values[0]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value - 273.15; + } + + }; + } else if (unitsPreferenceValue.equals(values[1])) { + tempSymbol = values[1]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return (value * 1.8) - 459.67; + } + + }; + } else { + tempSymbol = values[2]; + tempUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(final double value) { + return value; + } + + }; + } + + // 1.2 Wind + String windSymbol; + UnitsConversor windUnitsConversor; + keyPreference = this.getResources().getString(R.string.weather_preferences_wind_key); + unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + values = this.getResources().getStringArray(R.array.weather_preferences_wind); + if (unitsPreferenceValue.equals(values[0])) { + windSymbol = values[0]; + windUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(double value) { + return value; + } + }; + } else { + windSymbol = values[1]; + windUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(double value) { + return value * 2.237; + } + }; + } + + // 1.3 Pressure + String pressureSymbol; + UnitsConversor pressureUnitsConversor; + keyPreference = this.getResources().getString(R.string.weather_preferences_pressure_key); + unitsPreferenceValue = sharedPreferences.getString(keyPreference, ""); + values = this.getResources().getStringArray(R.array.weather_preferences_pressure); + if (unitsPreferenceValue.equals(values[0])) { + pressureSymbol = values[0]; + pressureUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(double value) { + return value; + } + }; + } else { + pressureSymbol = values[1]; + pressureUnitsConversor = new UnitsConversor(){ + + @Override + public double doConversion(double value) { + return value / 113.25d; + } + }; + } + + + // 2. Formatters + final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); + tempFormatter.applyPattern("#####.#####"); + + + // 3. Prepare data for UI. + final de.example.exampletdd.model.forecastweather.List forecast = forecastWeatherData + .getList().get((chosenDay)); + + final SimpleDateFormat dayFormatter = new SimpleDateFormat("EEEE - MMM d", Locale.US); + final Calendar calendar = Calendar.getInstance(); + final Long forecastUNIXDate = (Long) forecast.getDt(); + calendar.setTimeInMillis(forecastUNIXDate * 1000L); + final Date date = calendar.getTime(); + + String tempMax = ""; + if (forecast.getTemp().getMax() != null) { + double conversion = (Double) forecast.getTemp().getMax(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMax = tempFormatter.format(conversion) + tempSymbol; + } + String tempMin = ""; + if (forecast.getTemp().getMin() != null) { + double conversion = (Double) forecast.getTemp().getMin(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMin = tempFormatter.format(conversion) + tempSymbol; + } + Bitmap picture; + if ((forecast.getWeather().size() > 0) && (forecast.getWeather().get(0).getIcon() != null) + && (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) { + final String icon = forecast.getWeather().get(0).getIcon(); + picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon) + .getResourceDrawable()); + } else { + picture = BitmapFactory.decodeResource(this.getResources(), + R.drawable.weather_severe_alert); + } + + // TODO: string resource + String description = "no description available"; + if (forecast.getWeather().size() > 0) { + description = forecast.getWeather().get(0).getDescription(); + } + + // TODO: units!!!! + String humidityValue = ""; + if (forecast.getHumidity() != null) { + final double conversion = (Double) forecast.getHumidity(); + humidityValue = tempFormatter.format(conversion); + } + String pressureValue = ""; + if (forecast.getPressure() != null) { + double conversion = (Double) forecast.getPressure(); + conversion = pressureUnitsConversor.doConversion(conversion); + pressureValue = tempFormatter.format(conversion); + } + String windValue = ""; + if (forecast.getSpeed() != null) { + double conversion = (Double) forecast.getSpeed(); + conversion = windUnitsConversor.doConversion(conversion); + windValue = tempFormatter.format(conversion); + } + String rainValue = ""; + if (forecast.getRain() != null) { + final double conversion = (Double) forecast.getRain(); + rainValue = tempFormatter.format(conversion); + } + String cloudsValue = ""; + if (forecast.getRain() != null) { + final double conversion = (Double) forecast.getClouds(); + cloudsValue = tempFormatter.format(conversion); + } + + String tempDay = ""; + if (forecast.getTemp().getDay() != null) { + double conversion = (Double) forecast.getTemp().getDay(); + conversion = tempUnitsConversor.doConversion(conversion); + tempDay = tempFormatter.format(conversion) + tempSymbol; + } + String tempMorn = ""; + if (forecast.getTemp().getMorn() != null) { + double conversion = (Double) forecast.getTemp().getMorn(); + conversion = tempUnitsConversor.doConversion(conversion); + tempMorn = tempFormatter.format(conversion) + tempSymbol; + } + String tempEve = ""; + if (forecast.getTemp().getEve() != null) { + double conversion = (Double) forecast.getTemp().getEve(); + conversion = tempUnitsConversor.doConversion(conversion); + tempEve = tempFormatter.format(conversion) + tempSymbol; + } + String tempNight = ""; + if (forecast.getTemp().getNight() != null) { + double conversion = (Double) forecast.getTemp().getNight(); + conversion = tempUnitsConversor.doConversion(conversion); + tempNight = tempFormatter.format(conversion) + tempSymbol; + } + + + // 4. Update UI. + this.getActivity().getActionBar().setSubtitle(dayFormatter.format(date).toUpperCase()); + + final TextView tempMaxView = (TextView) getActivity().findViewById(R.id.weather_specific_temp_max); + tempMaxView.setText(tempMax); + final TextView tempMinView = (TextView) getActivity().findViewById(R.id.weather_specific_temp_min); + tempMinView.setText(tempMin); + final ImageView pictureView = (ImageView) getActivity().findViewById(R.id.weather_specific_picture); + pictureView.setImageBitmap(picture); + + final TextView descriptionView = (TextView) getActivity().findViewById(R.id.weather_specific_description); + descriptionView.setText(description); + + final TextView humidityValueView = (TextView) getActivity().findViewById(R.id.weather_specific_humidity_value); + humidityValueView.setText(humidityValue); + ((TextView) getActivity().findViewById(R.id.weather_specific_pressure_value)).setText(pressureValue); + ((TextView) getActivity().findViewById(R.id.weather_specific_pressure_units)).setText(pressureSymbol); + ((TextView) getActivity().findViewById(R.id.weather_specific_wind_value)).setText(windValue);; + ((TextView) getActivity().findViewById(R.id.weather_specific_wind_units)).setText(windSymbol); + final TextView rainValueView = (TextView) getActivity().findViewById(R.id.weather_specific_rain_value); + rainValueView.setText(rainValue); + final TextView cloudsValueView = (TextView) getActivity().findViewById(R.id.weather_specific_clouds_value); + cloudsValueView.setText(cloudsValue); + + final TextView tempDayView = (TextView) getActivity().findViewById(R.id.weather_specific_day_temperature); + tempDayView.setText(tempDay); + final TextView tempMornView = (TextView) getActivity().findViewById(R.id.weather_specific_morn_temperature); + tempMornView.setText(tempMorn); + final TextView tempEveView = (TextView) getActivity().findViewById(R.id.weather_specific_eve_temperature); + tempEveView.setText(tempEve); + final TextView tempNightView = (TextView) getActivity().findViewById(R.id.weather_specific_night_temperature); + tempNightView.setText(tempNight); + } + + @Override + public void onResume() { + super.onResume(); + + final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext()); + final Forecast forecast = store.getForecast(); + + if (forecast != null) { + this.updateUI(forecast, this.mChosenDay); + } + + // TODO: Overview is doing things with mListState... Why not here? + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/Consts.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/Consts.java new file mode 100644 index 0000000..614849f --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/Consts.java @@ -0,0 +1,51 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package de.example.exampletdd.httpclient; + +import java.nio.charset.Charset; + +/** + * Commons constants. + * + * @since 4.2 + */ +public final class Consts { + + public static final int CR = 13; // + public static final int LF = 10; // + public static final int SP = 32; // + public static final int HT = 9; // + + public static final Charset UTF_8 = Charset.forName("UTF-8"); + public static final Charset ASCII = Charset.forName("US-ASCII"); + public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); + + private Consts() { + } + +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/ContentType.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/ContentType.java new file mode 100644 index 0000000..8c02532 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/ContentType.java @@ -0,0 +1,248 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package de.example.exampletdd.httpclient; + +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.util.Locale; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.ParseException; +import org.apache.http.message.BasicHeaderValueParser; + +/** + * Content type information consisting of a MIME type and an optional charset. + *

T_$gWlv$K zX#Cm1U*@Rd%dHM`0>dn6jjejs_}F7fzKcp(O`1{4Ni!p!iSb){=h1%o&-+<9LGPuL z6J$*qVVl`eP>!S*?t}5oea}Q=JOlnI1P5X=btx84JP} z@?<-F2m3~#Jjbxvy}BJb!37i#ULxKl>U0oRG*{8g+g3E5@u+?0!$(t=hAINI=icq~ zz+5XfVzBR_qQWUih-?qtM9f#Yy7oduE-C&JJH@W*nuX9-DWs@3sZ6n#a9Gz_zzcRx zOm)KGiuR%JLt9&0Wp32>->{75J@%pSZ5#JZ#AH4%a`PQ-Q)YlZHG`3$h6czA*Ol_s z7rXfB6TKQ5r@f65<#%V|$&v!Hr6oE3rgRd#Kz`Nfkfo3Ex>k}LlFQQp9=qsIcwy%@ zVvYP-G@zX3yTgm?hmO#H=5MrDLBgRt0q#kZT`xg>K@&N?x9yf*kVTGUII01d=w)fw zmI;JN_gn_cV#K#=3sR5Le}<_Y9<5T338)^9)lFFLhma>J<_^numv$f*t*=0%Cs~n! zZYz-JBdH-U$Xaac2Nur&iGSGl1=t4-i59zlcWB{RFYiRC0hyQLyFwnjQonC0vSmK9 z

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 FV1iGa7mfe` literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_showers.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_showers.png new file mode 100644 index 0000000000000000000000000000000000000000..6a1860c254fd0ed6b1098e398cb35315ef55fffe GIT binary patch literal 3991 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_showers_scattered.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_showers_scattered.png new file mode 100644 index 0000000000000000000000000000000000000000..97d0f77a80cd6596b70765c9da1471f7eac6debd GIT binary patch literal 4381 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 XW@J}O5c2d`00000NkvXXu0mjfOoUYJ literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_snow.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_snow.png new file mode 100644 index 0000000000000000000000000000000000000000..ac714ccc0aa593f2ff0adb19d74403916e1cd38b GIT binary patch literal 5016 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/layout-large/weather_main.xml b/Android/WeatherInformation/app/src/main/res/layout-large/weather_main.xml new file mode 100644 index 0000000..95e773e --- /dev/null +++ b/Android/WeatherInformation/app/src/main/res/layout-large/weather_main.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/Android/WeatherInformation/app/src/main/res/layout/appwidget.xml b/Android/WeatherInformation/app/src/main/res/layout/appwidget.xml new file mode 100644 index 0000000..08f33cc --- /dev/null +++ b/Android/WeatherInformation/app/src/main/res/layout/appwidget.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Android/WeatherInformation/app/src/main/res/layout/appwidget_configure.xml b/Android/WeatherInformation/app/src/main/res/layout/appwidget_configure.xml new file mode 100644 index 0000000..f5df9a0 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/res/layout/appwidget_configure.xml @@ -0,0 +1,55 @@ + + + + + + + + + +

+ * This class makes no attempts to verify validity of the MIME type. + * The input parameters of the {@link #create(String, String)} method, however, may not + * contain characters <">, <;>, <,> reserved by the HTTP specification. + * + * @since 4.2 + */ + +public final class ContentType { + + // constants + public static final ContentType APPLICATION_ATOM_XML = create( + "application/atom+xml", Consts.ISO_8859_1); + public static final ContentType APPLICATION_FORM_URLENCODED = create( + "application/x-www-form-urlencoded", Consts.ISO_8859_1); + public static final ContentType APPLICATION_JSON = create( + "application/json", Consts.UTF_8); + public static final ContentType APPLICATION_OCTET_STREAM = create( + "application/octet-stream", (Charset) null); + public static final ContentType APPLICATION_SVG_XML = create( + "application/svg+xml", Consts.ISO_8859_1); + public static final ContentType APPLICATION_XHTML_XML = create( + "application/xhtml+xml", Consts.ISO_8859_1); + public static final ContentType APPLICATION_XML = create( + "application/xml", Consts.ISO_8859_1); + public static final ContentType MULTIPART_FORM_DATA = create( + "multipart/form-data", Consts.ISO_8859_1); + public static final ContentType TEXT_HTML = create( + "text/html", Consts.ISO_8859_1); + public static final ContentType TEXT_PLAIN = create( + "text/plain", Consts.ISO_8859_1); + public static final ContentType TEXT_XML = create( + "text/xml", Consts.ISO_8859_1); + public static final ContentType WILDCARD = create( + "*/*", (Charset) null); + + // defaults + public static final ContentType DEFAULT_TEXT = TEXT_PLAIN; + public static final ContentType DEFAULT_BINARY = APPLICATION_OCTET_STREAM; + + private final String mimeType; + private final Charset charset; + + /** + * Given a MIME type and a character set, constructs a ContentType. + * @param mimeType The MIME type to use for the ContentType header. + * @param charset The optional character set to use with the ContentType header. + * @throws UnsupportedCharsetException + * If no support for the named charset is available in this Java virtual machine + */ + ContentType(final String mimeType, final Charset charset) { + this.mimeType = mimeType; + this.charset = charset; + } + + public String getMimeType() { + return this.mimeType; + } + + public Charset getCharset() { + return this.charset; + } + + /** + * Converts a ContentType to a string which can be used as a ContentType header. + * If a charset is provided by the ContentType, it will be included in the string. + */ + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append(this.mimeType); + if (this.charset != null) { + buf.append("; charset="); + buf.append(this.charset); + } + return buf.toString(); + } + + private static boolean valid(final String s) { + for (int i = 0; i < s.length(); i++) { + final char ch = s.charAt(i); + if ((ch == '"') || (ch == ',') || (ch == ';')) { + return false; + } + } + return true; + } + + /** + * Creates a new instance of {@link ContentType}. + * + * @param mimeType MIME type. It may not be null or empty. It may not contain + * characters <">, <;>, <,> reserved by the HTTP specification. + * @param charset charset. + * @return content type + */ + public static ContentType create(final String mimeType, final Charset charset) { + if (mimeType == null) { + throw new IllegalArgumentException("MIME type may not be null"); + } + final String type = mimeType.trim().toLowerCase(Locale.US); + if (type.length() == 0) { + throw new IllegalArgumentException("MIME type may not be empty"); + } + if (!valid(type)) { + throw new IllegalArgumentException("MIME type may not contain reserved characters"); + } + return new ContentType(type, charset); + } + + /** + * Creates a new instance of {@link ContentType} without a charset. + * + * @param mimeType MIME type. It may not be null or empty. It may not contain + * characters <">, <;>, <,> reserved by the HTTP specification. + * @return content type + */ + public static ContentType create(final String mimeType) { + return new ContentType(mimeType, (Charset) null); + } + + /** + * Creates a new instance of {@link ContentType}. + * + * @param mimeType MIME type. It may not be null or empty. It may not contain + * characters <">, <;>, <,> reserved by the HTTP specification. + * @param charset charset. It may not contain characters <">, <;>, <,> reserved by the HTTP + * specification. This parameter is optional. + * @return content type + */ + public static ContentType create( + final String mimeType, final String charset) throws UnsupportedCharsetException { + return create(mimeType, charset != null ? Charset.forName(charset) : null); + } + + private static ContentType create(final HeaderElement helem) { + final String mimeType = helem.getName(); + String charset = null; + final NameValuePair param = helem.getParameterByName("charset"); + if (param != null) { + charset = param.getValue(); + } + return create(mimeType, charset); + } + + /** + * Parses textual representation of Content-Type value. + * + * @param s text + * @return content type + * @throws ParseException if the given text does not represent a valid + * Content-Type value. + */ + public static ContentType parse( + final String s) throws ParseException, UnsupportedCharsetException { + if (s == null) { + throw new IllegalArgumentException("Content type may not be null"); + } + final HeaderElement[] elements = BasicHeaderValueParser.parseElements(s, null); + if (elements.length > 0) { + return create(elements[0]); + } else { + throw new ParseException("Invalid content type: " + s); + } + } + + /** + * Extracts Content-Type value from {@link HttpEntity} exactly as + * specified by the Content-Type header of the entity. Returns null + * if not specified. + * + * @param entity HTTP entity + * @return content type + * @throws ParseException if the given text does not represent a valid + * Content-Type value. + */ + public static ContentType get( + final HttpEntity entity) throws ParseException, UnsupportedCharsetException { + if (entity == null) { + return null; + } + final Header header = entity.getContentType(); + if (header != null) { + final HeaderElement[] elements = header.getElements(); + if (elements.length > 0) { + return create(elements[0]); + } + } + return null; + } + + /** + * Extracts Content-Type value from {@link HttpEntity} or returns default value + * if not explicitly specified. + * + * @param entity HTTP entity + * @return content type + * @throws ParseException if the given text does not represent a valid + * Content-Type value. + */ + public static ContentType getOrDefault(final HttpEntity entity) throws ParseException { + final ContentType contentType = get(entity); + return contentType != null ? contentType : DEFAULT_TEXT; + } + +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/CustomHTTPClient.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/CustomHTTPClient.java new file mode 100644 index 0000000..ba1bb99 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/httpclient/CustomHTTPClient.java @@ -0,0 +1,126 @@ +package de.example.exampletdd.httpclient; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; + +import android.net.http.AndroidHttpClient; + +public class CustomHTTPClient { + private final AndroidHttpClient httpClient; + + public CustomHTTPClient(final AndroidHttpClient httpClient) { + this.httpClient = httpClient; + } + + public String retrieveDataAsString(final URL url) + throws URISyntaxException, ClientProtocolException, IOException { + + final ResponseHandler handler = new ResponseHandler() { + @Override + public String handleResponse( + final HttpResponse response) + throws UnsupportedEncodingException, IOException { + + if (response != null) { + final HttpEntity entity = response.getEntity(); + if (entity != null) { + try { + final ContentType contentType = ContentType.getOrDefault(entity); + final ByteArrayOutputStream buffer = CustomHTTPClient.this + .sortResponse(response); + return new String(buffer.toByteArray(), contentType.getCharset()); + } finally { + entity.consumeContent(); + } + } + + throw new IOException("There is no entity"); + } + + throw new IOException("There is no response"); + } + }; + + final HttpGet httpGet = new HttpGet(); + httpGet.setURI(url.toURI()); + + return this.httpClient.execute(httpGet, handler); + } + + public ByteArrayOutputStream retrieveRawData(final URL url) + throws URISyntaxException, ClientProtocolException, IOException { + final ResponseHandler handler = new ResponseHandler() { + + @Override + public ByteArrayOutputStream handleResponse( + final HttpResponse response) + throws UnsupportedEncodingException, IOException { + + if (response != null) { + final HttpEntity entity = response.getEntity(); + if (entity != null) { + try { + return CustomHTTPClient.this.sortResponse(response); + } finally { + entity.consumeContent(); + } + } + + throw new IOException("There is no entity"); + } + + throw new IOException("There is no response"); + } + }; + + final HttpGet httpGet = new HttpGet(); + httpGet.setURI(url.toURI()); + + return this.httpClient.execute(httpGet, handler); + } + + public void close() { + this.httpClient.close(); + } + + private ByteArrayOutputStream sortResponse(final HttpResponse httpResponse) throws IOException { + + if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + throw new IOException("Unexpected response code: " + + httpResponse.getStatusLine().getStatusCode()); + } + + final HttpEntity entity = httpResponse.getEntity(); + final InputStream inputStream = entity.getContent(); + try { + return this.readInputStream(inputStream); + } finally { + inputStream.close(); + } + + } + + private ByteArrayOutputStream readInputStream (final InputStream inputStream) throws IOException { + final ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); + final int bufferSize = 1024; + final byte[] buffer = new byte[bufferSize]; + + int len = 0; + while ((len = inputStream.read(buffer)) != -1) { + byteBuffer.write(buffer, 0, len); + } + + return byteBuffer; + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/DatabaseQueries.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/DatabaseQueries.java new file mode 100644 index 0000000..e53f97d --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/DatabaseQueries.java @@ -0,0 +1,44 @@ +package de.example.exampletdd.model; + +import android.content.Context; + +public class DatabaseQueries { + private final Context localContext; + + public DatabaseQueries(final Context context) { + this.localContext = context; + } + + public WeatherLocation queryDataBase() { + + final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext); + try { + final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper); + return queryDb.queryDataBase(); + } finally { + dbHelper.close(); + } + } + + public long insertIntoDataBase(final WeatherLocation weatherLocation) { + + final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext); + try { + final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper); + return queryDb.insertIntoDataBase(weatherLocation); + } finally { + dbHelper.close(); + } + } + + public void updateDataBase(final WeatherLocation weatherLocation) { + + final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext); + try { + final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper); + queryDb.updateDataBase(weatherLocation); + } finally { + dbHelper.close(); + } + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocation.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocation.java new file mode 100644 index 0000000..f20b0b6 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocation.java @@ -0,0 +1,89 @@ +package de.example.exampletdd.model; + +import java.io.Serializable; +import java.util.Date; + + +public class WeatherLocation implements Serializable { + private static final long serialVersionUID = -1469725417020355109L; + private int id; + private String city; + private String country; + private boolean isSelected; + private double latitude; + private double longitude; + private Date lastCurrentUIUpdate; + private Date lastForecastUIUpdate; + + public WeatherLocation setId(int id) { + this.id = id; + return this; + } + + public WeatherLocation setCity(String city) { + this.city = city; + return this; + } + + public WeatherLocation setCountry(String country) { + this.country = country; + return this; + } + + public WeatherLocation setIsSelected(boolean isSelected) { + this.isSelected = isSelected; + return this; + } + + public WeatherLocation setLatitude(double latitude) { + this.latitude = latitude; + return this; + } + + public WeatherLocation setLongitude(double longitude) { + this.longitude = longitude; + return this; + } + + public WeatherLocation setLastCurrentUIUpdate(Date lastCurrentUIUpdate) { + this.lastCurrentUIUpdate = lastCurrentUIUpdate; + return this; + } + + public WeatherLocation setLastForecastUIUpdate(Date lastForecastUIUpdate) { + this.lastForecastUIUpdate = lastForecastUIUpdate; + return this; + } + + public int getId() { + return this.id; + } + + public String getCity() { + return this.city; + } + + public String getCountry() { + return this.country; + } + + public boolean getIsSelected() { + return this.isSelected; + } + + public double getLatitude() { + return this.latitude; + } + + public double getLongitude() { + return this.longitude; + } + + public Date getLastCurrentUIUpdate() { + return this.lastCurrentUIUpdate; + } + + public Date getLastForecastUIUpdate() { + return this.lastForecastUIUpdate; + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationContract.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationContract.java new file mode 100644 index 0000000..91e3472 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationContract.java @@ -0,0 +1,32 @@ +package de.example.exampletdd.model; + +import android.provider.BaseColumns; + +public class WeatherLocationContract { + + // This class can't be instantiated + private WeatherLocationContract() {} + + public static final class WeatherLocation implements BaseColumns { + + // This class can't be instantiated + private WeatherLocation() {} + + public static final String TABLE_NAME = "locations"; + + public static final String COLUMN_NAME_IS_SELECTED = "isSelected"; + + public static final String COLUMN_NAME_LATITUDE = "latitude"; + + public static final String COLUMN_NAME_LONGITUDE = "longitude"; + + public static final String COLUMN_NAME_COUNTRY = "country"; + + public static final String COLUMN_NAME_CITY = "city"; + + public static final String COLUMN_NAME_LAST_FORECAST_UI_UPDATE = "lastForecastUpdate"; + + public static final String COLUMN_NAME_LAST_CURRENT_UI_UPDATE = "lastCurrentUpdate"; + } + +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbHelper.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbHelper.java new file mode 100644 index 0000000..8083516 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbHelper.java @@ -0,0 +1,43 @@ +package de.example.exampletdd.model; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +public class WeatherLocationDbHelper extends SQLiteOpenHelper { + private static final String TAG = "LocationDbHelper"; + public static final int DATABASE_VERSION = 1; + public static final String DATABASE_NAME = "Location.db"; + + public WeatherLocationDbHelper(final Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(final SQLiteDatabase db) { + db.execSQL("CREATE TABLE " + WeatherLocationContract.WeatherLocation.TABLE_NAME + " (" + + WeatherLocationContract.WeatherLocation._ID + " INTEGER PRIMARY KEY, " + + WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY + " TEXT" + " NOT NULL, " + + WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY + " TEXT" + " NOT NULL, " + + WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " INTEGER" + " NOT NULL, " + + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE + " INTEGER, " + + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE + " INTEGER, " + + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE + " REAL" + " NOT NULL, " + + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE + " REAL" + " NOT NULL " + + ");"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + + newVersion + ", which will destroy all old data"); + + // Kills the table and existing data + db.execSQL("DROP TABLE IF EXISTS " + WeatherLocationContract.WeatherLocation.TABLE_NAME); + + // Recreates the database with a new version + onCreate(db); + } + +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbQueries.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbQueries.java new file mode 100644 index 0000000..fa97ca2 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbQueries.java @@ -0,0 +1,176 @@ +package de.example.exampletdd.model; + +import java.util.Calendar; +import java.util.Date; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +public class WeatherLocationDbQueries { + private final SQLiteOpenHelper mDbHelper; + + public interface DoQuery { + + public WeatherLocation doQuery(final Cursor cursor); + } + + public WeatherLocationDbQueries(final SQLiteOpenHelper dbHelper) { + this.mDbHelper = dbHelper; + } + + public WeatherLocation queryDataBase() { + final String selection = WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " = ?"; + final String[] selectionArgs = { "1" }; + final String[] projection = { + WeatherLocationContract.WeatherLocation._ID, + WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, + WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, + WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE, + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE, + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE + }; + + + final WeatherLocationDbQueries.DoQuery doQuery = new WeatherLocationDbQueries.DoQuery() { + + @Override + public WeatherLocation doQuery(final Cursor cursor) { + final int id = cursor.getInt(cursor.getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation._ID)); + final String city = cursor.getString(cursor. + getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY)); + final String country = cursor.getString(cursor. + getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY)); + final boolean isSelected = (cursor.getInt(cursor + .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED)) == 0) ? false : true; + Date lastCurrentUIUpdate = null; + if (!cursor.isNull(cursor + .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE))) { + final long javaTime = cursor.getLong(cursor + .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE)); + lastCurrentUIUpdate = new Date(javaTime); + } + Date lasForecastUIUpdate = null; + if (!cursor.isNull(cursor + .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE))) { + final long javaTime = cursor.getLong(cursor + .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE)); + lasForecastUIUpdate = new Date(javaTime); + } + final double latitude = cursor.getDouble(cursor. + getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE)); + final double longitude = cursor.getDouble(cursor. + getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE)); + + + return new WeatherLocation() + .setId(id) + .setCity(city) + .setCountry(country) + .setIsSelected(isSelected) + .setLastCurrentUIUpdate(lastCurrentUIUpdate) + .setLastForecastUIUpdate(lasForecastUIUpdate) + .setLatitude(latitude) + .setLongitude(longitude); + } + }; + + return this.queryDataBase( + WeatherLocationContract.WeatherLocation.TABLE_NAME, projection, + selectionArgs, selection, doQuery); + } + + public long insertIntoDataBase(final WeatherLocation weatherLocation) { + // Create a new map of values, where column names are the keys + final ContentValues values = new ContentValues(); + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, weatherLocation.getCity()); + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, weatherLocation.getCountry()); + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, weatherLocation.getIsSelected()); + Date javaTime = weatherLocation.getLastCurrentUIUpdate(); + if (javaTime != null) { + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE, javaTime.getTime()); + } + javaTime = weatherLocation.getLastForecastUIUpdate(); + if (javaTime != null) { + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE, javaTime.getTime()); + } + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, weatherLocation.getLatitude()); + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE, weatherLocation.getLongitude()); + + return this.insertIntoDataBase(WeatherLocationContract.WeatherLocation.TABLE_NAME, values); + } + + public void updateDataBase(final WeatherLocation weatherLocation) { + final String selection = WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " = ?"; + final String[] selectionArgs = { "1" }; + // Create a new map of values, where column names are the keys + final ContentValues values = new ContentValues(); + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, weatherLocation.getCity()); + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, weatherLocation.getCountry()); + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, weatherLocation.getIsSelected()); + Date javaTime = weatherLocation.getLastCurrentUIUpdate(); + if (javaTime != null) { + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE, javaTime.getTime()); + } else { + values.putNull(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE); + } + javaTime = weatherLocation.getLastForecastUIUpdate(); + if (javaTime != null) { + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE, javaTime.getTime()); + } else { + values.putNull(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE); + } + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, weatherLocation.getLatitude()); + values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE, weatherLocation.getLongitude()); + + this.updateDataBase(WeatherLocationContract.WeatherLocation.TABLE_NAME, selectionArgs, selection, values); + } + + // TODO: May I perform another query after this method (after closing almost everything but mDbHelper) + private WeatherLocation queryDataBase(final String table, + final String[] projection, final String[] selectionArgs, + final String selection, final DoQuery doQuery) { + // TODO: execute around idiom? I miss try/finally with resources + final SQLiteDatabase db = this.mDbHelper.getReadableDatabase(); + try { + final Cursor cursor = db.query(table, projection, selection, selectionArgs, null, null, null); + try { + if (!cursor.moveToFirst()) { + return null; + } + else { + return doQuery.doQuery(cursor); + } + } finally { + cursor.close(); + } + } finally { + db.close(); + } + } + + // TODO: May I perform another query after this method (after closing almost everything but mDbHelper) + private long insertIntoDataBase(final String table, final ContentValues values) { + final SQLiteDatabase db = this.mDbHelper.getWritableDatabase(); + try { + return db.insert(table, null, values); + } finally { + db.close(); + } + } + + // TODO: May I perform another query after this method (after closing almost everything but mDbHelper) + private long updateDataBase(final String table, final String[] selectionArgs, + final String selection, final ContentValues values) { + final SQLiteDatabase db = this.mDbHelper.getWritableDatabase(); + try { + return db.update(table, values, selection, selectionArgs); + } finally { + db.close(); + } + } + +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Clouds.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Clouds.java new file mode 100644 index 0000000..8da14c3 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Clouds.java @@ -0,0 +1,22 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; + +public class Clouds implements Serializable { + private static final long serialVersionUID = 3034435739326030899L; + private Number all; + + public Number getAll(){ + return this.all; + } + public void setAll(final Number all){ + this.all = all; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Clouds [all=").append(this.all).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Coord.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Coord.java new file mode 100644 index 0000000..9eececd --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Coord.java @@ -0,0 +1,30 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; + +public class Coord implements Serializable { + private static final long serialVersionUID = 7151637605146377486L; + private Number lat; + private Number lon; + + public Number getLat(){ + return this.lat; + } + public void setLat(final Number lat){ + this.lat = lat; + } + public Number getLon(){ + return this.lon; + } + public void setLon(final Number lon){ + this.lon = lon; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Coord [lat=").append(this.lat).append(", lon=").append(this.lon) + .append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Current.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Current.java new file mode 100644 index 0000000..a7bc22e --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Current.java @@ -0,0 +1,139 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * Auto generated by: http://jsongen.byingtondesign.com/ + * (with my own modifications) + * + */ +public class Current implements Serializable { + private static final long serialVersionUID = -730690341739860818L; + private String base; + private Clouds clouds; + private Number cod; + private Coord coord; + private Number dt; + private Number id; + private Main main; + private String name; + private Rain rain; + private Snow snow; + private Sys sys; + private List weather; + private Wind wind; + private byte[] iconData; + private Date date; + + public String getBase(){ + return this.base; + } + public void setBase(final String base){ + this.base = base; + } + public Clouds getClouds(){ + return this.clouds; + } + public void setClouds(final Clouds clouds){ + this.clouds = clouds; + } + + public Number getCod() { + return this.cod; + } + + public void setCod(final Number cod) { + this.cod = cod; + } + public Coord getCoord(){ + return this.coord; + } + public void setCoord(final Coord coord){ + this.coord = coord; + } + public Number getDt(){ + return this.dt; + } + public void setDt(final Number dt){ + this.dt = dt; + } + public Number getId(){ + return this.id; + } + public void setId(final Number id){ + this.id = id; + } + public Main getMain(){ + return this.main; + } + public void setMain(final Main main){ + this.main = main; + } + public String getName(){ + return this.name; + } + public void setName(final String name){ + this.name = name; + } + public Rain getRain(){ + return this.rain; + } + public void setRain(final Rain rain){ + this.rain = rain; + } + public Snow getSnow() { + return this.snow; + } + public void setSnow(final Snow snow) { + this.snow = snow; + } + public Sys getSys(){ + return this.sys; + } + public void setSys(final Sys sys){ + this.sys = sys; + } + public List getWeather(){ + return this.weather; + } + public void setWeather(final List weather){ + this.weather = weather; + } + public Wind getWind(){ + return this.wind; + } + public void setWind(final Wind wind){ + this.wind = wind; + } + + public byte[] getIconData() { + return this.iconData; + } + + public void setIconData(final byte[] iconData) { + this.iconData = iconData; + } + + public Date getDate() { + return this.date; + } + + public void setDate(final Date date) { + this.date = date; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Current [base=").append(this.base).append(", clouds=") + .append(this.clouds).append(", cod=").append(this.cod).append(", coord=") + .append(this.coord).append(", dt=").append(this.dt).append(", id=").append(this.id) + .append(", main=").append(this.main).append(", name=").append(this.name) + .append(", rain=").append(this.rain).append(", snow=").append(this.snow) + .append(", sys=").append(this.sys).append(", weather=").append(this.weather) + .append(", wind=").append(this.wind).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Main.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Main.java new file mode 100644 index 0000000..397f71b --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Main.java @@ -0,0 +1,73 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; + +public class Main implements Serializable { + private static final long serialVersionUID = -6000879164436289447L; + private Number grnd_level; + private Number humidity; + private Number pressure; + private Number sea_level; + private Number temp; + private Number temp_max; + private Number temp_min; + + public Number getGrnd_level() { + return this.grnd_level; + } + + public void setGrnd_level(final Number grnd_level) { + this.grnd_level = grnd_level; + } + + public Number getHumidity(){ + return this.humidity; + } + public void setHumidity(final Number humidity){ + this.humidity = humidity; + } + public Number getPressure(){ + return this.pressure; + } + public void setPressure(final Number pressure){ + this.pressure = pressure; + } + + public Number getSea_level() { + return this.sea_level; + } + + public void setSea_level(final Number sea_level) { + this.sea_level = sea_level; + } + + public Number getTemp(){ + return this.temp; + } + public void setTemp(final Number temp){ + this.temp = temp; + } + public Number getTemp_max(){ + return this.temp_max; + } + public void setTemp_max(final Number temp_max){ + this.temp_max = temp_max; + } + public Number getTemp_min(){ + return this.temp_min; + } + public void setTemp_min(final Number temp_min){ + this.temp_min = temp_min; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Main [grnd_level=").append(this.grnd_level).append(", humidity=") + .append(this.humidity).append(", pressure=").append(this.pressure) + .append(", sea_level=").append(this.sea_level).append(", temp=").append(this.temp) + .append(", temp_max=").append(this.temp_max).append(", temp_min=") + .append(this.temp_min).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Rain.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Rain.java new file mode 100644 index 0000000..0e151ef --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Rain.java @@ -0,0 +1,23 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; + +public class Rain implements Serializable { + private static final long serialVersionUID = 1318464783605029435L; + private Number three; + + public Number get3h(){ + return this.three; + } + + public void set3h(final Number threeh) { + this.three = threeh; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Rain [three=").append(this.three).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Snow.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Snow.java new file mode 100644 index 0000000..5174763 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Snow.java @@ -0,0 +1,23 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; + +public class Snow implements Serializable { + private static final long serialVersionUID = 6769716772818311879L; + private Number three; + + public Number get3h() { + return this.three; + } + + public void set3h(final Number threeh) { + this.three = threeh; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Snow [three=").append(this.three).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Sys.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Sys.java new file mode 100644 index 0000000..3e20bef --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Sys.java @@ -0,0 +1,46 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; + + +public class Sys implements Serializable { + private static final long serialVersionUID = 5333083785731053139L; + private String country; + private Number message; + private Number sunrise; + private Number sunset; + + public String getCountry(){ + return this.country; + } + public void setCountry(final String country){ + this.country = country; + } + public Number getMessage(){ + return this.message; + } + public void setMessage(final Number message){ + this.message = message; + } + public Number getSunrise(){ + return this.sunrise; + } + public void setSunrise(final Number sunrise){ + this.sunrise = sunrise; + } + public Number getSunset(){ + return this.sunset; + } + public void setSunset(final Number sunset){ + this.sunset = sunset; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Sys [country=").append(this.country).append(", message=") + .append(this.message).append(", sunrise=").append(this.sunrise).append(", sunset=") + .append(this.sunset).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Weather.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Weather.java new file mode 100644 index 0000000..fc44d20 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Weather.java @@ -0,0 +1,45 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; + +public class Weather implements Serializable { + private static final long serialVersionUID = -34336548786316655L; + private String description; + private String icon; + private Number id; + private String main; + + public String getDescription(){ + return this.description; + } + public void setDescription(final String description){ + this.description = description; + } + public String getIcon(){ + return this.icon; + } + public void setIcon(final String icon){ + this.icon = icon; + } + public Number getId(){ + return this.id; + } + public void setId(final Number id){ + this.id = id; + } + public String getMain(){ + return this.main; + } + public void setMain(final String main){ + this.main = main; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Weather [description=").append(this.description).append(", icon=") + .append(this.icon).append(", id=").append(this.id).append(", main=") + .append(this.main).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Wind.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Wind.java new file mode 100644 index 0000000..4edc55d --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/currentweather/Wind.java @@ -0,0 +1,30 @@ +package de.example.exampletdd.model.currentweather; + +import java.io.Serializable; + +public class Wind implements Serializable { + private static final long serialVersionUID = 5495842422633674631L; + private Number deg; + private Number speed; + + public Number getDeg(){ + return this.deg; + } + public void setDeg(final Number deg){ + this.deg = deg; + } + public Number getSpeed(){ + return this.speed; + } + public void setSpeed(final Number speed){ + this.speed = speed; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Wind [deg=").append(this.deg).append(", speed=").append(this.speed) + .append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/City.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/City.java new file mode 100644 index 0000000..904ff5d --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/City.java @@ -0,0 +1,53 @@ +package de.example.exampletdd.model.forecastweather; + +import java.io.Serializable; + + +public class City implements Serializable { + private static final long serialVersionUID = 3079687975077030704L; + private Coord coord; + private String country; + private Number id; + private String name; + private Number population; + + public Coord getCoord(){ + return this.coord; + } + public void setCoord(final Coord coord){ + this.coord = coord; + } + public String getCountry(){ + return this.country; + } + public void setCountry(final String country){ + this.country = country; + } + public Number getId(){ + return this.id; + } + public void setId(final Number id){ + this.id = id; + } + public String getName(){ + return this.name; + } + public void setName(final String name){ + this.name = name; + } + public Number getPopulation(){ + return this.population; + } + public void setPopulation(final Number population){ + this.population = population; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("City [coord=").append(this.coord).append(", country=").append(this.country) + .append(", id=").append(this.id).append(", name=").append(this.name) + .append(", population=").append(this.population).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Coord.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Coord.java new file mode 100644 index 0000000..fcfee58 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Coord.java @@ -0,0 +1,30 @@ +package de.example.exampletdd.model.forecastweather; + +import java.io.Serializable; + +public class Coord implements Serializable { + private static final long serialVersionUID = 8069257976701986700L; + private Number lat; + private Number lon; + + public Number getLat(){ + return this.lat; + } + public void setLat(final Number lat){ + this.lat = lat; + } + public Number getLon(){ + return this.lon; + } + public void setLon(final Number lon){ + this.lon = lon; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Coord [lat=").append(this.lat).append(", lon=").append(this.lon) + .append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Forecast.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Forecast.java new file mode 100644 index 0000000..5a59a02 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Forecast.java @@ -0,0 +1,62 @@ +package de.example.exampletdd.model.forecastweather; + +import java.io.Serializable; +import java.util.List; + +/** + * Auto generated by: http://jsongen.byingtondesign.com/ + * (with my own modifications) + * + */ +public class Forecast implements Serializable { + private static final long serialVersionUID = 5095443678019686190L; + private City city; + private Number cnt; + private Number cod; + private List list; + private Number message; + + public City getCity(){ + return this.city; + } + public void setCity(final City city){ + this.city = city; + } + public Number getCnt(){ + return this.cnt; + } + public void setCnt(final Number cnt){ + this.cnt = cnt; + } + + public Number getCod() { + return this.cod; + } + + public void setCod(final Number cod) { + this.cod = cod; + } + + public List getList() { + return this.list; + } + + public void setList(final List list) { + this.list = list; + } + public Number getMessage(){ + return this.message; + } + public void setMessage(final Number message){ + this.message = message; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Forecast [city=").append(this.city).append(", cnt=") + .append(this.cnt).append(", cod=").append(this.cod).append(", list=") + .append(this.list).append(", message=").append(this.message).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/List.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/List.java new file mode 100644 index 0000000..2104579 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/List.java @@ -0,0 +1,93 @@ +package de.example.exampletdd.model.forecastweather; + +import java.io.Serializable; + + +public class List implements Serializable { + private static final long serialVersionUID = 838468273188666785L; + private Number clouds; + private Number deg; + private Number dt; + private Number humidity; + private Number pressure; + private Number rain; + private Number snow; + private Number speed; + private Temp temp; + private java.util.List weather; + + public Number getClouds(){ + return this.clouds; + } + public void setClouds(final Number clouds){ + this.clouds = clouds; + } + public Number getDeg(){ + return this.deg; + } + public void setDeg(final Number deg){ + this.deg = deg; + } + public Number getDt(){ + return this.dt; + } + public void setDt(final Number dt){ + this.dt = dt; + } + public Number getHumidity(){ + return this.humidity; + } + public void setHumidity(final Number humidity){ + this.humidity = humidity; + } + public Number getPressure(){ + return this.pressure; + } + public void setPressure(final Number pressure){ + this.pressure = pressure; + } + public Number getRain(){ + return this.rain; + } + public void setRain(final Number rain){ + this.rain = rain; + } + public Number getSnow() { + return this.snow; + } + public void setSnow(final Number snow) { + this.snow = snow; + } + public Number getSpeed(){ + return this.speed; + } + public void setSpeed(final Number speed){ + this.speed = speed; + } + public Temp getTemp(){ + return this.temp; + } + public void setTemp(final Temp temp){ + this.temp = temp; + } + + public java.util.List getWeather() { + return this.weather; + } + + public void setWeather(final java.util.List weather) { + this.weather = weather; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("List [clouds=").append(this.clouds).append(", deg=").append(this.deg) + .append(", dt=").append(this.dt).append(", humidity=").append(this.humidity) + .append(", pressure=").append(this.pressure).append(", rain=").append(this.rain) + .append(", snow=").append(this.snow).append(", speed=").append(this.speed) + .append(", temp=").append(this.temp).append(", weather=").append(this.weather) + .append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Temp.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Temp.java new file mode 100644 index 0000000..e4b1a7a --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Temp.java @@ -0,0 +1,60 @@ +package de.example.exampletdd.model.forecastweather; + +import java.io.Serializable; + +public class Temp implements Serializable { + private static final long serialVersionUID = -7614799035018271127L; + private Number day; + private Number eve; + private Number max; + private Number min; + private Number morn; + private Number night; + + public Number getDay(){ + return this.day; + } + public void setDay(final Number day){ + this.day = day; + } + public Number getEve(){ + return this.eve; + } + public void setEve(final Number eve){ + this.eve = eve; + } + public Number getMax(){ + return this.max; + } + public void setMax(final Number max){ + this.max = max; + } + public Number getMin(){ + return this.min; + } + public void setMin(final Number min){ + this.min = min; + } + public Number getMorn(){ + return this.morn; + } + public void setMorn(final Number morn){ + this.morn = morn; + } + public Number getNight(){ + return this.night; + } + public void setNight(final Number night){ + this.night = night; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Temp [day=").append(this.day).append(", eve=").append(this.eve) + .append(", max=").append(this.max).append(", min=").append(this.min) + .append(", morn=").append(this.morn).append(", night=").append(this.night) + .append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Weather.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Weather.java new file mode 100644 index 0000000..f0de236 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/model/forecastweather/Weather.java @@ -0,0 +1,45 @@ +package de.example.exampletdd.model.forecastweather; + +import java.io.Serializable; + +public class Weather implements Serializable { + private static final long serialVersionUID = -5066357704517363241L; + private String description; + private String icon; + private Number id; + private String main; + + public String getDescription(){ + return this.description; + } + public void setDescription(final String description){ + this.description = description; + } + public String getIcon(){ + return this.icon; + } + public void setIcon(final String icon){ + this.icon = icon; + } + public Number getId(){ + return this.id; + } + public void setId(final Number id){ + this.id = id; + } + public String getMain(){ + return this.main; + } + public void setMain(final String main){ + this.main = main; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Weather [description=").append(this.description).append(", icon=") + .append(this.icon).append(", id=").append(this.id).append(", main=") + .append(this.main).append("]"); + return builder.toString(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/parser/IJPOSParser.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/parser/IJPOSParser.java new file mode 100644 index 0000000..14a1d55 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/parser/IJPOSParser.java @@ -0,0 +1,17 @@ +package de.example.exampletdd.parser; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.model.forecastweather.Forecast; + +public interface IJPOSParser { + + public Current retrieveCurrenFromJPOS(final String jsonData) + throws JsonParseException, IOException; + + public Forecast retrieveForecastFromJPOS(final String jsonData) + throws JsonParseException, IOException; +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/parser/JPOSWeatherParser.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/parser/JPOSWeatherParser.java new file mode 100644 index 0000000..b71e342 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/parser/JPOSWeatherParser.java @@ -0,0 +1,405 @@ +package de.example.exampletdd.parser; + +import java.io.IOException; +import java.util.ArrayList; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; + +import de.example.exampletdd.model.currentweather.Clouds; +import de.example.exampletdd.model.currentweather.Coord; +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.model.currentweather.Main; +import de.example.exampletdd.model.currentweather.Rain; +import de.example.exampletdd.model.currentweather.Sys; +import de.example.exampletdd.model.currentweather.Wind; +import de.example.exampletdd.model.forecastweather.City; +import de.example.exampletdd.model.forecastweather.Forecast; +import de.example.exampletdd.model.forecastweather.Temp; + +public class JPOSWeatherParser implements IJPOSParser { + + @Override + public Current retrieveCurrenFromJPOS(final String jsonData) + throws JsonParseException, IOException { + final JsonFactory f = new JsonFactory(); + + final Current currentWeatherData = new Current(); + currentWeatherData.setClouds(new Clouds()); + currentWeatherData.setCoord(new Coord()); + currentWeatherData.setMain(new Main()); + currentWeatherData.setRain(new Rain()); + currentWeatherData.setSys(new Sys()); + currentWeatherData + .setWeather(new ArrayList()); + currentWeatherData.setWind(new Wind()); + final JsonParser jParser = f.createParser(jsonData); + + this.getCurrentWeatherData(currentWeatherData, jParser); + + return currentWeatherData; + } + + @Override + public Forecast retrieveForecastFromJPOS(final String jsonData) + throws JsonParseException, IOException { + final JsonFactory f = new JsonFactory(); + + final Forecast forecastWeatherData = new Forecast(); + forecastWeatherData + .setList(new ArrayList(15)); + final City city = new City(); + city.setCoord(new de.example.exampletdd.model.forecastweather.Coord()); + forecastWeatherData.setCity(city); + final JsonParser jParser = f.createParser(jsonData); + + this.getForecastWeatherData(forecastWeatherData, jParser); + + return forecastWeatherData; + } + + private void getCurrentWeatherData(final Current currentWeatherData, + final JsonParser jParser) throws JsonParseException, IOException { + if (jParser.nextToken() == JsonToken.START_OBJECT) { + + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String fieldname = jParser.getCurrentName(); + final JsonToken nextToken = jParser.nextToken(); + if (nextToken == JsonToken.START_OBJECT) { + this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname); + } + if (nextToken == JsonToken.START_ARRAY) { + JsonToken tokenNext = jParser.nextToken(); + while (tokenNext != JsonToken.END_ARRAY) { + if (tokenNext == JsonToken.START_OBJECT) { + this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname); + } + tokenNext = jParser.nextToken(); + } + } + if ((nextToken == JsonToken.VALUE_NUMBER_INT) + || (nextToken == JsonToken.VALUE_STRING)) { + this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname); + } + } + } + } + + private void getCurrentWeatherDataObjects(final Current currentWeatherData, + final JsonParser jParser, final String fieldname) throws JsonParseException, + IOException { + if (fieldname == "coord") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("lon".equals(namefield)) { + currentWeatherData.getCoord().setLon(jParser.getDoubleValue()); + } + if ("lat".equals(namefield)) { + currentWeatherData.getCoord().setLat(jParser.getDoubleValue()); + } + } + } + if (fieldname == "sys") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("message".equals(namefield)) { + currentWeatherData.getSys().setMessage(jParser.getDoubleValue()); + } + if ("country".equals(namefield)) { + currentWeatherData.getSys().setCountry(jParser.getValueAsString()); + } + if ("sunrise".equals(namefield)) { + currentWeatherData.getSys().setSunrise(jParser.getValueAsLong()); + } + if ("sunset".equals(namefield)) { + currentWeatherData.getSys().setSunset(jParser.getValueAsLong()); + } + } + } + if (fieldname == "weather") { + final de.example.exampletdd.model.currentweather.Weather weather = new de.example.exampletdd.model.currentweather.Weather(); + currentWeatherData.getWeather().add(weather); + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("id".equals(namefield)) { + weather.setId(jParser.getIntValue()); + } + if ("main".equals(namefield)) { + weather.setMain(jParser.getText()); + } + if ("description".equals(namefield)) { + weather.setDescription(jParser.getText()); + } + if ("icon".equals(namefield)) { + weather.setIcon(jParser.getText()); + } + + } + } + if (fieldname == "base") { + currentWeatherData.setBase(jParser.getText()); + } + if (fieldname == "main") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("temp".equals(namefield)) { + currentWeatherData.getMain().setTemp(jParser.getDoubleValue()); + } + if ("temp_min".equals(namefield)) { + currentWeatherData.getMain().setTemp_min(jParser.getDoubleValue()); + } + if ("temp_max".equals(namefield)) { + currentWeatherData.getMain().setTemp_max(jParser.getDoubleValue()); + } + if ("pressure".equals(namefield)) { + currentWeatherData.getMain().setPressure(jParser.getDoubleValue()); + } + if ("sea_level".equals(namefield)) { + currentWeatherData.getMain().setSea_level(jParser.getDoubleValue()); + } + if ("grnd_level".equals(namefield)) { + currentWeatherData.getMain().setGrnd_level(jParser.getDoubleValue()); + } + if ("humidity".equals(namefield)) { + currentWeatherData.getMain().setHumidity(jParser.getDoubleValue()); + } + } + } + if (fieldname == "wind") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("speed".equals(namefield)) { + currentWeatherData.getWind().setSpeed(jParser.getDoubleValue()); + } + if ("deg".equals(namefield)) { + currentWeatherData.getWind().setDeg(jParser.getDoubleValue()); + } + } + } + if (fieldname == "clouds") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("all".equals(namefield)) { + currentWeatherData.getClouds().setAll(jParser.getDoubleValue()); + } + } + } + if (fieldname == "dt") { + currentWeatherData.setDt(jParser.getLongValue()); + } + if (fieldname == "rain") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("3h".equals(namefield)) { + currentWeatherData.getRain().set3h(jParser.getDoubleValue()); + } + } + } + if (fieldname == "snow") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("3h".equals(namefield)) { + currentWeatherData.getSnow().set3h(jParser.getDoubleValue()); + } + } + } + if (fieldname == "id") { + currentWeatherData.setId(jParser.getLongValue()); + } + if (fieldname == "name") { + currentWeatherData.setName(jParser.getText()); + } + if (fieldname == "cod") { + currentWeatherData.setCod(jParser.getIntValue()); + } + } + + private void getForecastWeatherData(final Forecast forecastWeatherData, + final JsonParser jParser) throws JsonParseException, IOException { + if (jParser.nextToken() == JsonToken.START_OBJECT) { + + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String fieldname = jParser.getCurrentName(); + final JsonToken nextToken = jParser.nextToken(); + if (nextToken == JsonToken.START_OBJECT) { + this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname); + } + if (nextToken == JsonToken.START_ARRAY) { + JsonToken tokenNext = jParser.nextToken(); + while (tokenNext != JsonToken.END_ARRAY) { + if (tokenNext == JsonToken.START_OBJECT) { + this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname); + } + tokenNext = jParser.nextToken(); + } + } + if ((nextToken == JsonToken.VALUE_NUMBER_INT) + || (nextToken == JsonToken.VALUE_STRING)) { + this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname); + } + } + } + } + + private void getForecastWeatherDataObjects(final Forecast forecastWeatherData, + final JsonParser jParser, final String fieldname) throws JsonParseException, + IOException { + + if (fieldname == "cod") { + final String stringCod = jParser.getText(); + forecastWeatherData.setCod(Long.valueOf(stringCod)); + } + if (fieldname == "message") { + forecastWeatherData.setMessage(jParser.getDoubleValue()); + } + if (fieldname == "city") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + final JsonToken nextToken = jParser.nextToken(); // move to + // value + if ("id".equals(namefield)) { + forecastWeatherData.getCity().setId(jParser.getLongValue()); + } + if ("name".equals(namefield)) { + forecastWeatherData.getCity().setName(jParser.getText()); + } + if ("coord".equals(namefield)) { + if (nextToken == JsonToken.START_OBJECT) { + this.getForecastWeatherDataObjects(forecastWeatherData, jParser, namefield); + } + } + if ("country".equals(namefield)) { + forecastWeatherData.getCity().setCountry(jParser.getText()); + } + if ("population".equals(namefield)) { + forecastWeatherData.getCity().setPopulation(jParser.getLongValue()); + } + } + } + if (fieldname == "cnt") { + forecastWeatherData.setCnt(jParser.getIntValue()); + } + if (fieldname == "coord") { + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("lon".equals(namefield)) { + forecastWeatherData.getCity().getCoord().setLon(jParser.getDoubleValue()); + } + if ("lat".equals(namefield)) { + forecastWeatherData.getCity().getCoord().setLat(jParser.getDoubleValue()); + } + } + } + if (fieldname == "list") { + final de.example.exampletdd.model.forecastweather.List list = new de.example.exampletdd.model.forecastweather.List(); + list.setTemp(new Temp()); + list.setWeather(new ArrayList()); + forecastWeatherData.getList().add(list); + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + final JsonToken nextToken = jParser.nextToken(); // move to + // value + if ("dt".equals(namefield)) { + list.setDt(jParser.getLongValue()); + } + if ("temp".equals(namefield)) { + if (nextToken == JsonToken.START_OBJECT) { + this.getForecastWeatherDataObjects(forecastWeatherData, jParser, namefield); + } + } + if ("pressure".equals(namefield)) { + list.setPressure(jParser.getDoubleValue()); + } + if ("humidity".equals(namefield)) { + list.setHumidity(jParser.getDoubleValue()); + } + if ("weather".equals(namefield)) { + if (nextToken == JsonToken.START_ARRAY) { + JsonToken tokenNext = jParser.nextToken(); + while (tokenNext != JsonToken.END_ARRAY) { + if (tokenNext == JsonToken.START_OBJECT) { + this.getForecastWeatherDataObjects(forecastWeatherData, jParser, + namefield); + } + tokenNext = jParser.nextToken(); + } + } + } + if ("speed".equals(namefield)) { + list.setSpeed(jParser.getDoubleValue()); + } + if ("deg".equals(namefield)) { + list.setDeg(jParser.getDoubleValue()); + } + if ("clouds".equals(namefield)) { + list.setClouds(jParser.getDoubleValue()); + } + if ("rain".equals(namefield)) { + list.setRain(jParser.getDoubleValue()); + } + } + } + if (fieldname == "temp") { + final de.example.exampletdd.model.forecastweather.List list = forecastWeatherData + .getList().get( + (forecastWeatherData.getList().size() - 1)); + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + if ("day".equals(namefield)) { + list.getTemp().setDay(jParser.getDoubleValue()); + } + if ("min".equals(namefield)) { + list.getTemp().setMin(jParser.getDoubleValue()); + } + if ("max".equals(namefield)) { + list.getTemp().setMax(jParser.getDoubleValue()); + } + if ("night".equals(namefield)) { + list.getTemp().setNight(jParser.getDoubleValue()); + } + if ("eve".equals(namefield)) { + list.getTemp().setEve(jParser.getDoubleValue()); + } + if ("morn".equals(namefield)) { + list.getTemp().setMorn(jParser.getDoubleValue()); + } + } + } + if (fieldname == "weather") { + final de.example.exampletdd.model.forecastweather.List list = forecastWeatherData + .getList().get( + (forecastWeatherData.getList().size() - 1)); + final de.example.exampletdd.model.forecastweather.Weather weather = new de.example.exampletdd.model.forecastweather.Weather(); + while (jParser.nextToken() != JsonToken.END_OBJECT) { + final String namefield = jParser.getCurrentName(); + jParser.nextToken(); // move to value + + if ("id".equals(namefield)) { + weather.setId(jParser.getIntValue()); + } + if ("main".equals(namefield)) { + weather.setMain(jParser.getText()); + } + if ("description".equals(namefield)) { + weather.setDescription(jParser.getText()); + } + if ("icon".equals(namefield)) { + weather.setIcon(jParser.getText()); + } + } + list.getWeather().add(weather); + } + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/IconsList.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/IconsList.java new file mode 100644 index 0000000..ea53085 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/IconsList.java @@ -0,0 +1,143 @@ +package de.example.exampletdd.service; + +import java.util.HashMap; +import java.util.Map; + +import de.example.exampletdd.R; + +public enum IconsList { + ICON_01d("01d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_clear; + } + }, + ICON_01n("01n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_clear_night; + } + }, + ICON_02d("02d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_few_clouds; + } + }, + ICON_02n("02n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_few_clouds_night; + } + }, + ICON_03d("03d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_few_clouds; + } + }, + ICON_03n("03n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_few_clouds; + } + }, + ICON_04d("04d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_overcast; + } + }, + ICON_04n("04n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_overcast; + } + }, + ICON_09d("09d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_showers; + } + }, + ICON_09n("09n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_showers; + } + }, + ICON_10d("10d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_showers_scattered; + } + }, + ICON_10n("10n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_showers_scattered; + } + }, + ICON_11d("11d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_storm; + } + }, + ICON_11n("11n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_storm; + } + }, + ICON_13d("13d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_snow; + } + }, + ICON_13n("13n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_snow; + } + }, + ICON_50d("50d") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_fog; + } + }, + ICON_50n("50n") { + @Override + public int getResourceDrawable() { + return R.drawable.weather_fog; + } + }; + + private final String icon; + // Map with every enum constant. Class variable initializer. JLS§12.4.2 + // Executed in textual order. + private static final Map codeMap = new HashMap(); + + // Static initializer. JLS§12.4.2 Executed in textual order. + static { + for (final IconsList code : IconsList.values()) { + codeMap.put(code.getIcon(), code); + } + } + + private IconsList(final String icon) { + this.icon = icon; + } + + public static final IconsList getIcon(final String icon) { + return codeMap.get(icon); + } + + private String getIcon() { + return this.icon; + } + + public abstract int getResourceDrawable(); +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/PermanentStorage.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/PermanentStorage.java new file mode 100644 index 0000000..49eac40 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/PermanentStorage.java @@ -0,0 +1,140 @@ +package de.example.exampletdd.service; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.StreamCorruptedException; + +import android.content.Context; +import android.util.Log; +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.model.forecastweather.Forecast; + + +/** + * TODO: show some error message when there is no enough space for saving files. :/ + * + */ +public class PermanentStorage { + private static final String TAG = "PermanentStorage"; + private static final String CURRENT_DATA_FILE = "current.file"; + private static final String FORECAST_DATA_FILE = "forecast.file"; + private final Context context; + + public PermanentStorage(final Context context) { + this.context = context; + } + + public void saveCurrent(final Current current) { + + try { + this.saveObject(CURRENT_DATA_FILE, current); + } catch (FileNotFoundException e) { + Log.e(TAG, "saveCurrent exception: ", e); + } catch (IOException e) { + Log.e(TAG, "saveCurrent exception: ", e); + } + } + + public Current getCurrent() { + + try { + return (Current) this.getObject(CURRENT_DATA_FILE); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "getCurrent exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "getCurrent exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "getCurrent exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "getCurrent exception: ", e); + } + + return null; + } + + public void saveForecast(final Forecast forecast) { + + try { + this.saveObject(FORECAST_DATA_FILE, forecast); + } catch (FileNotFoundException e) { + Log.e(TAG, "saveForecast exception: ", e); + } catch (IOException e) { + Log.e(TAG, "saveForecast exception: ", e); + } + } + + public Forecast getForecast() { + + try { + return (Forecast) this.getObject(FORECAST_DATA_FILE); + } catch (final StreamCorruptedException e) { + Log.e(TAG, "getForecast exception: ", e); + } catch (final FileNotFoundException e) { + Log.e(TAG, "getForecast exception: ", e); + } catch (final IOException e) { + Log.e(TAG, "getForecast exception: ", e); + } catch (final ClassNotFoundException e) { + Log.e(TAG, "getForecast exception: ", e); + } + + return null; + } + + private void saveObject(final String fileName, final Object objectToStore) + throws FileNotFoundException, IOException { + final String temporaryFileName = fileName.concat(".tmp"); + + final FileOutputStream tmpPersistFile = this.context.openFileOutput( + temporaryFileName, Context.MODE_PRIVATE); + try { + final ObjectOutputStream oos = new ObjectOutputStream(tmpPersistFile); + try { + oos.writeObject(objectToStore); + + // Don't fear the fsync! + // http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/ + tmpPersistFile.flush(); + tmpPersistFile.getFD().sync(); + } finally { + oos.close(); + } + } finally { + tmpPersistFile.close(); + } + + this.renameFile(temporaryFileName, fileName); + } + + private Object getObject(final String fileName) throws StreamCorruptedException, FileNotFoundException, + IOException, ClassNotFoundException { + final InputStream persistFile = this.context.openFileInput(fileName); + try { + final ObjectInputStream ois = new ObjectInputStream(persistFile); + try { + return ois.readObject(); + } finally { + ois.close(); + } + } finally { + persistFile.close(); + } + } + + private void renameFile(final String fromFileName, final String toFileName) throws IOException { + final File filesDir = this.context.getFilesDir(); + final File fromFile = new File(filesDir, fromFileName); + final File toFile = new File(filesDir, toFileName); + if (!fromFile.renameTo(toFile)) { + if (!fromFile.delete()) { + throw new IOException("PermanentStorage, delete file error"); + } + throw new IOException("PermanentStorage, rename file error"); + } + } +} + diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/ServiceParser.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/ServiceParser.java new file mode 100644 index 0000000..e05a67f --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/service/ServiceParser.java @@ -0,0 +1,64 @@ +package de.example.exampletdd.service; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Locale; + +import com.fasterxml.jackson.core.JsonParseException; + +import de.example.exampletdd.model.currentweather.Current; +import de.example.exampletdd.model.forecastweather.Forecast; +import de.example.exampletdd.parser.IJPOSParser; + +public class ServiceParser { + private final IJPOSParser JPOSParser; + + public ServiceParser(final IJPOSParser JPOSWeatherParser) { + this.JPOSParser = JPOSWeatherParser; + } + + public Current retrieveCurrentFromJPOS(final String jsonData) + throws JsonParseException, IOException { + return this.JPOSParser.retrieveCurrenFromJPOS(jsonData); + } + + public Forecast retrieveForecastFromJPOS(final String jsonData) + throws JsonParseException, IOException { + return this.JPOSParser.retrieveForecastFromJPOS(jsonData); + } + + public String createURIAPIForecast(final String urlAPI, final String APIVersion, + final double latitude, final double longitude, final String resultsNumber) { + + final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); + final Object[] values = new Object[4]; + values[0] = APIVersion; + values[1] = latitude; + values[2] = longitude; + values[3] = resultsNumber; + + return formatURIAPI.format(values); + } + + public String createURIAPICurrent(final String urlAPI, final String APIVersion, + final double latitude, final double longitude) { + + final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); + final Object[] values = new Object[3]; + values[0] = APIVersion; + values[1] = latitude; + values[2] = longitude; + + return formatURIAPI.format(values); + } + + public String createURIAPIicon(final String icon, final String urlAPI) { + + final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US); + final Object[] values = new Object[1]; + values[0] = icon; + + return formatURIAPI.format(values); + } + +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetConfigure.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetConfigure.java new file mode 100644 index 0000000..bb5d8ca --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetConfigure.java @@ -0,0 +1,88 @@ +package de.example.exampletdd.widget; + +import android.app.ActionBar; +import android.app.Activity; +import android.app.Fragment; +import android.appwidget.AppWidgetManager; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import de.example.exampletdd.R; + +public class WidgetConfigure extends Activity { + private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; + + final View.OnClickListener mOnClickListener = new View.OnClickListener() { + public void onClick(View v) { + + + // When the button is clicked, save the string in our prefs and return that they + // clicked OK. + // Push widget update to surface with newly set prefix + final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance( + WidgetConfigure.this.getApplicationContext()); + WidgetProvider.updateAppWidget( + WidgetConfigure.this.getApplicationContext(), + appWidgetManager, + mAppWidgetId); + + // Make sure we pass back the original appWidgetId + final Intent resultValue = new Intent(); + resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); + WidgetConfigure.this.setResult(RESULT_OK, resultValue); + finish(); + } + }; + + @Override + public void onCreate(final Bundle icicle) { + super.onCreate(icicle); + + // Find the widget id from the intent. + final Intent intent = getIntent(); + final Bundle extras = intent.getExtras(); + boolean isActionFromUser = false; + + if (extras != null) { + mAppWidgetId = extras.getInt( + AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + + isActionFromUser = extras.getBoolean("actionFromUser", false); + } + + // If they gave us an intent without the widget id, just bail. + if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { + this.finish(); + } + + if (!isActionFromUser) { + // Set the result to CANCELED. This will cause the widget host to cancel + // out of the widget placement if they press the back button. + this.setResult(RESULT_CANCELED); + } + + // Set the view layout resource to use. + this.setContentView(R.layout.appwidget_configure); + + final Bundle args = new Bundle(); + args.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); + final Fragment preferences = new WidgetPreferences(); + preferences.setRetainInstance(true); + preferences.setArguments(args); + this.getFragmentManager() + .beginTransaction() + .replace(R.id.weather_appwidget_configure_preferences, preferences) + .commit(); + + // Bind the action for the save button. + this.findViewById(R.id.weather_appwidget_configure_save_button).setOnClickListener(mOnClickListener); + } + + @Override + public void onResume() { + super.onResume(); + + final ActionBar actionBar = this.getActionBar(); + actionBar.setTitle(this.getString(R.string.widget_preferences_action_settings)); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetPreferences.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetPreferences.java new file mode 100644 index 0000000..7744ea8 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetPreferences.java @@ -0,0 +1,172 @@ +package de.example.exampletdd.widget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.PreferenceFragment; +import android.preference.SwitchPreference; +import de.example.exampletdd.R; + +/** + * TODO: + * IT DOES NOT WORK IF USER IS WORKING WITH TWO OR MORE WIDGET PREFERENCE WINDOWS AT THE SAME TIME + * (hopefully nobody will realize...) + * How to implement custom preference activities (no extending from PreferenceActivity or PreferenceFragment) + * without pain? + */ +public class WidgetPreferences extends PreferenceFragment implements OnSharedPreferenceChangeListener { + private int appWidgetId; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Retain this fragment across configuration changes. + this.setRetainInstance(true); + + final Bundle bundle = this.getArguments(); + appWidgetId = bundle.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + + // Load the preferences from an XML resource + this.addPreferencesFromResource(R.xml.appwidget_preferences); + + + /******************* Show/hide country field *******************/ + String keyPreference = this.getActivity().getApplicationContext().getString( + R.string.widget_preferences_country_switch_key); + String realKeyPreference = keyPreference + "_" + appWidgetId; + + // What was saved to permanent storage (or default values if it is the first time) + boolean countryValue = this.getActivity().getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE) + .getBoolean(realKeyPreference, false); + + // What is shown on the screen + final SwitchPreference countryPref = (SwitchPreference) this.findPreference(keyPreference); + countryPref.setChecked(countryValue); + + /********************* Temperature units **********************/ + final String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature); + final String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value); + + keyPreference = this.getActivity().getApplicationContext().getString( + R.string.widget_preferences_temperature_key); + realKeyPreference = keyPreference + "_" + appWidgetId; + + + // What was saved to permanent storage (or default values if it is the first time) + final String tempValue = this.getActivity().getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE) + .getString(realKeyPreference, this.getString(R.string.weather_preferences_temperature_celsius)); + String humanValue = this.getString(R.string.weather_preferences_temperature_celsius_human_value); + int index = 0; + if (tempValue.equals(values[0])) { + index = 0; + humanValue = humanValues[0]; + } else if (tempValue.equals(values[1])) { + index = 1; + humanValue = humanValues[1]; + } else if (tempValue.equals(values[2])) { + index = 2; + humanValue = humanValues[2]; + } + + + // What is shown on the screen + final ListPreference listPref = (ListPreference) this.findPreference(keyPreference); + listPref.setSummary(humanValue); + listPref.setValueIndex(index); + listPref.setValue(tempValue); + } + + @Override + public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { + + /******************* Show/hide country field *******************/ + String keyPreference = this.getActivity().getApplicationContext().getString( + R.string.widget_preferences_country_switch_key); + if (key.equals(keyPreference)) { + final String realKeyPreference = keyPreference + "_" + appWidgetId; + // Saving to permanent storage. + final SharedPreferences.Editor prefs = + this.getActivity().getSharedPreferences( + "WIDGET_PREFERENCES", + Context.MODE_PRIVATE).edit(); + // What is shown on the screen + final SwitchPreference preference = (SwitchPreference) this.findPreference(key); + if (preference.isChecked()) + { + // Saving to permanent storage. + prefs.putBoolean(realKeyPreference, true); + } else { + // Saving to permanent storage. + prefs.putBoolean(realKeyPreference, false); + } + prefs.commit(); + } + + /********************* Temperature units **********************/ + keyPreference = this.getActivity().getApplicationContext().getString( + R.string.widget_preferences_temperature_key); + if (key.equals(keyPreference)) { + final String[] values = this.getResources().getStringArray( + R.array.weather_preferences_temperature); + final String[] humanValues = this.getResources().getStringArray( + R.array.weather_preferences_temperature_human_value); + + // What is shown on the screen + final ListPreference listPref = (ListPreference) this.findPreference(key); + final String value = listPref.getValue(); + String humanValue = ""; + if (value.equals(values[0])) { + humanValue = humanValues[0]; + } else if (value.equals(values[1])) { + humanValue = humanValues[1]; + } else if (value.equals(values[2])) { + humanValue = humanValues[2]; + } + // Update data on screen + listPref.setSummary(humanValue); + + + // Saving to permanent storage. + final String realKeyPreference = keyPreference + "_" + appWidgetId; + + final SharedPreferences.Editor prefs = + this.getActivity().getSharedPreferences( + "WIDGET_PREFERENCES", + Context.MODE_PRIVATE).edit(); + prefs.putString(realKeyPreference, value); + prefs.commit(); + return; + } + + + + } + + @Override + public void onResume() { + super.onResume(); + this.getPreferenceManager().getSharedPreferences() + .registerOnSharedPreferenceChangeListener(this); + } + + @Override + public void onPause() { + super.onPause(); + this.getPreferenceManager().getSharedPreferences() + .unregisterOnSharedPreferenceChangeListener(this); + } + + public static void deletePreference(final Context context, final int appWidgetId) { + final String keyPreference = context.getApplicationContext().getString( + R.string.widget_preferences_temperature_key); + final String realKeyPreference = keyPreference + "_" + appWidgetId; + + final SharedPreferences.Editor prefs = context.getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE).edit(); + prefs.remove(realKeyPreference); + prefs.commit(); + } +} diff --git a/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetProvider.java b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetProvider.java new file mode 100644 index 0000000..b5126f6 --- /dev/null +++ b/Android/WeatherInformation/app/src/main/java/de/example/exampletdd/widget/WidgetProvider.java @@ -0,0 +1,64 @@ +package de.example.exampletdd.widget; + + +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.appwidget.AppWidgetProviderInfo; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import de.example.exampletdd.WidgetIntentService; + +public class WidgetProvider extends AppWidgetProvider { + + @Override + public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) { + // For each widget that needs an update, get the text that we should display: + // - Create a RemoteViews object for it + // - Set the text in the RemoteViews object + // - Tell the AppWidgetManager to show that views object for the widget. + final int N = appWidgetIds.length; + for (int i=0; i + + + diff --git a/Android/WeatherInformation/app/src/main/res/anim/weather_map_exit_progress.xml b/Android/WeatherInformation/app/src/main/res/anim/weather_map_exit_progress.xml new file mode 100644 index 0000000..f425b7e --- /dev/null +++ b/Android/WeatherInformation/app/src/main/res/anim/weather_map_exit_progress.xml @@ -0,0 +1,8 @@ + + + + diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_import_export.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_import_export.png new file mode 100644 index 0000000000000000000000000000000000000000..18c0fe7d63774763dd23a014a5bafb6aa2798b95 GIT binary patch literal 457 zcmV;)0XF`LP)L<49_M` zTZp}W_|W8mn8Qvt=e_{@KKas&+H7345D^@v+y~N{mFNnxOJDYZzrlL}16zkY+MO%ablgb15WwU^v5*K50U|&IhyW2_ zXeTZj*10J_$C*avfUi)x2dv4`wYhRGVaMXHUx4qt>keJBw&aaj2t=+#s703x`W&6G zP=m{U6?a73HCtg?z!=5;%Y2BtSjWmL#5vKeZr@v7MnUj`qR!uxH_Cn<-`08!J00FK z6GpOhrUeB2`zbe-C$%9Wvi0XiAP{(hrvL*0bYz4`Hhrth00000NkvXXu0mjf#6iL8 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_map.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_map.png new file mode 100644 index 0000000000000000000000000000000000000000..370cf5c38f3efec6d186a1e65ee9b23efbf0c1cb GIT binary patch literal 802 zcmV+-1Ks?IP)|3eB;0~7!SPyjh)Rx^smmSjcNVBlsnV2tHk-QM2Geu_G7 zPY(bO0Cx^xAii8KmkE80JK}fQ>-Bbj0FVu7q#Xgk#FzffP^bbSyE0$XDu&boAdaoC z$$QGtSrY(lIg!AL7(eZ4p$<4VqK`8jpM6lsx8q#lW)KQtXPlb?6hF78<5HZH?BE0d zE4IJ{>n5v1*M9J8Xz-PN74j!Zbqr9lWf-c>>+WMxA;G(x#wR(ISvsG>k(fa50pt); zg~aM-iZU$#qA)~bBo+Yk2+k+I0q7zSt2`v9Cjeq9c>F(wlCVMRK%^ww79$cR+z`19 z4o{%ZQQ|uToiZP-%fR4xX+am&gwqKe9b&E}pN9a(aD3cq1fb7vO(%qtqbfzA-=knT zz^OnZcdVFW%Sg#OzeL1OzLJHV2&C5|D5W87p*lN~KqwuyAEQSju2Dxq56h>Ej}eyQ{zP-{b{`mPkL z+yH2XYyL!^K3>{t=4PnIZ=#b_Zq8eWy%a?r{*}%4(03&^@pl8oG07^^^g+x-k+uNH z(XiP^GY#FMHUZ2ldUG{l53T^XAn*l1`{5q|!avt3h-I6>G=(g$*#r2YP*tKz$!Ap~ z08*W2C)Ews8h{#(mk!CdQ(6ZBzR(paA2OPFa9$KAu^8`ydYTA(10Y9$SK`9uMsRrP z&>W_^2-(PJEQPv=0va00m5)ly9GbfSI3D9kM&^S;OxmP}a6Gr@pX>qf#tl2H5VmN# z)$Cg);4u(@VH+wG(u$^!Vd?;+Hl1d`q)zLeMGZ9C--)+1H}!_*6kXq28JkBk-L}Vz g?gxN-2k;}n0Dm9>SJ?%Fr~m)}07*qoM6N<$f=nP{CIA2c literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_place.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_place.png new file mode 100644 index 0000000000000000000000000000000000000000..dba994d8a7f0b5a8d113467b2ccabe2c1338e34b GIT binary patch literal 555 zcmV+`0@VG9P)Q2BcO>9fKqQieJO92Dt@E4WI5n3Lx?w3;|Gn3B#jB@h-F% zHbA1BoB%5S;`#dRi$B6{@~l(QF5SUB;Y+4g}@ghft@%3ba};~d`&qUP|N5i0|C+;Bm%g*HpJwu zCL_RL!6K9+Woc_K&RBm*U7M?wD5kJJ_pQVbFR)mjyO}GbtRI}s=BK%nX zlUx%QIv80pc1(T;vVlKX)Vx1|;n|hBVn^gfP_BsCW76<^*ogv|EgstVEbOtsZ1pcL zlxj9#id5*3d^awHe#@2VtpWK|BL5rURme>gU_=6$qQDWzPtV~B!U*IqVR%)hjSibG zF(9lNt2zE$$Ws;Inv@y!NrBNhD?o{X4`u2aT&VO^Bm7vu&Si}ifX%KvRAn3LHwRJA zK{?2bDkKL`Py3=(5PK%CyUdksvyg9$oLazhXCl!YoOz!tFw=B0`k{c-AdqorI&+xC zhq8*yp{t}GfxzBiUv8QKZHjtMT(>kJzo@7;8Z)4c1vZ4bl~k#r+oYOGO%y$Mlq-vk z1)4V963KHUugm)>^}ZE5j>X2Tf#vC}#uZm}Z5bCXG>2hMSei>CC&W*QLGQjMwp73b zImV6gwZ%mY6qrVBdZZ#)*VOKYD+>rW$RzTjz%Q|DH%2!}2ywEbrrE9(_#17hKoI8QGX!~*m^_#PXe04cx%%--ZTFyA14Gmmwu;gv|$2 zxQ0c1*h&;@xVvikvml365O(6)A?9dQQ(07}_)*z$d0h1^~N?6?9btxc>Su#Z)2YWI$PL8H2%B-;qg5Cv_Au0jcmS*c76rF1PHD=qcO#5~|BiWF^iQr6!iVZ(}^ zM;hb3iwUjnM5gxke7I33GBwOD%Ciif^)Mr(y#ruCmdd1ci*m&L2_CEpy-ky5vCXMO z(Gt(lm`xSyN=~_Dv8PiI!Wo#5)X|M4wLqBYh3-|a6@i?O8Gud;p$$S90N_BmmB!M$ z;ba6rO%RJ)hhfI%0a$jUvD6)<2Q)n)4-#HSJ(1n<#Kw6PlAcfwzJiCFZ*h9(JO7F7 kpL`a81z-V~r5^zX03bgQxSV;wqW}N^07*qoM6N<$f~DIU2><{9 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_settings.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/ic_action_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..54eecded35495a5d6e6bf2ea5f68003aec682bd0 GIT binary patch literal 807 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 e@XSq2PYp^I7wsV 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_few_clouds.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_few_clouds.png new file mode 100644 index 0000000000000000000000000000000000000000..ab3e43079b8005595a46c4cdafb2f4f241ea532f GIT binary patch literal 3208 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 Tr;QOK00000NkvXXu0mjf%}*n5 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_fog.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_fog.png new file mode 100644 index 0000000000000000000000000000000000000000..bc3c429aa31012687813adc1df494f70eae3f9b9 GIT binary patch literal 3474 zcmV;D4Q=v?P)ABLg{1W}PllTs6k!SEeu6oP1w4-sNODVFlF{n+;IJ2S8(c-EMc6+f-Fi)m>^cGB!jF zSTg=85jkB%7K9MQ%(jTgovl`DV`{wBY7Mk$W)eb3HjfjLQ$q;*m{|~!jUj}!RaI?D zlT%gIP!kH^R1rBT#74~Q#Sp^1RaLz`Tbs2r9cSkgs=AKkJ0t$ar-8-O$10FdnZCmP?79N)m^_nnhzQ%^Dn*Uz;8_V<%D z7e}2%vf~<^;hgMuBl)VCotR=mO|19^fJwIkXE?-!gIvSY9Y`Oly0P2s9$#9KW_AI9?e2Z=6w4e$H=t+DY*Ebt z@;#E8*`(_qGsmS6@r0QjIIFFts*35flxWK#!z~B6~ z>f>;~I%#GEkZfM%w(3Euy4kIg#{D!i0|1hf09FjO)d1WaXT@);MveN;0x(s*A`a$h zKYM*vPib{d@3q*kZ^wQno5u_1GSi*Ar2 zA~drQL052tN)AmYo&x52058SgOUHfBiBfa)`uK8#2cU&*(-UWWEc5MS>M;PT zRkf4HDUXw~_z99Psp`pTU%v7>S;JG*)J7<+D|hq z!alQH!Z%9`C+Y9=6R*ZL3oyevoz7nQ(M@tqb~+dP=bU_vL>!RkKjwg+MHFoSZpz_) z!cHV_&r^po3YfW*RrUOQATF7G!a2UQ^_fF~xV279RS4h5PN#D)$$vX&UZ2Ct(E80wB=oE9?x85X6;g4Csq;;A^Ff0R-Kxp!X)M? z$;wjAC)p%<9LX2z^1y7Ho?RQHn zqjb!FZbn6s9^FkVXfA|ifSRezW|+o!mm9KH{LTL4Vd*(CWg$@2!SU{@wS9Kf1_ zy@YLyX zj6L;plH}*-d_n@)7r^5=AJ&J}NT~Mbbpxrf*@V?NzfV6u2H^Ru)WbZ%%`yd3)fKbG z2-~-B7XUZKJgAs}))cN%qIado8vsOAM*!SaNJR#fFVgSlBwHj!Ri)eQwn+Xlt(+29 zSK}y<>;U-kP=VXc^to}MC6cg?_L;HY0W8lbnyUw7=cN*cfB$Wghh>icjdOUDB3(Y2 z&yw7KsK6bmW)#Y)P1yoEK74U>(#3hzph;mZXEY*#I1>ALUJV`I)KPFOYa@g$Bo~wX zd#MCc8cbHq%4@p@;4xJ_D<-ZOwlrHqAU+7-Yrd9MQyFaH`DF7a#p^FVY23PXYisYl z_x_WJ948_SQ;#?nV45%pA>?#Q9qkiHPJ|Hlid2$#CL*VOGG;<@<|EQRA|g9N2p@2! zLQWl(XrE*wV^hS;AR?ExTCJOVXdhKQpsK2iMdU|mAtesWHI@d;5JF{U+eM@;A|uIJ zIhB)~8ao(r+AF<7(jsWx96~tQ%%&&DQAB=na%V^asi}QVd9f0acg$@6s;YwPkEe*d zvx11cDIymGSU);CI$5de0ufo~oMXNWQZq9eLby;wu5&$~_M_voLi%(Bq-BJl#Fh1i znJqK3+dRV0$v(d_(qL2D?^0-z9R7-#EfbM@lLLKU9B*chJ3B~3)>c(@gQ~U#z_&_Z zt)?K3Sbe-S2FW(bTeJH(!_qzgpsMuN#}yR##?uqGo`H}7{1d=_dFBk@cmV$?9OI>HEzHP(hkat~@~SfdbQ|6VN$n*z z^^U9tJ&o;ZIKaAFD%T6io)whSKJjN0fTQx9%FWQxF|#)}OLeF?U0`|4k2$`{4$p!jEGt?cwXQ#QRuL)di~huqXc= zcrudrce~v$3~?Lwi>kVzkf|qo9RPQ!>L(i^*QtSh9l-O^v8B9k2Y|b}-R`0$HqC5r zRlUO9cAEhjV_#QwyWRFQ13~f!8U67ffKya;KM|4f@$rGQkBdnQNUi|zXtqu7jPYu( zVQC)#2LreOz$+Q;a|?i_>1tk6+Gk>7LR9sm@g6|e+1m_YxvI9M=?wlqvKoUNInQd$ zKYJjnG0b*V)ka0C-C=W>turezO9+aeZ?#}U?us0s_uDWmUuyP zi-+`c6|<=71pv0!W!1fBn!;k^Fm?aU2 z?}?ZtyUkrIW|SW@qmKDV;BtHURlM^e~vKo!W zEQvDnVwNpiw)7;7s@ih*15xLs49^TLX31`Rly0J}EP*~ZktZespoV4bFJ^IUfxn>H zSIpwUm8#yIJ1N<9C*TY*O9|$CF$>8@3UW~vn23v-R47QEkfl6>#VjOW&)9+;B%e{$ zb45g+d+xc$Vir|h3E(X=n;~Y2r_;2UWl;66K={3u_^jEAS<)CLCnxt+)ms2G6SJ7v z5;I$2W@A-V1(MTZ7Bdr7mC@1Bfdg_Pkps-^v=G8lnNmhe2w~1*mJq^n5n1f6xy(t- z0^raP!U_?2|B6|52Q}4%_IW?}X8xIf-sjJM0j+D|$?dVi5&!@I07*qoM6N<$g5jxl AOaK4? literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_overcast.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_overcast.png new file mode 100644 index 0000000000000000000000000000000000000000..8075b1307882b23a247179e59339c9b8b39f069a GIT binary patch literal 1409 zcmV-{1%CR8P) zK~#9!?OIQWRaG4RzH^^WVmelcn@FU{Hbp482?{X@qeX?eiKs;p6c|RdXcI(15VWvW z5K+{o%-RSEwyK38Awe4#w&;(mph6pE-o3xy*J93jow<(VJm-z`{+w^~&b)W$+;hJ3 z{r=ty6ciK`6ciK`6ciK`6ciK`6ciK;FS^|>BrW;+rfDXJ95YLwH<;OWcR%RvXU$BK z$;tW&+9m0KhqbWZ&~h5=q8LxE;W~V?of=)YLXfThkr^5P02iP;2ZAY9e<>2qBrxG=Muu?gQ``fSn}a?nxm>C4EHl9soDR%_Sl58keAS z;3S_M)V?@Ka@>8|-CqbH><6#|K$R_i-hsP20Q^OA6UiV6B(HivqAp{NuK^Zw) zB^@ETQ&J!)l8B}Q0Lf3Nb$?}6vRtI;2S(7cO)Qf0u%zR0lb(~4ZTvDa(q`hdST0HN zFw{@6yJAi{rSxX@2!OBS<`N@}8`l;5Y5Jo_%Agb!?{VJDwq)wXwUV|Rdxx1#lRQcC zt~6I7s->RmhLjhP{9DplNnce}^)5-78LFzfev5JUPg0VXs_fN7R?y}(n#}AsGrK?U z9;}#x(kYnPP5?hyKksyex1QOwFD?Q&CJ#1Icv&UUT=Un5?cyn7@zY`aHK8=8i!M@yRa%*aP6UR2nUrpgwviYuhp& zW@IG{V-mYT(!Rbk=}xDUll1_}T_o2>)-M70f#mm+y4h)r0+=FKrlx}c4lkLYrfJaW zbkH=-vm{>uunoYCt?MsHI!E%?ctdJPJ@f)9O3pf!BeyT<|59G#?rSA|O7cMR#hEPA z$>CaZ$@(b z3Jp7EZB6Cl5hN%nzh10b=n+J63&|%^M~*3JXho;2t;u{miVBM7dc@35WDhB2X78EV z-R>R|QEZy#8Im7|5R{wH7(-F{c^4B|)?EX5-`(F>vu4e|A%t)sbp}T)bT2cgQ7v*5 z&94LCPzd22ckj^M(}f&FS8vp%mAfKIJ36i8X`;!A?j`Zm0q{88U89=QtRPS6Io%&Y z(l?TrC4!TToE!nTH30a0fy!4CETR1AZZ`lp0pMKvF=KEd`N^A+lD-W9{*-hy_HR8? zkR~MLw=E_gA5JeoZY237$-RliENL8-f_=FSHDy&lCH(|ocZh9{^O7Ew^jZ8d5!3VP zV;;7U?-#%f$(O6D`X{6&8Od%{RZjzW3c$~jE+!KjXP=b4R}@HIlyuD9?+hV)C+W)V z(!8TM?nz|yzcqm4RaKo%h3aKbVJGUX^+iy4C@3f>C@3f>C@3f>SY7-Fk?vQNlfK^0 P00000NkvXXu0mjfEJuZ| literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_severe_alert.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_severe_alert.png new file mode 100644 index 0000000000000000000000000000000000000000..42334e8e83ac7ccb015833ed50acf90d4abbf951 GIT binary patch literal 2068 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_storm.png b/Android/WeatherInformation/app/src/main/res/drawable-hdpi/weather_storm.png new file mode 100644 index 0000000000000000000000000000000000000000..b829abf982f3f9654a5553f11dc78813cf0cdfbb GIT binary patch literal 2864 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_map.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_map.png new file mode 100644 index 0000000000000000000000000000000000000000..50a91002ad0cbf33ea70fdeb8dcb560404ae25ca GIT binary patch literal 604 zcmV-i0;BzjP)U01dc+ zPyi`_6aWRJ0N@S<;Ctc%oC0Wo22_AufO02qnN>!k(ONbHCkJ+Bv4y4Gw;w&(N%D|C zmXvoWB@1V4*)9$s_*Q03eD`m2cVIb)jhqV+y`6=3BWZ5 zsecyG8JDt!me6PD7qoV!xBhx17_GTRB{hmLXU6GF7=UH~q-$rY+uUUo01PkK2rZmq zTmeKKz+eFwr?!LTDe#|d5Cg}rLi9AJVW1PQiOmoIQV&q7stZwsqt7@4EzdIyi2mQ* z3gA5X3bLQquR@A z)3*mgLY(j+ooay|*x$kfRluk{y^=uBG#R{@~9K{o@Va={(@Y`@r9P}5TfDCS6tn(cK&rbkNwB0gLBhYu&7l3uXibU>$(2*m17vceF z7hFiAuk#Ma8MErUbXqDQn#$exH^@BpuBkdwYJLHL_K51_Gp7n1M29=R5*B_bRN$O1 qk`YBYL{pCZUC=(h3;%_D3orn$Rk5nL;If_o0000F6XV1NN5sT%(O|8ESW ze1X^=hLU%LO901MF zq!h8Yh$#a|O@v!WP`jK~b-`vFS(4<$M{YKpMI|*9Rmb>3fh6CPTM*5nmhZ_50X(5V zvhOJ=iW{(q^^#){Sq^|UyO7I;vp}%}4D-z^uNgfEYJ?X0v;e4!2PF!d%e@SmQ!PVe6+gr*@umuEKASwcC)f< z|GWWrF_jO)uwTspfWO^ZxARn*Qddzc&{8(7&^q)l<2?OSBuUZ-8$gO4se3R$x#Vc0 zf!eXo&j9TD2<2QfcDex=pHGFcp8*2+=+0Nutyp`amRUUWKGy>W20re%Az(?_vju$q z5zvlG>PiOwMBqwTTjT6);!MTFVL-=r)DrmFaZI@g;K%^c1Ee%(;8zJ802*px6z zlwg&mXlX(#B5nCr5nu)5G*ZoW6*o6x#QO-Y29R_M_BPg=Ye0`&o~~q2>vvI_8SAE^ yG?c!76r+gfb>ugXi>NOna_8m$aT-&;1Q-A|?2p+^qB;uz00006(JFc6ISQ^2_Z8gK&? zKnh3$Pyh{301bo!NCCP3<^H4r7XSsgfG{hqB`d-vmX_Q-veIaUz4DA5@0g-kVu?Qv zHKk}628~n!8$k2$9q52xrPTdn0ziIb@>n?F0uhb40Fc*6hJO-43nI&NG+qKbp8v+& zN$lIu&Vd{718fp?hHI#{k|Ni<;4MWy65++JbGTNKalezsA9?aSD%B$qhxy)G0`#~?&hQ7DWg!+qj)|D%1X3cJ rV$Ps%4xE82Ipy;Ie~Et^PXPu1!=KTV_gtK200000NkvXXu0mjf`(nR7 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_settings.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_action_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..25c36db42c6128d7038fc7c684b299be7c66dee2 GIT binary patch literal 550 zcmV+>0@?kEP)q{gd6P_X zX7OEux~{vX%Li$IrIs}FeZL;N*M%eS8Atv`8jP zU!`JLwub=lbF6Q{5P;YWk$9tIfTATmy8}=>!1kA5yq6yTQ~)Rh&^Ox&u$}@0ND>Os zOEU{I_>`h5k?8%mAS(9f;e6oJwJ#C9lRh4uhy?L?s;8WMg(O;v9Ce7<_aJHGq&RX4vc53+DiCGD1UqCU$Uhby1%a>C3-s5A5l5L of+qpc$SHRPFv%ommtO$}002SWC@^W*^#A|>07*qoM6N<$g24Xmxc~qF literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_launcher.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..6ae570b4db4da165fada0650079061cb56aa8793 GIT binary patch literal 3777 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/thermometer.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/thermometer.png new file mode 100644 index 0000000000000000000000000000000000000000..f6456578808110b662ab3ce8a86f34a775298e6f GIT binary patch literal 1059 zcmV+;1l;?HP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00WCjL_t(&-tC!9h#W;2hTpe$ zdQ3v3dcYVKFQT|gyeJY>Br2PO5CuU{58i?Y@g#W2A>u(W5b%~mAO<`t;z1IkX0D-*v zgVHd~vZXrq?9?ehzK ztsMC3Or%ZPCqdIg`fmsr*Mlp9yG5u)s70tns70tns70tns70tns70tns70tn=>Lt7 zww!?6`}?XVz8*qx{-I#DJ(x{bz}SG`{hI*3lmx|p`>uh|yrjQX6c0{SKF%(V)J5>Bu}U`?3vWLR{&g!tjvrNihkG* z010_9b?y$3rvX6ZM*wzjRK!F%EqE`LFFBZI*;~O3BVbn|oh5K@HDyLIzfqb`d%d3` zf?ol+N7C7DmK|tRK<@p^0Nwz3uIt>xxfuxDCFxs|s>A>zMJ#oQAoq1jB%sQ6 z_~ksyU{<37NG1ZRri2il(b#RYpdGD7d9vC>{{`!?rA& zj)2QNaU+4_BA??*?^DgY!x63wwKbaAbaBuLej4!e@>nI dz7E63<6n;&7FOuF{)7Mk002ovPDHLkV1m5<-FE;0 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_clear.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_clear.png new file mode 100644 index 0000000000000000000000000000000000000000..0bdb0da11d02af69ddb729f27af4cde3f68d53a2 GIT binary patch literal 1690 zcmV;L24(q)P)uNt_nr>ZnE?r5DTRsB#0nc*!mw-k%Dfl;Le4h z+wK(Fg+=JjsKpedL?|klrYVio+L`-(=eWqd)7$6FTeieML=N~+HAnrbrhp8w(2w-I}7+jtrhy}p;6vV?9 zfYoW3i7{RVuriYn1@o(B=I-t!e;o`4^Vz4{SZ$PW<0zjAV4mbJz8f?SV09`X01TNY z=^0H(8p#cJuiBhb3OPyO#xoUwjdT~yi~yz=BF4Cqu$u`zEJ2}@yf#kg;`0#z$IWcf z%og4KILW!atU>Zxa=GEX+$GQM)CxvJ2&dg$R5fc)pD4+X0;uY`9;&0RYkBA#9r2Z|?qCRaKw&dcCI5wYwip0k0VdL_`uCpKgoe`M_HMvgR$h z(@u8fTs|vz>I516YeO9-0YCA3l6ole`*ZTq`wC za*pJO*GRE)IW%i1RVNiGN`^!aX;Rhi^j)yD&fHSQ+vKXU= z5RRqPEvo8fwiQB#BNFRd0&OkE(h;GY{a1sva+V_COFWovXQWb@%51%!!CpRVAu=KJk|MT<`UI%W7sW zBGxF_LRD4j?n3f-dT605i4Qlk%@D%r5W-fnf~%?(AmXYTLazA6X(fd4Os-lF zlKB#m@_Tm=dsxgv3$4tQH#)M&B<6>CK*x1YDX|Ph1UYcLZF@B%&joYYwTDcP;8TN{ zt%%6Bh}=!Dd+vUrkn~Rxx!+~-n&d?}4%~fHL>?A>$^{X*SMa%QW-FRuw8)76fKdR~ zLkKSyCB%WCQDI#*v#;v9ex(Vcd0>_j>sH%Db}lEf4hp#OS!{RuVI)1q_-bdx-0j=9 z^~8x2mU>(5I+%<8+jCN@s;bo;t%|vmCr`SFTu{}J0=v^#E||~F{F`mZG5ac~6H@3t zH9t&VNjdjKrx+$kKRaNz?nSJW+AzQjYjafDC?yiMJ)yzI=%lxdB>4#+()kRBL z^u-rD4XlFcD#IDc!vL=5)-t!X4KSIejm+iqRd+v>$A@NCkDL5WBSZjjEylQJW=rMF zh~)cY#ww%66V{xqOd6{ISOTy{^4jL+=5#xZJpGC>&I8!Ucaq#8d8!<;n%O0iPYt#T zi&l# ztmpvVYK|5GETub&@Su^rGi{)L++b$t?*P_vOq8^}y{!Pw0Qj2ZI?3Mw+)EbPB>4k? zFU{=C7ykd?Z(=8PdiWFUJ^X zTk?%cAZ-sxoBGZDZ0gH<_kzxeoBF!0%UYE|{8I&Y-^203+{nD7Cf8UO$Q07*qoM6N<$f*j~DZ~y=R literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_clear_night.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_clear_night.png new file mode 100644 index 0000000000000000000000000000000000000000..2617ec17dd4a7ee7be6f9a6939fd6ead2536f82b GIT binary patch literal 2436 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 N002ovPDHLkV1oJ*pHlz; literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_few_clouds_night.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_few_clouds_night.png new file mode 100644 index 0000000000000000000000000000000000000000..3dcd13fa6901fc92da3cbf378379f9ba27fa8fd3 GIT binary patch literal 2402 zcmV-o37z(dP)KdsBm)NJf4KMsHa*rBR7t7@00eMK%2Av4R*8vz^vFq#+{ z$MD$AEHiIoUyc*Z2{fvzM?_?!x5#B@KHV1q*qRnrGlOOIUeva^yJhD6Z{9$viYyF( zt*W}%uX)*+k1_TE7|a?kv_65!^5e{+<7HFL^b+l(F~+{xx)jgEd|lThB5OhjzcVun zA$SurGh2Q)vrJEkXqcHLeP1*4d@~DavznPvqQ!Z$n^~sKX11oT>jMC&s;c${$P-0m zH8cN~nLBc{NK9nTjfg^8cpnk%H?xTVIqu|9ux1K1!UD^#`eb46qTKx0x(jm_QCR-TA4Zko(>%nSe; z0PZea;-dim0N|a>xQILq;Q1W?ogl*^@}jEVTI{*I0W{1Elevam-{P4gxqMB8Nrfn*i2}$oBx8OM<|;qQw{=Dc0ZSvbGm|L_}6htNld4 zW1Fl2h{)-3!-~kAiSZ}R?2{t0D!I+E^XJc3#n?(j4rIoCFc6UkG7losCnBfwruK;* zz>XQAM$WVj!{o`2P8QBYWMho6)4g|y$U^59TVjkqQ`OHT`fC9k%ofWQ6p`B<54)TK zJ@&AfBGBdnbY<9JjYeb1RLFFiV6d$~pAU|Vj09)(%FL>gUZc@iGL-aoLjwdS5%?rdiNb>kjO_xGvl9#uU=M1PDi-WNikj*bqBF|JKx?hGOP zf{41y?Un@Y4Iz9-RUaavL1^F;P&DKoo1wOc;r)_Fe>b>`Y* zyb&(eF}3r#QB}PVLRgx7EsvgWW<5moYGQ6X5q*`2zG7xWM6^7FKmgt*qJJe?KUUSR zCjlxVI$>siW9A_1F15xroY@o0(lOv(X6xB%gaj zRX>yl=Gu=#2)7Z@@6*r&MAXg9kE!Z0B3f@|*P7X`7~@b9;5dL)X7*WT{wWdtv##qm zCjpL&Q+2jG@v_SeS(7#I0}BzIG_$v+N@PEG?$){k_>CKLorv7z7+C<|*|ayloA%Rn z?ev(^^F9%|#l0Vzq!nWTc27rebJ1OBAyG4%mlGaN|36$4!|#q&fH!A>tc*o zt`iEUDu?lR8`eKh-h8vHv39#XIub(jO=`EiAr-D_qqPulXkeEy%i8m|)3eMGdnuIvB&57oQO U(jGzsCIA2c07*qoM6N<$f{l1zm;e9( literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_fog.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_fog.png new file mode 100644 index 0000000000000000000000000000000000000000..7d99916fdbdf5092d087fb8d892520a91a5edbea GIT binary patch literal 2193 zcmV;C2yXX@P)}|5iJPjL4p-3 zf*?&1qb&&HPYV}9eaMU4`V^_f6cSo!1Cn}6eP~UhNqR|gGc#v@-&%c`y{Bu=ocXy) zsaV}G%*;9GJL~7{z1FwCBl7?8pB-V^1pwwnWP1ofRP|E3-Nr082Cx`H*k)!DLbzC# zB}qzImeX(_2q7$qh!#b0A%tMvZdVo-7G{r%q=<;b7{8;cF9SHMs%KU8r5NLv{54HD zRs9~x)2e!oxK&68ZqxB;L)l%$d*fS)*9VrGjZpLg~Kc5?hAqpCiVp6=vn1K`2o#AP4) zj-*U#-xut2_=73)8KVx92S|1S+~bn=e0bC>b$!S6C1)wC=IbiO_=AQ&f zi!ttsG5)|gug)1Airg$uiH@0l48WntTX?>)rxFRGs@&#_r4K4z( z$E}ga5>VZBLqQ~K2H;LNJ&)$a?@FbgLvRg&k^=S7nH zrnP+l`vIKJI92^C$$Q4N{k#}S9s+PiRnMvFzW_W3VD~h-K=N^tuP1u)Pm)JEolZHp zIe=wVy%oU13^yAPwuD5YwzMm`c_6cH%_+)MHWS1q0*xvMP8 z5oZ!c04xAlQPuT?F_OO``SFt{Pmbq56Xy4^To%*f&%Y~@Kd+N2hkMpJkcX*iMe@M7 zi~@Ki<8rx7|F5a)o@r0sXFdRUHf4{lE1RRrM)DUK13*X?0RH5!@mw%Bqa1{)=KeAV z;H0DKO%2)r+&?RwJ^;X6;~1gFu3>%EW$@8@tOuJ)jJ&S_l{2c4qtC{*GS&J zzP>){{FN(Lau9c9C)~}N=ycwo7=YVJKI9yj{`;<5*-#*wGcv3)k}%R&L=vZ zS!?h#T0}gqP}LV&t=63bzpAQQAo)nE)w(Dm+Y{d(;_o8zI>`%(>SlVIKR1_Uxs;sF zRV`=iB~|St!|7h{Yc0q{kVUAN!WadbN2-URSrl3(-tVm}2PQ(h60 zS8H_I&vR4N18$)o9>3l|L0AA5bh-`v~`B%iM_Uvmxe zNl&NM(dh`_88a(=(@FA48Do6LH94=}^Z@*<-mIKlv*wzWukk%q{b?PS`qE9VPnfTO zBv&LaVz&?YGs(L~a?A;$@Y`v$1ZPK|(_Qsu?L^$7H>U2>Q+f`M}Y|HAjs!CB57t69_j8WR{_EdFR zM3zKEMdU)O)w*$Y+RV<9oLQX)Fr-ea>ZusxebaC;#>1*QP^U>=pE_-3EdX0qr%4W} z(>3f^bsE5sI_=8x*3{`#Cfg*BIa0@(&^n?{1CXk!<^ilV1U;lqlN?c}0la(aG|2~> zge%{0UEAO1vUsr0L_JeT9k)@PuF;XP>NJ4q>U7G~M0MJ={)y^zgFu}(HP@w11Gq7D zI#JsZb=u6dD2jJYo%Yu!nk{CgH>^%4rFlf1E{bBTIxQk0)9G2&X;nRu)ajfg+p;?C z%FbH=ZX@}gsnfk)Z(da&cI1!sS3RCiH>%T)k?wI^=CL|0zEO2LFW9;|ZDvC9s4uP8 ztxl`zSarIV_3Kur0W_-90A2&os7?d;r2u%iNu36;nzAsWZ6-0;zbByEa=^;oWE}Y@T%W~IL+wuk{7Y6o>$fLBwx&LAFHYw%M1bRSJl%_)t*V625<<#8IoI4 zrvW?;V7xj_a!8$?h2F*(7gco`z_OXOXQk5swq-SZnmS!o)gX9P{U1`N|69h}N*9$- T=9D^@00000NkvXXu0mjfb&3+U literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_overcast.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_overcast.png new file mode 100644 index 0000000000000000000000000000000000000000..79303a5824ac8c6a2e9afcf77be0c99c54106752 GIT binary patch literal 955 zcmV;s14R6ZP)E_uQ|l2aFgoV#J6M zBS!pp5fSM7et5*p3;-bMQ8Rnp-9M8Q?jG(Ql5R-4Y-W!EK+bu1M)ZAuNzyNpqL6n< zDq~1;GdsvRZx6R#!L1n*Z_u9ioVjG`(}_$dJdNtWji z&m}zizJEm0E0V64IIl_ilbLEJ%l9P0fbS%|xQP7H1SIW~e5uyObt->KQU?H!h&vJS z!elb}<4hhfvnK#NRTK1-n!YyjWvu%=P4d#xRVe4YA!*CZw#;m!xO3Vxria;TW)-RI zlgjwsqCZUB9qx|9!$a)s>|6)%27t%Q{5_I40Zg$%U3_3GO8;m)@%E_}o7oo0Z%J;K zBx2*z6cK1j{drwSp1CAlle9UVPC-eZ1Gqvm&LK%xzAu-MuFY*$og(6U z0I${~7j{fO{#6Z{px^E5M% zMAvn2_fOpYO_H0n^bah784(%4S6$b=d*Z1w=e&_p+9+4U!F@+{cbiNmzqOw)M~oOT dV#NO!e*;4BN)fjRmNftX002ovPDHLkV1kDSv`+v4 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_severe_alert.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_severe_alert.png new file mode 100644 index 0000000000000000000000000000000000000000..308931bbad54abcc8b37c48117fcf989670a2255 GIT binary patch literal 1448 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_snow.png b/Android/WeatherInformation/app/src/main/res/drawable-mdpi/weather_snow.png new file mode 100644 index 0000000000000000000000000000000000000000..9364b58347206374960cc24915cb00cc90b182c1 GIT binary patch literal 2247 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 Hu0mjffa|Id literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_import_export.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_import_export.png new file mode 100644 index 0000000000000000000000000000000000000000..b247edafa412fa6e2059817b7f93e625239cec55 GIT binary patch literal 580 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7@v8%IEGZ*dNb=_;9&y+*IfQ^t_G$%4pIe-0S%f8JCome zzH4DB@~=_9Q^>f45hxeb@KfsBffS*~Hzw(L*Qc9U7v{MCUKG1_iSMEVs)`Iu3LwNC zbp31Y28M(huC0ypSS-&Z{1AJ~oZDU|dxfLnAZv)0eEx-J2N@bZN`};xSRVd*N0edX z!v)(Nt<9gvKeG7urIO{0bWixE0!2BMwts&$uha|1A8kEk&0uuZH~L;(`|tOA85Nv= z{XBGBuH9#n(CNB*uU!ts{0%<2k;jh*pA{j{D~Rn;}!R$8Gw2`FWGxzu11_k-;oMg}Jd=Rk0VZ|8R_9n7eMlsd?)oUuvzF zRAF22`IXMb)r_L^^h>{{o>2I4MN#t7OQ*w32loG9{aU1HB3t+Vj0s0_SwOySe*A0; z-!eu13}OCn26b;!l~kOo5--1>dzvNH%Q`%D)0B#b literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_map.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_map.png new file mode 100644 index 0000000000000000000000000000000000000000..537c5a49c6b2cd48308429f3420d64757321af3a GIT binary patch literal 1022 zcmVN(we1wFVu9_11PrvDY{boe3 z7c5w?V8Mdjto7y2*Vor0Z63e5&q=@EPl}x%w;lljfLjM(P;q`mExU3bC)8qF05T$s z-8Fkp#2!+>B?T@$T4UPWQ;Vo6acWDE_>60YI5&~y?5Y7Erxf&u(wxqz?VwR2^QHfk7u{w3%Ww){YKy2OsD;3;cfN4i~(G-y`e~&ybip0os4j-;r zbPDusEe4o90)ZWV7S2CW+jmL_kh60!LOqPm8y$Z|PMYSqD)JdX@-q$q;G<$xTOq-y zw9k3>iM)L$Ct{3bT{{58m(sJR*P;X?ayX?nL!QO8XJ7sP9`|iDz+O!mTnmR%+N1{I z&s=gRNbZ39XX03Kdh?Cv;MkMmi!{!g+7<+QxMUT0 zff97J*y5f9a#%*oJ1WTowPopiBLMJA6lAN5{2f``I>(6jgfwRDp_r3EqDi9wpmr}D zNpR?J-&`Z4a?!uFCMA}Q=zxL`7?cb1)fW0=T$Ij|r9v+(Ph4XM0K&JJibgob(ZEa0 z+nNq!7&Y5Sh|uyA!fOqFNK96-1_tD%G;?mA4DEpUz9Nlsy7rgQ`rpBck&w|V=05VTMEHp#a zs4~N^+MEvOhS6|uI!CCuBz2g8c@sh=x%X+&mt92#IWB@aF2z|3p&ZN7b#gVUTZ0V% z*b7ytTH^p#gEdlRVcC~c0OUe}sHXYX1Zn0G9|@T`~jJtpET307*qoM6N<$f=bxXTL1t6 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_place.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_place.png new file mode 100644 index 0000000000000000000000000000000000000000..5e93aeb0bb08a45f68ecf24f74a5ac3300aa5dfe GIT binary patch literal 698 zcmV;r0!96aP)E+E{4cG%1?#yHv_$uj88XngQ*_4KsTuHEYy z30(Z<55Vg@8^J4XOGKZe62(c_+ggjHt))@ljxX~3z1HT5PbM=P9lMgA-V z_z8+*7q{Tp9p+jLaj0Oay%qkd0vD;0@R23gwm9ckrSKyc4_pdu{qvJ;E_qeuF z;J9lvuUqa)JKu@|erS$FnjTdE0ur!SZ%JF@=(qJ^SL(oVR~847Wlx(5;-=5#27|$1 gFc=I5Mtle`0Jtu}*?$Y-5C8xG07*qoM6N<$f*gJ=A^-pY literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_refresh.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..ab4ab9da697b8c68c0c7ba498dc3bb3dc3da9c2b GIT binary patch literal 895 zcmV-_1AzRAP)CckPh%V0R3M2y&0fcAOnyAGC(sxGXNQY0rI3fagVyT<9`H*tvelU4-CJbC0VlE z2Nt+IL;@lKk$^}*Bp?znO}ShyPr=R{fM0=r1!(~QJcrAhkFk;)esl(xN6J>A;2~0ia@Ib@6GAwB|VR1RG@nRSrhnA zj=0q28)rQNFIpg;WKR~v1AYN=j-#;v0FN{N*L7wDA|n&6W_SW<);~ICJPAoWfk)rm zX!tp!Acr$nQ_yS3T5ybvt_y?Lr-Kq82~4~o$Xy%EB=;P+6=O-RbWIk65kO|I0^b7P z0q{mUGXIbGqjv!ncr@=<#f+2FLTJs0&G z3HWij0IkoW=!})yA%q>FN6FuJQ{7lGB|zx=Q=NTZ1WXpZ5dob@{mcJ@AV87z)l(+G zxf*m`hdq|#Dd(a`ot>hD-G>x{__Wn=&)_>lCKhleR?j2!`>b~YsI=XVbRy@H31fHf z0*Xqo4uSwC--SMfLcmG{UbixxdV4&RBxu^%>C`PiwryVBJpr^cwUkt++SzI1=|erm@*+zKXNh0OrE?o zV)}{!ZLjZ{Iri^6;~Aec(Gf4_1i3T2KLQgSXkIe?6CeD_(H@j+`Y@?J2#_9J?6lTZ zfvydZ$G$-KQJGap0-oTWT2<*Q2-XywDi)&L>PTCZ9wh$HP$VD{5DAC`ge?CA7yzOq VDq)Usy-@%F002ovPDHLkV1gKjk--1} literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_search.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_search.png new file mode 100644 index 0000000000000000000000000000000000000000..19658e4a2acbe30df1aeb743ba5ac5e16a5edd21 GIT binary patch literal 827 zcmV-B1H}A^P))F4ccon= z%S0lPNF)-8M88uiMW>g`Wde^Gv^o6>KYu~1pq-(elv3sB0Kmi-@VJMzXz@CNI6~V4 zjMJb2z{GK-H_)bmT@=vX07Nx705JJAJeCcwp}FS`fY2gd0YWhd0OaRe!_Vy%Me{E0 zRfX^A*zkA-2txQ60)VZ<*Grl})zNi&gP`q(K{z<_bpcCl9s z`rTL%YIGCm_nZ>IUBGuXj+O6huF%JZVu#kWMR4sG0Ibr3<*#Lk+5ezd+6}apKBO)E(gmB7F;Y~X8n9j5|zKL!0da@1;E^~=ciKX zI6Sf01@ua#Jh$6@PqyYy60G#^@OpbtCa{zE^7-T8{=ad1r zH2})YOe=UyF(9z4+yZdq;sW+yrj!}R){~>S!Un+J&J1HFD+KhvlsI*X%nJZjZ$GWw zU>#}l6Gy83&MF-?24%*Adn#sho&3&`YJac;KoQwagAu|u#2v`&_l{(%&U#Rnq9_(e zUL0oyOlJ>Gr7Vi}PYwD0Csm600r&xe263dUu5#@0bB}XGQV20FM!Mb#nJI96#UgMg z$jMFcz2{iP(pXnx==)1*zHtC2{jLL^qdI);RJw`*A@=2{uHh{jOkBH2;o9f>grHIe z7)qFIi>TY2?XTQCMTd|SKu374tuZ=;yNs`99`Ef!kK~*Il%BAHAaDloocYxrgCHoz z0L&c0r~2d-6F6Idz9d-%Si*7)F3<%+J{kal5Xw;j@Ptrj9%Zz_0B8vT|GxG)6b%YM z1B9BQzt^>$$_6SU1I@|ji`4&5Boc{4B9TZW8k7DBFaWjb9TtHJeu)48002ovPDHLk FV1n6#bKn2~ literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_settings.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/ic_action_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..425a8bc8dce5daa8c5f4f78b0b7052805a66e950 GIT binary patch literal 1124 zcmV-q1e^PbP)a#gEG{9ZUYOS($BP^+nHK00&W5;K-y8C zuT21H%J9n(0HM+jiTZRJkoDB}`U#-ZA6pnd5%(B#-ENRJ$?j}M?Le-p&`@GIpgkYtNzZ4Fa~CxJF&F^|XkKhLM{Ug~MB^Ul?>mE$D?n5Za#ju= zVM%M`p$OO+!dVflx?2dYx(+&sYR|@VVKL@H{U3S{g&~ZM@M}IvkE@b^s0B2Q=lKO~ zFk!@dBN7h1Y5*;AP#7v1dp<#2lS$GJY#Say;-YIUxN#JIY$1F}o7iBplLo;GG*j}! zbFBC}pl_2Fqsgg9qOZe8w5R9D|#3TrGWb8bq-x{(+(HMFQ-S=JoN5js904$ZVoIDUEOd>z#}ac*x-4teDmVdx@I&c&hFtzH_l4-ucK%Eg z?VS)Q4yCyl!3Yq9SE=hxYJ^Q{TA{Wv;Cd|nwystcV%Pb0Wd&5yP3K)QE65agev6dzJ;?8dUq zSKq6u2jB!<+~FaF@SzJLxkKO6XDNudXhESVaj8P-^OqyQP%H516A9=Fw}A;b!4s&W qJ6(Jb5fKp)5fKp)5zzyF3orown8LjDzzdE50000Al;2fhX_b_H$!(yr=WHoOzl)fEwqZl|>V1FuJHhd92cP;)+IZb%XWJHo{vS%6?KQsMx!WMLWsBBVA_0ZM@;`i4T>ABg5!-j8KH8bz&}^`6Yx zV|buri=K8jdLyw{MbH0k02-78Fw+6gA^lLF)DI0A{m{fmOL+z@kx!u6?Ey4s--PlJ z1kMW>2pjDnV9LAa8My3(_0_V)T2~_r72LzBBtFHb^6rT*@^C(1@1v}C4aLf(nycHl z=?}E;)ScJ9R`my=a5Y~JLY*E1jp@%|M(<-NI`jZ?&pm{k8xJ7+?tRF-e+!cCUx(Ox z*C77Zbx68+4bqNXgRH)5OhNe-L5bbb$GIa&+9443-Sbpld&yx>!&=>egldKIX<-sS zy>qGOUqJ|~GXFGZma1#b3av9Ux9C5sTB#NZ&|ufk)~$R3C08Fn=A(y@DR>O|%ws4P z5PJlLf_uOhT!QI>li(mY4t9bgU@Q0?Y?CBu^wvZDi3!_oMUC8W z)v2X(m(gHG3vaV;io7ZnAKp>#e%pFD&V!Gjn7Iq7EQ(J> ze+c>PJxGH)kPLUJr2u+AT!C;n4PI~pT;V7vkreoT7Qj4x7Q8>Z0~y@&_tKh9JodbQgAHKsKpOiH z3YdG41-Bs)?m;>{gK}V?8UM>{v`)M|6YfJ1oP%Ka13VFcD;xr6*v~k??g2a4@zff& zKD1yq+%jf1-mzd;TrgppH|QL!USVuMd%5}77=0hYyBq-|FJA%v-%)&vhfuoeKIA>U z0Ws`-HV1{x1I+E{<;n0ADu9J{6n!pQH`;t^gLvO<$VC95a1#9B7YpSooRDl3m(PlzFv>=Rnyss9m4jw`!T*Jql#mAn4AOzrt z0K8$pz#Vo!bAs)UCd1}?*0BDj1+2MZ0?W@E!s3(qF#mU5X7=t$=bAR^BsQ!u`bN~Y zzEk28I|s4$_n_$bZOCTMLnwO#GTYvcmmvYYKNoX-5vHGF>gnYB*D&{A#i$_X zD|kK+F>nU!z)Ac+$G{&Bvp%qY&=Yn)b%E^ei{=C|#uDO@_38H-*171((>4CzD5=g@pCD zpp-cUVc0TGMIqy;h(}>Mo`VoXGzuGv-Ay1CSn_o!1w#ZUb{g#z+8=n|afEgRA9GMJ z9rg`OgI$k3VfzDD*nGzk`mWo->dRKJ{G1tjKZ<`;2j(BvgRXr#(7s(08rG``%9kpi zEbLM=eCtyY@%$}d^VRQy@S2N|{p1Xr%M&YKxVL<>K==X;s{V8zZStz~l5QF!# zz9{Z=OfP|G!Bp&H2;&%@j}8fcm4zTvJEv!6m z1xx=hf!^cJu;TbMn18?=X6@33ncK9Wp--Ky>QxaGb}Ma2ZBv*)=YqEp0`V-eZnNi! zx8pG;?#yYHFE}_DKs%M4kFkG$ngq88cS1jN2ObQbgaeObu#mc7KKF(L0v}8*SYR2< z@k{`O?Co(F8c<$|8?2x~4+hE?ZnVd*Io=sOb%cb=Sr zrvrE3+^zMnc)tg+lhN~Sq4%^kO*?xomSXn9pUet?VFqFE z*%oNtpbhow)S;?Z8HyLGFxef7yOV0UlioT2#QPh7_wj~nPOdxe2b|seIE>kTZyNO7 zw8H+}6#A}BfyNEg(t(uTU# z>QMO`0ieugckmu1*Ko2D3dVi&R;3}b7`Eh$%`fXNyVP#E<=4OE)--nQ6Dz;^!97cu8SHn8juD_DHY0u~-Ih3-Sf(6!eHww)@1n-BhgOV>_9+tP3-U!sEP zM-{LLL-7I?0)R=J!PyW|JdyiWMFEL`rKhb`R-JR)v+lA7v-;v>w)dPd_T`4OH}5@* zcG4F5PDR4H)1fGyHT0gr-u;3NrV=~!>d8X8;y^uo%_X6&zUY8C9#hRZ;_-Iq@wW8; zE;()qi;kMZg2O2OK_e930A}yfgN|(mFmJmn%v|FNCG$0*VyP;6zZ!zjfRY882tb*M zuadbLULfV>$me|WRzv|!KYMr|FFI=B`P<3KkCvaA%q~4?f-RxG&`ud(ku*dzf<-3` zVbO8YtDC{nljan{^0QX3;+ze&mFH|}Y9V4TKST06Ni*o}CvC9Hv4+J|c=Y<;&0zi^ z6PUN(2<8y+ck5xxsRM0Wbf9SiNjnevbI(Tecm9!uvOQJL= zam;t!Z^KeGc@aIw?0;Br$Z|%{5ev5Gs42Vfh%OdJT{4kE&oTWWGk`_M458;J+A(7U zfsjs^qOj&eW`W*qiD#iLIblgXounBede0H!@h^n$+GhxzyA5F0P85F|5q}aiZ`6jy z^_oz(h5*3azf2v)SHt|T2KilTklDs#;wohrf4;;9&(w)y--A?rS~qK>_*zu_dKABACAOZusE9?YYrkB|&7hZ_!=5t=dHhvx%E_KIq=*rO~4Y~}_u~Umqq_cMun}hSS=PRN2D*(TZ3rTgd5LqI{c*Tng?0v)odH%eQNg8?~JXyzD z{wct!FUXlcwCVr<0^wC}*z@rXsQFU(VCGRo?VK;%_ zaRt(rpB2Q9lg@(dX+ctFGD(q;8*sa7i3q^m~;~R+Z>okOEhlr19XT}Pl z_g5@ahO#9j0+cZSD?-*R1xRg@XJgCd`@;)4e*|T7y4)fsD3JO^UdKs6rtNt)WzAK{ zxN;Nn9{j-uKHl}z_Q8f*mY0{DGF;iQOWV4wPw%rg0)hOJBf$UUI^@`21OCp-kaqt% z6bxKqvzgtGT?hNF+hD6{cXHld+o;()%)cfPKwd~nyTQnmYTfjNBI9fE1*U9Lg)XGk zsX^9E9u&=2p)FzEYAw1vK!hb;-LV6WM8Gbg&E73Ea^EYqgFIdcs11R&ZqXjf{n+*N zX(I$JEWDbS_cfq&p*rMsszQ3RGQ?FXK~$j{gl6bKK&&C_5v23T#+^IUda4A6Y+{B@JdylAv!p z9<9aMebEw899GkRA@=5e6V6Y7qtiB)|{(4W_(UzAu2u2uNIFE+|oLr+{^4MP-yNA8L*?}x6ke2KP`(HrC@CT4p{}v?VzX7p{U&E+zU&60qe~00t z{|-No{2YE9@frLu{8RY;=TG6gpFe@`e)wgbARzHK8>#tz%KN{Sk#K0#-971v@veVO~*vbCl z0p5ItZ{sTEcVL=g>(^>Bt(&mGZ_$UAjYN1&+DTy%XH)9s8K0C1%N&BnjC;KRFqO>i zb05{T#=Nt7g&I@6LYb|>!dA0V1FDzf6Iw<>TorO>E3w#7u>SmsryQqA{M5F=!Mb&m z{{01qP3RESd)5@zUbchvS0=;C3;6XJ3%uV779O&OuH6>UvDqA&R+~cgQX?pvuMb6Y z^dNWUB*<*ig7i8~NU7F<#7Z@YE9XH>nG%{JL?g`TQZB@nb0NM;9ulh+Ah}Kf(wY>> zfQ8RV8S=VFx>JVIMc4%`R-to1#ZuucP%xK=k5j}#EXM@rNHTW5W3#)I>L(6 zm=aD+#wpnrmK?Ljsn`;Fez(AgG{cG57`pZtV)vv^+fz~#8rEszEI?L3Rj~-8@bh>$ z11LgTqXGpNS;S$z6UVWZ9%8u!KxnS?{){#`wrsHqTh*&Z#V2P1uV_93=ul+iDhL3{ zHv?eSCjSw&y;iNo^HrF_ZUvTf5e3BNDWZod;u9iX$7Q3-q*$+5iL2($660$YxtkQt z)4E%>Sdpz{RErkVwyoN6fFKXd0`2h^?r z87;zSiN#0?&zEJr;>WV)?xWHPfRJp?@$?p17GdFYSEJ&S1v~_T9TdWASH$iK0YqU0 zxV znjWa3;4@IDDipnPnNWBlSjj?V>a|3C>MXM`JSU@jWI zpxjRKg5+_eCjg{bkLYn%4eSs=w})}gOwGFm^SC5sv89W7Ac8=mK?Fi%wX4;r)vQwc zhub(%tq9YU(h=@+aBKckD^+NH9=M&NLyU_b* zlV}wVV5yjX605O}lqf+c0`QC-$C|s16#~eXIg{EX%VNG~Y0X$h(vK?rnIwH>&QxTv z_Au_zl0A0b;^J>40z?4v5I}wx5nloF<|ttPSHMCh56Sg%EROW7d-S;LhV~;RE9Q6@ zXSHhH&7C91V!zCmEL5WFFcr&q)PrX%SD{9RC9+gN&qIULj1{EtsnIk-2dKrWFn2>B z96i4V`UjrCqbIjv*YPfBUg<;y78Y1l`Zy|l4-sDI`BZ!?ws~`ugx)`tez1#ygc zRjdFZIULp_X6$nSK^fAo0$3^pK!6gE8Ep#aY;qU@5}oGmBS*b<0Ns7T!)tqOnhU#C znY=mjEJC2-ll2tr2q2@COI{EgRl)&`fCr||W96&n`55tAH16hf%8{Bu3wP-v9+WRd z04OSfP=x@VTQ4!;f*FYv;>k6=hA@9~82o;A1w8A2NcVSN94y>_bPaYKodxY{yr8^C zn~E+n()keaNvD%Xyub6M^wTT^5KjOU$qNBQ69D5W0RME!GpUUTV7@Xb#I*Y%fL{Sn zBFDH!Oqla#0Bj2TspdDk8HMvynA|yB79jw!T=f3z4tdf6VFU;PxJQk9Xzn7WSlKnz zFr!KBZuTr$Oj(NfVif5zK-rQZ2)`i!v`T8ig|gB`iu8pxt+0XKUFqoYtKrGBd%&_R zi2gm7UvwYKz}<(JVfXR5FmFRRR4y_?k$BWWi06~rxt+pJjiw)LI|+c~I(dkr9ncE^ zmabz{rX@}KDIk5~)szMfIu4J0Il2e{5=j}Y3T$LC0We+&!0~mrp*urD4eIt z)x;)q&{{jRn zG6o(zz6qxRPev*Dj0Zwa@7Xql@LPQ}Kg0iGpw@3uwJUW;F2tWWS z^&FDENGBw$Ej_{+fTXhYW_cEeHP$U+LYt|F*oZd-zySfMF*&ojZ1yZJz9{1TTzpYn zNNbkEmJTDJ7$YEZEY^Tum1^dCtE4rkU(RTg#fZVy6}zUQ1;R8$Ae18noDuLvDZp== zD&XP6dsIpW1!RUi|F0ed0K+g80zr5A>N%+G42PtKiPZZu+ep27833sPN|=J=gaBN{ zg5&t22p9seP?GTuH%9ulTAnXrAkr&SU*^jc8K>EFB}3eTL>VmfWtb6jH@@X|K;b`4xoEY z!Z)=`?Q;o$>{)Uz0HF7i4oC<9Q&15BFpjnM6xS`EJ57lKXyM@FaUQL;|{y_ZGeZ5?t?%uNIm-Br6Q5n4-O8(t=rdO<+=sn zA7cVWP9vbWE(*?FI01W(ECYVC8VV;z#KV~d0n`WqB$Vkvc%BM+^H_|4alyfHdc%EF zC)`e|&M<=5$U+6yHB9Qw0jTetl1Bh!b;z+I@rn0mU;$2T zl*67{2*5pREMx5|u3Jq2)N5WzYv$nNg#gF^N1~v3Az4e3hx%R%ICp&)_4q--0BqT} z08%Tgz&8P-q#+Xa9NY+Z@7=}%D;V-__SN!B#TUT!8&_b%)@6`d-~sMovXEZx1UvSx zcn)UE-X2J*R-ulPhTczFP$2*%A%I*0Kpf1S#|1_5&BXmuCq7K7lR*Had*e~@ixvnM z??^qt2x6m(lv($1*_ug?!+(1H0QMk&6$F4flhrQAX12>A067F8N4+YgK^EextGBkp-TOC&9!mfW zz~!u7{j^4rlx_-GsCIT4DBmia#0c5la0VLNG0J3a&0qrIj zbH`D-rCnZ%X?2>H)0$-P@dyBmc7E4T8k$cQ^W*A@bE z*rr`Q5L3c~#9CRJez0Z6h!p~eCjfGI;1Vv*m^zO2j6neYX%qWN1Yo|W0E&hNJ2F$y zbuauGkp%=Ar%=!C+izbh0J^={$N#cnxl?jMm-^CVt(iDu z<}ykztI?X1R;O_;bqE0InnY1+PJiCkO3}#t~_1F zE||xKszruy>hhL98MI!2c>3%ioVu_VX7;3kSF{XxNAqCrvI;nV`6yi*qE|n&|2#Lm z3?Qmd5hq^`6(2h`k}@H-T$ut0$yNfFFpOLmapzD1ApKPUMErtz!Xb>z5-IfxSh$s0 zmk>_D8;gMF0I;v;x1sngF9EhWWwdcv>iq~Htx1*^;KUjZ#FWcGNS-8vDTuZ6mb9Y)YBWx# z5CE;DaK8XRma_A@xKP>ip8+5T>4Yv{Jq7vo&d|~m3HKk~q+tHH*?<(`_1nAAITYw~ zOstk00)SCap#rhRx)7YDKmnLIju!$*K>#%}bnB5Uz7-4sAZtowDI>X70SmVZ;~XlT z!ZjK8#cK!9cb5NI;|kZ{!Y<8wC_bAp!_Lfap?bAp5E$1zCHHx67`vluoPD zKAqek!(y!Vi9(da0*JE#Pv;?Fh~J(D8S1AFeTBY3<@Aeg>eev zq;gGuc@qHI5P*Ad!5nP_z+uyyIgr*Y^!{Yb|D?D@Q2-N$0EpXVH(5%j69Dx>0HkFl zb$~_zS<0Rx_m=@&LIBw{PSCs%0X+H(05%W+BuX(=R>=whloJ5z2tWq{`3N9{q#%hY zVJSxHI0-WZK$Zx=TvC7$z%05FiYZqCLUU9EPC+tBJnLWo{#q~SeGXuydtkvFt-B%s zsZAW}{iFcL&yX3400KaaHGc(wGzCCfRuO<)vXRp%2NgXAe*pkPBY*-}@K*t}qhP`a zh{NJb(oak|)`AL6h%TIj0JsEzz|>`&Wk{N##&i*Yb_H5^iTHVQcoaZ-i#*xNWJ9x5 z`<;V0krEQaUhiiQk*nhN>}mM8d4>B_jDVY%e%Le=Kc!I!fD|hN;CTdui?L?zV)pz7 z6REUXtrHjl49*Hd0PQc*5CyQ%;4i13?CSp;fDi;gBY+fNwCFOd0p*$yRiFg{8FC0f zY{1xgtVvLc9!9_f3LtX`Kpq94jL%((E@cn^A(^WEQvzhd-Uxs`==-Q?g_lRcoJrTo z)dHy~eoBLkF#X^YjjNJ@$YLo7%AUZugpXm(+{7klG+Ia^fFnr=Agx)BA%&aF56=P2 zmV@$zhH&!o=KpB*^Z%NHo;`aCD>n)wAf}9ixnGv1pO`WfvQi&ni}WFwuLMrP;uHXh z01*HZ0i^H}@pC)r)ex9^$wHnIMu7Sgw-Ci34rkaWZv;T|N>8`KIoj7S{jgO0dKn<8y)k z-J;ub02l#H|3L%@ThIX*80d#pn-D;*EP6eu13~~K0+OqYAf>_&OM zrRizH6hvCioY_2VKb7e@t6hn%B_+;KX2Y_y?|Ve3dZ9!gzGeVGFFUVU=4xHosdIsd znNrVTiTH^_-XBvg4dI0dAd>(PW6V4xZ1NiIB{S-E5da4P$T6gCrGQ!$q6IqA|KGlI9eUTyf#76)bPh@MdRYn} zh5#tVfvj8~5=tx}EK3Kb1Wp(*m?CEG8)f>vZ<6fc*a{BIZ&hTnJJ9=QtKf51!ROB- zTbT^j4nahg$uXZOJ)<}BrarPBRMzRJ%5R#qEwP#-K(A*KX2`HZ;!6yu#J z!PxnYIcMr1!6|L`lFVzf`aPvykwLFv$g+h90EvR^*}_N&D-;K}i1CnH=?{mFY<~_y zwCDSe5kLX_NdyS{ezGim4Yu!I3vrn)VC?)W*!uknp?T7;q@d^$A%MhEONh!b1E&B^ zzp3LmOY;5z-*`pOuso#;8I8sR1+y##1+y)fybd!qqfwuUFVh-`$v3$cm};2i>d*V} zO?~#z2Zb#*Uq$4phX-YH&f*j}7@nuX1ZQ$t|8!Z_CsB@ZkC0>Rd?#EqaTy(D9wzZ= zV^4@=)m*PbIc@qF0SeCnkd;&lfJDJ;vYagkVFeQ48Z{hz|6zf)e+$6&jD+n;ouQH9;T;Fgzy6C=P8Ip0=cd zODrKK*9srceQM+&VLA+Z`d~ii%fL((_vA{GrG+!y{wV95db6nA^G;f|&H1Q&y}s}) zo!Gz>jgfEqT{0g`OH%yFD_YjaJ67qp=?Rn0_{3=5_KHxwJ|p4_fEuz~N)NXb}~y z>0G>WN(f*9nS^iPbUa84?c>J}VCUZTP|=ux5H-kD3qDB_*p=aQo-0kgpX^shmvU$n zM3*9f5(2;wQxF2kK>*Xa_w?+?X_MDU1}pN>mf=Ne6H;rl{0q><@&mW$on`2C|KD0$x1sqj{2NDvA#b3M@>sZ z$JQabL;$dnnU;)$pWF$3hcTR&h5c9W1N(3KY@t8(2I4iv9kE}Ow)-aJwb%`&*7MlZ z2I2aVC>7C79kR3b5&*iv(;`Q&vLM@>DfM!6@hq%hBDjQ)1-}?=2+dN0gmNwLickkD z@6iZ|eADSFx7LfBUTwcVu1tL(u2PmE%ho9k9C$e$iA)4Q1c6*@l-9(30b+(c`12*O zPE3SIoVur{OOlIfshGsuspvJr%T35tZ{$pj+#fGmekM^-CWn!NlY5~$if_$Ep!a)5 z@Xp!>NLZ7%s1AE;KGGONwW=!Y)AVu&*Qk7*6F3MBkaiV?V3TTu+k(mULV=0UB1>&-P=-3|pQ<|GlgK?gHI9?* z6(u?H?fpbu0-?eG@8Ow~3;w4b9eM0{P0fr>Ajy{gP!pNNYXpZT}>7QTrBApgkrsTQ|rr ziP!HHD**xNT!_j?Pc1Wt^s32_S>s5JUo#oft8EdC^$;9OHlxmp$*8wxGaGE#tVTOF zyJ<4o6v%0Ig4||j$Zc_hycT!7?LjT4$pf+*T!CNf2&pq{Ag;t1BJy>vhUaO_56xBa z56e@NA#bOBsgW4=mO~JJltJ0dC{944?tL@2U%P+LSf4^C~EVC;`ZrKHY)%s=LAFL+z_;2sOSoWvQ9rJ zYM+V#oFKW<67#(d_$8^bUJ;tClRvL%T8yF$c`xug_bKY4{<(g3m`p^L{yiI?5n$r- zGplF+Bk0=x1p4;F!NhqKSWOj&$^H`H5-NpYFo5tJT?D9sLaV^kXhm=i;eeg*1Tc3O2g4~N!Dz}@*3LtnwQy9- z*Ki#5J(<+sxsR|H0jTYcn3zy%bjLk<3^)dlVr_kY1#^!PVB|Og^z24}j`gpgZTTx` zm<|VRvoWA>$1kZoi$0F&LI&nqL3^0-&KgVoX|%@g@I^aWE}OoOO>D zLlC3E)@L+Wc#H;9m(d7gG)4r9XfF;rR-**!dZYB7PvJwy!Gj0C@Ch?oq+#|wqiOyl zqhs?k7&wd=5?qXWzqz{@-W~%MZW64+Gz8!xpZ3lI5FJem!$xH_m|h6Yp8!GG60Bbu zS%4b{?onf5N{~3%Oe5lrK?tM3c*_@)>KokiG;%~lDhO>0-eiZ21{lpkM z4#!kBiUOQGeH_A+07o>300bK_k#!5y9JKL305~Lek;M}syl^6f zl7`p{Df00K5LF@#5ryQc3Tc?0 zhTTuBBshg&B=|~#sk8W>0tiYp?J#p2F0l0am6_~68eGE0f=A2*m>Mqy(-Nh@2aN#r zis7(RBPR_`_U63@FuN~)R9TnhMY5S6S1HBDR*;=4vSA_(Vfi=@WXoVWl0pxb0H+`+ zuyh|M(6f^GR{%bYOt`{1WDE-LJkY4bibCx z2<3n1f+&E5{K@T3A>#zjVPhDtxN+c{DhUC6jHGN?G&u;$l0^v8;Frv0{o-^6o&4Sd z7*@9`@aN)A%e{#;vg8wM+1N@1K%)R5lyKx#%$Az9mxC=v>X>4U*S%Gi33+i2}7`Qyto02L6^ zQ9`l3t#6X-UEdT*L13l~OT-T^An$%xf~aC1y(B#(N1h2tmlyaYC?9eO;Tr1c4f|-= zyZUDghYkH1!^CnOgUBL<{V}CHHlb3JjVo7SqDz#Rm{L_HrbLU0D$rqrGBg>FD7n*9 zrjK_KeU|4x{;a}6o3BDL6>7tCd5;sy44C99LpG(_kWH&IWi#q6*tA*;Hm+2k4bD`) z;+-Is=oK>Zhj&-}mnP!aV(u3KnR2#4nY@)T1qKh}i_F-#B2zZL#DYyIv1MZmteypD z=2#U8&jev7G12&Pn%(UB)8dNu(;iWEuZ6y=Evr>dOS<2FxwTD zqaN;`EIs1=pD=uJeBc;0>htMIQj-2D3R8nJ)N8}C^p;2EnXHP=H*E>aHVB%Ytf}Dd z&--65{~)WHk>v{CCRM1brPUe)X1Cf@6t+9J7Ie6jWi;7(C0Clr#uvW$bGh%2mmrX| zLO!$KoiFjVKcDww3}5d@{{o|L!onmz9ZEU>QLz*iWpXV~e2dms{5HF9Nv+`z{XKwp u_AlqXKi(hjkN3y> zLBRN54iOc^e-|fM2uL*0)!9M70^32irwT|s#>FQV1d>$vaUk?nLO>iLNGpLD7pmoqar5w^NGpLrkTQ&eohNB* zr3^>Yz$*8o9!&Iy+lCHseLE^Dv%q)OiX}Wr>t6fwL0Kfx=R)q|ZrGzj3e7;PerzU#j>IcN1w-A~QQa9yp{}&=} zA@3mXz(K+UVS{b=R>Ad&?=Cpojja8U|Ko`ItG&YzeN8>`7g=;z##j# z3V-ZMkNpt$roG3QKahPb)+YW5^0c~6JZKHAhy%;N8`O z2U>qlJxx*IV}Tvu$ZBbiId_YLebHchF6SHfMrEx(w#5b2?s&%Z(%0^_ghP#SHZ>FT z-(@+8p8LAl9LUe&fV!&3h|{i5JWS=33t=gF8xWrdW{wG%TG@bo4p(0xzdaYT@biRGloagwIPov~-tlnO*6z4Z(7y;S6qcR6_5qA-ryA8ar&hVRO;O&o9qhJW@@Wl+p0&uA{ z>W#&9g`vqPn;Ol_G8X#=!<%0G`lW4(%An@&Bk;aR$;gOusVP4mZ2GHEu(7B+D*N&4 zHwEr0T>fC_=QQ8hF;@&>K8gcAt9D{hbzNW7AvMt`=+mIgR&QswB=OqW zgqMMuMEwk>)8r=Uuz@Bf2`^U;x~Arc=7hI!oUST~l$k==kv*r7DlF>PFkbtrM*{JXtq4enZ&XF%ke zl$g%pvW{k>P4dVTp3`)pzT->^$gyGC!jATkrzxV(^ThIKW)Df!%} zDPHnv@HZxb-=59b8%f(FzdS6|5xAXvkESOV^`w5OHA<*KiCsGscvRERWem1%a^r@4 zJRxgE6&jABtk1d__Y)E#+(km6$X3>S5+*#KHPx3s#O^pdMCVj)dTt*NpZy#Cvcs$J z-Z;ZqeYUNDRoOdN{508Lj=kE(qv!S=N;9x0`3~8LQ`|duPQ+tzpC=86VDHHrx;ExM zhM|hz>}aPlymx&tUNFQSBe!`8J^=bjonR5hfhbIZ(Y8Z_!upLnaqnGfrDDQgJz{;# z&ZlxCb{`h7$TsUv=!ee-B3b6Fxx>CZ(K=tDMhlKh2E>ni~qz4L7+KZmkbwpBF z_x&8%Q-gdRCnvHl`!R6hkf>0rLTeKwz%?A8uvWvS)gLR>!sm7by+mV1SU$T}nb4yf zR{GcFcag5EeO+$8CC*(fxk>?3x{LQ3XHI$oI7f)rx&FU6oK)t=iCX#<=8EPS-z=NL zGt#*bzH3^`Z-lm37SH5BBmWD_A3Ig}ypvza5eiodt)_p50(le&&&Zye3JNF^dfzmH zm}>sZAmz{x~~%;sW^Wy*6xoMimsOGt0cy#|_=CpC)Pr9w;o5@VWO+ zZR|=Z)trjiI%u}_7kP5TzO`;SOJ`ZAOoWkp0X!5!9v7Q@WV2GpR%|)vG8W#hztFbv zFA%P4+|4j#(XUg9va)z7mbD=LLQJavEvkE2%B#k=PXga@`SXb1hj6nwo5P%B@b(Qk zHh-sl9c_GiI7Gv~t7Z0JX@qoEZ-x;i_+~&DM|X!O_V~2_0AIvaF#rGn literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_clear.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_clear.png new file mode 100644 index 0000000000000000000000000000000000000000..42bad9c2fb013e578c7ab4a6b6dd538df18b1a69 GIT binary patch literal 3443 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_few_clouds.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_few_clouds.png new file mode 100644 index 0000000000000000000000000000000000000000..954a7fdeaad46fe267d61c729bb3893031860753 GIT binary patch literal 3868 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_fog.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_fog.png new file mode 100644 index 0000000000000000000000000000000000000000..bcca0a861a779ae2517cdb2ac45e38697f9de05c GIT binary patch literal 3031 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 Na}wSOS7Yse?SECkxcvYC literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_overcast.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_overcast.png new file mode 100644 index 0000000000000000000000000000000000000000..5096963169a924f8b6c8e75f95471a64515d522c GIT binary patch literal 1740 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 Vs1gUwOVa=V002ovPDHLkV1iIAN~-_> literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_showers.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_showers.png new file mode 100644 index 0000000000000000000000000000000000000000..28264f24a69366e4b19f649539dccc61ff2429af GIT binary patch literal 3999 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_snow.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_snow.png new file mode 100644 index 0000000000000000000000000000000000000000..52264841dc1e9b8ad21090bf671ac7ec01d19b4f GIT binary patch literal 4911 zcmV+~6VU95P)+P8b~5JN%r?VPk&^so%gJK`*w29 zNp{SdIdk^8?7i1|ug`m1+ifpd0KBTIgGruXW@o$mIc9d6nVGwrnVF>To7qif_Bk`V zRnq-+T{mWC-EP;WrlxG)8e@^n#9t2JuO!__QY0lw+`g0+!|z3M6M&BZI4i%Nqclli#3**nCNE4wBCx?IUxbjUyxl z;8sbGi|@B@&1S+1lIu&eqg`7)pOC(PSd#Cf_Ri*~L-M~Ov35o3`!E6|y8zB#j5Ade zCjGyXu)Tcyl9~BDGT7YRC3Vc~9Fm=dHbWD`005P{uQam*eS2gzuf$IQn@h5)s?6Ol zFtekos@lhZv>q?%MTzh>-^5QEpu_~3S;x%I-YZQ|4x+|ofSDb;kPtCxmbrUQU;M#d z!+>l{@4owPGcyNp9Dp+b{Jo?H+JFqne7UhD3iAbrua^z6GNleDF(s@0NKWCy&!Xe*l{lk|kTt{<9c1|%k&D(Omh zKh4ahgDsz>{(<-krp8;Cv?vj`q*Lm;zH{PCP`2|Vr%Ari%x-q~Gm>*tqIqw%2u1vx z+}%=ev?xN8w^UWtg61ST3ne}7ZryJ805kibq*cj&D@T~)Sdr))7cb`9zE6^mO{5Qy zbRd8))pdP(QfK)hQg9vwNRqs&Dvw%S*Y%!lf|BDhN$*I+m%B%Ny~nR$?zWP=kmNG} z9J~+$cS-lS`+KUYy3%ZW@ut)1?0yrJwUgwZ7R0v+BYw~C=j2>QVP>YP zs*X0ZD@guh(=>;4I-R*j_VaIo032s#x48TANpia5n5FR8C4HLYg`G}k(_9_&yur|I z+qRjzzsAg#$6#s#rN5s_D5ofVhkC!Ps;a4(nVFZ?bpOO59B_o0ElrZY*S8deZoA6e zmzde_1E|KWpv@-(j?bG~BmR21kC~4R=JY25E>Aenw?;lK$ql^=Y>{y@%(v@7s7F0xyuX) zoo5ckz>}-vl##+F`#b(ZXNj_y1n3x#j zB(GTD{cZ2^-QKJEi*qtTsb+hEyMM{uPs~s&q-IqHBCepU>IL=(`8_qK14?=dfOReX^}BrqGk9gU+x1BNHb%7BU`Z!SdNj@r%-0cP zyZfAwi=_QXzTe%C%>uF;3n)E&pAYEnBKb2j``pyjlrq-N-4>FbK=O*FY2HV2d0p4D zn2^r1TGCf+N5S9cB(eP^-_7j7VZz=zdjQ~ck{gSulHDTgZT_Wcnst&sS(>E8gi}av z4br$3z$tzF+zSER0bpYQ72MVH1`WN573mYK0%LvKCDUuh*p}w~9nK{fCl>W0f z3YCOoo1{PKnJa&oY64~(1YEO|gBWY7Ec)0s!N#|5mwWeR8BmX`-zK|Tt zs4mxX`@(K_uOz)!(koM)_dqi{*vytlTAEvFQs7r29Uu4TwxhqPNoejmCwZ2c-7udO ztn%RT=a@z?vyEnUjhTH}(to-;)8ANC)uWO4{fIe;0c}JtlV!=g9U`gg?vIHqZuY8coGvthNQHvo8B z(=>HvKzPmG{FUL=FI@LB7)Nk29%LnxhvufQ#Jyih1Z< zP>~6BGuvWj-;=b~%cPRaLDSH8bGu)-=sjUDp@8`&Z0tJ;^6YI^W&TboV1A9Z*$Ogzm$NQ9Vm6 z=_&*8{9V<6avD9&SY1u>6~m-@j8w_$GDysWdM#7fD5ofs#I2r}WZ4c4IiKV$<;d$8 zPWvGP@U)oh+LbBK`~!eLBw1w%e(bTq?UmPEcU|A~Ln8h$ZMeM+t;8Hw0S8+n)m@zd zle9m84~&~@%KLEuN4Wd{y8BTvJe)&1Ly}--e_Yq~hev7C2$Af8B%kB%rx_!Ldd{v|yGcqXtSk=L0dOwKP35H__v9??>`KT6_UVb-+#2+!`f2Z0bmoU(FDX>B()iHmP-xI*w z202Us#{yVYpo&-=S=BVnv4fl~$=5}u<+B1<1K>oGmjU>3AZo_%YX+2Zf6_;IS?u)| z00)&DI)UU5TTsMMZD^Y2k`}voT!e~6!i*%pF6rL33zY!8ag>IEekLgYz0F<+qP@9H zpd|)83gEs1QI-3DY9Fn-tq(MhW^)^Wb7ob<5+Yga?$3Aky9yMbaCwFLK*pUsenteb za-GpjN(nq$(own49?;6xs;chpN4OGQ#fvq{OEw1e?~}a6%r=M4hMX!m)ZLHF6*V7o zHZ}y07G5KxqDImi>bkyer;=p)=XGZGEHk?-!#xOWMRbcfURreqw#6 zmlDYb%#2Ov+(L5gA{2k_H?wVJG#{oht>xAfm-MZ=uD{dAJRV*44TY~8&FuWTuHWA` z1_?f)*Omg{ntpkmpl;vp;{y&M`R{GH_W_Q5ebY3@jS?sg$^{K8!zL5CzRyisEYMcA z|KIHAgh?LSR^LbknX_~I&PV~^T*CG8MT@fFB>;XpEO`}d@`p$+9k$_8F!ImC_D6Cl zfDa84tOAT|Zkpz!{pd3ay+|(pb!bHpa{|eK2GAVw$90jO#g+DJj!wXxZ2%MO@!{fP6&Q76HYa=x(otim$jL7Nq)VmDku43 zGrK!<3uaBq&0!q?%O=_cMQH^vL-KDV?O!!oJW~?;o2=D(tBv%$b z+vDvD{_+t1~t-X$Rb{O-8j8UQYAnx-=<2|x*B$qW!b66&DKSC75|8AQOsO z_JNY>iPfCY)o>Jm>(hYU4*|SvnB=|fG^yeGA@l*1PJ`Kw7DGKo;~Xp%oJM~PZe46Vc}7`6?- zcK|$lST>a8GbMdJJx2qQaSW~JEXs;Z=28Hzku*Jt45$G7QA$Cmtqrp1q*Wig{UeeW zWmGb1MU3RD({NsE9ir&AF87t4_jhxhdZN%!-t5+`TeEY!K~huFprx0lL@ysqmqL|D zsjmh^LUp^{{YhS)H8GgBSx&lTKU+xt6Uied5{AY?w4@Gzl>mM=Lh?q~zV0M>ZodF( zl!{o9i#kElXG2-C71D+%`XQ1lLW+7~BjFXP>v?0&Yz_*b0Ne}U^&}4)bntO%!Wrgv zyWI|e-y!+mu|(RZLjwRFOlkAU`n0_eguRL6BLgk~DG$CeLen7{HdbFy47>n5Gqsct z)W$p?Ch6WBK+e~c&4Q;NNWP=!i!TumTjquz%_-wi7%-{^wD_l!NIn{U&w%gIG@dtK zQSpM6BvW7LQZsv(nK8HLg{$Zl+8)bk61Oq#G|i>RQKwo0^QLU}6?eV8l(%lh-dK0P zHlJ~iWk5RM@k!D=e13rKxP!yZwl}MmjlTz(*)NZSv~r*6IQH4y&oZ-v^PU0|HoN=Q zd=*-(IcH|&&z#(&86as*l&m13?(X+WdZ(FvKTe;AY18Q;nboS>?M}xJh6oM6*6ntu zyWMUz%xRW)9VLSQK+=Wo{{5g~`EU6Ex9!mkAZeXWXS11I?C#xcZX`WmW*;=OUvl@q zHnR-zGls@CqH@t$~rPp;y>m^-KRTU;8GfJ`|`E-(RP6d@?B;|uwBtO#DAO+x(lK5M;Y^fz( z1>lh|AIz4bd;l?Dr_@OvaLB6&OjpXh>3oT8NU zf;26oP`|wgz~M79Gx09Fr;@y9P#a-^q{^-^DhXH(<~#=+YvUV zS%4`?O+I3`B}NQy_NxE z`jQ^ZjGu0iC*f`O7*!8>6&JR)GGKSEY68qtet2mJ-13#hUkKM{=04FJ?0q2wQ2Fc9 zwuIikH5wzPNS;sfMv~viJ)M0m zdxLg_E6{9#FX`ULfMIBA(r|mVH%R{uS0Ke9>wOGZ9O=I_qoRO%F5L%P78f0@N|(>x h3t-irh<5s|{|A&CJWk%Foc90#002ovPDHLkV1o3jf*t?> literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_storm.png b/Android/WeatherInformation/app/src/main/res/drawable-xhdpi/weather_storm.png new file mode 100644 index 0000000000000000000000000000000000000000..7539dee7925d49054794f2e99af40e14316216e1 GIT binary patch literal 3396 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_map.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_map.png new file mode 100644 index 0000000000000000000000000000000000000000..ed72ce91c8788fad8b1a8ade10783d10b60f3ae7 GIT binary patch literal 1529 zcmVE2apfI zxBtjKWKRxY_JO_49Iab zo&hT*5C{YUfj}S-2m}JbCE?0;=llD6pl?PJ9#$k*S69cP1U&1TiNuT*u_j=Vz4Kb) z(k_GmAwUQaw1}HBRa_rO30Wabd=PN7RdIn;MgEZ#BsD-F1PrVQ_bm@oD`kp;7~n9m z(=~19IG3J#(vK%XK>5H^(7z)1d5SK{1bku~L|&+mtq@Q=@H2h$ppS6@IsH=~xB8qX z1l)Gc9Aq9$vT_jV8S~aS0s2kOF=7t3Zl9;rLe~t_6ru0iI7WPI(d2agW5LUfajhbt zYn3M8x@ItF#4R!MUMLXyxbw`x2G=ul`r2X=SMV*JHji~x&@A&ejlx$D<74y(#)v)> zjhV1A3DNf*^z$c{;yVl#gq-Wjw-3mlPt0j)mPrrFAmL44GfMM(U)D5kDh8iM-w(&b zRJ86f@+d7i*(j+C%Bh`2}LtOd&Jc+H(T3&aWM2W_u!_9&nnMR){dlc?$&2kM;LX#yf+ zbY_V-)(rgCk!E6CH%48u`GF%IPmjk>oN})SNMPGTkG&I{TaD4riB0Vf>3M!{S>i$F zbSNo^3gWT>2OJqa8oK6->zWxtY%cm~2sMC$u*mzc%yr~!v@pU`pJ7cg*_mi`Mt`V| zZ8*EB7?8IreGi5ryma(t(suJ4&r4HO>XE)d0v$OFM=%`7VHXXkoB7$K{k z5ul75pX8WJTT8{2ilVBL{F1k&OcBt;aMqNXzERW9an9Zm{HIoCK-TPdD#~7!78P54 z{D+kE*}{6n8T{Hl01h+lt&mI{!2})98;Y3-@TIl_tSO{vZVQ#KkbSmbb+BPokw-IS|uQw61q^m7ldT_+dsATia@2{=!6+A_kqfeWc4 zs&Hz=xMQO?1f;d$7xMWg|AS+5Q?hR7gEZp9$b9TDOd8=vdrl&(8>O z?cj@hOF#()QM-R$P+q#y;mOjr_%LKmZ8GyU1Ma&Jd;@z&>iMVRi7oG;Y6)BfOga>N zg;9RY1b@+1$1@K%4G_?D@ITa$PK#s|=brpVcL;!v9_Of?R$9GCH9OUDaHOEXk#84m z_Su^PHX|&%L_iw+_yU4YpZ!_Y*uBS51F{=fJ6Y^J1fS~OM%CQF%e^SSyO7}1LK4ej z64!Uc&WdN?fv08EN5!~BhNA}jHk8NPKm$L*sQ;yy_a||*qbcZXBQFju@Z@1$k#g9- zu)$ITNN(ykdQijr#r2Ky{8cBmA`Ih`3~2NRs)6sB$*(55G3|>J7Ier53<(Dzphdt? zdN-Alf_jvK0{jk}pd|uEO8&8rq#z+cAOr{j0zSEGyHoy^p%)~VuvjG!2m}IwKp+qZ f1Oh=m{t7SvM#&ydtJi}g00000NkvXXu0mjfVK&0o literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_place.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_place.png new file mode 100644 index 0000000000000000000000000000000000000000..25623c77978465aeb0d75674a88bd721f2aa3bbb GIT binary patch literal 958 zcmV;v13~ES_G;v+i=t>LfM4KUz!&!V z*z+xFd+n?c2MW+V@GHsqA#je^A_`G}1%4`lUygJO=ZG&zrKtc4{@ng~l=?mnr8BZyFB731A1k z9I(yw;YK>Id`ggXJYSWw|0Q>}6g}tSfE8Hq9iOsrfYjR`o^MmhqNW#6`(Ez^CmjyOa{8&j>F--|T9;OpdbK*>`pOo&vn4PcZw=1GAI`m<7<# z1U)Z)7g&Jf5T!`6yf&}*f`;f|nv?|?>ah?P=q31P#4ACvm^vC<+R)DqX-vX3umHgy z+?wPt$PWBWUI1(HI&`Oj>`tw9Km{25O5>45Edln-enkP~(4+wh{!vP!$;APV9gqNO zj+`i49%VAFvJ*fiJcP-((s&>X!2u{`NVOqQ6+kji(*+0ZuPse7&p>qtstX_)sF8(g zttXlT9Azf=#1ufm1upyd6hN;RFHr`K_B~;jm9qfZzd#u?+EWo_PT3FVfB-Il%6>!# zI5xRtKcoO7c0@3p54r=!%G45ZppXKL-~!0(M|Qx_8M{FpB&-19f*}@X2jpMOLVr5C z1anee0t|3oP$OqQOa6&S%Gc4o-IH!H+_Kb1+S}r>a}@+8>nw z;)1ec_O}#ZSP}MDF3#MdtBhq_F?~tz+Lm$~(}1E9;EKiB0pXxMWe1#H(58_6Q3@cf z7;2`~@+6JvxBLI@#*5JCtc ggb+gd@LPZZ00z4O$j^F$r~m)}07*qoM6N<$f)f{~B>(^b literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_refresh.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..44ee117ee91541ed71f27685dde0b03b51b89f7f GIT binary patch literal 1239 zcmV;|1StE7P) z5dr`J0000000000003wMK0iOlU?Cj&OWC$yA{_Z2)WC*+^3#HR9|H6uA>~fK3{<1{ zx9TJMcVE5FWjmGLALzB$>t!`#{^HAzC-VQuuTB6-#z?*lWgC?UZweA&FWb8$^H76) z!mN&nQ463fJ(caDWZAAk*8D0--5QX89Reugr;2!Apm6o7yyK}t@QoB;(@6m&@zm+L zXX5LERe&ULj9)N@8dqSwza)^=FVx@~0|uQDK$1_LS#ozOCiFa$|7_vXxk@E}=lGX$ zb9tSisuhN+*`}~Zd988O0$7lrt4w7tNjO<#STx9wn~EW?eIKm=4av_`_K`WdhrYUp zLE8jKT1Gxu{Fb+Mkv?Z6e-TR| zcH_A714GMutBO%J^{XIKHqUZ+Pi82)Wa2B=Cc9ad>)`Hx-zc06bN9JrtLsAQx;^H{e0&r zy5Iq3)}MiVUIBD7p2&PcdjM$mQwLna5j08F}_ENY*|b4D(*pbw1z z_Z=a7T`}HKqA_b@2$k5EUi_T?zSj zn$Hix1h^9DLeL2U@IqJZH;w{5aBE-d2#eWXcz~Y#k!}FCneBxDdguhOnrwss)z(i1 zm~Nrj9s=+oHTVuZfYJJO0_<#`_CbKlpoM0-IUwuvgph`ww|<&_elf^?tanc)9y;^2 zh#6E^R$o+ahWO`r8jf|QD)cN3zUpM5nU7tPZ^Hd_E>)g0ru_v=gUrX--eDhOfa}S+ z6C?SlFx%g-balESWzp8qF%rjSyd#J{w&Cwng{~| z2mtZ}3D5`m;YApM1poj50000000000fS~v#zyO={=$CR|bEp6S002ovPDHLkV1lVS BMRNcE literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_search.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/ic_action_search.png new file mode 100644 index 0000000000000000000000000000000000000000..a10863887e448e59e0eb34d7d08eb5f273498628 GIT binary patch literal 1152 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 literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/thermometer.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/thermometer.png new file mode 100644 index 0000000000000000000000000000000000000000..37b3747f5011bf3f45c07867054a6995f6362015 GIT binary patch literal 3272 zcmds4i#OB%|9_8J?q-EdWo#5picukE#x7DRG5Y8thTP3vv=oxaCU=XpC_2=oHSe-0021>5r0~Q zX@6Z3B8p#ZJ~fH};$}<0i%?`6R{U!skP0L^(*Qtb`(FnEx%oRq$!#GdJL_!|U>MXu zDSUJ5g(#&OVoeFL3h?vu@DBm3f;}#Uc(^0Ny+gbZ1d`n;r|a@603dsigtv5v7+qlb zRqQ^il<=`(;rQ6Cc{|YlLc~rPVtgFpcCMtC*BzZA4VdNe%jFiY3hlubKQt`!u-nr$ z-`v%;Ye^%Lux?w@X}655u`hIQ0uSPJ)RheRN?x9$n?Em4x6VGLJ&WoYkESlVT#Fiu z?#Y?$dNLF>WE#CBPWfvNJDizaKaR352g;w7@RY!7%mabLwdxeH_5z!pm}jL!VLfOP zKAK96fQhXcZ?yI()6uepeM*^4yb_*5f%Tz)!9FBIsE2qiuLGa;Oy86=17BS6Rm^!J zU-&6u@ir@(qxs@l!&!WCw~g0Y26wjUfp2WOkLGAA@YU+ay+3AhZI3|jxHTEkh67>$ zsA5x;`jrRcQ);7K_IWFAs}3fLMQ8;3SApDvK!OXh+CgAo3A~)0G~>KSOk1A4W37Xt zU6eP@NP#qQ+6)vw2vdEBkN0)%!yx-wMIAbc??AB!5;vMb4liqraI}*#yM{2QwnxGl zkWXmf6;N~VubP#ik+ZkFvKhnksTEh2yNJFK1Y_UggUCK|c033}88JZi0r0YS*$gj0 zu6y7XCQUV|_&Qn^AtUa!D zy%#+?@8HF~N={$4DFR_ICz1VFDk>N9e^P^b|364AO0?ex18d6`!U@W)ihw-ph5ynx znsh>pjwZ<#n&9DL{isN*T-3G9TGy7i^I8>}NPFM}lxrk2RmE6`^k#eJ2^h~I!UN1D zah>`MmNy3G{L7N`n5wbQmZ=6H{D{U^c3>GaV!H4!ljCM@Nzn|Twi3}47`?Lwx|rG= z0LIhc_hM27xQJX~aF}uf6HL^1iqO>$&#>Nj8naJkN|hNvPOk6c-Kqmc~%j5;7 znoCtBxZYw7MDSt+aSk*;cY1bOG9sDnNuiZ{oe-alG^8(lK#^9GKU%FaXew+{T$rV) zwBl~lL^K#bQI%OM+43)Q_<`V8AnW+)k zvLe3pPc#X7G@Qkz0rT_BnaoETigt#cTBGY0?azEG^I|Q3G&@e2I zcejS0*YXQT@hL-n(r}i{`|8kfWe7*rKtq(H>n6?fa#28aElmmduYTr`!?Bc87FR7_UHO9*Jg*=TAC}&Ztd#s z&l4y(<5%m^H|GXWIp+p*2@}ZGSQ&a9OZPteeQ2cr8@R{)rYBNUL4Ym!{3=m6USmFS z?HSvYvXH9>iZBTFCn;=w-zoTaZ1DzgFqosfUTmyd(zww^ayea`2dbFYHb;I*O9(tf zHzhhAdz;LhV8kyUw;j<Wjf{i0NN(|;UKzv(Qgg5`Pe z4D?CFD4$%^-4IoNKO&IZneL*-ylh*9e<%6ox2gk= zWW1T{!Pe$^vZgU+0CF;!T5qNulC+to?sUF0QZVhPTu^d=sFE zNrzgq2cCBIZRM2^+yMjqSwi%kXnYT71DQM8omx@_>6khag_xn%UoDkQ%Zwx?=0VCD zlXV7;cr){dt;Mx~wN%@!(*k6c+v2yRd#OG{SOdCEyTVhI7EV1H#oW(#FJ-+h89E{h zFb{{)eVRuNwUUOP>Op#EM%Sc-Prk1?J?hV@fezcB0}gx3)=CH#7_>h=f7UUiX)#Ji z>GEU8RvR5ma{;hSCK)>e-jO5!6uQAiz8yH2``rHYf|GE z`yS{Oj-rX{T_sVO(4*^hgOQecpEgQ$?xI(N8xEAe;BB~oc0@maW_2z$Dih@to^#_W zhwVhYS#Z@VUg=R_;_^|qukxDldqyYx&I%}@FGFvmZ*FR_`i!?MnQN~m^pB^zcl3Y8 zkg%)Afpf)2HvwTcgO;@zZmvOZaU+e9dUPT`(irOm7b&%%9p$>Qt)<3#qyz1^2!plQ zj$OiG(ffYTpY;`v@x9;%3RwT!`TUTM4PnmburO|(^?ld8X^7Ds49Vem-^Cv~TZ-8ovo8C9|drQx9 zt4>KcVtM5irkzZ%rV6wX)KaEMW%)53MeAZAu*VZLjK*rI*-Ev1M1IN4m_0IpMGoS` zQmwQ^MEg zs2OljV-^`2_qZN--J=oauRu52cg=xeh5v0LGgUV9tFRQOj4DXUKc{L+AUctwpe<{A zOg29Pzok|Qfb#2!0^DSee3V`fQ`m+$%r%=kxo0N1dfoJEJ>gX4`WM^(>|ldwO=X10 zNaNteY{9BgS?Cv*dAWz`_c*aPRvmB-j%zQBucoQZMJQZpCb-S-a$99s8$JhhHgVU8laS`Fn7&0i~RR~8lbMCv;8Vh?H5o2h}%#yrX z)_R7Al9`GmU66o=D%tlRt6pCcTq%x*pJ{cmbgh%S?H*dm$2+lR**N;=P5xy zCyN`kFq3`->843j;HK;N0Zu6L`J#6)96vv9#aIUi9;NG9EB9Vc<+?pRv?-y`LM4}L zewnt4DoPsS&0d&&dcnIBM{$(=@DSMbA#rlSuzTivsE<%ym}gU&oIhqp{wM(8&leZQ zz#L0Xw3gxpK`cJyBh~7t|Ww~_8lGNCDVIqVS5?)cpSaJuYYip#2 zGSkY~jis#3?Nei9i|pdlcmMg$^PKa0p0oUS&Ut>n42Lr~xQLtx003|hZ|Ss;xxZXU zU_WxKKR@3Gfs3{{%YEFpO^eo~eGm@EyG89!eE8)sb7XPceo`e_h#Q;tJbTM?_{iQhPBv&O6YYM(2z%wPMrf*ciQM26AqxQ1_A)os;Z4Vt(`mZB`FK9O+kQ8;ypE( z9>RF$kgf{a%nACF2V;90p+44a5kwRA1r$5FJ(yz!CD#!n-SOHc_NFL-C_J3_-zVGB%)_e|LfliyLl;5SX<(EVL7AdQ1w2b_n z$*lUJuKh~ct%m%j{LP{Fr$ETlKJO|d zmP=+XokMUC^GY#Gb3G%y9%h->7FpTr>vjuCST5)TY?$v_!?FlyM z9*qFw>h}|dc5R{vg>E-4Zf`12DC@Pdu~Tll;7xNpsOZ5A_6&$lOdgbwp}j(RrnS3? z>nmWkMMUkorphvxW`s*0L02X;ZmsEGxe#xg;z#sPcpk7>q4u1=wEd<__RR67m-h1P zM1BNhq7vMOC^wNROiA02@ehvzLJtm=0z2}ItEepby26cdSOdUraljP*$cPH{od=*M zFV<-8V;0mxXzuNn*;WwsuKk3FC5;;IEuvBJt=2#-EL@aNGw^Ttf`F%zjd%$lz4#u#BcDdx@uC)iBjYdeL zH%x&J^B+2CY29h7571|I?N78ivmyC+AYHC=IN;i==RInu@cycedWRkVZ`DA z%#mWv^wx2(G&lOe>#21IR(RfYnd-Gxo2%xmD#p*2ddEkSP>vtfMOwhXQQ++^+Gg2* zvfRxl7zf@VY&7m7@cVl8gw1_rTJ?m&#%UNamcE5YLwO47*GD)$!M>eAlm) zq=!JZ^r{$QzMHK1-iKd;Nkf1J1>&WRDoVEcef>w%3*7#kf4Zh$`a!+Jh^gZe{giZR zq|L$O9`2T|>8ChFQv|p?<50y06W+^Z zU1)D0gg;y}tnj0{eEn}IPR@cYISQnsda}#l5Z!=U&7*B{ z5T3a6=OX`7sDzKao_?fXU|_Q@8#Z=D<^fS$VdX$u_JY6j3ivG6xJ0Z!R1(N<8b-%z z@*wG>W5EO}bV>X4?(1{LvdQO5qLgsJYVQh#9q@BN;~aw}2TYE2>5yi5(VPo}_LpBX za@|hO6TMqax`j4s+j-K|Hw0LIxA7OSkP(N3SG0n6M%<2i%O}5> z#$*(hMY_9)_RKMjqb#0sPlMwy@-11R&$z^P^mU zS9o>E^^{?*2fYS1-KC$H9>=sjP3GPy3JJ52YF0lJ`)P*rcuY`b(*@Xj=frb@)WC2J z1|{Hy^`c0+cgxH*3BsD^-fcEFUw27(%tLB=|6CL*JG1qP>ru8>{qbVvvZQNkh$P6c z{E_h@#3n~6qk{-^9e-9gdR>$0#_>3-{Z*`H$Ln_6)-0YE+ZQqbLKHt-VQK8%c_XM5 z7HqwFe%m0QJQHn9ocbhFOf8(wc<19cFI>`b|B+gsOsi#X zPL%>HyJ=Cq3Wd>fUt~t?SOJ`g6=Eg}@lvV!`Qi`v`ok@gC&^KL_ex^v^@~kW3k@r0 zK7>GuTDPq868h1x^573mjK5 zQ6GV?z0~|JPvji81cOf0c)N(;3)R!a6mGy5e0xg-!&OqMb!L7;ZCfb#?38oQMYL>7 zwpp+iUGFvE4J-5%M7}; z<3Li;JKidupt6ypr@oN$`)t}N7iH&H?r?%k^m3IpVnFqamfj^YhY!=A#LSOnJw>L< zz3I&-tPv)(TDnyF8;%ExB3(uz8wW^b*egB0Ic3gmoswJOZ1W z94(iRqgv6%L+7H&ImM&v#b0mhceZW&ejxa!Z`rVVTul%~mhuT9;(qkWr2k9=VETjVoG^7G#> z>*}o3mOwH)vFYCh%A5L>)WIhji_cN!damM>K`WxixuIwZo5G@>c1_7R!_s>5C=LlZ zBjCsw20ybA!kDt6m+buF&zsA&cll$WVpWCKOr3tCT8ri96u2r8Bp0WsRTu3_v3E&01&yoz^kltb{M6(n zqroI@Osjm&hB9Qp-!{6`s8&>0#0X3@U4`@f2ytSmBU-x@QcThBprHaiT%>MpGKsRu zaM$nfnRbncWLUL| z(;HtCN5W1mR>Va0j+g=*L!o76iiY6@}zC zz3XoFW+J?f6~{|5ZUSD0)Ew24$lelj4E;eg*2vtOqTdb1B z#9>F&{nFXSWqRzxN-I_(6jfw}0ZGS*-l-ME87XHp@)4uMQa#`@uC#hoq@5OhekibU z^c%HH@k-dL&4K5L9#^3(KWfNu$N1c*{KP94hK-Z#msQm?r|X;!{Wd_DYTn}GP4dIJ zC?em!UTlCYTA3B%)__$ekSPTla=O_zk6V5!hdoxaGnNRs>-qdE7yeHcSOL;hEIi;i zk3are`M;vTGVoC4jY|l>E=7m_yODSB`i@oQ!Oti+csAUWX0Q+D_4)tz+nL>GW@mP0cV_3A-6zJx=m7&AHyr=~3~-pX*%c=L&uOTxB1w0# zkYHC_o1#dTXmHIW zZdBWb@wSLaK0INS-A*=OJn^}3 zs+QaLD>^3aREpNd70)*IH-Bw3GMSj_uvuFCKY|?1bcVbW{03+PaLT(>q(K9``K8%3 z-9i9kw-?Y(xo{tTmo#@H9bkAOL`$+iKYI$DH6pqZHUI!6MT?-4k}K}%s+ahAp$X3< z58~~9MzS}4WBFO#n?)2Fw|ol|a%fZ%3&F&rQm`-JNw6H7L9@_nBi7(*0|R?yA`gaL zU#U8${%@VzyOeYHewr~^P2up%daQf>T2%!Fn+_4iuj_lLeDHM#+p^u9nkUpxTx*dn zA?Ny9&`KS$?Up;}pMTXP4RDm3Ee@h9uS}%eDFl#nn!pho+&s^(YPO@a#*k7(w=fJg zf6XZ(>4%3HjvSo{{-NWG1rzd>n>CB_D%YK%%2M9#i0>z~K>RX9SxKp;ib6EE8Vc%u zm0O=bc1IPmS~}FKW-0z5@!Q@fKQT0kHiS`81QJN0lTB%sz47DWY}Ajqdj|5$~_+ox5Lq;`ZJ?l0j1~=VFoSkCy1mJ z72miUH{rT_bikw9FM{nF2hBSLJoZ4X6@(Y&zfw z)KPT{K|{Z)u_}_-%N$k6)T6O|1jZD(A;LRg1(0qn(*B6(39QWydyQ36Qj))&=Wt(p zm3>zM-$9a9i!C7^Bb%ppE}J=Sz`g-brEKtjJ7B>~O|CE1mA3kkdZ_j*1^e2ZB8wp~ zUyS{2%~YK%m=gSE@C%{V1lOe8<%wL%z2x?ib4plBp1yCb5CuXywnS9Seo6SBUH@Cw za=63&xrs>~R~gBa=$Bmm%&RfHdP{THc4#n}3?LRhS^GC`AzaS}P^J1rhR<&mrcyV= zOtX48-gH}iiQRWJvSFXogXY>J&r2<9#|b@T$ExTs{T+g1;822CJWwDil$BwU@F-x&ft^MMl0996X;Nss0g6wT3oCltxc&JOcu47VA8iC5 zuvH!6O-fj1Lm;1N{MQ#Wu+*`ck(OZ(*9oy-pQ>?CE`e*r{8+bT)lt?zHCh`NxAV^w zUbVyY93CD9;8^5u22=DiP?ng4(i%H2WU_LOtO&aMcsIa*b*8y!%ZlH7$^~yzxHwMG$bEocOjA-=Rc{ZSn3!0AkcYzOK?@@)XBHBOQ{ih8b2@uV zA8j`$L|%vAL1&J3O(7_s##iV2tw+!C9rA@pA3WRbYrL1Fw6eZF+mb&57Ah!k+9RU> z8@#-EQlRogkQR;)wX}O}vs2ZieiPoSXKSKfspVyCJX|p}G$fjI#-%fAK$`P>RWx9B zu-#4Gt$k2Fb}>yr8X7Fn0cTO1nZ}^&=+wcD8IeUDDKbtQ^yaA~$$l!imqo>`S?9}}?s$>oIX=wrMmZ_B{Tc^@+n4PlgqnmZ7glDLzhUpQrzJ2$!_FKhu(M4} z4ZWv<{u(#NKp!4W85N9a7faeT+WW-&mYKX80yh#0zS+Oe^5ouV(sMnfZgUHlAI+hU z`B`@;D>b1PVP%kIeOo@;5LhCixa~sGyS^Mdb->-93C=gz3sRdm2j?$W6?L$g)xiqV zDP!8(=05@vogE(JAt6q`V!)f2MkZ@ER+n6zhEo1TVfLh3!FkwDfU;)sNQzJ&EQh)eY&Y#N6;OXc+7@Xoxl~cslbC`yN{#!Mrjd z`Un^g+{fE*Xn$LBS=~VEiXs1f7g%XdgJC?q`{4z zowW=CiW(amr+D7g-;~q(16hm_jnxy&dVyd@2MFfG=D%|yb3vR@aDxH+7>h40@V7aKALxbrU0?CAlKK+@G z?b7G&Rh;-97a^x3F>us4v>ZxSy-~)E2sm5ROz#9pT88q_5|A+x*vZTOF*-Yo@5na& zclfGvQ(uVmd-oC9;6&b?YpPYiKf|~8gL8q;DKER4uT8%ju8zI^xumr8$;St+%m}1> ze{k^V3?YM>+siA1WZx5!$T$iC6r8inSar@6Rt;#>J<*qVX-5+T6|@S($yPWo-Ixj< z?2FO7b^Xt~(yip%WjGo)Rvq(M!@(5Z^!x8qpg~IEXyor(ePf46)qZ~yUrYW_81aGD zCLvn8$iz=(MaGsi7uIQIH1r&AIen_0{0bske`5e^tVjtcfgLIZ_!1J|`g~)v~g?`IHFu znShPM(WT|ZR_^XsaE-(FQd5C}flS6rro_==OrLMX0BJEqok8RXfpUELB+^Pq=J_k^ zEY*z?@V7E%DW4#pR%5a!*Vdf24U1Z;o~K=IGhsXN*7?S!#6&K?j-+P_Z1SvB{rsk^ z3GUt4br3IKVKHj<&)n1GL<(thV&#_(&VVIVOt{#p5%f%3^KBrsaZFg1+Nn~(yP9(O z2iEDZ!nCvvP)WSdtKKcv$eKP?DwGA15UY{dt+JL6*|qOgdQj~B3~k|ePF7JR>4n&s zc^1*Jx*u>CacWjUUKrQ9mFt+wO{?uI^)ta{s!VOE`cHuN6~qwUV7#hJ`J zPdl(9%^4w@ic=Pb@|8Ide{TU^r*&W5J)<=1t%ilv@f63Lzyaj|Z@T}>?xL9@NyYwc za7nF~o>IFbOwd$p1BR&*RwW&cN*X^p%<>7mv_}b*W;Cie6pz9LIPG(aFWo5U<2%)` z$Hw%dGCzCH>B;0I!wZ%*274;No;rKH7*sA~vg|^L#Bi>u4r-*1>iBw--%@ z_cWnr2$H-g`wux2RteeP=mi_O4S`RB+UOtI)82jVowi(09Ynwd(#Vew_`rBcz zqHfB3D`4yyfhp+R=`o5lM-R9$EgPMl7wv-#_9JSKKrLMb&$kP^aMMP;VLN?yxw$2(U8;A(@A#OEVP*soaDkgVl13c(M*Z)wG%Kt7=zCk6W!q9 zQOj=NFe@U?sz-oh+(JC1g>j6~ID zeF0HBfqOhkFuC-M>w;N2cGwYV4`1gle-&p656?!{O<>^jbn&)#!9eyf{91*?rS%H8TEa&Db01tdO;!!w`$0w`6hyh@fEeWrddhi^6mZCz4 z2Kn|6J868TFn+-hA0i-09uc+Cz=kpe`x$(ZSZ#vePg8G*qcRzToXD6F^Ix?dkngM# z{55vt&yTfxf;oA<^Gj4;x3bq#9G{O$+iim+p-FD)`I2zRRPF|NjOS%9+;&}n2iK>* z*7m9&Q(#Q9`Wcfbcw%LRFK=#Eh?8g&suMZZ$R@*~o}w(x5ZnEa1WbnCZlz1@%U{<6 zQ&#iuozUP;_Fc>>=Z#K-1!OCP+dnP0gn<90qqe{5Y8v~(6L*K{2&ngjYozm=j&v$$ z18YYSs|A}F+Mv|sUzjE?1HRMsvPG{8A=jT@H2o3Iz5gba!tTW_yI*|i<3=qliu80e zPb)zUj`wXWN}2MuY|*{eTj`nM($Q?!?+t{l)}VYMu;f&6zp$FjyB=!bRXm0f5)A5h zrS)IGvf1MDa>&VMzAztTH8K8ZKy9MWFRo-|@dGj)_2La(i@&vN=J>86)Qi228}U0{ zKfh3R4F&Uk780#`mv&aq7NgmHK=p?Oj(>0T^~Az7>PY{zBnhIrg>p2KJHlZh;2$EZ z^=UJwg22Jyp)2?8{whuGq42z6rwZ7=<^win?R7%L>tuiIu)V>fsjxz971$7i^UDwX zd26-jUh1eDR5C?QhDqFIVNA5cAuE&GCt z_zc{K`NWr#X(M;+xD<~FjDLHA(lirCZMuHF>4hPw|3IJ2RK?zY zG@WNd1zNFQQT1a4HIS8Gz+0$-G%jG23vGZAACl&d;P;sp_<`*xDb-u6;PrBahL@j9 zKR<-7%QiAcoOobFoJ7Tbb*MZ9=sZ6#RcuU|ed;xBO7Rb<>_9QRk)FXh_eH}T7i;G~ zl#9Pe!6HdE8 zLi}Y%mkU?>4KV~2v^O^gYFAs${%8DjP_a20>j+i8@$c>xBZ!sl`Ya~&#tKW2@92=` zw8Fx|Dkh#~b3|q*Q0~Z{uHUu=wf~q=Z06t8q};MdU5>iP+%-D7qM?%IXBN@x&)Xms zR=WxWW;bY1*z?PT=U?x(4?9#7ao5tQki_&><%|CkS(Fv0c_HlnZ|39k+%|iK$K#3M zR_cEJf7+yZ39p;?ehMi{GDgWOYs}BCNeVekHn)l|&)GR?%*+xB)X{6#53R}-w7b^w z@OQMY_-1n>Z`PXl7lACn8bOsklBf8AIwRuCLR~x|skMx9rS@*iCxVegB+4iE$B!R& z3A~C8cuy~SlS{>el2sAP_BA{gE;-FEU*202nT~5&ptuWHBHuKi4PAQAviC;VT_s8p zo-t2QO8HPuK6$FpAAtGuz|`MK zHL#6~Lq$;g(cWS3WF_{KIm3#bYjI6FSf$<#sepbZr<7Vt{(&-1HcB_GktQ#>}i92oR?rrcY< z78JsBDaGC?zyEac&8{c#DD_K&Cb!jJiWAx^$!4l}Nf z-}Hh$)mY3G(O6_YxX|1Tz&a1sGYbwPU^Ss?4P2U_NJ>JZaWoc_}1kg zT|@&E#f?@3I+L%zLkgJB^#)+V85i7!TB&EeUm@fC0*vF5deU-%?At&7GGO9_^Q{IS zhF%*pfG3Iifb>nv5j?z#7^#;NhQ5ORrB&Hn;gNDP)-A_r*q`r`V<=rzdvNMRQ*a=E zh4aN9O}jjzup)CeBSPMYcn_dH`Nkc5T?m8gBjjO!0zm_WEpn6Rhgp9AA8FfS6!GAa ZNj9mcN{NxQ>x_jiyuN{{a94l12ak literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_few_clouds.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_few_clouds.png new file mode 100644 index 0000000000000000000000000000000000000000..2d38702db544e375449ee7336ba2cca3eeece286 GIT binary patch literal 3949 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 NL8OWP#~V(M{|}a)0~!DT literal 0 HcmV?d00001 diff --git a/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_fog.png b/Android/WeatherInformation/app/src/main/res/drawable-xxhdpi/weather_fog.png new file mode 100644 index 0000000000000000000000000000000000000000..1bebc5460a333ba423b7319c3faa93db14355dd4 GIT binary patch literal 3554 zcmY*c2T&8;+D_;o%>pV#L=q4Jwt#|&N+&c65K5#&BqlWJNRz5aT?iNmV2OxAG!O|* zl%_}wEr^67M3g3h50N5j{QlMX@65eBbIv=v?>TRIo@e&#-aKz_DJ7vG0f9iIP*!Fa zL7Vqyh>3vnoW*n_XheK$EX_a*UR$OuiJ%b=v2qOqcZ~cQP?LkD(cnYTaFm_7=%mn2 z0U-mts;oBX3r3k4J4TN!mBm;2JMDd45mkmfe%~R>!1{Pj33gUAwbI}1zKQ+D-J5p` zy(;Ckwv5xQ0`~9P1$$|!s&fYtU?;F}bG<5XqL|FO5GuWlj zuv2s8xve9UKUwh=iOV7XlwF&wpNwibG7Nxq2m7-r{v}j%Puc9aOz_Y z4P~(1mRvt&orV3tRNfjMP`Gob#}Ji}=BEgG(m0)Yl4q3lISR%P&C7?KKsBS;wXmov zHfeM&PZ#C6e=7{7sOKUBJTLs5k5tw#v%j21Y1*UvF5u|NF9eif<-R50><-u_Y->d* z5(|y6PK$3A?CH1pk`ufSz90^$u*Sxs*JE1=luNrYcg2aqgYp3W;<)C5G^#Z&_uO57 z%`(%g@SbG~zlX~FvGxMRyg4?DMd<+NW>dTs{FTkGy5HO03VeR6b;$aMO3zLQKO3Of zy5ums*fkND(8fg+q|CL}BAx1jG!3F74=Zp}>MAMq@R6Ki;zX`%FrHk9!HM1Gx*9Vh);r#b3^~fv=5zEm0UFLWUa*S>Xqn7Co^hyFR z{IMt089TA+$npKSTv?Nk7U%Tbd{Qc)v|w{r`@zYIblE-<_up2PHVX)~%lJjF{kXzR zg%B-)oRr%hNujJ4NarO-MzRRF*?y+LL4^>tBxH36GpX-1JT*iSC8=mU+HZAQm}}}} zpk93RgpHfB$@eKCK{KaKjih20p&{)@-I}Jhe9YzH0SMlvvh%9zLuuzC=*0RlusDs36i=1