From 07349a887eae3bd2e544e71713dd4f66bf8167e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=96=87=E6=9D=B0?= <71892154+18948589010@users.noreply.github.com> Date: Wed, 13 Oct 2021 00:19:48 +0800 Subject: [PATCH] =?UTF-8?q?C/S=E8=BD=AF=E4=BB=B6=E4=BD=93=E7=B3=BB?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/AndroidManifest.xml | 54 +++ .../com/dommy/qrcode/util/BitmapUtil.java | 115 +++++ main/java/com/dommy/qrcode/util/Constant.java | 13 + main/java/com/dommy/qrcode/util/UriUtil.java | 95 +++++ .../zxing/activity/CaptureActivity.java | 385 +++++++++++++++++ .../zxing/camera/AutoFocusCallback.java | 48 +++ .../camera/CameraConfigurationManager.java | 278 ++++++++++++ .../geogle/zxing/camera/CameraManager.java | 398 ++++++++++++++++++ .../zxing/camera/FlashlightManager.java | 150 +++++++ .../camera/PlanarYUVLuminanceSource.java | 133 ++++++ .../geogle/zxing/camera/PreviewCallback.java | 59 +++ .../decoding/CaptureActivityHandler.java | 141 +++++++ .../zxing/decoding/DecodeFormatManager.java | 106 +++++ .../geogle/zxing/decoding/DecodeHandler.java | 116 +++++ .../geogle/zxing/decoding/DecodeThread.java | 87 ++++ .../geogle/zxing/decoding/FinishListener.java | 47 +++ .../zxing/decoding/InactivityTimer.java | 71 ++++ .../com/geogle/zxing/decoding/Intents.java | 190 +++++++++ .../zxing/decoding/RGBLuminanceSource.java | 104 +++++ .../zxing/encoding/EncodingHandler.java | 132 ++++++ .../view/ViewfinderResultPointCallback.java | 33 ++ .../com/geogle/zxing/view/ViewfinderView.java | 286 +++++++++++++ .../edu/hzuapps/androidlabs/MainActivity.java | 14 + .../androidlabs/watchtv/CollectFragment.java | 88 ++++ .../androidlabs/watchtv/HomeFragment.java | 108 +++++ .../androidlabs/watchtv/MovieActivity.java | 65 +++ .../androidlabs/watchtv/MyBaseAdapter.java | 56 +++ .../watchtv/MyFragmentAdapter.java | 31 ++ .../androidlabs/watchtv/MyVideoView.java | 32 ++ .../androidlabs/watchtv/SelectActivity.java | 35 ++ .../androidlabs/watchtv/UserFragment.java | 59 +++ .../androidlabs/watchtv/WatchTVActivity.java | 300 +++++++++++++ .../androidlabs/watchtv/room/Programs.java | 93 ++++ .../androidlabs/watchtv/room/ProgramsDao.java | 16 + .../watchtv/room/ProgramsDatabase.java | 24 ++ .../watchtv/room/manager/DBEngine.java | 49 +++ .../androidlabs/watchtv/until/ToolUtils.java | 13 + .../drawable-v24/ic_launcher_foreground.xml | 30 ++ main/res/drawable-v24/logo.jpg | Bin 0 -> 28498 bytes .../abc_ic_menu_moreoverflow_mtrl_alpha.png | Bin 0 -> 218 bytes main/res/drawable/account_select.xml | 6 + main/res/drawable/btn_back.png | Bin 0 -> 172375 bytes main/res/drawable/edit_background.xml | 14 + main/res/drawable/flash_off.png | Bin 0 -> 5785 bytes main/res/drawable/flash_on.png | Bin 0 -> 4825 bytes main/res/drawable/house_select.xml | 5 + .../ic_baseline_account_circle_24.xml | 10 + .../ic_baseline_account_circle_24_actvite.xml | 10 + .../drawable/ic_baseline_attach_money_24.xml | 10 + .../drawable/ic_baseline_chevron_left_24.xml | 10 + .../drawable/ic_baseline_chevron_right_24.xml | 10 + main/res/drawable/ic_baseline_email_24.xml | 10 + .../ic_baseline_format_list_bulleted_24.xml | 10 + main/res/drawable/ic_baseline_house_24.xml | 10 + .../drawable/ic_baseline_house_24_active.xml | 10 + main/res/drawable/ic_baseline_live_tv_24.xml | 10 + .../ic_baseline_local_fire_department_24.xml | 10 + .../drawable/ic_baseline_more_horiz_24.xml | 10 + .../ic_baseline_qr_code_scanner_24.xml | 10 + main/res/drawable/ic_baseline_search_24.xml | 10 + main/res/drawable/ic_baseline_settings_24.xml | 10 + main/res/drawable/ic_baseline_share_24.xml | 10 + main/res/drawable/ic_baseline_star_24.xml | 10 + .../drawable/ic_baseline_star_24_actvite.xml | 10 + main/res/drawable/ic_baseline_update_24.xml | 10 + main/res/drawable/ic_launcher_background.xml | 170 ++++++++ main/res/drawable/ic_switch_screen.xml | 4 + main/res/drawable/myphoto.jpg | Bin 0 -> 49018 bytes main/res/drawable/search_shape.xml | 15 + main/res/drawable/star_select.xml | 5 + main/res/drawable/thumbnail.xml | 4 + main/res/layout/activity_bottom.xml | 83 ++++ main/res/layout/activity_main.xml | 18 + main/res/layout/activity_mid.xml | 17 + main/res/layout/activity_movie.xml | 17 + main/res/layout/activity_relative_layout.xml | 33 ++ main/res/layout/activity_scanner.xml | 45 ++ main/res/layout/activity_select.xml | 32 ++ .../res/layout/activity_soft1914080902251.xml | 16 + main/res/layout/activity_top.xml | 38 ++ main/res/layout/activity_view_by_java.xml | 16 + main/res/layout/activity_watch_t_v.xml | 14 + main/res/layout/fragment_collect.xml | 13 + main/res/layout/fragment_home.xml | 54 +++ main/res/layout/fragment_user.xml | 218 ++++++++++ main/res/layout/list_item.xml | 14 + main/res/layout/list_item_tag.xml | 13 + main/res/layout/toolbar_scanner.xml | 45 ++ main/res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + main/res/raw/beep.ogg | Bin 0 -> 12237 bytes main/res/values-night/themes.xml | 16 + main/res/values/array.xml | 49 +++ main/res/values/attrs.xml | 23 + main/res/values/colors.xml | 23 + main/res/values/ids.xml | 28 ++ main/res/values/strings.xml | 10 + main/res/values/themes.xml | 16 + 98 files changed, 5328 insertions(+) create mode 100644 main/AndroidManifest.xml create mode 100644 main/java/com/dommy/qrcode/util/BitmapUtil.java create mode 100644 main/java/com/dommy/qrcode/util/Constant.java create mode 100644 main/java/com/dommy/qrcode/util/UriUtil.java create mode 100644 main/java/com/geogle/zxing/activity/CaptureActivity.java create mode 100644 main/java/com/geogle/zxing/camera/AutoFocusCallback.java create mode 100644 main/java/com/geogle/zxing/camera/CameraConfigurationManager.java create mode 100644 main/java/com/geogle/zxing/camera/CameraManager.java create mode 100644 main/java/com/geogle/zxing/camera/FlashlightManager.java create mode 100644 main/java/com/geogle/zxing/camera/PlanarYUVLuminanceSource.java create mode 100644 main/java/com/geogle/zxing/camera/PreviewCallback.java create mode 100644 main/java/com/geogle/zxing/decoding/CaptureActivityHandler.java create mode 100644 main/java/com/geogle/zxing/decoding/DecodeFormatManager.java create mode 100644 main/java/com/geogle/zxing/decoding/DecodeHandler.java create mode 100644 main/java/com/geogle/zxing/decoding/DecodeThread.java create mode 100644 main/java/com/geogle/zxing/decoding/FinishListener.java create mode 100644 main/java/com/geogle/zxing/decoding/InactivityTimer.java create mode 100644 main/java/com/geogle/zxing/decoding/Intents.java create mode 100644 main/java/com/geogle/zxing/decoding/RGBLuminanceSource.java create mode 100644 main/java/com/geogle/zxing/encoding/EncodingHandler.java create mode 100644 main/java/com/geogle/zxing/view/ViewfinderResultPointCallback.java create mode 100644 main/java/com/geogle/zxing/view/ViewfinderView.java create mode 100644 main/java/edu/hzuapps/androidlabs/MainActivity.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/CollectFragment.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/HomeFragment.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/MovieActivity.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/MyBaseAdapter.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/MyFragmentAdapter.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/MyVideoView.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/SelectActivity.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/UserFragment.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/WatchTVActivity.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/room/Programs.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/room/ProgramsDao.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/room/ProgramsDatabase.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/room/manager/DBEngine.java create mode 100644 main/java/edu/hzuapps/androidlabs/watchtv/until/ToolUtils.java create mode 100644 main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 main/res/drawable-v24/logo.jpg create mode 100644 main/res/drawable/abc_ic_menu_moreoverflow_mtrl_alpha.png create mode 100644 main/res/drawable/account_select.xml create mode 100644 main/res/drawable/btn_back.png create mode 100644 main/res/drawable/edit_background.xml create mode 100644 main/res/drawable/flash_off.png create mode 100644 main/res/drawable/flash_on.png create mode 100644 main/res/drawable/house_select.xml create mode 100644 main/res/drawable/ic_baseline_account_circle_24.xml create mode 100644 main/res/drawable/ic_baseline_account_circle_24_actvite.xml create mode 100644 main/res/drawable/ic_baseline_attach_money_24.xml create mode 100644 main/res/drawable/ic_baseline_chevron_left_24.xml create mode 100644 main/res/drawable/ic_baseline_chevron_right_24.xml create mode 100644 main/res/drawable/ic_baseline_email_24.xml create mode 100644 main/res/drawable/ic_baseline_format_list_bulleted_24.xml create mode 100644 main/res/drawable/ic_baseline_house_24.xml create mode 100644 main/res/drawable/ic_baseline_house_24_active.xml create mode 100644 main/res/drawable/ic_baseline_live_tv_24.xml create mode 100644 main/res/drawable/ic_baseline_local_fire_department_24.xml create mode 100644 main/res/drawable/ic_baseline_more_horiz_24.xml create mode 100644 main/res/drawable/ic_baseline_qr_code_scanner_24.xml create mode 100644 main/res/drawable/ic_baseline_search_24.xml create mode 100644 main/res/drawable/ic_baseline_settings_24.xml create mode 100644 main/res/drawable/ic_baseline_share_24.xml create mode 100644 main/res/drawable/ic_baseline_star_24.xml create mode 100644 main/res/drawable/ic_baseline_star_24_actvite.xml create mode 100644 main/res/drawable/ic_baseline_update_24.xml create mode 100644 main/res/drawable/ic_launcher_background.xml create mode 100644 main/res/drawable/ic_switch_screen.xml create mode 100644 main/res/drawable/myphoto.jpg create mode 100644 main/res/drawable/search_shape.xml create mode 100644 main/res/drawable/star_select.xml create mode 100644 main/res/drawable/thumbnail.xml create mode 100644 main/res/layout/activity_bottom.xml create mode 100644 main/res/layout/activity_main.xml create mode 100644 main/res/layout/activity_mid.xml create mode 100644 main/res/layout/activity_movie.xml create mode 100644 main/res/layout/activity_relative_layout.xml create mode 100644 main/res/layout/activity_scanner.xml create mode 100644 main/res/layout/activity_select.xml create mode 100644 main/res/layout/activity_soft1914080902251.xml create mode 100644 main/res/layout/activity_top.xml create mode 100644 main/res/layout/activity_view_by_java.xml create mode 100644 main/res/layout/activity_watch_t_v.xml create mode 100644 main/res/layout/fragment_collect.xml create mode 100644 main/res/layout/fragment_home.xml create mode 100644 main/res/layout/fragment_user.xml create mode 100644 main/res/layout/list_item.xml create mode 100644 main/res/layout/list_item_tag.xml create mode 100644 main/res/layout/toolbar_scanner.xml create mode 100644 main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 main/res/raw/beep.ogg create mode 100644 main/res/values-night/themes.xml create mode 100644 main/res/values/array.xml create mode 100644 main/res/values/attrs.xml create mode 100644 main/res/values/colors.xml create mode 100644 main/res/values/ids.xml create mode 100644 main/res/values/strings.xml create mode 100644 main/res/values/themes.xml diff --git a/main/AndroidManifest.xml b/main/AndroidManifest.xml new file mode 100644 index 0000000..3c81179 --- /dev/null +++ b/main/AndroidManifest.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/main/java/com/dommy/qrcode/util/BitmapUtil.java b/main/java/com/dommy/qrcode/util/BitmapUtil.java new file mode 100644 index 0000000..8adaa43 --- /dev/null +++ b/main/java/com/dommy/qrcode/util/BitmapUtil.java @@ -0,0 +1,115 @@ +package com.dommy.qrcode.util; + +import android.content.ContentResolver; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Bitmap util. + *

从Uri直接读取图片流,避免路径转换的适配问题

+ */ +public class BitmapUtil { + /** + * 读取一个缩放后的图片,限定图片大小,避免OOM + * + * @param uri 图片uri,支持“file://”、“content://” + * @param maxWidth 最大允许宽度 + * @param maxHeight 最大允许高度 + * @return 返回一个缩放后的Bitmap,失败则返回null + */ + public static Bitmap decodeUri(Context context, Uri uri, int maxWidth, int maxHeight) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; //只读取图片尺寸 + readBitmapScale(context, uri, options); + + //计算实际缩放比例 + int scale = 1; + for (int i = 0; i < Integer.MAX_VALUE; i++) { + if ((options.outWidth / scale > maxWidth && + options.outWidth / scale > maxWidth * 1.4) || + (options.outHeight / scale > maxHeight && + options.outHeight / scale > maxHeight * 1.4)) { + scale++; + } else { + break; + } + } + + options.inSampleSize = scale; + options.inJustDecodeBounds = false;//读取图片内容 + options.inPreferredConfig = Bitmap.Config.RGB_565; //根据情况进行修改 + Bitmap bitmap = null; + try { + bitmap = readBitmapData(context, uri, options); + } catch (Throwable e) { + e.printStackTrace(); + } + return bitmap; + } + + private static void readBitmapScale(Context context, Uri uri, BitmapFactory.Options options) { + if (uri == null) { + return; + } + String scheme = uri.getScheme(); + if (ContentResolver.SCHEME_CONTENT.equals(scheme) || + ContentResolver.SCHEME_FILE.equals(scheme)) { + InputStream stream = null; + try { + stream = context.getContentResolver().openInputStream(uri); + BitmapFactory.decodeStream(stream, null, options); + } catch (Exception e) { + Log.w("readBitmapScale", "Unable to open content: " + uri, e); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + Log.e("readBitmapScale", "Unable to close content: " + uri, e); + } + } + } + } else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) { + Log.e("readBitmapScale", "Unable to close content: " + uri); + } else { + Log.e("readBitmapScale", "Unable to close content: " + uri); + } + } + + private static Bitmap readBitmapData(Context context, Uri uri, BitmapFactory.Options options) { + if (uri == null) { + return null; + } + Bitmap bitmap = null; + String scheme = uri.getScheme(); + if (ContentResolver.SCHEME_CONTENT.equals(scheme) || + ContentResolver.SCHEME_FILE.equals(scheme)) { + InputStream stream = null; + try { + stream = context.getContentResolver().openInputStream(uri); + bitmap = BitmapFactory.decodeStream(stream, null, options); + } catch (Exception e) { + Log.e("readBitmapData", "Unable to open content: " + uri, e); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + Log.e("readBitmapData", "Unable to close content: " + uri, e); + } + } + } + } else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) { + Log.e("readBitmapData", "Unable to close content: " + uri); + } else { + Log.e("readBitmapData", "Unable to close content: " + uri); + } + return bitmap; + } +} \ No newline at end of file diff --git a/main/java/com/dommy/qrcode/util/Constant.java b/main/java/com/dommy/qrcode/util/Constant.java new file mode 100644 index 0000000..9a490e0 --- /dev/null +++ b/main/java/com/dommy/qrcode/util/Constant.java @@ -0,0 +1,13 @@ +package com.dommy.qrcode.util; + +/** + * 常量 + */ +public class Constant { + // request参数 + public static final int REQ_QR_CODE = 11002; // // 打开扫描界面请求码 + public static final int REQ_PERM_CAMERA = 11003; // 打开摄像头 + public static final int REQ_PERM_EXTERNAL_STORAGE = 11004; // 读写文件 + + public static final String INTENT_EXTRA_KEY_QR_SCAN = "qr_scan_result"; +} diff --git a/main/java/com/dommy/qrcode/util/UriUtil.java b/main/java/com/dommy/qrcode/util/UriUtil.java new file mode 100644 index 0000000..6f4cd2c --- /dev/null +++ b/main/java/com/dommy/qrcode/util/UriUtil.java @@ -0,0 +1,95 @@ +package com.dommy.qrcode.util; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.CursorLoader; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +/** + * Uri路径工具 + * + * @Deprecated 该方法存在终端适配问题,较为麻烦,已经弃用,新方法为BitmapUtil + * @see BitmapUtil + */ +@Deprecated +public class UriUtil { + /** + * 根据图片的Uri获取图片的绝对路径(适配多种API) + * + * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null + */ + public static String getRealPathFromUri(Context context, Uri uri) { + int sdkVersion = Build.VERSION.SDK_INT; + if (sdkVersion < 11) return getRealPathFromUri_BelowApi11(context, uri); + if (sdkVersion < 19) return getRealPathFromUri_Api11To18(context, uri); + else return getRealPathFromUri_AboveApi19(context, uri); + } + + /** + * 适配api19以上,根据uri获取图片的绝对路径 + */ + @TargetApi(Build.VERSION_CODES.KITKAT) + private static String getRealPathFromUri_AboveApi19(Context context, Uri uri) { + String filePath = null; + String wholeID = DocumentsContract.getDocumentId(uri); + + // 使用':'分割 + String[] ids = wholeID.split(":"); + String id = null; + if (ids == null) { + return null; + } + if (ids.length > 1) { + id = ids[1]; + } else { + id = ids[0]; + } + + String[] projection = {MediaStore.Images.Media.DATA}; + String selection = MediaStore.Images.Media._ID + "=?"; + String[] selectionArgs = {id}; + + Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,// + projection, selection, selectionArgs, null); + int columnIndex = cursor.getColumnIndex(projection[0]); + if (cursor.moveToFirst()) filePath = cursor.getString(columnIndex); + cursor.close(); + return filePath; + } + + /** + * 适配api11-api18,根据uri获取图片的绝对路径 + */ + private static String getRealPathFromUri_Api11To18(Context context, Uri uri) { + String filePath = null; + String[] projection = {MediaStore.Images.Media.DATA}; + CursorLoader loader = new CursorLoader(context, uri, projection, null, null, null); + Cursor cursor = loader.loadInBackground(); + + if (cursor != null) { + cursor.moveToFirst(); + filePath = cursor.getString(cursor.getColumnIndex(projection[0])); + cursor.close(); + } + return filePath; + } + + /** + * 适配api11以下(不包括api11),根据uri获取图片的绝对路径 + */ + private static String getRealPathFromUri_BelowApi11(Context context, Uri uri) { + String filePath = null; + String[] projection = {MediaStore.Images.Media.DATA}; + Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null); + if (cursor != null) { + cursor.moveToFirst(); + filePath = cursor.getString(cursor.getColumnIndex(projection[0])); + cursor.close(); + } + return filePath; + } +} diff --git a/main/java/com/geogle/zxing/activity/CaptureActivity.java b/main/java/com/geogle/zxing/activity/CaptureActivity.java new file mode 100644 index 0000000..e26e6ce --- /dev/null +++ b/main/java/com/geogle/zxing/activity/CaptureActivity.java @@ -0,0 +1,385 @@ +package com.geogle.zxing.activity; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.content.res.AssetFileDescriptor; +import android.graphics.Bitmap; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.media.MediaPlayer.OnCompletionListener; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Vibrator; + +import android.text.TextUtils; +import android.view.SurfaceHolder; +import android.view.SurfaceHolder.Callback; +import android.view.SurfaceView; +import android.view.View; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; + + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.BinaryBitmap; +import com.google.zxing.ChecksumException; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.geogle.zxing.camera.CameraManager; +import com.google.zxing.common.HybridBinarizer; + +import com.geogle.zxing.decoding.InactivityTimer; +import com.geogle.zxing.decoding.RGBLuminanceSource; +import com.google.zxing.qrcode.QRCodeReader; +import com.geogle.zxing.view.ViewfinderView; + +import java.io.IOException; +import java.util.Hashtable; +import java.util.Vector; + +import com.geogle.zxing.decoding.CaptureActivityHandler; +import edu.hzuapps.androidlabs.R; + + +/** + * Initial the camera + * + * @author Ryan.Tang + */ +public class CaptureActivity extends AppCompatActivity implements Callback { + + private static final int REQUEST_CODE_SCAN_GALLERY = 100; + + private CaptureActivityHandler handler; + private ViewfinderView viewfinderView; + private ImageButton back; + private ImageButton btnFlash; + private Button btnAlbum; // 相册 + private boolean isFlashOn = false; + private boolean hasSurface; + private Vector decodeFormats; + private String characterSet; + private InactivityTimer inactivityTimer; + private MediaPlayer mediaPlayer; + private boolean playBeep; + private static final float BEEP_VOLUME = 0.10f; + private boolean vibrate; + private ProgressDialog mProgress; + private String photo_path; + private Bitmap scanBitmap; + // private Button cancelScanButton; + /** + * Called when the activity is first created. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_scanner); + //ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card); + CameraManager.init(getApplication()); + viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_content); + back = (ImageButton) findViewById(R.id.btn_back); + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + btnFlash = (ImageButton) findViewById(R.id.btn_flash); + btnFlash.setOnClickListener(flashListener); + + btnAlbum = (Button) findViewById(R.id.btn_album); + btnAlbum.setOnClickListener(albumOnClick); + +// cancelScanButton = (Button) this.findViewById(R.id.btn_cancel_scan); + hasSurface = false; + inactivityTimer = new InactivityTimer(this); + + } + + private View.OnClickListener albumOnClick = new View.OnClickListener() { + @Override + public void onClick(View view) { + //打开手机中的相册 + Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); //"android.intent.action.GET_CONTENT" + innerIntent.setType("image/*"); + startActivityForResult(innerIntent, REQUEST_CODE_SCAN_GALLERY); + } + }; + + + @Override + protected void onActivityResult(final int requestCode, int resultCode, Intent data) { + if (resultCode==RESULT_OK) { + switch (requestCode) { + case REQUEST_CODE_SCAN_GALLERY: + handleAlbumPic(data); + break; + } + } + super.onActivityResult(requestCode, resultCode, data); + } + + /** + * 处理选择的图片 + * @param data + */ + private void handleAlbumPic(Intent data) { + //获取选中图片的路径 + final Uri uri = data.getData(); + + mProgress = new ProgressDialog(CaptureActivity.this); + mProgress.setMessage("正在扫描..."); + mProgress.setCancelable(false); + mProgress.show(); + + runOnUiThread(new Runnable() { + @Override + public void run() { + Result result = scanningImage(uri); + mProgress.dismiss(); + if (result != null) { + Intent resultIntent = new Intent(); + Bundle bundle = new Bundle(); + bundle.putString(com.dommy.qrcode.util.Constant.INTENT_EXTRA_KEY_QR_SCAN ,result.getText()); + + resultIntent.putExtras(bundle); + CaptureActivity.this.setResult(RESULT_OK, resultIntent); + finish(); + } else { + Toast.makeText(CaptureActivity.this, "识别失败", Toast.LENGTH_SHORT).show(); + } + } + }); + } + + /** + * 扫描二维码图片的方法 + * @param uri + * @return + */ + public Result scanningImage(Uri uri) { + if (uri == null) { + return null; + } + Hashtable hints = new Hashtable<>(); + hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); //设置二维码内容的编码 + + scanBitmap = com.dommy.qrcode.util.BitmapUtil.decodeUri(this, uri, 500, 500); + RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap); + BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source)); + QRCodeReader reader = new QRCodeReader(); + try { + return reader.decode(bitmap1, hints); + } catch (NotFoundException e) { + e.printStackTrace(); + } catch (ChecksumException e) { + e.printStackTrace(); + } catch (FormatException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onResume() { + super.onResume(); + SurfaceView surfaceView = (SurfaceView) findViewById(R.id.scanner_view); + SurfaceHolder surfaceHolder = surfaceView.getHolder(); + if (hasSurface) { + initCamera(surfaceHolder); + } else { + surfaceHolder.addCallback(this); + surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + } + decodeFormats = null; + characterSet = null; + + playBeep = true; + AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE); + if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) { + playBeep = false; + } + initBeepSound(); + vibrate = true; + + //quit the scan view +// cancelScanButton.setOnClickListener(new OnClickListener() { +// +// @Override +// public void onClick(View v) { +// CaptureActivity.this.finish(); +// } +// }); + } + + @Override + protected void onPause() { + super.onPause(); + if (handler != null) { + handler.quitSynchronously(); + handler = null; + } + CameraManager.get().closeDriver(); + } + + @Override + protected void onDestroy() { + inactivityTimer.shutdown(); + super.onDestroy(); + } + + /** + * Handler scan result + * + * @param result + * @param barcode + */ + public void handleDecode(Result result, Bitmap barcode) { + inactivityTimer.onActivity(); + playBeepSoundAndVibrate(); + String resultString = result.getText(); + //FIXME + if (TextUtils.isEmpty(resultString)) { + Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show(); + } else { + Intent resultIntent = new Intent(); + Bundle bundle = new Bundle(); + bundle.putString(com.dommy.qrcode.util.Constant.INTENT_EXTRA_KEY_QR_SCAN, resultString); + System.out.println("sssssssssssssssss scan 0 = " + resultString); + // 不能使用Intent传递大于40kb的bitmap,可以使用一个单例对象存储这个bitmap +// bundle.putParcelable("bitmap", barcode); +// Logger.d("saomiao",resultString); + resultIntent.putExtras(bundle); + this.setResult(RESULT_OK, resultIntent); + } + CaptureActivity.this.finish(); + } + + private void initCamera(SurfaceHolder surfaceHolder) { + try { + CameraManager.get().openDriver(surfaceHolder); + } catch (IOException ioe) { + return; + } catch (RuntimeException e) { + return; + } + if (handler == null) { + handler = new CaptureActivityHandler(this, decodeFormats, + characterSet); + } + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, + int height) { + + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + if (!hasSurface) { + hasSurface = true; + initCamera(holder); + } + + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + hasSurface = false; + + } + + public ViewfinderView getViewfinderView() { + return viewfinderView; + } + + public Handler getHandler() { + return handler; + } + + public void drawViewfinder() { + viewfinderView.drawViewfinder(); + + } + + private void initBeepSound() { + if (playBeep && mediaPlayer == null) { + // The volume on STREAM_SYSTEM is not adjustable, and users found it + // too loud, + // so we now play on the music stream. + setVolumeControlStream(AudioManager.STREAM_MUSIC); + mediaPlayer = new MediaPlayer(); + mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mediaPlayer.setOnCompletionListener(beepListener); + + AssetFileDescriptor file = getResources().openRawResourceFd( + R.raw.beep); + try { + mediaPlayer.setDataSource(file.getFileDescriptor(), + file.getStartOffset(), file.getLength()); + file.close(); + mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME); + mediaPlayer.prepare(); + } catch (IOException e) { + mediaPlayer = null; + } + } + } + + private static final long VIBRATE_DURATION = 200L; + + private void playBeepSoundAndVibrate() { + if (playBeep && mediaPlayer != null) { + mediaPlayer.start(); + } + if (vibrate) { + Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); + vibrator.vibrate(VIBRATE_DURATION); + } + } + + /** + * When the beep has finished playing, rewind to queue up another one. + */ + private final OnCompletionListener beepListener = new OnCompletionListener() { + public void onCompletion(MediaPlayer mediaPlayer) { + mediaPlayer.seekTo(0); + } + }; + + /** + * 闪光灯开关按钮 + */ + private View.OnClickListener flashListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + try { + boolean isSuccess = CameraManager.get().setFlashLight(!isFlashOn); + if(!isSuccess){ + Toast.makeText(CaptureActivity.this, "暂时无法开启闪光灯", Toast.LENGTH_SHORT).show(); + return; + } + if (isFlashOn) { + // 关闭闪光灯 + btnFlash.setImageResource(R.drawable.flash_off); + isFlashOn = false; + } else { + // 开启闪光灯 + btnFlash.setImageResource(R.drawable.flash_on); + isFlashOn = true; + } + }catch (Exception e){ + e.printStackTrace(); + } + } + }; +} \ No newline at end of file diff --git a/main/java/com/geogle/zxing/camera/AutoFocusCallback.java b/main/java/com/geogle/zxing/camera/AutoFocusCallback.java new file mode 100644 index 0000000..7f118bd --- /dev/null +++ b/main/java/com/geogle/zxing/camera/AutoFocusCallback.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.camera; + +import android.hardware.Camera; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +final class AutoFocusCallback implements Camera.AutoFocusCallback { + + private static final String TAG = AutoFocusCallback.class.getSimpleName(); + + private static final long AUTOFOCUS_INTERVAL_MS = 1500L; + + private Handler autoFocusHandler; + private int autoFocusMessage; + + void setHandler(Handler autoFocusHandler, int autoFocusMessage) { + this.autoFocusHandler = autoFocusHandler; + this.autoFocusMessage = autoFocusMessage; + } + + public void onAutoFocus(boolean success, Camera camera) { + if (autoFocusHandler != null) { + Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success); + autoFocusHandler.sendMessageDelayed(message, AUTOFOCUS_INTERVAL_MS); + autoFocusHandler = null; + } else { + Log.d(TAG, "Got auto-focus callback, but no handler for it"); + } + } + +} diff --git a/main/java/com/geogle/zxing/camera/CameraConfigurationManager.java b/main/java/com/geogle/zxing/camera/CameraConfigurationManager.java new file mode 100644 index 0000000..ae66cc2 --- /dev/null +++ b/main/java/com/geogle/zxing/camera/CameraConfigurationManager.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.camera; + +import android.content.Context; +import android.graphics.Point; +import android.hardware.Camera; +import android.os.Build; +import android.util.Log; +import android.view.Display; +import android.view.WindowManager; + +import java.util.regex.Pattern; + +final class CameraConfigurationManager { + + private static final String TAG = CameraConfigurationManager.class.getSimpleName(); + + private static final int TEN_DESIRED_ZOOM = 27; + private static final int DESIRED_SHARPNESS = 30; + + private static final Pattern COMMA_PATTERN = Pattern.compile(","); + + private final Context context; + private Point screenResolution; + private Point cameraResolution; + private int previewFormat; + private String previewFormatString; + + CameraConfigurationManager(Context context) { + this.context = context; + } + + /** + * Reads, one time, values from the camera that are needed by the app. + */ + void initFromCameraParameters(Camera camera) { + Camera.Parameters parameters = camera.getParameters(); + previewFormat = parameters.getPreviewFormat(); + previewFormatString = parameters.get("preview-format"); + Log.d(TAG, "Default preview format: " + previewFormat + '/' + previewFormatString); + WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + Display display = manager.getDefaultDisplay(); + screenResolution = new Point(display.getWidth(), display.getHeight()); + Log.d(TAG, "Screen resolution: " + screenResolution); + + //图片拉伸 + Point screenResolutionForCamera = new Point(); + screenResolutionForCamera.x = screenResolution.x; + screenResolutionForCamera.y = screenResolution.y; + // preview size is always something like 480*320, other 320*480 + if (screenResolution.x < screenResolution.y) { + screenResolutionForCamera.x = screenResolution.y; + screenResolutionForCamera.y = screenResolution.x; + } + + cameraResolution = getCameraResolution(parameters, screenResolutionForCamera); + Log.d(TAG, "Camera resolution: " + screenResolution); + + } + + /** + * Sets the camera up to take preview images which are used for both preview and decoding. + * We detect the preview format here so that buildLuminanceSource() can build an appropriate + * LuminanceSource subclass. In the future we may want to force YUV420SP as it's the smallest, + * and the planar Y can be used for barcode scanning without a copy in some cases. + */ + void setDesiredCameraParameters(Camera camera) { + Camera.Parameters parameters = camera.getParameters(); + Log.d(TAG, "Setting preview size: " + cameraResolution); + parameters.setPreviewSize(cameraResolution.x, cameraResolution.y); + setFlash(parameters); + setZoom(parameters); + //setSharpness(parameters); + //modify here + camera.setDisplayOrientation(90); + camera.setParameters(parameters); + } + + Point getCameraResolution() { + return cameraResolution; + } + + Point getScreenResolution() { + return screenResolution; + } + + int getPreviewFormat() { + return previewFormat; + } + + String getPreviewFormatString() { + return previewFormatString; + } + + private static Point getCameraResolution(Camera.Parameters parameters, Point screenResolution) { + + String previewSizeValueString = parameters.get("preview-size-values"); + // saw this on Xperia + if (previewSizeValueString == null) { + previewSizeValueString = parameters.get("preview-size-value"); + } + + Point cameraResolution = null; + + if (previewSizeValueString != null) { + Log.d(TAG, "preview-size-values parameter: " + previewSizeValueString); + cameraResolution = findBestPreviewSizeValue(previewSizeValueString, screenResolution); + } + + if (cameraResolution == null) { + // Ensure that the camera resolution is a multiple of 8, as the screen may not be. + cameraResolution = new Point( + (screenResolution.x >> 3) << 3, + (screenResolution.y >> 3) << 3); + } + + return cameraResolution; + } + + private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) { + int bestX = 0; + int bestY = 0; + int diff = Integer.MAX_VALUE; + for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) { + + previewSize = previewSize.trim(); + int dimPosition = previewSize.indexOf('x'); + if (dimPosition < 0) { + Log.w(TAG, "Bad preview-size: " + previewSize); + continue; + } + + int newX; + int newY; + try { + newX = Integer.parseInt(previewSize.substring(0, dimPosition)); + newY = Integer.parseInt(previewSize.substring(dimPosition + 1)); + } catch (NumberFormatException nfe) { + Log.w(TAG, "Bad preview-size: " + previewSize); + continue; + } + + int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y); + if (newDiff == 0) { + bestX = newX; + bestY = newY; + break; + } else if (newDiff < diff) { + bestX = newX; + bestY = newY; + diff = newDiff; + } + + } + + if (bestX > 0 && bestY > 0) { + return new Point(bestX, bestY); + } + return null; + } + + private static int findBestMotZoomValue(CharSequence stringValues, int tenDesiredZoom) { + int tenBestValue = 0; + for (String stringValue : COMMA_PATTERN.split(stringValues)) { + stringValue = stringValue.trim(); + double value; + try { + value = Double.parseDouble(stringValue); + } catch (NumberFormatException nfe) { + return tenDesiredZoom; + } + int tenValue = (int) (10.0 * value); + if (Math.abs(tenDesiredZoom - value) < Math.abs(tenDesiredZoom - tenBestValue)) { + tenBestValue = tenValue; + } + } + return tenBestValue; + } + + private void setFlash(Camera.Parameters parameters) { + // FIXME: This is a hack to turn the flash off on the Samsung Galaxy. + // And this is a hack-hack to work around a different value on the Behold II + // Restrict Behold II check to Cupcake, per Samsung's advice + //if (Build.MODEL.contains("Behold II") && + // CameraManager.SDK_INT == Build.VERSION_CODES.CUPCAKE) { + if (Build.MODEL.contains("Behold II") && CameraManager.SDK_INT == 3) { // 3 = Cupcake + parameters.set("flash-value", 1); + } else { + parameters.set("flash-value", 2); + } + // This is the standard setting to turn the flash off that all devices should honor. + parameters.set("flash-mode", "off"); + } + + private void setZoom(Camera.Parameters parameters) { + + String zoomSupportedString = parameters.get("zoom-supported"); + if (zoomSupportedString != null && !Boolean.parseBoolean(zoomSupportedString)) { + return; + } + + int tenDesiredZoom = TEN_DESIRED_ZOOM; + + String maxZoomString = parameters.get("max-zoom"); + if (maxZoomString != null) { + try { + int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString)); + if (tenDesiredZoom > tenMaxZoom) { + tenDesiredZoom = tenMaxZoom; + } + } catch (NumberFormatException nfe) { + Log.w(TAG, "Bad max-zoom: " + maxZoomString); + } + } + + String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max"); + if (takingPictureZoomMaxString != null) { + try { + int tenMaxZoom = Integer.parseInt(takingPictureZoomMaxString); + if (tenDesiredZoom > tenMaxZoom) { + tenDesiredZoom = tenMaxZoom; + } + } catch (NumberFormatException nfe) { + Log.w(TAG, "Bad taking-picture-zoom-max: " + takingPictureZoomMaxString); + } + } + + String motZoomValuesString = parameters.get("mot-zoom-values"); + if (motZoomValuesString != null) { + tenDesiredZoom = findBestMotZoomValue(motZoomValuesString, tenDesiredZoom); + } + + String motZoomStepString = parameters.get("mot-zoom-step"); + if (motZoomStepString != null) { + try { + double motZoomStep = Double.parseDouble(motZoomStepString.trim()); + int tenZoomStep = (int) (10.0 * motZoomStep); + if (tenZoomStep > 1) { + tenDesiredZoom -= tenDesiredZoom % tenZoomStep; + } + } catch (NumberFormatException nfe) { + // continue + } + } + + // Set zoom. This helps encourage the user to pull back. + // Some devices like the Behold have a zoom parameter + if (maxZoomString != null || motZoomValuesString != null) { + parameters.set("zoom", String.valueOf(tenDesiredZoom / 10.0)); + } + + // Most devices, like the Hero, appear to expose this zoom parameter. + // It takes on values like "27" which appears to mean 2.7x zoom + if (takingPictureZoomMaxString != null) { + parameters.set("taking-picture-zoom", tenDesiredZoom); + } + } + + public static int getDesiredSharpness() { + return DESIRED_SHARPNESS; + } + +} diff --git a/main/java/com/geogle/zxing/camera/CameraManager.java b/main/java/com/geogle/zxing/camera/CameraManager.java new file mode 100644 index 0000000..1366466 --- /dev/null +++ b/main/java/com/geogle/zxing/camera/CameraManager.java @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.camera; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.graphics.Point; +import android.graphics.Rect; +import android.hardware.Camera; +import android.os.Build; +import android.os.Handler; +import android.view.SurfaceHolder; + +import java.io.IOException; +import java.util.List; + +/** + * This object wraps the Camera service object and expects to be the only one talking to it. The + * implementation encapsulates the steps needed to take preview-sized images, which are used for + * both preview and decoding. + */ +public final class CameraManager { + + private static final String TAG = CameraManager.class.getSimpleName(); + + private static final int MIN_FRAME_WIDTH = 240; + private static final int MIN_FRAME_HEIGHT = 240; + private static final int MAX_FRAME_WIDTH = 480; + private static final int MAX_FRAME_HEIGHT = 360; + + private static CameraManager cameraManager; + + static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT + + static { + int sdkInt; + try { + sdkInt = Integer.parseInt(Build.VERSION.SDK); + } catch (NumberFormatException nfe) { + // Just to be safe + sdkInt = 10000; + } + SDK_INT = sdkInt; + } + + private final Context context; + private final CameraConfigurationManager configManager; + private Camera camera; + private Rect framingRect; + private Rect framingRectInPreview; + private boolean initialized; + private boolean previewing; + private final boolean useOneShotPreviewCallback; + /** + * Preview frames are delivered here, which we pass on to the registered handler. Make sure to + * clear the handler so it will only receive one message. + */ + private final PreviewCallback previewCallback; + /** + * Autofocus callbacks arrive here, and are dispatched to the Handler which requested them. + */ + private final AutoFocusCallback autoFocusCallback; + + /** + * Initializes this static object with the Context of the calling Activity. + * + * @param context The Activity which wants to use the camera. + */ + public static void init(Context context) { + if (cameraManager == null) { + cameraManager = new CameraManager(context); + } + } + + /** + * Gets the CameraManager singleton instance. + * + * @return A reference to the CameraManager singleton. + */ + public static CameraManager get() { + return cameraManager; + } + + private CameraManager(Context context) { + + this.context = context; + this.configManager = new CameraConfigurationManager(context); + + // Camera.setOneShotPreviewCallback() has a race condition in Cupcake, so we use the older + // Camera.setPreviewCallback() on 1.5 and earlier. For Donut and later, we need to use + // the more efficient one shot callback, as the older one can swamp the system and cause it + // to run out of memory. We can't use SDK_INT because it was introduced in the Donut SDK. + //useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > Build.VERSION_CODES.CUPCAKE; + useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > 3; // 3 = Cupcake + + previewCallback = new PreviewCallback(configManager, useOneShotPreviewCallback); + autoFocusCallback = new AutoFocusCallback(); + } + + /** + * Opens the camera driver and initializes the hardware parameters. + * + * @param holder The surface object which the camera will draw preview frames into. + * @throws IOException Indicates the camera driver failed to open. + */ + public void openDriver(SurfaceHolder holder) throws IOException { + if (camera == null) { + camera = Camera.open(); + if (camera == null) { + throw new IOException(); + } + camera.setPreviewDisplay(holder); + + if (!initialized) { + initialized = true; + configManager.initFromCameraParameters(camera); + } + configManager.setDesiredCameraParameters(camera); + + //FIXME + // SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + //�Ƿ�ʹ��ǰ�� +// if (prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false)) { +// FlashlightManager.enableFlashlight(); +// } + FlashlightManager.enableFlashlight(); + } + } + + /** + * Closes the camera driver if still in use. + */ + public void closeDriver() { + if (camera != null) { + FlashlightManager.disableFlashlight(); + camera.release(); + camera = null; + } + } + + /** + * Asks the camera hardware to begin drawing preview frames to the screen. + */ + public void startPreview() { + if (camera != null && !previewing) { + camera.startPreview(); + previewing = true; + } + } + + /** + * Tells the camera to stop drawing preview frames. + */ + public void stopPreview() { + if (camera != null && previewing) { + if (!useOneShotPreviewCallback) { + camera.setPreviewCallback(null); + } + camera.stopPreview(); + previewCallback.setHandler(null, 0); + autoFocusCallback.setHandler(null, 0); + previewing = false; + } + } + + /** + * A single preview frame will be returned to the handler supplied. The data will arrive as byte[] + * in the message.obj field, with width and height encoded as message.arg1 and message.arg2, + * respectively. + * + * @param handler The handler to send the message to. + * @param message The what field of the message to be sent. + */ + public void requestPreviewFrame(Handler handler, int message) { + if (camera != null && previewing) { + previewCallback.setHandler(handler, message); + if (useOneShotPreviewCallback) { + camera.setOneShotPreviewCallback(previewCallback); + } else { + camera.setPreviewCallback(previewCallback); + } + } + } + + /** + * Asks the camera hardware to perform an autofocus. + * + * @param handler The Handler to notify when the autofocus completes. + * @param message The message to deliver. + */ + public void requestAutoFocus(Handler handler, int message) { + if (camera != null && previewing) { + autoFocusCallback.setHandler(handler, message); + //Log.d(TAG, "Requesting auto-focus callback"); + camera.autoFocus(autoFocusCallback); + } + } + + /** + * Calculates the framing rect which the UI should draw to show the user where to place the + * barcode. This target helps with alignment as well as forces the user to hold the device + * far enough away to ensure the image will be in focus. + * + * @return The rectangle to draw on screen in window coordinates. + */ + public Rect getFramingRect() { + Point screenResolution = configManager.getScreenResolution(); + if (screenResolution == null) + return null; + if (framingRect == null) { + if (camera == null) { + return null; + } + + //修改之后 + int width = screenResolution.x * 7 / 10; + int height = screenResolution.y * 7 / 10; + + if (height >= width) { //竖屏 + height = width; + } else { //黑屏 + width = height; + } + + int leftOffset = (screenResolution.x - width) / 2; + int topOffset = (screenResolution.y - height) / 3; + framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height); + + } + return framingRect; + } +// public Rect getFramingRect() { +// Point screenResolution = configManager.getScreenResolution(); +// if (framingRect == null) { +// if (camera == null) { +// return null; +// } +// int width = screenResolution.x * 3 / 4; +// if (width < MIN_FRAME_WIDTH) { +// width = MIN_FRAME_WIDTH; +// } else if (width > MAX_FRAME_WIDTH) { +// width = MAX_FRAME_WIDTH; +// } +// int height = screenResolution.y * 3 / 4; +// if (height < MIN_FRAME_HEIGHT) { +// height = MIN_FRAME_HEIGHT; +// } else if (height > MAX_FRAME_HEIGHT) { +// height = MAX_FRAME_HEIGHT; +// } +// int leftOffset = (screenResolution.x - width) / 2; +// int topOffset = (screenResolution.y - height) / 2; +// framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height); +// Log.d(TAG, "Calculated framing rect: " + framingRect); +// } +// return framingRect; +// } + + /** + * Like {@link #getFramingRect} but coordinates are in terms of the preview frame, + * not UI / screen. + */ + public Rect getFramingRectInPreview() { + if (framingRectInPreview == null) { + Rect rect = new Rect(getFramingRect()); + Point cameraResolution = configManager.getCameraResolution(); + Point screenResolution = configManager.getScreenResolution(); + //modify here +// rect.left = rect.left * cameraResolution.x / screenResolution.x; +// rect.right = rect.right * cameraResolution.x / screenResolution.x; +// rect.top = rect.top * cameraResolution.y / screenResolution.y; +// rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y; + rect.left = rect.left * cameraResolution.y / screenResolution.x; + rect.right = rect.right * cameraResolution.y / screenResolution.x; + rect.top = rect.top * cameraResolution.x / screenResolution.y; + rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y; + framingRectInPreview = rect; + } + return framingRectInPreview; + } + + /** + * Converts the result points from still resolution coordinates to screen coordinates. + * + * @param points The points returned by the Reader subclass through Result.getResultPoints(). + * @return An array of Points scaled to the size of the framing rect and offset appropriately + * so they can be drawn in screen coordinates. + */ + /* + public Point[] convertResultPoints(ResultPoint[] points) { + Rect frame = getFramingRectInPreview(); + int count = points.length; + Point[] output = new Point[count]; + for (int x = 0; x < count; x++) { + output[x] = new Point(); + output[x].x = frame.left + (int) (points[x].getX() + 0.5f); + output[x].y = frame.top + (int) (points[x].getY() + 0.5f); + } + return output; + } + */ + + /** + * A factory method to build the appropriate LuminanceSource object based on the format + * of the preview buffers, as described by Camera.Parameters. + * + * @param data A preview frame. + * @param width The width of the image. + * @param height The height of the image. + * @return A PlanarYUVLuminanceSource instance. + */ + public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) { + Rect rect = getFramingRectInPreview(); + int previewFormat = configManager.getPreviewFormat(); + String previewFormatString = configManager.getPreviewFormatString(); + switch (previewFormat) { + // This is the standard Android format which all devices are REQUIRED to support. + // In theory, it's the only one we should ever care about. + case PixelFormat.YCbCr_420_SP: + // This format has never been seen in the wild, but is compatible as we only care + // about the Y channel, so allow it. + case PixelFormat.YCbCr_422_SP: + return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height); + default: + // The Samsung Moment incorrectly uses this variant instead of the 'sp' version. + // Fortunately, it too has all the Y data up front, so we can read it. + if ("yuv420p".equals(previewFormatString)) { + return new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height); + } + } + throw new IllegalArgumentException("Unsupported picture format: " + + previewFormat + '/' + previewFormatString); + } + + public Context getContext() { + return context; + } + + /** + * 打开或关闭闪光灯 + * @param isOpen 是否开启闪光灯 + * @return boolean 操作成功/失败。 + */ + public boolean setFlashLight(boolean isOpen) { + if (camera == null || !previewing) { + return false; + } + Camera.Parameters parameters = camera.getParameters(); + if (parameters == null) { + return false; + } + List flashModes = parameters.getSupportedFlashModes(); + // 检查手机是否有闪光灯 + if (null == flashModes || 0 == flashModes.size()) { + // 没有闪光灯则返回 + return false; + } + String flashMode = parameters.getFlashMode(); + if (isOpen) { + if (Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode)) { + return true; + } + // 开启 + if (flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) { + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); + camera.setParameters(parameters); + return true; + } else { + return false; + } + } else { + if (Camera.Parameters.FLASH_MODE_OFF.equals(flashMode)) { + return true; + } + // 关闭 + if (flashModes.contains(Camera.Parameters.FLASH_MODE_OFF)) { + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); + camera.setParameters(parameters); + return true; + } else { + return false; + } + } + } +} diff --git a/main/java/com/geogle/zxing/camera/FlashlightManager.java b/main/java/com/geogle/zxing/camera/FlashlightManager.java new file mode 100644 index 0000000..6fd1041 --- /dev/null +++ b/main/java/com/geogle/zxing/camera/FlashlightManager.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.camera; + +import android.os.IBinder; +import android.util.Log; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * This class is used to activate the weak light on some camera phones (not flash) + * in order to illuminate surfaces for scanning. There is no official way to do this, + * but, classes which allow access to this function still exist on some devices. + * This therefore proceeds through a great deal of reflection. + * + * See + * http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/ and + * + * http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java. + * Thanks to Ryan Alford for pointing out the availability of this class. + */ +final class FlashlightManager { + + private static final String TAG = FlashlightManager.class.getSimpleName(); + + private static final Object iHardwareService; + private static final Method setFlashEnabledMethod; + static { + iHardwareService = getHardwareService(); + setFlashEnabledMethod = getSetFlashEnabledMethod(iHardwareService); + if (iHardwareService == null) { + Log.v(TAG, "This device does supports control of a flashlight"); + } else { + Log.v(TAG, "This device does not support control of a flashlight"); + } + } + + private FlashlightManager() { + } + + /** + * �����������ƿ��� + */ + //FIXME + static void enableFlashlight() { + setFlashlight(false); + } + + static void disableFlashlight() { + setFlashlight(false); + } + + private static Object getHardwareService() { + Class serviceManagerClass = maybeForName("android.os.ServiceManager"); + if (serviceManagerClass == null) { + return null; + } + + Method getServiceMethod = maybeGetMethod(serviceManagerClass, "getService", String.class); + if (getServiceMethod == null) { + return null; + } + + Object hardwareService = invoke(getServiceMethod, null, "hardware"); + if (hardwareService == null) { + return null; + } + + Class iHardwareServiceStubClass = maybeForName("android.os.IHardwareService$Stub"); + if (iHardwareServiceStubClass == null) { + return null; + } + + Method asInterfaceMethod = maybeGetMethod(iHardwareServiceStubClass, "asInterface", IBinder.class); + if (asInterfaceMethod == null) { + return null; + } + + return invoke(asInterfaceMethod, null, hardwareService); + } + + private static Method getSetFlashEnabledMethod(Object iHardwareService) { + if (iHardwareService == null) { + return null; + } + Class proxyClass = iHardwareService.getClass(); + return maybeGetMethod(proxyClass, "setFlashlightEnabled", boolean.class); + } + + private static Class maybeForName(String name) { + try { + return Class.forName(name); + } catch (ClassNotFoundException cnfe) { + // OK + return null; + } catch (RuntimeException re) { + Log.w(TAG, "Unexpected error while finding class " + name, re); + return null; + } + } + + private static Method maybeGetMethod(Class clazz, String name, Class... argClasses) { + try { + return clazz.getMethod(name, argClasses); + } catch (NoSuchMethodException nsme) { + // OK + return null; + } catch (RuntimeException re) { + Log.w(TAG, "Unexpected error while finding method " + name, re); + return null; + } + } + + private static Object invoke(Method method, Object instance, Object... args) { + try { + return method.invoke(instance, args); + } catch (IllegalAccessException e) { + Log.w(TAG, "Unexpected error while invoking " + method, e); + return null; + } catch (InvocationTargetException e) { + Log.w(TAG, "Unexpected error while invoking " + method, e.getCause()); + return null; + } catch (RuntimeException re) { + Log.w(TAG, "Unexpected error while invoking " + method, re); + return null; + } + } + + private static void setFlashlight(boolean active) { + if (iHardwareService != null) { + invoke(setFlashEnabledMethod, iHardwareService, active); + } + } + +} diff --git a/main/java/com/geogle/zxing/camera/PlanarYUVLuminanceSource.java b/main/java/com/geogle/zxing/camera/PlanarYUVLuminanceSource.java new file mode 100644 index 0000000..c6f34ea --- /dev/null +++ b/main/java/com/geogle/zxing/camera/PlanarYUVLuminanceSource.java @@ -0,0 +1,133 @@ +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.camera; + +import android.graphics.Bitmap; + +import com.google.zxing.LuminanceSource; + +/** + * This object extends LuminanceSource around an array of YUV data returned from the camera driver, + * with the option to crop to a rectangle within the full data. This can be used to exclude + * superfluous pixels around the perimeter and speed up decoding. + * + * It works for any pixel format where the Y channel is planar and appears first, including + * YCbCr_420_SP and YCbCr_422_SP. + * + * @author dswitkin@google.com (Daniel Switkin) + */ +public final class PlanarYUVLuminanceSource extends LuminanceSource { + private final byte[] yuvData; + private final int dataWidth; + private final int dataHeight; + private final int left; + private final int top; + + public PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top, + int width, int height) { + super(width, height); + + if (left + width > dataWidth || top + height > dataHeight) { + throw new IllegalArgumentException("Crop rectangle does not fit within image data."); + } + + this.yuvData = yuvData; + this.dataWidth = dataWidth; + this.dataHeight = dataHeight; + this.left = left; + this.top = top; + } + + @Override + public byte[] getRow(int y, byte[] row) { + if (y < 0 || y >= getHeight()) { + throw new IllegalArgumentException("Requested row is outside the image: " + y); + } + int width = getWidth(); + if (row == null || row.length < width) { + row = new byte[width]; + } + int offset = (y + top) * dataWidth + left; + System.arraycopy(yuvData, offset, row, 0, width); + return row; + } + + @Override + public byte[] getMatrix() { + int width = getWidth(); + int height = getHeight(); + + // If the caller asks for the entire underlying image, save the copy and give them the + // original data. The docs specifically warn that result.length must be ignored. + if (width == dataWidth && height == dataHeight) { + return yuvData; + } + + int area = width * height; + byte[] matrix = new byte[area]; + int inputOffset = top * dataWidth + left; + + // If the width matches the full width of the underlying data, perform a single copy. + if (width == dataWidth) { + System.arraycopy(yuvData, inputOffset, matrix, 0, area); + return matrix; + } + + // Otherwise copy one cropped row at a time. + byte[] yuv = yuvData; + for (int y = 0; y < height; y++) { + int outputOffset = y * width; + System.arraycopy(yuv, inputOffset, matrix, outputOffset, width); + inputOffset += dataWidth; + } + return matrix; + } + + @Override + public boolean isCropSupported() { + return true; + } + + public int getDataWidth() { + return dataWidth; + } + + public int getDataHeight() { + return dataHeight; + } + + public Bitmap renderCroppedGreyscaleBitmap() { + int width = getWidth(); + int height = getHeight(); + int[] pixels = new int[width * height]; + byte[] yuv = yuvData; + int inputOffset = top * dataWidth + left; + + for (int y = 0; y < height; y++) { + int outputOffset = y * width; + for (int x = 0; x < width; x++) { + int grey = yuv[inputOffset + x] & 0xff; + pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101); + } + inputOffset += dataWidth; + } + + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + bitmap.setPixels(pixels, 0, width, 0, 0, width, height); + return bitmap; + } +} diff --git a/main/java/com/geogle/zxing/camera/PreviewCallback.java b/main/java/com/geogle/zxing/camera/PreviewCallback.java new file mode 100644 index 0000000..5fbbddb --- /dev/null +++ b/main/java/com/geogle/zxing/camera/PreviewCallback.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.camera; + +import android.graphics.Point; +import android.hardware.Camera; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +final class PreviewCallback implements Camera.PreviewCallback { + + private static final String TAG = PreviewCallback.class.getSimpleName(); + + private final CameraConfigurationManager configManager; + private final boolean useOneShotPreviewCallback; + private Handler previewHandler; + private int previewMessage; + + PreviewCallback(CameraConfigurationManager configManager, boolean useOneShotPreviewCallback) { + this.configManager = configManager; + this.useOneShotPreviewCallback = useOneShotPreviewCallback; + } + + void setHandler(Handler previewHandler, int previewMessage) { + this.previewHandler = previewHandler; + this.previewMessage = previewMessage; + } + + public void onPreviewFrame(byte[] data, Camera camera) { + Point cameraResolution = configManager.getCameraResolution(); + if (!useOneShotPreviewCallback) { + camera.setPreviewCallback(null); + } + if (previewHandler != null) { + Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x, + cameraResolution.y, data); + message.sendToTarget(); + previewHandler = null; + } else { + Log.d(TAG, "Got preview callback, but no handler for it"); + } + } + +} diff --git a/main/java/com/geogle/zxing/decoding/CaptureActivityHandler.java b/main/java/com/geogle/zxing/decoding/CaptureActivityHandler.java new file mode 100644 index 0000000..0642453 --- /dev/null +++ b/main/java/com/geogle/zxing/decoding/CaptureActivityHandler.java @@ -0,0 +1,141 @@ +package com.geogle.zxing.decoding;/* + * Copyright (C) 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +import android.app.Activity; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.Result; +import com.geogle.zxing.camera.CameraManager; +import com.geogle.zxing.view.ViewfinderResultPointCallback; + +import java.util.Vector; + +import com.geogle.zxing.activity.CaptureActivity; +import edu.hzuapps.androidlabs.R; + + +/** + * This class handles all the messaging which comprises the state machine for capture. + */ +public final class CaptureActivityHandler extends Handler { + + private static final String TAG = CaptureActivityHandler.class.getSimpleName(); + + private final CaptureActivity activity; + private final DecodeThread decodeThread; + private State state; + + private enum State { + PREVIEW, + SUCCESS, + DONE + } + + public CaptureActivityHandler(CaptureActivity activity, Vector decodeFormats, + String characterSet) { + this.activity = activity; + decodeThread = new DecodeThread(activity, decodeFormats, characterSet, + new ViewfinderResultPointCallback(activity.getViewfinderView())); + decodeThread.start(); + state = State.SUCCESS; + // Start ourselves capturing previews and decoding. + CameraManager.get().startPreview(); + restartPreviewAndDecode(); + } + + @Override + public void handleMessage(Message message) { + switch (message.what) { + case R.id.auto_focus: + //Log.d(TAG, "Got auto-focus message"); + // When one auto focus pass finishes, start another. This is the closest thing to + // continuous AF. It does seem to hunt a bit, but I'm not sure what else to do. + if (state == State.PREVIEW) { + CameraManager.get().requestAutoFocus(this, R.id.auto_focus); + } + break; + case R.id.restart_preview: + Log.d(TAG, "Got restart preview message"); + restartPreviewAndDecode(); + break; + case R.id.decode_succeeded: + Log.d(TAG, "Got decode succeeded message"); + state = State.SUCCESS; + Bundle bundle = message.getData(); + + /***********************************************************************/ + Bitmap barcode = bundle == null ? null : + (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);//���ñ����߳� + + activity.handleDecode((Result) message.obj, barcode);//���ؽ�� + /***********************************************************************/ + break; + case R.id.decode_failed: + // We're decoding as fast as possible, so when one decode fails, start another. + state = State.PREVIEW; + CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode); + break; + case R.id.return_scan_result: + Log.d(TAG, "Got return scan result message"); + activity.setResult(Activity.RESULT_OK, (Intent) message.obj); + activity.finish(); + break; + case R.id.launch_product_query: + Log.d(TAG, "Got product query message"); + String url = (String) message.obj; + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); + activity.startActivity(intent); + break; + } + } + + public void quitSynchronously() { + state = State.DONE; + CameraManager.get().stopPreview(); + Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit); + quit.sendToTarget(); + try { + decodeThread.join(); + } catch (InterruptedException e) { + // continue + } + + // Be absolutely sure we don't send any queued up messages + removeMessages(R.id.decode_succeeded); + removeMessages(R.id.decode_failed); + } + + private void restartPreviewAndDecode() { + if (state == State.SUCCESS) { + state = State.PREVIEW; + CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode); + CameraManager.get().requestAutoFocus(this, R.id.auto_focus); + activity.drawViewfinder(); + } + } + +} diff --git a/main/java/com/geogle/zxing/decoding/DecodeFormatManager.java b/main/java/com/geogle/zxing/decoding/DecodeFormatManager.java new file mode 100644 index 0000000..4107c8b --- /dev/null +++ b/main/java/com/geogle/zxing/decoding/DecodeFormatManager.java @@ -0,0 +1,106 @@ +package com.geogle.zxing.decoding;/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + + + +import android.content.Intent; +import android.net.Uri; + +import com.google.zxing.BarcodeFormat; + +import java.util.Arrays; +import java.util.List; +import java.util.Vector; +import java.util.regex.Pattern; + +final class DecodeFormatManager { + + private static final Pattern COMMA_PATTERN = Pattern.compile(","); + + static final Vector PRODUCT_FORMATS; + static final Vector ONE_D_FORMATS; + static final Vector QR_CODE_FORMATS; + static final Vector DATA_MATRIX_FORMATS; + static { + PRODUCT_FORMATS = new Vector(5); + PRODUCT_FORMATS.add(BarcodeFormat.UPC_A); + PRODUCT_FORMATS.add(BarcodeFormat.UPC_E); + PRODUCT_FORMATS.add(BarcodeFormat.EAN_13); + PRODUCT_FORMATS.add(BarcodeFormat.EAN_8); + ONE_D_FORMATS = new Vector(PRODUCT_FORMATS.size() + 4); + ONE_D_FORMATS.addAll(PRODUCT_FORMATS); + ONE_D_FORMATS.add(BarcodeFormat.CODE_39); + ONE_D_FORMATS.add(BarcodeFormat.CODE_93); + ONE_D_FORMATS.add(BarcodeFormat.CODE_128); + ONE_D_FORMATS.add(BarcodeFormat.ITF); + QR_CODE_FORMATS = new Vector(1); + QR_CODE_FORMATS.add(BarcodeFormat.QR_CODE); + DATA_MATRIX_FORMATS = new Vector(1); + DATA_MATRIX_FORMATS.add(BarcodeFormat.DATA_MATRIX); + } + + private DecodeFormatManager() {} + + static Vector parseDecodeFormats(Intent intent) { + List scanFormats = null; + String scanFormatsString = intent.getStringExtra(Intents.Scan.SCAN_FORMATS); + if (scanFormatsString != null) { + scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString)); + } + return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE)); + } + + static Vector parseDecodeFormats(Uri inputUri) { + List formats = inputUri.getQueryParameters(Intents.Scan.SCAN_FORMATS); + if (formats != null && formats.size() == 1 && formats.get(0) != null){ + formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0))); + } + return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE)); + } + + private static Vector parseDecodeFormats(Iterable scanFormats, + String decodeMode) { + if (scanFormats != null) { + Vector formats = new Vector(); + try { + for (String format : scanFormats) { + formats.add(BarcodeFormat.valueOf(format)); + } + return formats; + } catch (IllegalArgumentException iae) { + // ignore it then + } + } + if (decodeMode != null) { + if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) { + return PRODUCT_FORMATS; + } + if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) { + return QR_CODE_FORMATS; + } + if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) { + return DATA_MATRIX_FORMATS; + } + if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) { + return ONE_D_FORMATS; + } + } + return null; + } + +} diff --git a/main/java/com/geogle/zxing/decoding/DecodeHandler.java b/main/java/com/geogle/zxing/decoding/DecodeHandler.java new file mode 100644 index 0000000..58ba546 --- /dev/null +++ b/main/java/com/geogle/zxing/decoding/DecodeHandler.java @@ -0,0 +1,116 @@ +package com.geogle.zxing.decoding;/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.util.Log; + + +import com.geogle.zxing.camera.PlanarYUVLuminanceSource; +import com.google.zxing.BinaryBitmap; +import com.google.zxing.DecodeHintType; +import com.google.zxing.MultiFormatReader; +import com.google.zxing.ReaderException; +import com.google.zxing.Result; + +import com.geogle.zxing.camera.CameraManager; + +import com.google.zxing.common.HybridBinarizer; + +import java.util.Hashtable; + +import com.geogle.zxing.activity.CaptureActivity; +import edu.hzuapps.androidlabs.R; + + +final class DecodeHandler extends Handler { + + private static final String TAG = DecodeHandler.class.getSimpleName(); + + private final CaptureActivity activity; + private final MultiFormatReader multiFormatReader; + + DecodeHandler(CaptureActivity activity, Hashtable hints) { + multiFormatReader = new MultiFormatReader(); + multiFormatReader.setHints(hints); + this.activity = activity; + } + + @Override + public void handleMessage(Message message) { + switch (message.what) { + case R.id.decode: + //Log.d(TAG, "Got decode message"); + decode((byte[]) message.obj, message.arg1, message.arg2); + break; + case R.id.quit: + Looper.myLooper().quit(); + break; + } + } + + /** + * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency, + * reuse the same reader objects from one decode to the next. + * + * @param data The YUV preview frame. + * @param width The width of the preview frame. + * @param height The height of the preview frame. + */ + private void decode(byte[] data, int width, int height) { + long start = System.currentTimeMillis(); + Result rawResult = null; + + //modify here + byte[] rotatedData = new byte[data.length]; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) + rotatedData[x * height + height - y - 1] = data[x + y * width]; + } + int tmp = width; // Here we are swapping, that's the difference to #11 + width = height; + height = tmp; + + PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height); + BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); + try { + rawResult = multiFormatReader.decodeWithState(bitmap); + } catch (ReaderException re) { + // continue + } finally { + multiFormatReader.reset(); + } + + if (rawResult != null) { + long end = System.currentTimeMillis(); + Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString()); + Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult); + Bundle bundle = new Bundle(); + bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap()); + message.setData(bundle); + //Log.d(TAG, "Sending decode succeeded message..."); + message.sendToTarget(); + } else { + Message message = Message.obtain(activity.getHandler(), R.id.decode_failed); + message.sendToTarget(); + } + } + +} diff --git a/main/java/com/geogle/zxing/decoding/DecodeThread.java b/main/java/com/geogle/zxing/decoding/DecodeThread.java new file mode 100644 index 0000000..4ba3acf --- /dev/null +++ b/main/java/com/geogle/zxing/decoding/DecodeThread.java @@ -0,0 +1,87 @@ +package com.geogle.zxing.decoding;/* + * Copyright (C) 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +import android.os.Handler; +import android.os.Looper; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.DecodeHintType; +import com.google.zxing.ResultPointCallback; + +import java.util.Hashtable; +import java.util.Vector; +import java.util.concurrent.CountDownLatch; + +import com.geogle.zxing.activity.CaptureActivity; + +/** + * This thread does all the heavy lifting of decoding the images. + * �����߳� + */ +final class DecodeThread extends Thread { + + public static final String BARCODE_BITMAP = "barcode_bitmap"; + private final CaptureActivity activity; + private final Hashtable hints; + private Handler handler; + private final CountDownLatch handlerInitLatch; + + DecodeThread(CaptureActivity activity, + Vector decodeFormats, + String characterSet, + ResultPointCallback resultPointCallback) { + + this.activity = activity; + handlerInitLatch = new CountDownLatch(1); + + hints = new Hashtable(3); + + if (decodeFormats == null || decodeFormats.isEmpty()) { + decodeFormats = new Vector(); + decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS); + decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS); + decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS); + } + + hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats); + + if (characterSet != null) { + hints.put(DecodeHintType.CHARACTER_SET, characterSet); + } + + hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback); + } + + Handler getHandler() { + try { + handlerInitLatch.await(); + } catch (InterruptedException ie) { + // continue? + } + return handler; + } + + @Override + public void run() { + Looper.prepare(); + handler = new DecodeHandler(activity, hints); + handlerInitLatch.countDown(); + Looper.loop(); + } + +} diff --git a/main/java/com/geogle/zxing/decoding/FinishListener.java b/main/java/com/geogle/zxing/decoding/FinishListener.java new file mode 100644 index 0000000..40dc709 --- /dev/null +++ b/main/java/com/geogle/zxing/decoding/FinishListener.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.decoding; + +import android.app.Activity; +import android.content.DialogInterface; + +/** + * Simple listener used to exit the app in a few cases. + * + */ +public final class FinishListener + implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener, Runnable { + + private final Activity activityToFinish; + + public FinishListener(Activity activityToFinish) { + this.activityToFinish = activityToFinish; + } + + public void onCancel(DialogInterface dialogInterface) { + run(); + } + + public void onClick(DialogInterface dialogInterface, int i) { + run(); + } + + public void run() { + activityToFinish.finish(); + } + +} diff --git a/main/java/com/geogle/zxing/decoding/InactivityTimer.java b/main/java/com/geogle/zxing/decoding/InactivityTimer.java new file mode 100644 index 0000000..bfc8b20 --- /dev/null +++ b/main/java/com/geogle/zxing/decoding/InactivityTimer.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.decoding; + +import android.app.Activity; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +/** + * Finishes an activity after a period of inactivity. + */ +public final class InactivityTimer { + + private static final int INACTIVITY_DELAY_SECONDS = 5 * 60; + + private final ScheduledExecutorService inactivityTimer = + Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory()); + private final Activity activity; + private ScheduledFuture inactivityFuture = null; + + public InactivityTimer(Activity activity) { + this.activity = activity; + onActivity(); + } + + public void onActivity() { + cancel(); + inactivityFuture = inactivityTimer.schedule(new FinishListener(activity), + INACTIVITY_DELAY_SECONDS, + TimeUnit.SECONDS); + } + + private void cancel() { + if (inactivityFuture != null) { + inactivityFuture.cancel(true); + inactivityFuture = null; + } + } + + public void shutdown() { + cancel(); + inactivityTimer.shutdown(); + } + + private static final class DaemonThreadFactory implements ThreadFactory { + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable); + thread.setDaemon(true); + return thread; + } + } + +} diff --git a/main/java/com/geogle/zxing/decoding/Intents.java b/main/java/com/geogle/zxing/decoding/Intents.java new file mode 100644 index 0000000..afcdd47 --- /dev/null +++ b/main/java/com/geogle/zxing/decoding/Intents.java @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.decoding; + +/** + * This class provides the constants to use when sending an Intent to Barcode Scanner. + * These strings are effectively API and cannot be changed. + */ +public final class Intents { + private Intents() { + } + + public static final class Scan { + /** + * Send this intent to open the Barcodes app in scanning mode, find a barcode, and return + * the results. + */ + public static final String ACTION = "com.google.zxing.client.android.SCAN"; + + /** + * By default, sending Scan.ACTION will decode all barcodes that we understand. However it + * may be useful to limit scanning to certain formats. Use Intent.putExtra(MODE, value) with + * one of the values below ({@link #PRODUCT_MODE}, {@link #ONE_D_MODE}, {@link #QR_CODE_MODE}). + * Optional. + * + * Setting this is effectively shorthnad for setting explicit formats with {@link #SCAN_FORMATS}. + * It is overridden by that setting. + */ + public static final String MODE = "SCAN_MODE"; + + /** + * Comma-separated list of formats to scan for. The values must match the names of + * {@link com.google.zxing.BarcodeFormat}s, such as {@link com.google.zxing.BarcodeFormat#EAN_13}. + * Example: "EAN_13,EAN_8,QR_CODE" + * + * This overrides {@link #MODE}. + */ + public static final String SCAN_FORMATS = "SCAN_FORMATS"; + + /** + * @see com.google.zxing.DecodeHintType#CHARACTER_SET + */ + public static final String CHARACTER_SET = "CHARACTER_SET"; + + /** + * Decode only UPC and EAN barcodes. This is the right choice for shopping apps which get + * prices, reviews, etc. for products. + */ + public static final String PRODUCT_MODE = "PRODUCT_MODE"; + + /** + * Decode only 1D barcodes (currently UPC, EAN, Code 39, and Code 128). + */ + public static final String ONE_D_MODE = "ONE_D_MODE"; + + /** + * Decode only QR codes. + */ + public static final String QR_CODE_MODE = "QR_CODE_MODE"; + + /** + * Decode only Data Matrix codes. + */ + public static final String DATA_MATRIX_MODE = "DATA_MATRIX_MODE"; + + /** + * If a barcode is found, Barcodes returns RESULT_OK to onActivityResult() of the app which + * requested the scan via startSubActivity(). The barcodes contents can be retrieved with + * intent.getStringExtra(RESULT). If the user presses Back, the result code will be + * RESULT_CANCELED. + */ + public static final String RESULT = "SCAN_RESULT"; + + /** + * Call intent.getStringExtra(RESULT_FORMAT) to determine which barcode format was found. + * See Contents.Format for possible values. + */ + public static final String RESULT_FORMAT = "SCAN_RESULT_FORMAT"; + + /** + * Setting this to false will not save scanned codes in the history. + */ + public static final String SAVE_HISTORY = "SAVE_HISTORY"; + + private Scan() { + } + } + + public static final class Encode { + /** + * Send this intent to encode a piece of data as a QR code and display it full screen, so + * that another person can scan the barcode from your screen. + */ + public static final String ACTION = "com.google.zxing.client.android.ENCODE"; + + /** + * The data to encode. Use Intent.putExtra(DATA, data) where data is either a String or a + * Bundle, depending on the type and format specified. Non-QR Code formats should + * just use a String here. For QR Code, see Contents for details. + */ + public static final String DATA = "ENCODE_DATA"; + + /** + * The type of data being supplied if the format is QR Code. Use + * Intent.putExtra(TYPE, type) with one of Contents.Type. + */ + public static final String TYPE = "ENCODE_TYPE"; + + /** + * The barcode format to be displayed. If this isn't specified or is blank, + * it defaults to QR Code. Use Intent.putExtra(FORMAT, format), where + * format is one of Contents.Format. + */ + public static final String FORMAT = "ENCODE_FORMAT"; + + private Encode() { + } + } + + public static final class SearchBookContents { + /** + * Use Google Book Search to search the contents of the book provided. + */ + public static final String ACTION = "com.google.zxing.client.android.SEARCH_BOOK_CONTENTS"; + + /** + * The book to search, identified by ISBN number. + */ + public static final String ISBN = "ISBN"; + + /** + * An optional field which is the text to search for. + */ + public static final String QUERY = "QUERY"; + + private SearchBookContents() { + } + } + + public static final class WifiConnect { + /** + * Internal intent used to trigger connection to a wi-fi network. + */ + public static final String ACTION = "com.google.zxing.client.android.WIFI_CONNECT"; + + /** + * The network to connect to, all the configuration provided here. + */ + public static final String SSID = "SSID"; + + /** + * The network to connect to, all the configuration provided here. + */ + public static final String TYPE = "TYPE"; + + /** + * The network to connect to, all the configuration provided here. + */ + public static final String PASSWORD = "PASSWORD"; + + private WifiConnect() { + } + } + + + public static final class Share { + /** + * Give the user a choice of items to encode as a barcode, then render it as a QR Code and + * display onscreen for a friend to scan with their phone. + */ + public static final String ACTION = "com.google.zxing.client.android.SHARE"; + + private Share() { + } + } +} diff --git a/main/java/com/geogle/zxing/decoding/RGBLuminanceSource.java b/main/java/com/geogle/zxing/decoding/RGBLuminanceSource.java new file mode 100644 index 0000000..15dddb0 --- /dev/null +++ b/main/java/com/geogle/zxing/decoding/RGBLuminanceSource.java @@ -0,0 +1,104 @@ +/* + * Copyright 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.decoding; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import com.google.zxing.LuminanceSource; + +import java.io.FileNotFoundException; + +/** + * This class is used to help decode images from files which arrive as RGB data + * from Android bitmaps. It does not support cropping or rotation. + * + */ +public final class RGBLuminanceSource extends LuminanceSource { + + private final byte[] luminances; + + public RGBLuminanceSource(String path) throws FileNotFoundException { + this(loadBitmap(path)); + } + + public RGBLuminanceSource(Bitmap bitmap) { + super(bitmap.getWidth(), bitmap.getHeight()); + + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + + int[] pixels = new int[width * height]; + bitmap.getPixels(pixels, 0, width, 0, 0, width, height); + + // In order to measure pure decoding speed, we convert the entire image + // to a greyscale array + // up front, which is the same as the Y channel of the + // YUVLuminanceSource in the real app. + luminances = new byte[width * height]; + for (int y = 0; y < height; y++) { + int offset = y * width; + for (int x = 0; x < width; x++) { + int pixel = pixels[offset + x]; + int r = (pixel >> 16) & 0xff; + int g = (pixel >> 8) & 0xff; + int b = pixel & 0xff; + if (r == g && g == b) { + // Image is already greyscale, so pick any channel. + luminances[offset + x] = (byte) r; + } else { + // Calculate luminance cheaply, favoring green. + luminances[offset + x] = (byte) ((r + g + g + b) >> 2); + } + } + } + } + + + + + @Override + public byte[] getRow(int y, byte[] row) { + if (y < 0 || y >= getHeight()) { + throw new IllegalArgumentException("Requested row is outside the image: " + y); + } + int width = getWidth(); + if (row == null || row.length < width) { + row = new byte[width]; + } + + System.arraycopy(luminances, y * width, row, 0, width); + return row; + } + + // Since this class does not support cropping, the underlying byte array + // already contains + // exactly what the caller is asking for, so give it to them without a copy. + @Override + public byte[] getMatrix() { + return luminances; + } + + private static Bitmap loadBitmap(String path) throws FileNotFoundException { + Bitmap bitmap = BitmapFactory.decodeFile(path); + if (bitmap == null) { + throw new FileNotFoundException("Couldn't open " + path); + } + return bitmap; + } + +} diff --git a/main/java/com/geogle/zxing/encoding/EncodingHandler.java b/main/java/com/geogle/zxing/encoding/EncodingHandler.java new file mode 100644 index 0000000..a0f1956 --- /dev/null +++ b/main/java/com/geogle/zxing/encoding/EncodingHandler.java @@ -0,0 +1,132 @@ +package com.geogle.zxing.encoding; + +import android.graphics.Bitmap; +import android.graphics.Canvas; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +/** + * @author Ryan Tang + * + */ +public final class EncodingHandler { + private static final int BLACK = 0xff000000; + + public static Bitmap createQRCode(String str, int widthAndHeight) throws WriterException { + Hashtable hints = new Hashtable(); + hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); + BitMatrix matrix = new MultiFormatWriter().encode(str, + BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight); + int width = matrix.getWidth(); + int height = matrix.getHeight(); + int[] pixels = new int[width * height]; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (matrix.get(x, y)) { + pixels[y * width + x] = BLACK; + } + } + } + Bitmap bitmap = Bitmap.createBitmap(width, height, + Bitmap.Config.ARGB_8888); + bitmap.setPixels(pixels, 0, width, 0, 0, width, height); + return bitmap; + } + + /** + * 创建二维码 + * + * @param content content + * @param widthPix widthPix + * @param heightPix heightPix + * @param logoBm logoBm + * @return 二维码 + */ + public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm) { + try { + if (content == null || "".equals(content)) { + return null; + } + // 配置参数 + Map hints = new HashMap<>(); + hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); + // 容错级别 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); + // 图像数据转换,使用了矩阵转换 + BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix, + heightPix, hints); + int[] pixels = new int[widthPix * heightPix]; + // 下面这里按照二维码的算法,逐个生成二维码的图片, + // 两个for循环是图片横列扫描的结果 + for (int y = 0; y < heightPix; y++) { + for (int x = 0; x < widthPix; x++) { + if (bitMatrix.get(x, y)) { + pixels[y * widthPix + x] = 0xff000000; + } else { + pixels[y * widthPix + x] = 0xffffffff; + } + } + } + // 生成二维码图片的格式,使用ARGB_8888 + Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888); + bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix); + if (logoBm != null) { + bitmap = addLogo(bitmap, logoBm); + } + //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大! + return bitmap; + } catch (WriterException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 在二维码中间添加Logo图案 + */ + private static Bitmap addLogo(Bitmap src, Bitmap logo) { + if (src == null) { + return null; + } + if (logo == null) { + return src; + } + //获取图片的宽高 + int srcWidth = src.getWidth(); + int srcHeight = src.getHeight(); + int logoWidth = logo.getWidth(); + int logoHeight = logo.getHeight(); + if (srcWidth == 0 || srcHeight == 0) { + return null; + } + if (logoWidth == 0 || logoHeight == 0) { + return src; + } + //logo大小为二维码整体大小的1/5 + float scaleFactor = srcWidth * 1.0f / 5 / logoWidth; + Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888); + try { + Canvas canvas = new Canvas(bitmap); + canvas.drawBitmap(src, 0, 0, null); + canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2); + canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null); + canvas.save(); + canvas.restore(); + } catch (Exception e) { + bitmap = null; + e.getStackTrace(); + } + return bitmap; + } +} diff --git a/main/java/com/geogle/zxing/view/ViewfinderResultPointCallback.java b/main/java/com/geogle/zxing/view/ViewfinderResultPointCallback.java new file mode 100644 index 0000000..032ff63 --- /dev/null +++ b/main/java/com/geogle/zxing/view/ViewfinderResultPointCallback.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2009 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.view; + +import com.google.zxing.ResultPoint; +import com.google.zxing.ResultPointCallback; + +public final class ViewfinderResultPointCallback implements ResultPointCallback { + private final ViewfinderView viewfinderView; + + public ViewfinderResultPointCallback(ViewfinderView viewfinderView) { + this.viewfinderView = viewfinderView; + } + + public void foundPossibleResultPoint(ResultPoint point) { + viewfinderView.addPossibleResultPoint(point); + } + +} diff --git a/main/java/com/geogle/zxing/view/ViewfinderView.java b/main/java/com/geogle/zxing/view/ViewfinderView.java new file mode 100644 index 0000000..173b6d4 --- /dev/null +++ b/main/java/com/geogle/zxing/view/ViewfinderView.java @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.geogle.zxing.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.ComposeShader; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.RadialGradient; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Shader; +import android.graphics.SweepGradient; +import android.util.AttributeSet; +import android.view.View; + + +import com.google.zxing.ResultPoint; +import com.geogle.zxing.camera.CameraManager; + +import java.util.Collection; +import java.util.HashSet; + +import edu.hzuapps.androidlabs.R; + + +/** + * This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial + * transparency outside it, as well as the laser scanner animation and result points. + * @author dswitkin@google.com (Daniel Switkin) + */ +public final class ViewfinderView extends View { + + private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64}; + private static final long ANIMATION_DELAY = 10L; + private static final int OPAQUE = 0xFF; + private static final int CORNER_RECT_WIDTH = 8; //扫描区边角的宽 + private static final int CORNER_RECT_HEIGHT = 40; //扫描区边角的高 + private static final int SCANNER_LINE_MOVE_DISTANCE = 5; //扫描线移动距离 + private static final int SCANNER_LINE_HEIGHT = 10; //扫描线宽度 + + private final Paint paint; + private Bitmap resultBitmap; + //模糊区域颜色 + private final int maskColor; + private final int resultColor; + //扫描区域边框颜色 + private final int frameColor; + //扫描线颜色 + private final int laserColor; + //四角颜色 + private final int cornerColor; + //扫描点的颜色 + private final int resultPointColor; + private int scannerAlpha; + //扫描区域提示文本 + private final String labelText; + //扫描区域提示文本颜色 + private final int labelTextColor; + private final float labelTextSize; + + public static int scannerStart = 0; + public static int scannerEnd = 0; + + private Collection possibleResultPoints; + private Collection lastPossibleResultPoints; + + // This constructor is used when the class is built from an XML resource. + public ViewfinderView(Context context, AttributeSet attrs) { + super(context, attrs); + + //初始化自定义属性信息 + TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ViewfinderView); + laserColor = array.getColor(R.styleable.ViewfinderView_laser_color, 0x00FF00); + cornerColor = array.getColor(R.styleable.ViewfinderView_corner_color, 0x00FF00); + frameColor = array.getColor(R.styleable.ViewfinderView_frame_color, 0xFFFFFF); + resultPointColor = array.getColor(R.styleable.ViewfinderView_result_point_color, 0xC0FFFF00); + maskColor = array.getColor(R.styleable.ViewfinderView_mask_color, 0x60000000); + resultColor = array.getColor(R.styleable.ViewfinderView_result_color, 0xB0000000); + labelTextColor = array.getColor(R.styleable.ViewfinderView_label_text_color, 0x90FFFFFF); + labelText = array.getString(R.styleable.ViewfinderView_label_text); + labelTextSize = array.getFloat(R.styleable.ViewfinderView_label_text_size, 36f); + + // Initialize these once for performance rather than calling them every time in onDraw(). + paint = new Paint(); + paint.setAntiAlias(true); + scannerAlpha = 0; + possibleResultPoints = new HashSet(5); + + + } + + @Override + public void onDraw(Canvas canvas) { + Rect frame = CameraManager.get().getFramingRect(); + if (frame == null) { + return; + } + if(scannerStart == 0 || scannerEnd == 0) { + scannerStart = frame.top; + scannerEnd = frame.bottom; + } + + int width = canvas.getWidth(); + int height = canvas.getHeight(); + // Draw the exterior (i.e. outside the framing rect) darkened + drawExterior(canvas, frame, width, height); + + + if (resultBitmap != null) { + // Draw the opaque result bitmap over the scanning rectangle + paint.setAlpha(OPAQUE); + canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint); + } else { + // Draw a two pixel solid black border inside the framing rect + drawFrame(canvas, frame); + // 绘制边角 + drawCorner(canvas, frame); + //绘制提示信息 + drawTextInfo(canvas, frame); + // Draw a red "laser scanner" line through the middle to show decoding is active + drawLaserScanner(canvas, frame); + + Collection currentPossible = possibleResultPoints; + Collection currentLast = lastPossibleResultPoints; + if (currentPossible.isEmpty()) { + lastPossibleResultPoints = null; + } else { + possibleResultPoints = new HashSet(5); + lastPossibleResultPoints = currentPossible; + paint.setAlpha(OPAQUE); + paint.setColor(resultPointColor); + for (ResultPoint point : currentPossible) { + canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint); + } + } + if (currentLast != null) { + paint.setAlpha(OPAQUE / 2); + paint.setColor(resultPointColor); + for (ResultPoint point : currentLast) { + canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint); + } + } + + // Request another update at the animation interval, but only repaint the laser line, + // not the entire viewfinder mask. + //指定重绘区域,该方法会在子线程中执行 + postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom); + } + } + + //绘制文本 + private void drawTextInfo(Canvas canvas, Rect frame) { + paint.setColor(labelTextColor); + paint.setTextSize(labelTextSize); + paint.setTextAlign(Paint.Align.CENTER); + canvas.drawText(labelText, frame.left + frame.width() / 2, frame.bottom + CORNER_RECT_HEIGHT * 1.5f, paint); + } + + + //绘制边角 + private void drawCorner(Canvas canvas, Rect frame) { + paint.setColor(cornerColor); + //左上 + canvas.drawRect(frame.left, frame.top, frame.left + CORNER_RECT_WIDTH, frame.top + CORNER_RECT_HEIGHT, paint); + canvas.drawRect(frame.left, frame.top, frame.left + CORNER_RECT_HEIGHT, frame.top + CORNER_RECT_WIDTH, paint); + //右上 + canvas.drawRect(frame.right - CORNER_RECT_WIDTH, frame.top, frame.right, frame.top + CORNER_RECT_HEIGHT, paint); + canvas.drawRect(frame.right - CORNER_RECT_HEIGHT, frame.top, frame.right, frame.top + CORNER_RECT_WIDTH, paint); + //左下 + canvas.drawRect(frame.left, frame.bottom - CORNER_RECT_WIDTH, frame.left + CORNER_RECT_HEIGHT, frame.bottom, paint); + canvas.drawRect(frame.left, frame.bottom - CORNER_RECT_HEIGHT, frame.left + CORNER_RECT_WIDTH, frame.bottom, paint); + //右下 + canvas.drawRect(frame.right - CORNER_RECT_WIDTH, frame.bottom - CORNER_RECT_HEIGHT, frame.right, frame.bottom, paint); + canvas.drawRect(frame.right - CORNER_RECT_HEIGHT, frame.bottom - CORNER_RECT_WIDTH, frame.right, frame.bottom, paint); + } + + //绘制扫描线 + private void drawLaserScanner(Canvas canvas, Rect frame) { + paint.setColor(laserColor); + //扫描线闪烁效果 +// paint.setAlpha(SCANNER_ALPHA[scannerAlpha]); +// scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length; +// int middle = frame.height() / 2 + frame.top; +// canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint); + //线性渐变 + LinearGradient linearGradient = new LinearGradient( + frame.left, scannerStart, + frame.left, scannerStart + SCANNER_LINE_HEIGHT, + shadeColor(laserColor), + laserColor, + Shader.TileMode.MIRROR); + + RadialGradient radialGradient = new RadialGradient( + (float)(frame.left + frame.width() / 2), + (float)(scannerStart + SCANNER_LINE_HEIGHT / 2), + 360f, + laserColor, + shadeColor(laserColor), + Shader.TileMode.MIRROR); + + SweepGradient sweepGradient = new SweepGradient( + (float)(frame.left + frame.width() / 2), + (float)(scannerStart + SCANNER_LINE_HEIGHT), + shadeColor(laserColor), + laserColor); + + ComposeShader composeShader = new ComposeShader(radialGradient, linearGradient, PorterDuff.Mode.ADD); + + paint.setShader(radialGradient); + if(scannerStart <= scannerEnd) { + //矩形 +// canvas.drawRect(frame.left, scannerStart, frame.right, scannerStart + SCANNER_LINE_HEIGHT, paint); + //椭圆 + RectF rectF = new RectF(frame.left + 2 * SCANNER_LINE_HEIGHT, scannerStart, frame.right - 2 * SCANNER_LINE_HEIGHT, scannerStart + SCANNER_LINE_HEIGHT); + canvas.drawOval(rectF, paint); + scannerStart += SCANNER_LINE_MOVE_DISTANCE; + } else { + scannerStart = frame.top; + } + paint.setShader(null); + } + + //处理颜色模糊 + public int shadeColor(int color) { + String hax = Integer.toHexString(color); + String result = "20"+hax.substring(2); + return Integer.valueOf(result, 16); + } + + // 绘制扫描区边框 Draw a two pixel solid black border inside the framing rect + private void drawFrame(Canvas canvas, Rect frame) { + paint.setColor(frameColor); + canvas.drawRect(frame.left, frame.top, frame.right + 1, frame.top + 2, paint); + canvas.drawRect(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1, paint); + canvas.drawRect(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1, paint); + canvas.drawRect(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1, paint); + } + + // 绘制模糊区域 Draw the exterior (i.e. outside the framing rect) darkened + private void drawExterior(Canvas canvas, Rect frame, int width, int height) { + paint.setColor(resultBitmap != null ? resultColor : maskColor); + canvas.drawRect(0, 0, width, frame.top, paint); + canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint); + canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint); + canvas.drawRect(0, frame.bottom + 1, width, height, paint); + } + + public void drawViewfinder() { + resultBitmap = null; + invalidate(); + } + + /** + * Draw a bitmap with the result points highlighted instead of the live scanning display. + * + * @param barcode An image of the decoded barcode. + */ + public void drawResultBitmap(Bitmap barcode) { + resultBitmap = barcode; + invalidate(); + } + + public void addPossibleResultPoint(ResultPoint point) { + possibleResultPoints.add(point); + } + +} diff --git a/main/java/edu/hzuapps/androidlabs/MainActivity.java b/main/java/edu/hzuapps/androidlabs/MainActivity.java new file mode 100644 index 0000000..fb58aa9 --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/MainActivity.java @@ -0,0 +1,14 @@ +package edu.hzuapps.androidlabs; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; + +public class MainActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + } +} \ No newline at end of file diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/CollectFragment.java b/main/java/edu/hzuapps/androidlabs/watchtv/CollectFragment.java new file mode 100644 index 0000000..b308b4c --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/CollectFragment.java @@ -0,0 +1,88 @@ +package edu.hzuapps.androidlabs.watchtv; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +import android.os.Parcelable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +import edu.hzuapps.androidlabs.R; +import edu.hzuapps.androidlabs.watchtv.room.Programs; + + +public class CollectFragment extends Fragment { + + ListView listView; + View rootView; + List dataList; + ArrayList tagList; + + public CollectFragment() { + // Required empty public constructor + } + + public static CollectFragment newInstances(List list, ArrayList tag){ + CollectFragment collectFragment = new CollectFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList("data", (ArrayList) list); + bundle.putStringArrayList("tag",tag);; + collectFragment.setArguments(bundle); + return collectFragment; + } + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if(getArguments()!=null){ + dataList = getArguments().getParcelableArrayList("data"); + tagList = getArguments().getStringArrayList("tag"); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + if(rootView == null){ + rootView = inflater.inflate(R.layout.fragment_collect, container, false); + } + // Inflate the layout for this fragment + initview(); + return rootView; + } + + private void initview() { + listView = rootView.findViewById(R.id.lv_home); + listView.setAdapter(new MyBaseAdapter(dataList,tagList,this.getContext())); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + String str = dataList.get(position).getAddr(); + ClipboardManager cm; + ClipData mClipData; + //获取剪贴板管理器: + cm = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); + // 创建普通字符型ClipData + mClipData = ClipData.newPlainText("Label", str); + // 将ClipData内容放到系统剪贴板里。 + cm.setPrimaryClip(mClipData); + Toast.makeText(getContext(), "视频地址已复制到剪切板", + Toast.LENGTH_SHORT).show(); + + } + }); + } +} \ No newline at end of file diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/HomeFragment.java b/main/java/edu/hzuapps/androidlabs/watchtv/HomeFragment.java new file mode 100644 index 0000000..bde221c --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/HomeFragment.java @@ -0,0 +1,108 @@ +package edu.hzuapps.androidlabs.watchtv; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; +import android.graphics.Point; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; + +import androidx.annotation.RequiresApi; +import androidx.fragment.app.Fragment; + +import android.util.Log; +import android.view.GestureDetector; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.MediaController; +import android.widget.RelativeLayout; +import android.widget.VideoView; + +import edu.hzuapps.androidlabs.R; +import edu.hzuapps.androidlabs.watchtv.until.ToolUtils; + +import static android.content.Context.WINDOW_SERVICE; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link HomeFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class HomeFragment extends Fragment implements View.OnClickListener { + + View rootView; + protected Button play; + protected VideoView videoView; + protected EditText edittext; + protected Button newplayer; + + + + public HomeFragment() { + // Required empty public constructor + } + + + public static HomeFragment newInstance() { + HomeFragment fragment = new HomeFragment(); + + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + if(rootView == null){ + rootView = inflater.inflate(R.layout.fragment_home, container, false); + } + edittext = rootView.findViewById(R.id.et_home); + play = rootView.findViewById(R.id.bt_play); + videoView = rootView.findViewById(R.id.vv_home); + videoView.setMediaController(new MediaController(rootView.getContext())); + videoView.setVisibility(View.INVISIBLE); + play.setOnClickListener(this); + newplayer = rootView.findViewById(R.id.newplayer); + newplayer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(getContext(),MovieActivity.class); + intent.setData(Uri.parse(edittext.getText().toString())); + startActivity(intent); + } + }); + + + + + return rootView; + } + + @Override + public void onClick(View v) { + if(videoView!=null && videoView.isPlaying()){ + videoView.stopPlayback(); + } + videoView.setVideoURI(Uri.parse(edittext.getText().toString())); + videoView.setVisibility(View.VISIBLE); + videoView.start(); + } + + + + + +} \ No newline at end of file diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/MovieActivity.java b/main/java/edu/hzuapps/androidlabs/watchtv/MovieActivity.java new file mode 100644 index 0000000..e4c01ae --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/MovieActivity.java @@ -0,0 +1,65 @@ +package edu.hzuapps.androidlabs.watchtv; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Context; +import android.content.res.Configuration; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.MediaController; +import android.widget.RelativeLayout; +import android.widget.VideoView; + +import edu.hzuapps.androidlabs.R; + +public class MovieActivity extends AppCompatActivity { + + VideoView videoView ; + EditText editText; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_movie); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.hide(); //隐藏标题栏 + } + + videoView = findViewById(R.id.videoview); + editText = findViewById(R.id.et_home); + videoView.setMediaController(new MediaController(this)); + videoView.setVideoURI(getIntent().getData()); + videoView.start(); + } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + videoView = findViewById(R.id.videoview); + if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,dip2px(this,235f)); + params.addRule(RelativeLayout.CENTER_IN_PARENT); + videoView.setLayoutParams(params); + } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + + videoView.setLayoutParams(new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT)); + } + } + + /** + * 根据手机的分辨率从 dp 的单位 转成为 px(像素) + */ + public static int dip2px(Context context, float dpValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + + } +} \ No newline at end of file diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/MyBaseAdapter.java b/main/java/edu/hzuapps/androidlabs/watchtv/MyBaseAdapter.java new file mode 100644 index 0000000..01cae42 --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/MyBaseAdapter.java @@ -0,0 +1,56 @@ +package edu.hzuapps.androidlabs.watchtv; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import java.util.List; + +import edu.hzuapps.androidlabs.R; +import edu.hzuapps.androidlabs.watchtv.room.Programs; + +public class MyBaseAdapter extends BaseAdapter { + + private List data; + private List datatag; + private Context context; + + public MyBaseAdapter(List data,List datatag, Context context) { + this.data = data; + this.datatag = datatag; + this.context = context; + } + + @Override + public int getCount() { + return data.size(); + } + + @Override + public Object getItem(int position) { + return null; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + if(datatag.contains(data.get(position).getName())){ + convertView = LayoutInflater.from(context).inflate(R.layout.list_item_tag, parent, false); + }else{ + convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false); + } + + } + TextView textview = convertView.findViewById(R.id.tv_item); + textview.setText(data.get(position).getName()); + return convertView; + } +} diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/MyFragmentAdapter.java b/main/java/edu/hzuapps/androidlabs/watchtv/MyFragmentAdapter.java new file mode 100644 index 0000000..d105a7a --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/MyFragmentAdapter.java @@ -0,0 +1,31 @@ +package edu.hzuapps.androidlabs.watchtv; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.Lifecycle; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import java.util.ArrayList; +import java.util.List; + +public class MyFragmentAdapter extends FragmentStateAdapter { + + List list = new ArrayList<>(); + + public MyFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle,List flist) { + super(fragmentManager, lifecycle); + list = flist; + } + + @NonNull + @Override + public Fragment createFragment(int position) { + return list.get(position); + } + + @Override + public int getItemCount() { + return list.size(); + } +} diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/MyVideoView.java b/main/java/edu/hzuapps/androidlabs/watchtv/MyVideoView.java new file mode 100644 index 0000000..e3259c4 --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/MyVideoView.java @@ -0,0 +1,32 @@ +package edu.hzuapps.androidlabs.watchtv; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.VideoView; + +public class MyVideoView extends VideoView { + public MyVideoView(Context context) { + super(context); + } + + public MyVideoView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public MyVideoView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int width = getDefaultSize(0, widthMeasureSpec); + int height = getDefaultSize(0, heightMeasureSpec); + setMeasuredDimension(width,height); + + } + + +} diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/SelectActivity.java b/main/java/edu/hzuapps/androidlabs/watchtv/SelectActivity.java new file mode 100644 index 0000000..9a1c9ee --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/SelectActivity.java @@ -0,0 +1,35 @@ +package edu.hzuapps.androidlabs.watchtv; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; + +import edu.hzuapps.androidlabs.R; + +public class SelectActivity extends AppCompatActivity implements View.OnClickListener { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_select); + + Button back = findViewById(R.id.btn_back); + back.setOnClickListener(this); + Button search = findViewById(R.id.btn_search); + search.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + switch (v.getId()){ + case R.id.btn_search: + break; + case R.id.btn_back: + finish(); + break; + } + } +} \ No newline at end of file diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/UserFragment.java b/main/java/edu/hzuapps/androidlabs/watchtv/UserFragment.java new file mode 100644 index 0000000..b6b9e0c --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/UserFragment.java @@ -0,0 +1,59 @@ +package edu.hzuapps.androidlabs.watchtv; + +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.CircleCrop; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; + +import edu.hzuapps.androidlabs.R; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link UserFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class UserFragment extends Fragment { + + View rootview; + + + public UserFragment() { + // Required empty public constructor + } + + + public static UserFragment newInstance() { + UserFragment fragment = new UserFragment(); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + if(rootview == null){ + rootview = inflater.inflate(R.layout.fragment_user, container, false); + } + ImageView imageView = rootview.findViewById(R.id.imageView); + Glide.with(this) + .load(R.drawable.myphoto) + .apply(RequestOptions.bitmapTransform(new RoundedCorners(180))) + .into(imageView); + // Inflate the layout for this fragment + return rootview; + } +} \ No newline at end of file diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/WatchTVActivity.java b/main/java/edu/hzuapps/androidlabs/watchtv/WatchTVActivity.java new file mode 100644 index 0000000..7d1e95e --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/WatchTVActivity.java @@ -0,0 +1,300 @@ +package edu.hzuapps.androidlabs.watchtv; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.viewpager2.widget.ViewPager2; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.net.Uri; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.MediaController; +import android.widget.RelativeLayout; +import android.widget.Toast; +import android.widget.VideoView; + +import com.dommy.qrcode.util.Constant; +import com.geogle.zxing.activity.CaptureActivity; + +import java.util.ArrayList; +import java.util.List; + +import edu.hzuapps.androidlabs.R; +import edu.hzuapps.androidlabs.watchtv.room.Programs; +import edu.hzuapps.androidlabs.watchtv.room.manager.DBEngine; + +public class WatchTVActivity extends AppCompatActivity implements View.OnClickListener{ + + private static final String TAG = "zhu"; + final WatchTVActivity thisActivity = this; + private List data = null; + private ArrayList datatag = null; + private Context thiscontext = this; + + protected ViewPager2 viewPager; + protected LinearLayout lhome,lstar,lacc; + protected ImageView ivhome,ivstar,ivacc,ivcurr; + protected Button btnSearch,btnScanner,btnMore; + + + + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_watch_t_v); + + ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE}, + 100); + + DBEngine db = new DBEngine(thiscontext); + + // dataInit(); + // data = dataQuery(); + dataInit(); + initPage(); + initMoudle(); + + + } + + private List dataQuery() { + List list = new ArrayList(); +// Resources resources = getResources(); +// String[] name = resources.getStringArray(R.array.name); +// String[] url = resources.getStringArray(R.array.addr); +// for (int i = 0; i < name.length; i++) { +// Programs programs = new Programs(); +// programs.setName(name[i]); +// programs.setAddr(url[i]); +// programs.setId(i); +// list.add(programs); +// } +// DBEngine db = new DBEngine(this); +// List list = db.queryAllPrograms(); + + + return list; + } + + private void dataInit() { + + data = new ArrayList<>(); + datatag = new ArrayList(); + Resources resources = getResources(); + String[] url = resources.getStringArray(R.array.addr); + datatag.add("新闻"); + Programs p = new Programs(); + p.setName("新闻"); + data.add(p); + int index = 0; + for (int i = 0; i < 5; i++) { + Programs programs = new Programs(); + programs.setName("新闻"+(i+1)); + programs.setAddr(url[index]); + programs.setId(index++); + data.add(programs); + } + + datatag.add("娱乐"); + p = new Programs(); + p.setName("娱乐"); + data.add(p); + for (int i = 0; i < 5; i++) { + Programs programs = new Programs(); + programs.setName("娱乐"+(i+1)); + programs.setAddr(url[index]); + programs.setId(index++); + data.add(programs); + } + datatag.add("自然"); + p = new Programs(); + p.setName("自然"); + data.add(p); + for (int i = 0; i < 5; i++) { + Programs programs = new Programs(); + programs.setName("自然"+(i+1)); + programs.setAddr(url[index]); + programs.setId(index++); + data.add(programs); + } + } + + private void initPage(){ + viewPager = findViewById(R.id.vp_mid); + ArrayList fragments= new ArrayList<>(); + fragments.add(HomeFragment.newInstance()); + fragments.add(CollectFragment.newInstances(data,datatag)); + fragments.add(UserFragment.newInstance()); + viewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(),getLifecycle(),fragments)); + viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + super.onPageScrolled(position, positionOffset, positionOffsetPixels); + } + + @Override + public void onPageSelected(int position) { + super.onPageSelected(position); + changTab(position); + } + + @Override + public void onPageScrollStateChanged(int state) { + super.onPageScrollStateChanged(state); + } + }); + } + + + + private void initMoudle(){ + lhome = findViewById(R.id.part_home); + lstar = findViewById(R.id.part_collect); + lacc = findViewById(R.id.ll_friend); + ivhome = findViewById(R.id.iv_home); + ivstar = findViewById(R.id.iv_collect); + ivacc = findViewById(R.id.iv_user); + btnSearch = findViewById(R.id.btn_search); + btnScanner = findViewById(R.id.btn_scanner); + btnMore = findViewById(R.id.btn_more); + + lhome.setOnClickListener(this); + lstar.setOnClickListener(this); + lacc.setOnClickListener(this); + btnSearch.setOnClickListener(this); + btnScanner.setOnClickListener(this); + btnMore.setOnClickListener(this); + + ivcurr = ivhome; + ivhome.setSelected(true); + } + + private void changTab(int position) { + ivcurr.setSelected(false); + switch (position){ + case R.id.part_home: + viewPager.setCurrentItem(0); + case 0: + ivhome.setSelected(true); + ivcurr = ivhome; + break; + case R.id.part_collect: + viewPager.setCurrentItem(1); + case 1: + ivstar.setSelected(true); + ivcurr = ivstar; + break; + case R.id.ll_friend: + case R.id.btn_more: + viewPager.setCurrentItem(2); + case 2: + ivacc.setSelected(true); + ivcurr = ivacc; + break; + } + } + + @Override + public void onClick(View v) { + switch (v.getId()){ + case R.id.btn_more: + case R.id.part_home: + case R.id.part_collect: + case R.id.ll_friend: + changTab(v.getId()); + break; + case R.id.btn_search: + Intent intent = new Intent(thisActivity, SelectActivity.class); + thisActivity.startActivity(intent); + break; + case R.id.btn_scanner: + startQrCode(); + break; + } + + } + + // 开始扫码 + private void startQrCode() { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { + Toast.makeText(WatchTVActivity.this, "请至权限中心打开本应用的相机访问权限", Toast.LENGTH_LONG).show(); + } + // 申请权限 + ActivityCompat.requestPermissions(WatchTVActivity.this, new String[]{Manifest.permission.CAMERA}, Constant.REQ_PERM_CAMERA); + return; + } + // 二维码扫码 + Intent intent = new Intent(WatchTVActivity.this, CaptureActivity.class); + startActivityForResult(intent, Constant.REQ_QR_CODE); + } + + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + String result = ""; + //扫描结果回调 + if (requestCode == Constant.REQ_QR_CODE && resultCode == RESULT_OK) { + if (data != null) { + Bundle bundle = data.getExtras(); + if (bundle == null) { + return; + } + result = bundle.getString(Constant.INTENT_EXTRA_KEY_QR_SCAN); + } + } + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(result)); //splitflowurl为分流地址 + if (!hasPreferredApplication(this,intent)){ + intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity"); + } + startActivity(intent); + + } + + public static boolean hasPreferredApplication(Context context, Intent intent) { + PackageManager pm = context.getPackageManager(); + ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); + return !"android".equals(info.activityInfo.packageName); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + switch (requestCode) { + case Constant.REQ_PERM_CAMERA: + // 摄像头权限申请 + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // 获得授权 + startQrCode(); + } else { + // 被禁止授权 + Toast.makeText(WatchTVActivity.this, "请至权限中心打开本应用的相机访问权限", Toast.LENGTH_LONG).show(); + } + break; + } + } + + +} \ No newline at end of file diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/room/Programs.java b/main/java/edu/hzuapps/androidlabs/watchtv/room/Programs.java new file mode 100644 index 0000000..e44181c --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/room/Programs.java @@ -0,0 +1,93 @@ +package edu.hzuapps.androidlabs.watchtv.room; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.room.Entity; +import androidx.room.Ignore; +import androidx.room.PrimaryKey; + +@Entity +public class Programs implements Parcelable { + + @PrimaryKey(autoGenerate = true) + private int id; + private String name; + private String addr; + + @Ignore + public Programs() { + } + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddr() { + return addr; + } + + public void setAddr(String addr) { + this.addr = addr; + } + + public Programs(int id, String name, String addr) { + this.id = id; + this.name = name; + this.addr = addr; + } + + @Override + public String toString() { + return "Programs{" + + "id=" + id + + ", name='" + name + '\'' + + ", addr='" + addr + '\'' + + '}'; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(id); + dest.writeString(name); + dest.writeString(addr); + } + + public static final Parcelable.Creator CREATOR = new Creator(){ + + @Override + public Programs createFromParcel(Parcel source) { + // TODO Auto-generated method stub + // 必须按成员变量声明的顺序读取数据,不然会出现获取数据出错 + Programs p = new Programs(); + p.setId(source.readInt()); + p.setName(source.readString()); + p.setAddr(source.readString()); + return p; + } + + @Override + public Programs[] newArray(int size) { + // TODO Auto-generated method stub + return new Programs[size]; + } + }; +} diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/room/ProgramsDao.java b/main/java/edu/hzuapps/androidlabs/watchtv/room/ProgramsDao.java new file mode 100644 index 0000000..296edb3 --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/room/ProgramsDao.java @@ -0,0 +1,16 @@ +package edu.hzuapps.androidlabs.watchtv.room; + +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.Query; + +import java.util.List; + +@Dao +public interface ProgramsDao { + @Insert + void insertPrograms(Programs... programs); + + @Query("SELECT * FROM programs") + List queryAllPrograms(); +} diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/room/ProgramsDatabase.java b/main/java/edu/hzuapps/androidlabs/watchtv/room/ProgramsDatabase.java new file mode 100644 index 0000000..ad39fce --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/room/ProgramsDatabase.java @@ -0,0 +1,24 @@ +package edu.hzuapps.androidlabs.watchtv.room; + +import android.content.Context; + +import androidx.room.Database; +import androidx.room.Room; +import androidx.room.RoomDatabase; + +@Database(entities = {Programs.class},version = 1,exportSchema = false) +public abstract class ProgramsDatabase extends RoomDatabase { + + public abstract ProgramsDao getProgramsDao(); + + private static ProgramsDatabase INSTANCE; + public static synchronized ProgramsDatabase getINSTANCE(Context context){ + if(INSTANCE == null){ + INSTANCE = Room.databaseBuilder + (context.getApplicationContext(),ProgramsDatabase.class,"programe_database") + .allowMainThreadQueries() + .build(); + } + return INSTANCE; + } +} diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/room/manager/DBEngine.java b/main/java/edu/hzuapps/androidlabs/watchtv/room/manager/DBEngine.java new file mode 100644 index 0000000..705cf35 --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/room/manager/DBEngine.java @@ -0,0 +1,49 @@ +package edu.hzuapps.androidlabs.watchtv.room.manager; + +import android.content.Context; + +import java.util.List; + +import edu.hzuapps.androidlabs.watchtv.room.Programs; +import edu.hzuapps.androidlabs.watchtv.room.ProgramsDao; +import edu.hzuapps.androidlabs.watchtv.room.ProgramsDatabase; + +public class DBEngine{ + + private ProgramsDao programsDao; + private List list; + private String teststr; + + + public DBEngine(Context context) { + ProgramsDatabase programsDatabase = ProgramsDatabase.getINSTANCE(context); + programsDao = programsDatabase.getProgramsDao(); + } + + public void insertPrograms(Programs... programs) { + programsDao.insertPrograms(programs); + } + + + public List queryAllPrograms() { + List list = programsDao.queryAllPrograms(); + return list; + } + +// private static class InsertAsyncTask extends AsyncTask{ +// +// private ProgramsDao dao; +// +// public InsertAsyncTask(ProgramsDao dao) { +// this.dao = dao; +// } +// +// @Override +// protected Void doInBackground(Programs... programs) { +// dao.insertPrograms(programs); +// return null; +// } +// } + + +} diff --git a/main/java/edu/hzuapps/androidlabs/watchtv/until/ToolUtils.java b/main/java/edu/hzuapps/androidlabs/watchtv/until/ToolUtils.java new file mode 100644 index 0000000..95a80bf --- /dev/null +++ b/main/java/edu/hzuapps/androidlabs/watchtv/until/ToolUtils.java @@ -0,0 +1,13 @@ +package edu.hzuapps.androidlabs.watchtv.until; + +import androidx.fragment.app.FragmentActivity; + +public class ToolUtils { + + public static int dip2px(FragmentActivity context, float dpValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } + + +} diff --git a/main/res/drawable-v24/ic_launcher_foreground.xml b/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..cc14f03 --- /dev/null +++ b/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/main/res/drawable-v24/logo.jpg b/main/res/drawable-v24/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..077f572baf11c7762ce2d34aee9f505f8383bd3b GIT binary patch literal 28498 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 z z%|`)<0MF_Ns%H5P=NoR=PHR0NbY4A+9qfVDIY7$fqdHiTB%ZaL^)>MY*(@4>14#LS z_UzwT7tq1CwYC7ct+d6Gl!cT}U4eH1{T^~6MFNx2V5(6S{K_Cx8(n$4^UDFClsTZi z^%Kh5n)g}JX#ksd=^;GN%%5`;=nkj9nkYahtQB1)I?l6L>#KFQW?Tw0;V)sU^;KJ8 zn-53Do6mjNE%oBN-R;ru3ohcLmLk%Q+wm?2tm-e_5&9#YxJX=UN?6=r%6QoqVsdK| ztc}w)&RIl4{eU(qR2fX$SdfF0>;n4~0O2JHc1zMVc`tjSnLv!ld85B<1i;tqi(7NS z0xZ&k;%&SUZ=>Wo=vBpkTmHx0t{=bFPnCSy6HI6YK!t1>N!&WXx<uHquvu8#pl zCd}n-;7B=qc-%Z^?yJVTtWq(0abtEc8VIzx`8!w(PmPuPBUe{9`{U$5l$jsUjh|~f zNLfv+leGYp=Zzpx(U~3Vd&C&(anTq7d>HVgj-EsYceq)ah2$xxq(G$SZzDD|O{I_t z_dmr09}z#+a5V42D|P$xS#(#f8aP6A=Cm`E)(lAf=Q0|N<7HY~Sbpjgx=jp$ zqA?@cKDgmVYPs&T)GXWU-a+YKzgq%Er%%hJP@e;MVsR5o((~zT)o)+=Hl;r}S`*(C zB3j2G85rJx~ZJYgMpff`_dqonKTMw0ZDc;el_j_aGv3t*+#ciR( z&J0_^qt;SpZ+S4xm@@X|aZ-whj2+J?s=EsiUL$MkV zWXJH8uj=B9$4|TZzy%+aKYMU{2ncRY#Yd;m+4M;sd(DB$HTd}LMU&N)4MPS>r|oca zFvXpNd*lDI-;i4LrDH>gcJfoeXZ&)9=p7%E`GQa{#`iyJ{SZtKL2NkjDXU4Yc0aGN z`T0LSQj_&uBB&xF{Z!H?=iwp9H5{~yNqDodJ%!QVf}>#oS_ z{uw`)ehd5Dt{PK^4>$LKt+?%8-YMKup91j9V6U;ZD^x)dK+n}+Nh$mpS!Y;qMHYD) zof>#$+L2=`G9vFUlaAxPn61r6HAD^xEXXve7BU#`ihp|3VKjSxEjqDLb>P>%Mz_cGe`yswYvvx%~dON~4%1a1;r>9SVVV zQh3GjlKX3kiK0OKvA5ms*Yc0I;JpFY&)xtDfL=}Zj{X&+lT$6ksA5g@&XEnh`~ zMF055|1v7!PKXDuO^QyFJv@x>u8`kYxBtrT@I}(3+2{Yl4jh8n%vZzi%lap~)lccx zS{%;c}6v_*b0~W>5uu23kx9s1loW3`~7Cu HpZ)&_yd{z3 literal 0 HcmV?d00001 diff --git a/main/res/drawable/abc_ic_menu_moreoverflow_mtrl_alpha.png b/main/res/drawable/abc_ic_menu_moreoverflow_mtrl_alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..c695e316c7636dc1784994ce123134e98f2536be GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sx&b~Ru0Z-f(O{v+>e)aI{3Stt z!3>(4zJA%L{^9@o^`F*?Yc;&J@#r0s$X3Ic~a{3{av7kYBf=sUD( z?J@P_6Z<2cJ5On^J=NVLttYRg^Fv!hrzKo5ZsEbEDSO{D@Aq7lC7si$yHR!9k!c)f YSb9=e3%kqafPBH=>FVdQ&MBb@0G^#`NdN!< literal 0 HcmV?d00001 diff --git a/main/res/drawable/account_select.xml b/main/res/drawable/account_select.xml new file mode 100644 index 0000000..5686596 --- /dev/null +++ b/main/res/drawable/account_select.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/main/res/drawable/btn_back.png b/main/res/drawable/btn_back.png new file mode 100644 index 0000000000000000000000000000000000000000..8079ece0477d0246fbd0ab618aa06191eca08042 GIT binary patch literal 172375 zcmeF)TaP5?c_(;bFBXdd<^$|rH8?jGc1w(ijEIaNteMT@jDgXt?GZ2r7JHFZnI#b; zi5!x)q`_Q}mPnD5C{h-6B&j1M(URGuEZRIYDFSo1Ut(|ERb74Mudu%-ve;x-$D5VG z;Q~8=eUQlReB(Vo$N%$xpZMc{_pkr?Kl@+)*~dQiv48$Y|7QND{`-HA|No!+}^q>FZQMp^vS!r@808|q_^NhyLRy@7fOP&p!3XS7!G;u(?uwVsvnn z<@uGm{zP6@b)EljSBfkz?#}#QeUO*;RP{Z@_{#bJ+@-e%*2nk!>3n(Kmw)@@U7vmE zq5JQ-`|dA(@r$4M;^-6iJ@A>k^R{i{8%1&87Y7f1`3n!NzI5<~2mi%;Uzl$mJbK{X z`yaaZzAs#fFRl*n`}2oBd6$uHr||jvZ+-R)51ucR1-tu8tNZWHKas_hx*x8OZvF25 zKY!qJUFYkgyEmWPe17wVhaU9X{MK)+(x*Ok>*u|n{ru-|{rbU&7Jp$x=X2}*^@E@O z^8K5;|8(=I32}pKfZ5$@9~!} z{ptGXp5yx-`25NO-y0X??)$&+nXb1_ed?Y+`oe<`t-f%y`J?$K?=sX++TG(Q15{)vGw#-4VOz-`xA4t@!f!W%>7;|8)LO zpS$-;cdG7L9mT=_Dg`MmuXKfCeK9oxC>{lRkyHTjH{>OCwz zQGVdW+?^W#gR8&TJ^Hq(>U`DY2Sr;R9~|Z7_@K?J@}M2p$8FJ6$Lo6Y-t2ov-;h4< zov#l$`t!v(`t0fppV^S5ci;8l=d)_drYct1LAk23gTuN!I%tc-&B3^A%l7!VZr9_y zZ$9-w;d0gY#Q#-8=ktN9yIq0{Q@J|?==PM|eenQp|9!rB;9fhmeBi#%TMd%tp1z~D z@8qKWy62+pbyQ>RZ^^HFKE3(UL;rU5<;?>Ro*%L4>ND>jw)cP6{pR1TK2KWB?z{iX zZt76C$@c` zJogh_o<01H)7P&3*VnIHf8(tf!Pg!(f<&jgTI}81jc0%SUtj-VXIDQQ@HuVr+xYKxz|p=`|2G7e$rq0cr3+x z=fJ0K{N@MO-+1cuiFZ%G{^-qze|Y1^zqtP96Nak0?cW;w_Rk&cIE&wUGXCM`ubzJY zo2GN}=-;1Q{mPBsUc3JG+b54bdUEy6)9=4>YlPZb|C?WV>E!XpV*Jfhe}rKxSlaQc%sPoKJaa`i_yfAHw(R~|ii?C(yWe&+h`pX=77a39Vm za_!OWpKq5j_Ql1!_WZU(3v%-ZFP^^qV%(M&zkB_SZ=V0`1HW({;?v(Wh~FZi{_ z*WY;3SN*dgIPK@h?7iMT*lIgczx?>g3tuA`tmgJ~I^t(P{l?jAKepxFuDtPtkDZ^~ zH=a3p`t>U#yK>{&)90(-$ryLw#XZNael{M`ufRRPdiM`$Jx7IJA3Ol*RQ>E zcJ;-xS03pG9b)_Bso$Mn%a?zC^7hl)PU7f4ZEn9f`{wH>zmJRL6rTO+t0z}~xcz|@ zGT`fP{l@C~lrwbl_}2(a;_x5ee(v=7UmM%DqwCim-Tv&hk2td3nY;e>4^O`J{cS@t zy>(A~Hbn0$Z*G5}i|udh`q|Z=p1u2=^*MR^`z}&+y%zu3dlUJEu?m z_~gakI+^hgSAW-i_O|n|6#;s*bZ4*qTr0mhzgO=Gi0!Age`_Lc$966!Pk-yiH(%Y3 z{N^JspFIAmJv#kn7@#qLPIZT{@Uv%se12=XQElgV^Ltls{_Oj4DxA{aeBGJ3{_fS& zXW!g@@O-{x)-Qi?^4+gmt{Yc>8bAIe3H8LuyN}ue|9bYy>svXs9diutxu4v;_N|kv zKeL;m7~IOvl!zg9AGz_}r%&E}=j4^Q&%XBB`QTsp(dqBLvmNlI)4y`^90~Nu_SbQI z>HN~g+3Kh3Z@hf+)HjKa(^tQB^5}14XPwk0ooyQ1b zC;a+b-~5M%-SeL24(E-l?#o-(-~H+7Bd@%7CF7i!(dm;fp1$zY>%af{KRoRJ9`TV| zzdw7&b^H6?-<&@G@Xg+Y?y7_~jk$}cECMZJ4>_S2W*sJ`)JjE5ES_D^mS`LT?lv+0717r*lxxA(=dB&EaH+?osB z&As{4zq|Ru&wTmhjj#Cf**kx8_Rc%eMfc^CXF_yef8*;XkAH951*J=jcULctZXEk( ze(A<+zqu92=c9e`tM-dpiR;i=B->&9{rqEwwvuAo;>%n8`r*l>jTxtKRAXHcmF#- zaO!Tn{M}fvTx^{v4)AHV+lt7pFtE#xO> zue@{i>Wg7Oz4ewcT>m|*{&(AdJ$dGFyBnwe1B=<7FXqioM&EqyF*DF>EZ2*_kM7@i z!<~#jdGW22mx#Yd&K~*U^|!xw=Zwz>bgA$EUlM-Of4Q{fi7UA{?C1$rr!^_;@8$Y;q^3Hcs-{1b_W#6FB&wl@HX7$#Nr7ze= ziBIC$oCw_nO+>dtd zYVzlo_2V2~f9L6)-@ff9mwoTHbDM}2esEha``%X3CN}K+FE9JXts{T)*NpW?_PEXO z|8S3Q^ZW_^Tb;1$w#)gCZ$B>AkX?W0sk5*D_Vl}7qkK-k^XkdV-}}e6Q*m)0`A}cm zW0YHwX2rO#ySMv2@ps#AFYDnW-}m>@3A`xQF%xW$Tkrt|(%0y+Ib471Z+(G|zV)5= z?7zQc;l*W&L`Wco`?j5%h~mRf4CS zHk5PY$1gJ?Z(YCB7k<%&MgMxc9#-P?Z-2^Uw+gubp#Scd=4`xQq%dqn{1^@}6iW(Z|QF8syG+Ybu>N1W&vFJ1Vn zD-s*0-}{Agb@OXa`@8MnZ~W>NvE>UtJ&zuBakAU~>iQesKKbpBw#V(Zzwj^ThcG0` zS8o05jjz0XgOFr6+on*sal}EvNTA z@P#W^?mND6<#YG_#pcSD{{Twyz?Ca-CEGtqeE8C4m)?gD7?*=mz>Lw`e}7p|w=Q{N zD)0aOWnWr-_Q8XHU1wL8xBlnK$*WJFe*fF=f1=-R+N0rReajDqczpFWCpj^Z+kSG{ z_qM9=c*d)Gp+fOe0UPMKH@Y2bTz8>*5{bfCU(Ed+or`vvV+4pY#^1ISPi7%c1u($<8P)uv;E7A{mK?mk{HUB z^S{0HD{{XlZ~Zv+mGi&7>?@aNI4%omU;c$l&9hs!elkb0J56(W`)&vw9C?f5z59Jp za~sn4{Xc#WY(D|`572xc4)|Y6p)ck|J|1PoENil6UV)R(@_IHZ7VT)!{$bbU=kC3Q z9R8PCJ}D+@1?ncRmgTH!$9dUmoafVJ(PrbG7NdDN&;7I>O`Gv7pH8RaTKnaARF>mn z*3+U^l#q|ASvi~3?WCHIvMS57Vp=xK$z-1OwpdJ>#kkJL?Ytc|`C?X8iz**a>q$1P z>Yf(kCaY()KH5B+jONqDJg?evIbST>wis1CEoOBw&&FBZX0v&@$jZrbUXR<-dX?i* z(Kqv1-DK?~%f@OerpsA2pN-U3ESokTjYhM+7G_b6XVr4FC}Stub~(>ltB^I*dOq*l zk7bt6irT)-s_CMcR!udJrK;OmK3+@~cg`a(^pH2jY&2Rd>%5Hl)}wMZtLMd}sOLQ` z%28F%Cgr@&+q@pt#U#&0(|I|Yk4N<)@0mxe$f9n>3Q9_S)U&FbR?F55nszqN%AP)| za=skT^U2iK=PDTHvx(CRWYAtZb~_xH+^f>)QfR7o=j@zaWXHQ%aH?C7u9IgP9{aqsG4yx zat|i+#i*PV#iYz;vuw1OIQ{v&?|$S>Ghfc9lSS6n(=s2;mbJ4rn{?Yb9`}xFT8}36 zcrjfrs>?HYBT5aMOBP?`cRluw#(_HE}Y;ZTQ0_Vv#hgeYx?E9Z>^^Dc2eifY}QOB zi>c1suE{JPO)4jJ)b#Y>;@HAPGn+2+x&K>~Sh_KjvS%K}Xue#|N2J4IHm=)B#n!AW z+`dUQ8TI$!nvd(EoklO?DjVgs6QY`?Aoj|lua7z}7PHZGoK5nwXo$E4?a(X;mb_}3 z9w}PXlf|s4ntERQuW4J?*<@Oi-J@ki#`j2{Voc;`E>YXm<8sty%SLD9Vl`=|&2)0- zeiTgzsIp#`(b;TNx>)(LX~xrbGAqVClA&mu$--@#&nHqk6qrk8-D?E*(XG}L5brgWPBs>jB^DA@($MbC{IRZYP# zp%6yPS-xB@$_d4}AXeJhv}$|ol969Cr--&TemKr`*RtSLayp8mo^wTtEZS?$TjD9u_(ywNt4eh1){R21$(6|8CSIaBCdNmrElF~ z!yD5MeJvJ~C z<+K>NNKNT9QfS4pq1UPP@qARf@OO@?9A#xSZ)gn`Lsm_SaaAw#8ClPenB+ZcRhEub zVdv)6)J8CO*_X?j4Qmyus^?sl_JZ9qD+t|KD#uny?ko)2wyfKpb5*(>P1x;(?>G!a7A32p950z> z<6_(+;Y#+u6PV8&yz!L%PSsAcd0ehVD9@hNZR_QtwOy?fTus`xnH8b?>v~$vrsJM_ zUfRI%A|u)8ncD9i*l=Ak(s7zseQV|5xlfIwk=4%dY)aoU-biiYx=+HD)QYq2jx>vg z#oEm5{Jfc2@iJVHo_Wm21Qx?>*|0(v4CT>yIvFMRz)qd% zd56H<`S5&b(?E z^foVKGYwU`8H8hAE|v|+*z}Fc2DGDWRuETI4o8yNP*0Z}t0{B8=hjxHoR1dM%mHVz zQHj&>oc~E9kowae3!s`d3yuK=R^_97La5rme6|P|v}(pZ=Zc?Ik;rY4Pio%nV!<_X zUf4eT4Bku6%-Oo5ie)re#8!}v+>3nV>bqX!KC6$ubJeUQA(Su6Df_r$QnvY`UM|Z% zONL~hH;jARV%p^Tg2hKUP_^ucyyw=|ND8u8s*1foA-dYu=$TDf5q4nD4srw88DoZF zK`FCZ!{Kgd6#o5knf2^ootv`jR<*83<**1m6!WIF=>>bB#{!6Jz?W*-B_on+k#VVt z$-K;(1*5a*Yr#!p_)Y90(KDKIi!3U0w^=T8zWSZ};pEv_Ucr)(o0iMWu_vfv-ZrM` zYtc6I5Fq)&*0E*?Yqmztk|kT~qDPIjBpVDhoZNAsT3Ue76zRv3VNJJ0BGW?xY)ie$my*{<7Q;Dmkq0( zE5uSMmi+muo%QrF&O~4=QI;*TIn6HSFdj{34A)7+i0Zi?W1@g^j+J5%Ps*yAFbQlC zZ+F3syK_Ix**Pg@#e~k}^jjmgW*P1XM|IJ2uEzPuyg6U9PMEf(4mi?F3*aoyd*tre zGEuNj>pXWD7rdiIKm2IFr7GzAe+xl3o=l#g+Fu6>z;Ep z=JhUWt_g|FOX1Lmo)TMgvZ&g=9UQy<*hj`(dU~X;=QH1Lc~tye#&XXo;Q`GiQ|Fbr zguaB`HZioBc*BIV-*>KfHzm(z#%H0&2qA)K(sFllUPxc0sL5wbJScMpP35pSA%`t+cq!|Wsq8DY~bj97xS53O~i==3JJ1VpG@Rf60ZV^#H^52 z#n5GrH4%m@8R+l!%C^IT}Vh*B=mvh%9oCya35oE*5f<38E;My zg3jmp*J8~=2!g$w=<$S+cIWE0);|x^L=ZVVNS7mmW-T#4;ve?Ryrr6#6J{$-Gvb#P zBI4XlQGVfuy6NkKqh`os9}aoT4C8#dC{z4D4B5Uu?3jxu?%F!S1<6G@IVJ6!-A6z6 z%p?3uhCW+nHqDkx;Tu`J(vI_Ozl+Nh?#r%WCyT5PzAV9Ziv--hIUeJrMhT#67$ zgaRlWcaja!Md5gtJ(eZYLS(@~8d2aR!hBxSIwfnY5kIecG!EOVWbzU?0=f>P1r_LQ z%K2QxsqK?K0%>F+lZ3VFIMH0SGc7w%lE ziJX2X2oXu(9t(~|=GbfgU;z^LHGrqK-lGL07H0m2wxV5C5W5E|Fza(o< z9~20~P;MoR3QE1M@=Odb!cs-qr_U#D4pBqgOpAKvbkTh_ZXB%~l%8A5&TGUBL}CPC z#Ha<2%aSEdx|O-aY|p49OlTwK72~>f>Sd&unhk$Y=A=(Y#r5IHmTgt=W}SClF8MhZ zA9tMlG-tR#Or@oOxme^(Fv2Ml?2|`kJ5GB}`;>VQAx=pKJ`piRaR>&x{NmSa@jK_C z<0;p1K?SgSBB3E6V3=$r^0CjdoJyumElMNEBr~`qwIapoGL2==`ZSL96n|M7ntjgX zB?OpQfnsu_iL^zJB@?^M1Eea2u*4{Yni@wyB#)PnPkN+JXo-qnD~K*@On6R0DNFRt z*aU88&&G(^VFK*S#MuTe zos5^;Gp;5T<8Z-XUrx$~YMb=v^C{oP4wIY`(>kCQ=}xLqkvHe$bH#e*F{h!JKas2*QBS&(Po78w(Ti-wo)%27DerI2EM$3$PkK{M2wH>Ve8rtrg_$*ac2IOdn0(onU~;>puSt{ zBlSY&zGrno07Phsjg0OY@o*NSykW~RDp?=Po?APcRELOW8e@kY$J}XTcwsDraF((fjaXif+$C!m&dS59$~ zMRVaF5m`$`P~JK7IWvDLT*W1q{pUdDLS^N$VG>mCOOIBYN2Fa$jGGx3Z$w1vXF`lj zOGmfop1VL(mJ*FQUbGTZ6*aS{q*@B6hq>7^DmmeNnaknJ8cbyXco9<(Bf;2_`_5-m%bok-j?N15 zr>$KpcS-Jmi!))JMX0|IYao7T2PZ@itF`2@zz{%hk&A36MpjQBTxxf&<((Cb9cUCs z3dt+;pR2I!IlBviV@`?~P7x8lwzYM|;`wh0P%}x4!Hv)g20195`G&VLK8C++`f1mqO@~qVf;KsMV4GpmGF}IUfl&JBe^} z_S)QexE789x$Ijj9wWz#I&(k5+jjHj6ZwG7>Zp74pqQO}@REHb;U!HJq4e!N7xrTa z_l!!QJs>MW4PcGnGOSS{uTW0{6XU*lh+xAkO(ZnLcU@oyhVQ5$h3#VA*@yT8Wiw|H zPNo8<@~}{AloLS^w5&;nALpOAmqd}P>G4>W1>sSMW!MoSSTu>D z^16X@Wk>JU2Lp zv}YcR5#1*hv#ekg=`t}kMrL>xjDmU3>Tdb#kqqPS##_F=XWeevYO^^!I23+3$aAFf zP2pdg(Q$LMYDVk&xMu-B_?h=H$60>J`P(3+mK=+3tqxYJ_2^*D{U|oa$Ia?+z_*Ug z;Rt#9;c*+^Iy_h%kFkT7$Hj4VINC@F-?<=(ah1j9sHs;6Rk2>jw~h`D5631tUgxX! zI4chOoV(Pw>f_C^rJ`6e-`doOs*l$PO}<(eC3h?Da~cxgs>jD!UL76OlKU|(pE=4l z2kTWPay#CvR`v1TbJTm=9M%ULcEkC4ZJO$!9j(VJSGzebHv50e1w^~;nS#36j_a^o zR|l(cz1eX3jszk0{?_r)xIHeigLN?~w&Oa?4{he=a8<94Dr>p-nEiDQWSjQ^)*2-7M)xr9(XpT4K zYD`}2J+3A@Jl?eHk7T_XH;Nk!?0dhaqGRv+izh4#){xQ5|hY&8Frv?R|%2Hr$r7J;+u~ckZ29 z0{>u5W^ay(`@=rtEio?9uA}3;w)P%JFvtIfwJ)mmaaJA`AH~``k!5yBe&yq1imj9P zdD$Es`?KThaCIc@vF}+eR>WVq9)A>fs5o407+Oak$+tGuNFe)&vT(Gv=WCSt*VX8F zR2-M>YO}XaqgTuIrat~C#x=?|qZKdWBl%X|9IZ#2)kkqA04p}D?8w6x8&a!VuZD?y zusM?W@~%hQ9Pcf^B80Q{PzGb9?7qeRI`%Tiam$ng;albP-uH2ISTbllFmjx)I(g3| zS*K6?|W89N8^SH{7BB%$V?#fY5wsl=C~;i4qGN?Tdm}%+D)_R13dN1 z3EyfrN6eBHxwrk+3e@M|=ogKY7VAWIJ z>rGXz4>`rz-e;m*9dE{?)hIMsXMfQh#(A*G>Z7BkVwLZ2=WqzUkF{DKR23m+j%+4? z6LKP4={3K2|MOMZ_`{}L9UK=$XWy@Vi($?z+#Kf>(b^Y|=wGkuP>7xG`Y7&pb!fAW zj}8yAjP-1eM{Z`F9UN~)hpW|Q1)|au^hk_rZJ|Wk9Rer8x57_zbdL&JgZ*{XtoOFb zD-P6ny@|(mw)QHU=_soXXl%t`o91w{zb$8et8CqD7+h|laj^kHv9;@{Dr}k!jkoU| zsx8xqRy#O`vWRbm8=7y}6UV%c4bN}0|F;|#i}fh`Vt`h=U#sGxLU6mf(m(Jjvl&Fl5o&4VqGsqADf`ap{Pb8HUt6*#Bku-UGc8&HVBxCN^t0oQDR z9%_z{+jTs}B|O%xJ+(3J*%-$%J~ zlAz+db7Es3ov$@_a!r1KbF5)>dV*#B>(!RzY15Jp`MC3uoe5~;gXZvX9q7W`>ECxB z+wsxJ$qJwEusdJ;ZHVcEBi@M1%?aN>2IGOZ%I$WvR^vEdr1eTR_<(QAr59!*#r7W8 zI%_wU_@nsNN`z`1iaIB$V(l9?02Oz%W*cN7^VfUJ=v5<-cGw)TbKFAT@(kedi0!)? zZHje$R5h!;?VQ8n2zHahSRCi)u}8@q!MS6vdHRrm-`;Vi!xe{nbeP4d>ioxWU&LUJ z*Cej^ha|@S-#Tm>L93P>y^WjjYYQ$QS$LcsACD~M-s^Q}ow&57x9arcf6JLTJkFzJ zV|<{(q+9!AUVOXZE5M2>dQ-o?|Jonthh=eme2@|Iv5(XSWZFTyYKrku!|h$|9qZuo z02c_YuDFrgZ>`pJZF@`>dJ~cs81SvtT1_K$Hm*XaS+BzlStu5K)EphEsu}GqbB^*u za73op`doLgeGl{FgZ1&47haNX`^P$tO0B{OFAujdKIdzctqwNTQNb>(4_AE&o__gt zBm+oej}A&UQmhv}wDM^-<~q;3FFHWi9&PfYRVc&}13bR9K3G9~c*s`rY*iG#x%at0 zI&N!6%opn8b6tB_u%3=qNB%;o6x(oL`6UOjsy4z^S+%u&`L*lg+@(Aebv-&bi!wrwE9kDXGL&v>o_x`nCAC^ZDIjz`sdv5zesqpzYeidBwrrF|#AN%M#W0L>aZtOj-s;C6~ z8I_@M&2dHMIJ#@_r%GJ^P$qBhZ%OQ7zwwzhDZl*|o$WqGeaSH)mhUa2H;1&u*!fx= z3F7-!*wHdrN1OGb4>g;kqy4|NY3f735Rp(p{B9qcH6?kxc6OE0A4ya1J4ZW3qUZc= zFxB`Ln~AGojl{^%wG9~gTt&kiU=})u;*_7`Jc-< zX7I2IG884iBZ7CsE=%&YJ-@Orwe#!o%DY6;>#7Ca7DKIL~_I`?i^&3}PkOWnds10J{LR z3X!SKCjf(~B`JZvK%Zp(Rdz*hQIn#!BFgV!yOPatm%xIJq~wMS655LEskk5f#Rh=? z0m3P?Le~T`lN_Y{xud9l0x+>_rcx6QeF7^LTag+hkRIH2R4M}F>J8tEI#Y=!rTqCc zdAMw=IW3{8aDX@^sL$Qv7 zdgMPuW5UtlDjmk#+7c`qG4a&=@XSP&6+s(!4qjB*7OWNkk7|xZkL1~&lrg}HYB&&N zkcZ%Mngt-Z!<#EOOg01XP!(o2kQLEv4vjfi3#Td)#H%OPyzLFDn+2=#%-Y$zKv_ij zaukOtuen_ zbsX&77!VFtBZ`c3Aa`*gaBQI4sP#$h8~pJCVp6eg*BjJ)27xFCr%G_yR~fP00MbfK zLKV=U`-TaloVQ~aauMWMsu5J(!lVvGO(6Q&zi-inPOovn6%9s;# z%i+3Imn*$hd#V7y>bTPimhrKutWC+1JX3^;VIjG+$rvZoemMJFoWrk zkEV2$)1BHkXWnu^>cO^!B1V{@v{uPFIS&Aq+Bd+q8o^dnehv|M0Qy#7p%70owjyh6 z5Ri-N*yDEFhtx`fzC!y&ffOjPeN#mfEJI3yb2S+$)fm)VKze5T zuS{qh<|Qg7>xcjehe&FWGf+#_$}@&%G*hXjz;KLb5oVe8Pc{oWi2(Dmdz})yhB#26 z0U$r@LCTy7L_PShih^MqfHD98wN%ry`R3Hjmm&kX(1No15})mgp#`BM}xRH-M-|6ryOIS;@~KmElNnxB+F8q3LFL zYofSj;F&}=A*`k>O)XN$k`eGXoNaLUDELi^AX|*H!Qndhs$lTvB_uASa-8tgN-BA1 zr&v4aR4a)qfiM}*kU(lS>8oGZ3I!Z%fVq@_GE^Q1ffo!Z&b1h#>hNT5%=wm2D*fMC zcq*wF7!I>~^7)QIG7=zr`LNv$;GnjOUmTlUSwmkW;(U;p$Ab8)$vdgcnV2vy!#L!| z^(D!+&6boDwG@PXo#a|BC+y!vfe4h_l-vNt98nLCagf*NzS#iK`?*R!e3+BeHI4FD zao?PjUcF}9NyFo07bUBDlTy;cIJ$tVN`euDmclqfr$+W1}4UJ6eTm{ z?Hdjir^_*hiIwHHVhS@}pV~WQ zQ$CXHO(|)Rrl^h#{YD&FM0FjAP81KMOl-Uw1RMpUa;v*I>N%A1D4<}mC`wQDRz%qu zeh}NJ0{oSCuu&!-BU!C0^)&*aciUNX-;?CF2TCIu{4w1F70=w~49N znbY1FDf&vrx{D({)l!Q?jb1fI=tGtARg6)=kEs&%U@uclCn(fMn0Vfsb4zNA11b0j z-Ho!Z6>V`~6qKa|p0fzZg$dAt#C>aoyF|>ChG#-n%XBjz*9&S{l_Q#w$Vzw^g~0%k zUJ`=NXVq5I^JYhTU@lZV5EWBuO;U%85KuvmRBYIGGd1}MQRX;Am@_U&9raIsZnQI?7R)OLZu_4ALq^tGFc) z-yxX^6Cx?hQM91bbi^!Vr>GQ~FP11i&|^W~qhOKZ)^oeVQqcf$5HTy8~WJFI3Eg;h! zYU!!AH?0TusSlg5}PX!~hS>-sw;B0vj2BPMJ}v8BX}%EumtzdO(0iA+CK; zx-LeRYQ{>!d?9hE&M@YtR8~DX-OwUu>nm{UZa6G3qaYZs1-6*L4YEFVs1T97gn&)5 zx0Xzd+I8_A`cOnv32}%e#6oCYlFfqT0QEgdw=hiE5fNh4KnM#Eprzsp3=@3NDjSh4 zbcQchX*57sS;#`knN)8GKv4^`g;^*eH8vTRSCDP8_^-+$!fYIY?Zp zxNIzZ)Cp=9#Mx2Q*->-#u?=ho$uTGHQR;h^BMe`88u8@?)&{b#uf+Yl*6;w z&J~5;h1_5%;`)S8DcjaBNWmoV&W)M8@O=L zkVyTiflmrNzFTk*A_LvJM^T474Vp8CI!3O<@tMOo6fkShVBm18kZ7c~J6Kh$9A2wILIFpR z5EY=qFrffggJug$yrgn>1CW)@iQ9;Q%+rxIZW^H&Jh14UTvN))dla%{PBbc(z->_6bg^ZR#-KH4B=T2L&ZlBs z0)Ga>g9Ck!4T#(p+r&0FEk2j(EqK^Nf(tBmrrHb@X1sBMFJYOEo0qIcd^D(nw^763 zf(YhLr1{=kNbg%v%L9v4UGTwCM&j$LF(&IE>`&hA2tk8?D+4j?!eW&u9~WR8I& zH8=TnVRe^_BnTx;vWKM*?iqhL-AraG?pJV1$0^|f3p04sfVTqXp6rb$)De{oyKiF1 zJo718+zACFQ&@q6Cx)7%4HCTx1tDSQ!&1iG-1bWp!uBx;vAm%T>C~co?tsW}fh{1? zNcJY)En+kL92>Ol$qf*(5-!2v!jq1b8 zOOm&J1Z&$37zZFy$O6hde|w1L1ah zfyCZI=K!TO@Rw0uHB`!A?8GXv= zjrXGB)rUYNMt3kGfNO*hO8^6JN>MrP6Kum!mtqPLioiV>&ue(408vlUdc~qU6IEb~ zR9%!_fCWfpBtqxZVSY;;WjL|mq8H5B3iB|vnmyLfucD1&6fGp}i2 zPalBiCC{X1cRWBPQ7wCI9VFG17BexBL}P7D%916MOEj8r^bAgHK)ocqD4u7=Lg1bR}L&5%O%U`ZZgjFjW!IN2$_nc@1ZXdl8{X*aqk{@zi*lr+ z{2*Je)E;g!%t7m9kI1|TMmAUYE^-ot1Yda6iV-jzlg;AI5KPrT&Q1%<$z>BcfYv6D z`rdEa?j0i|p4*}cmYqi&L|+k@);aZ@TusETo_;{~HAsb!dF)ZSf0k<;X;%&dX_&oI zn!@6#xpDJ3>F{Q*Ygi1WODeM2cneX)ETxQV(h?%Ze6~=Bj_HhCF4#ke=9A5AUcN3= z^o%Pk5rWF%=UrJ^xjs^>?FF6V)Ig>2BOQPUxl@r7Sva(G^I*rOUs5WPFNO5XoDd1d zA#+5mE?#%fgT!mSsonx0&2eCxY*EGgMQY+8Q(5R}w;3|Go7sgU6X_XvadKIh48mQ! zDWOf9fTCUGgkBb^fyznw1fV|g5(>1CoI+?;j~}RA0J1}WCT^LU8zxkwNnsau`XI>6 zLC{!jYML2X$!0*<0jWR7FEQeFwfS;ypx+eH`>#S&0KOoK$CDBMCrFNEj?#S3E2B&13A91ui!2GEh}%_6!ZvO&zY5DM`OvYH;qXCFw~%@AYOfH?8) zXxAI4FyP9>%Oc`C$*_dL6&0uAB5YDC84uApQ*(?_G7ZTk;nOnsB*S1;x@PF-#dt9F zU^Yx+d|~{>gh9F|TP%$;9ieQo2@xJ?`oxkzf59AByK`TTcqK2zZ*c|3Lu$!pOl#(^ z2v%oXva~xGAybHqNhY2!!~;u+Z|Uhj@-EZ0%P(qY-EYL4E}QK^qPJ+)mi84DC-I6%a678ZQ{Nl97FOx5L2e;>8qi6;JBK{4g1U2F> zlD%m4O%qE`7aO1s0k+mRWUaq4#pamR{jfpkQ^kRKk|PZ;jWqYpattC z9KA`vCP+0CV+dwzQMIjz1;CPF5bGD=NSD(&jS{yWe2IKl=z(|+FVKskWgd4+ULG|~ z)D)mqJhErI<8=>LiN%85K2I6Gk&$Qqqmbt*MsFbQy!H~V7=}8DgMz9cyCqSbk#4)W zfMB09m?1!{WE~4mW?=y#ee6$NZ^&a~&@4ZhlVq>}CAVBCk1T?tp{(XCD&{;~SUkL) zJY1dy09VG}P7?%hgmzPd7c|V_TO^mnDjSkljk*4o1a#4(ENo}T3-U9mb%0UC7nxey zSS%2~WK}$K#iD2Er%nmxWX@ZFOggZZ7cQkW07;-3nCQv5AxZx*8{k!N<^l@%K^Cm6 ztLJ`%UEQtDwPk|>NC1R5$2^k6-1y#NIf9hK1bV#24GrT(%|T$M2>E%lR3#NRF>W`a z^zJb`*bW|6N+?9w(Zd}w-rg>YM79L_BFsghFqQNvp`f<H<5&?oyl*y}R8}u{Kfl zngstxzzXI-AaU5-h*p>@bu-(Ly(iS5mqpAZK49LHb93=MA_)sGArnGDa3G`)83Pp3 zB=-$mzyrO_0-mMQ0mLh`k4%PG4evU&-4bssdU}75A_izx>Ey{;H@P!1%9+(H-L-fJ zbCKKtB<1!lAW+*lvl6L*O)c2JghI+2ZmJDbF^Wm}e~cb$A&KS~O(z=mW1Jrae#lff zDWI}mdI1X-v$UFuZ9Q$E?9-j~Bvi^F(+s=M+M&Sf78wuCBjuTs8?nRne4kWdAY8C-tGGuJq9Jq>h zVXKTZ6YoxjTbRloguoAg#xUjv*01I^VBI9%r0;>y?I7b_VKo>7LAycRAmQXCi(v{Ck36kj?B(d%#17 zYgm;6lMDvH>nY-TakvBpMUcG~sqR%uDCM?CX)IqOthElo=_xfzpT-y3AbV3Ljk>XT z7bad|8&Vl6{sUmAHk4G4m=K(hcLo466@YjhFL?v_h^6N!RL*oafLGT!jAIX{D)dU8 z67y$QtFalj0qz%*A|5yxG&iOJ;8jH#Z$p4Yx|*<=7`_BZ5~>1C2^=X}wieeX8KAVW^>hbCxv_EDMTZf(V@B5=$OB1&Eg0mw{T zQ~DRkls4AO%YQD5wP?QCyPPlV5BP}IhyLtarzMVO%b%(B~Tb?nr;L3J6sfo ze2h>HVvM+N0Cx-(R1lI1_9b<3WHULIytoLJge(DfDT3A_g;l>m3D85B88jQ6SsZFiI-cn&)lKZd}k)C;IbkWD3rJ7G?et2FbPmCTYS zlahmsvMm4-V5pcI$eU2Qh4g}pRAjmt(1Eht!0d(&;3v6%!cPma6#3(1Z;QzMMDk~g zISJ&t=ZeIp0VtCBM!GW#t`}L+E^gw~D0*hSs$O#fQqgR$uYDL1#CqlCBhIlh-AYR8 zsMX{+N?k}UrRGNb%qpp|VOAakNYqd<7NlEuxFBk1JkCGsf@PBGt(Ko;Sj#=OW%sku3Q(kb~sGAbv!QtV#rGN-0H$bFaNZ(>p z*33|;jCiyR$U;1Knk;hm4wXQ$0=I#ZOBuFO_~7x_y6pQET?X1AIKJXVxo#!#cPLX1 z$&leSNS+dz1WS$oV3>HF2=P~nScVbHL~RT!l$|ZBMc{!!$y0WZxsL&`lGhXz)>~vE zfUqVJ{!>aE?l;?npzeF*X?smoKN9CrB-Np=rsBAfZOO?O(0_#MnFPkrHSP+76^N>^$m|2(C1d10RTga5+kP}QqJv7`A@UFzbRLz09VA(CMO6wV(Ww!@kf{Qo z9d-la4NMV3S)+4d?oDp6j~oz-;hTypDD{%iRGQ1V@5HNMt$IXeiUNKi)x>s-$_qLO z{Ad(Q;qvXWy6f66ct(!JgMG3bSL8m@Pp%3S?;RvjFQq+Z_umw zYP^pL9T5VL8* zFnKH&8MQrOm+-4%3#fs3VKv!|Xj36hDie1q{g^PJdJx`AK}}O(7K|qxH{roy!dx>{ z0G{lQYLeJ)cU$U%j|)jfU?d00NRZ6Jo8nnabBot$Rmf3PVb&*QiL(yM7fFvUr{9Vn z$)?8LgJMiVXyGsspa_tNSA+<1w7jAU4xqlr4M=7D#M=PC<<{=nU&6F^BJ(;V&m6JR`Q4kIfT0eZ9$$c{|tPu)V z_)!s6L-2r(37;LVfwV_u9%^e_L^ec97`adoeiaVoMCXHdJDvr#}38K^nMD;U! znRn8~mElIC2065kW0@AONJ}T6c-}ehQg_&k;N`}MPyrFy4yoQCADL+YXy>pZ#e$wF zZK6mH2~twL0{M7J*sUWJLf|o*IGMPK#beXv3^F7kWIv+aIs-${i>3mdZh%cq@p=3s;vVvFPkKy!OP){9Q) z5zLJjvRnu`S$h$aWG!RdlVDzm4*S+ta?i({W$v@pfRS47SC6gUa!ouE)-FQ$51 z%vsrEreIX1xo^_73^0jQ|7q(|&46SU3Sh|8?I2k*iVY?6v5q*NiDtNq)w3(*qCz_} zRKQqjpS>lh!L>^^n+Uy*<=MAt5%EfJ|EZE*290oPZmL@65l(S7LvpE~$&@hykPr&N z!IkQbYlj~!?BcE>h!q<({=zfj8fioeZz~w@C^I3k*f-=4gb`X+EVlB1son%^9b?e} zLMQ~D@Of-Wjn;(il-dB+mBUg^~;tc6#Xg4On5#i&6ESW%#5S>t9 znP_6_Oe#_W+mxRe7HFKc0m1+^iv(kM9dg5*m+;!{T9R4a9z`~P?0|I<3;`fF9K9%A z$?i+Z65uVQ@tNHs`Jy+ZX*_j~5hi`rsi_T!iw3HPLMHg!?VDr-^nv%=0oTSUyF{t! zBH&{K)2+a+U9MH0YS0Y;DN&Xzb2Nx?Ffg(-FEE2%&26%9u7ZgMy_SKeG!7&ktN^+> z5~wo_VS_Nwj-3*S-6WNnq>`#Vye2I4&cI;EhA##R5CO>KeOpl8OZaQ)y%6Tidxg=^ ztl)p+S+X2U9N*nXJ1tH%WNvDqa4xc5Bi`t~dAQfhnxZvaGxJNG66gzNiGoW3D<-x; z9Fj=NRlE{(Div3rMaZ>QnKZ26l6&phg5Vh3B6T7O*UA|&=;JP>&SY02sRkjKd^!;X zhct&FP-nA*Y)##6ka3t4NP0EbF*m3r*nQBeD5&IuCzgbgawjWHb=&${c59FoI$Ufc zV^1}MAu&4v_qs!~L=-xB^*}mQha_nyL?T6Jl(r7Tn+t_O^@bY647RMHZR zEM?c!6BZ~SJD4dDNJ`)ds^E{V1>@x9Lw5tQicG@;Q~lOAImpmr?9`}ZwB3Y4P}$V{ zG2xnIJ-ZcjFXgj_k?0HfD0Xlh&;fORKonm^#ew=JB_hc|s(%B(;N=Vo{mr9rj^9By zZey>~m_R=0`hzt%33cYpN_Z|gq);ZEoMb6LtqWH&5|eJgYDS2uorBwo19z}YcPzaDn6~*J? z`)rRyGs;c1m`5^rR-wD0Zx9*?^QuQs)s{LXi##lHd&b7-dQ%q#1;C-j&XG(ZbFGAosEW%|X;T#H5C1nLU zxqhoW4QY9|-6FBzd+^J`bfUefK{Di_Qbe6FcZKTE1iOXWF@~4mQmUD%Vj(R=yi$uH z@Kh~9$%5d>RVkZHHIq11@2h(0PQg#V=exoo`9fNw)Fx5mh#e1=t;?);!N%kfVtmJl}@dQpHh%Apne|9Sgp#mku zegms^gHpYri2X1ZN5L&s1u?Z%R0{9J=2#gh@PbP%*_&!Z_Q$|Xri1VFd8lh4_!o8w zDXK~vb6^YzM(l1JslVCw{U00H>8V0#RgAkROLdk=? z4k}ZMa2ABgoyr$0gm6aXDghfc^r@AkZIu?N+*Hp*PAa$q@N&kGC_4kmB|&414pPi+ zYtD#4?DMcgP#%+|Qow_%NW8uwX2n^4xGnrIcRDq3$xQ2!RTT8h9n66Ud^TN0v~epV0kDpsc>FX%2IIrI8kuz z?4@o=WV*2G36cppGB;97Vsa>UP>`^LVs66Hu3j+PbIOwW?zKCz-XLvX$BVma?pseW zuT~z&g#=tPO|qku{@$#mpbsn0f_pvMf0Xfzx~F!J%guPRTDwH+RbsHmtK;f$9nbQv zM(0oIsvFM_)}zsSYzkgyKfJT)mp*_0C)VBTupQB-0? zrG?cfb$0@oHj-b`#NxAkNZ9xLl(g`Y3cFY3DW3%t9bjHW1TP0#n_YcgXbCFJ&0s>~ zii3?E($d{^26*=Z!}ZR2-ri@dP{SM}(xPIbNBgDbNgKsm(2P%%C(_TmMvG?7^ADQi3TgT1(i72$<*BJaT0<6ugrgU{^flWrAOF)e&4(K3MP zj{Ho~6%LFZ(fEF!x3AE4KjpCDSi+&$)#sfpCqy*q&T8rdD(~u3aII8TLk{gcea_p( z(+311--q6?H%YszPi^4HWfyvxOm?+|Lh?Eg+|8n|Dr#p-ppT6A5pc3$YYX85vLmex zPcp0}3Kyvcfj*@F16y)mGoCg#rpM{oHBYC&VMeF}pEs~iOcDh4qLAnw(vqQw8k1i0 z0zjX3NRC!5EAKKgmmR<6fIhX9&f_`=VR&g`SW8AO?iYK533gaZ;Txe|RCDvbqR3tI z#Ges`4)OBkkhKl`kXM1EF|OMGkp) zgyS=8v_R8LM-dxuG!1JB?1}CxjLyEu@2=6J*HfUP;)Vr2tWQs{!4=2@D0>*#(!m8h z^4v;ahHckqfmedq8K88~U9q1*sD;?JbAyMCHu8@UNIbWCmu+%U3+fXAlZb_i7f6qR zeNsqXO^({&L4C@sC{u-M0O##Qt1u2npAXO96349aI)z#E;?Jh59G0{C0b$iH^N;o`vXR+PnKUHS`Z9YJwE!b zJ{7-5@*yhvhujr(Z0K~D@FK?uMF)&l97Hxa>NWzKF~q_EOlQ_A0KifrA2Fm)&Ji7k z+*N6RUy?VuLedwOH*zQ9(tYnD?`o;~dZrLYR=Tf(CD~GRR(LdCRfP-L85Ovw1*0WH zK?s^M8ziZK?@+xvyL+)p^1b>gZY!JvHw=7zMBDyFrGJ`a)mY(qQP?G{}9S_?TJmCNe zS-j>tMBD3ACP;!fas6c_?n7R6Gg8T4Mjl#|ab!5;w4=`dE4w zH%vS5BtX8PPnX~Gp4PBFJ;^I_qAe2Nfh~c~aDl0?@2e2lB~6s%s(e+Ri%eihpEIBb zxB><07;J{<>_X1VQ}CXZLTx!DZlZ!)#+Ty_~xN0!i(q_nhhqVM+Enoymg}&#w(<|g*1)vhXV3*b&(5E~v zSWy;O*2ppsYpH}q39d3OY!$;=$_{(_4&yRcdss^@tEywD6K^>TXc^dGg@Pah@fgRD zc|zDiC6%5r_h{Q}h%^bJC@TBMsj|Aj9FoifM$2jKIO0(9d01h{Xjws^Xnb^`Mx}=X`qXl+ z7#lH5O#%)$w-YT<>O%#J5g{NO)MvbCA3WD8>xRS=&;>EzQTXG^7nL8N?I)5lm>Rsa zii90M*MQM-0K~UDlNv~7$O>sGVuJeeb;5t6Y z0WAql_zQ-OBq*2sYadG_9Rd;pVY?&0TB;Mp zIkJ6DI&dalCI(XRrcxgV#``N26dMRam2Y?`2&F1w>8u51N@6kwq&X~+r*YIaVJ94JeE z$cdL&28h5yfvOu-!GQhj2zDXAQ35J-*=2)WoTq9<2LT7SSOx-@0ewbp*_Lo07D_pX z+!ZZJudbfWtF%LIww4O>)d#EL6)GGyS}`|DQCYF_^Zi?PnN!8a=uaAP`2n|VK<4zq zu0%^lIKnQP8`J!-(R!#(A+OknM~eow^jfiK4N%0+I9ShUJyb7k%7;|uGoa6i$0N6A z)ZlCEqc2P8vdFK{pm;~s+^g>z&?g_J-W`z>WX&Oz9nccpT>xV+ z7(jq$17t!F`ij0GKvH|<4YmFI9N?i}*iU+sgDzQ%Hx$97rsRE9G_cG+J(e||5udbt~&pqop z`dTVr5oJV;wKJM^v87!>w7}mG8Wk8FFi$O275Sam$tt+ z+Q1pdW59@9ynVAPKGfS1cbl{Y@}gbRDI>4|)6x&`OlDuLwCgS}hgz<5ZR=@e5XPS#|=8S1PW zEH}!xMHz;yP_z^s@J1wL7kdBwS7-og zEg6e=Ur-$H#@}9SiB&WxsntBf8SkvlxY!cmX5;SAHQI|ULuY$s9(x^dMBhV9x7PMz z%ZRuz<;h%Ozdm;DWJ~k(hB#+giDKFJ?r*XsU54;L#Xh<F|yq=dIo16snH2&v-=H(-wq4roac1s}b~7lJ)>m#1@Ko?(Jv#8@a= z;C}8zSY2p|QX+t*m`enRF1clF;5_pt3oneJ7`3Xc8hk~v@lxQ)TVap%ZQV2sXQ7%)R#juup`hpkN7TGR-5}qsib%B!seG&>ZN~U4~ z5OSwgbFt6xt|0Zi#)&&=XVpSq%PBKFB)uy>V6>sjlysxGwVyk2;}`p+k%D0y6>fu3 zYsh}mNKIFFu=H5^&K$tSKDCUe!GxMghMicRo|c@zu%qNFcH%HDwCr%>rB`9bmDElj z`(^5uMa!utN4$CgWHldfSGtxpVrl3su#o|$FIuXy=IkI-r+L0>jtv@i$WrdI5rh5$|Q{w*P6_C?2dzv!a=oN{!)D>5kDU8nD2 zOWI+AqZV(p$KQ9Jp`MoBa9|c=6GGIrW1c-N1Jj`hN+svc{k+(cM%t6@;bKb<&n`V3 z&u1><4aWhaCHq`5w>n-XZFcSF#Xcjl1aDqo&_?#K%aZDA8I<0zf#Yet>waEn+2yV( z`DkJ8(gT$H&odBCuu71r$fQL62DBuHq>%QJnioeK9so+ecv7LlK{TMxVDFUi3X(un z(*xEPHCnu#uDCXrRoGekeqpq*uwF}nMQmx&-H6tUErWosfY4JPt2Sttq`ug4e>rra zWry$cKn~oMJo?U>HaZgK)jJ5@&-F`hMhk*@j0yl;?cdH59|&e}Fpw}5A+jnUyJ7t! z$YBueyk%4mBn=2z=XHc$!Bh*JfM_42de=z^6>I;9p73;J5y4r5WxUC}YP+)~j}KR$ zz)sgPB1=Mx(|8~Z+3&9G!Ps+6F1zpIX!rNfFSLwX)=-3M9XxqAA28a^=j|}{UII|} zy#GAAmWp0HZ5#2;U6$0v(e7XCb+M(#=w}r!DW!WZ_JBUAKfrHg5&}epV9oyXoDvQm zdsjt*uO2=0&X!&P@K)-GdlE5YHKX3S_v#Cb0u8*gWe`zR6E<6-Ug&@Z-x-(j101&6hO zRBym&$)VsHsk*n)cQVCY>@#FMR19C++tZ_6(T|HQ-E1gC&thU9LI6Hsv}`b5M{CT0 zZ#x+#F7}DFJqSvWjmP^QyEN~GmIH3~g_hx6aUh`I$`NGru5){_B|F|&+yA$-yMeYX zt;z#kg;-)Nfg$a{zbIl*Lg&V_|MxCYJZJBH0>&T$k&rMFZ{4~DXn-0}wiK;HP%y(t zA}ZK)WGE(0tI;45f0Lll?TEJ87(oRsF_2*R9WfDqu+^lW_gib9bL-q&Giz@hA{6(# zYwfkZHNQFE`M&RTJcJ5cMU#swhxd6et{mRyy|6NMnXwK$ew`|HRy(E;#(mO zViK&1G=;p_x2ToQN(1Hk>Plv;&Nh2;BpWMhL4oH!SxvgqoF4SwjcX`%=r>qtVa9gP zMzp}y-Cnrn9>4SYm8V9hYw^YMyy{(DyxZX!;|*5w<58#^GgK?}Z?JN0bi-ynOZ8jr zp^Gb%52;kfQsX%;&>qj$%ACAl8VONZxn8_xVxNAFo`WypM)Q!)ko+60)C0E}CB_c^ zJ?>T}mG-c?K^&t?cIky{rg9Z)7o6PDV@fRbMk`s~J|RJ#y9u z|4yop15XF@sQ8ou2Kt?lIE3ajqb$k<^;Y-0Aarc2 zYci7{uu?V(Jekq}tYa>wfw?&4NL8!^=w$3S((D;)ga}1=k3+z`${4NG8dE=XD--)r zE>YfCC25$H*Mvn*%;D?up{!)X!L=d7rAx(DG*WYJk-H2dv2P;JG}~z`!7Z+dP%QVE zczZrDdfwr>WpMFCM%}K@IIg%cDwvJwE1r;~A3~XV!oUG{ z5Ca4+Xl*VsHg0h$VIr8QOXp+!Zm!90hI2fCd=8W~{-C&Kh9OR4x!mtQ*rt*Y*EOt_ zYN`p_?K!{$d$C`cZg~7Eb+EJtizqhY%f%Ri&w}G1Y9`;xFjoRAGe`m)kR#j5LdMVlLT{nPvPqjq^-Q zpzs$7z)QFSr}X;8-QxBd0!@O{zfUKA7*A`cJSW@YJcF@d$+4K}R|d!6H7+E0_ z!b+3`748HLC;Qe6bcrz%_^~s&LR~T`wy1PihHGVTt=;OMXdKdnrZ_RM`#iJBSjKE5^98H#(~xz73MnVz zu$TZA&wc0n!C|ZXDMsc*(`+KYo})`9=*r6!gG!#_*_y}z>M;tn|H=lV5hE1_`e2&T zZQr5}>G{dT)FUa@t81=klp$fe>{z@VrYH{!b-F=laRBFiCYq?pOcIzdhpN0>!aH2p zeR|m4`Kj-^I_6p<9Qxj?J(MopR(vLq&bM+B^LS;eqC+NHIe3_?NFz%twaZQ7XqE)j zyag<_YR9WpQjZ1pX!|ytxy5p|Nc8 z_brAy+8Y-aoJ46^H50&rX(q9G$tJ?(2|0GfQ5*7DgaLCGJArfFNUakK_jd9Q-+fxN zsQ`UsEjJ+#GmCCzdfCkTsdWB|W%5fe)j^wz*_23?&N2G;aSrY3*`myzjD@Xn|CJ>( z&b&1&pi{;e#qabw$7afa+V(_$(ZdZsH#SqlDsP3M1(Rt=1p5VysVb9lq8N<@iuF5l zmPz8dF(N5=vly|}-O9GiM>nK3N168tYK|SU?~SiimG{}A&Ja>u?v2?AtfVxTbH3@> zRwx?c5xW-$Su+N+61uo{qwbbIqw=u|XOSwL#9n{S@5H9|m=OU;%!w+iOp2Jpuu;R3 zHILet4KwjvB|Ex?l_Lw2KbaQSWXT@VlqV$Fi?oRClOcmujQ6Jw%x|%j43wX*GEgqR zld&R_#Bz*lrLe1ZACe>spegHv?kkg1uceBflSo!g%aS&ms(_5KTRHsuT+8>k8H(}V zq$d>PT-7L!1>3Dk4Low*VW2SvrmN;ok_qmKLx%8D-jtctI?$e>qq`nUx@{&27`zn0^ByUorM|% zTSez$K=NwkoVzo~B3NBw!rV}I#~+4IO3CtfF6@ zSj5Xy+O3MWG|GfpbiUC_hb`zYw2v$Z>C-_D#i;I<3yPSqfG>8>77NYx36sh1Emt1A z|ovaRY-#I0YqfK_WQuH6zlB<0p<}B?y22mC{8E zZMd_jIZR_FF(mP05g3tb-lt8hm^=1WXM92xsl%^?e1Slj+gQmXZYA4gc&QMr6v*Zr z>yyMos;{n0#6}NvfD3-5FE$7wLsQg6it_Au!cojD{+a}V%o^{1579W!e1;jY){rI8 zfW8AMlLOydDx#*QBZ$sk*fECf1pbbg%kWM4Lvc;uo0Hc}-hDGETow^`CTnzdi(?Ky zwr%hPdB%(;pt>fHk7Rw*jQsSKG5+S-jBMv;&nl-(<%Vm?pxI*PeJ=IXPi)8#AsxL% z1S7?u8zpJR&Nj1N9;#%T^38=}aElnjSHThC@P zfuAu_Z}B$0UWk&e>+!T?lcn>Zl#*7Se`RT6AU)-$7x+*pQ47_-Il1gsXV6hS;gUKvQRJCL$AVt&627qJexT;r@c4Z6n zcgvm{uOr1hVqt}#i2&Njv&C7|OpitBqY0urTJ^8S>~)X92|H{&IM^wa0Ide>S557+ z(pX8w2I^2^0)GPT^X5&Cb>fZ9DxMJhh}9%S!SBmTh0j*>GC61gWT@V!l;B9rYB#qXb#S2-I)zvM55(QYaE5;RRo(IyoY8JxSc`@7S+@eeBQ_o zfU@b{)lZ03vy9p;cl*})q~DjRRZ`9}Ch+*iXZB6`v9=PavzDN#nmQ*OK8reg>|CJf zQD)B;?OZXPQf|?PE5R+RnBZ9|rBwIl-=|p%Y9E-fGNO1Zs^bISr?wcpBk0#r_E16@ z5(bx(5r=_FtSL z#^#IM@Nbbiwz~!SNReV}u{F)JctYZw2~0CiD9vA(vkCox%2m@srcgyNKm{a~Nh-(4 zoDMVJTm})~Jk{Q?+}WJ+y!>~4L2n6WjkRQCjQCL9Z3+k6fc{(=?uw_r$doJaHi2qz z>fv8Dw|E~E`(o;m7EO5C84ba@ek#%znH0CQoGVJfNjrIgy>>i^TP82Vs`jmCArGgK zkz6On=eh(M7#2tIHY=Wx$(b7|%yg=<>Ap`CNWBMVzRq(M!9of}ZES2&J|+4-~zA@Hw)o&^b6S-fz;9|sXJlj$1_S*qWurU&i7x%+FTa%IV4Bm2(A1;Wkd zbRLMC5jJhUcj>+}d|PW$R$h5Uj8O<3mkO#rlgc%R0() zLWmFjK9SW9%oC&{al9JsGR7cFRP&5w6-$+-*KkK#ATt0QzljM;7$493j3eW}TgF>9 z%Ts(ORbxA|wS4iRQBV~8^W$w5O^^{nqc)m1T}%}nl~+WTOnp!ks`u$bJn$?_>t^Lv zH$LSczcxa?&eRTA5!Fth?o(DP-fVR%HKTdYPc$tIzJkdYd&uTI@U0kBkeuBBidMOL zt_I85jDq2ER(Ut$V1O9`k~{Qc3%3o&)Bq}vz52>b5|@x30}xs!MM97c@fs@Y->eH9 zOoBPKXXI|Zm#AKct_hl`m`LJQJR#NY()Yhr;CEkHjOIcPM8{F%S1V_6ADCezb~RF% z4S_>X0sRkOQqakGJb3<6J~2&#HPWr&^yXUVeyCW{7>WJXoLl z1Y%fC074T8??=|SFF$KSAFplYf5Vq^&DAK00^sG?z`#+_-P1Qb@Chk*398LV*mW^e z^O}In8N)|=RGjwa{~q{+oR%n?vWb2Vg*8XVbBIM#9#r307! z3}P8UYs!^|tBtX0X8YD=quj%BC&XuV)=iPGm&E=;&@pJ;ZXksTQ(G0W(=^KMl zd@FNo+0!YZ79TPv5+iPUf=q&n^X+B!2&VKia(qR)Sg#q=|96U+8?>Mdy=PQT#KeUp!k5yNEHN7MyhtmU{1U4s^{jnnWlStobaOgldjtr2)l%t;ladZ0ndbBV7bs z!lpo3fx>7>0l6zS1zYkBrf1HUj+e?+%-OH)zu zo1$_|lC+=7XrbXjhx8&nV_kra(Oz-?sLpJ^E84g51cKG-vRHwdfz8eq!dc|h{#dwV z_5wLjYJ2QNttUtJR0TV!A~j6YC^@PpJ>u*H9WPcGcB6JGbwTljxG2W=Og7tbB7isP zxI*LgJSzP=ON$dk1op*!)XcscqyZ&$$fqxC@-@ltRITIlV2SD{XnqxU>rjEiI=K65 ziquheBPUYNRJt}QD6PGWWz)*c6IyT$kq)6^;8a)IE2ZvSc8Q7If1kK^kfz+T53j;+ zvr+>|`2f&Ly<*x2eUn*aLPF_=OfdsI!&=<2qUA$4Zya)FTdK7x?}KO~BF~VD{Yt1n zr0;2m+JV|T)$UsxJH{6}C~Q`OR`pfDF3g%_paq^_td$&1#Vh=^Q*ajXyJjmw4wHdu z_c`qxKF-c%$BJh9C!ZEa^rUdki=Chqf&_&3K|vL$SjC}T;k%xpA6Hse1BU@-K5pjZ z`LfZ%lveo+a6bSP)irG%>cU+Yb46(FQ#}Dy(^ym}>;zR3@SEalPi7!mli6Pg^2%iv z<9_oLXNflo%BcTX#XjjTWf~q~f6b^CxZiLc(XFiHpPgTm%Y=Rn-7Qv6@vWSmtaKE8 zX6lyggu!~uSOhAJW%1oL&FVv-Lm{)5z_CS!fx)ffGlN=s(K5!tJjSWsCpnvj*?Ek| z`cA;*Jy>~EXXmlI6;YhIsQ_S^Qcnm5A{nX1{Xd~8`8RAv`$iwJ1$sFcU0T_Uh zu-+Ed^L)eLaMMmwolv!9@q}=xW;(Q~e!KJRnBL}Sj+eML?X5UNalyjFc5Zi^Fvlhq ziL5nZ;#t-8SH&~cG@`>RXx~e^NX8I&UaUYWwu+{c9{Nm3IsZn7)elx4{A_h=g&to1 zU45S~%|{AeT6$2`-c<}S(>cp*(qHCk0jDH0F$cbSE1)viGI?ru&0s{jbg`WC*;jD^ zJSjhkesoV1%`Lf{dNu#5W*Oeorc{=h%v7TLc1kpA1C{``x+tcLrSMJB?mkNYNhWQg zWCkVlPbd{Lo+uX?cV6-Gt+avQL6F>*6Xj{GBS^}ws+=Z(JhHV3-v9Yd7`XeCQV>xm zSGO|Wh#Pk<4lx3+7{k;mY$@Vp!HV6NEw3h-1-YmVFuaNkZi*{458~0+4>^5ho*6lZ z2~c(5t)%G*XZQSfY9?X=QJ9g=6#JI2LrVpT0~xDfL@-~iSj_<^MTPlE_?6@{lIakB zoe&$W1}>1?G94C`GI!eCU~!|3XYN+U?ZP-&5?_PGiaZRzjngUIZWnKT*}BU(NJKnl zJ5|5)L_VdR3EXb+cChXqoT}Ouc)_=A``n0om>{eMm; z&RqnUb>+rqQaBKFOeNpHPdmXwg$%@OxN;M+^3WacMDfekXH{KTIg6Qsgt(h1rg*k^ z#y(h9K)}IHG}2o2eCU_i z@hcod{LrNz%hJ8-5>HK%Cgx;0-|vLs83s~xFk@&`+wuN?G)l(7o5r%Je2t|g8bWeJ zwk$1zNfL~+_O-HWvYCsWK##483%YrB3c|uP{j~0&8s*BE5hKnOnpA zCD6{;tSKy}inl8O8dG4fg>u*3qBIiv0PcjRb(w1#P844jO_F{mI8l^kz)qyF3a^>k zcBoOT&3gW1x~Dc(X1b~+tNa!uNs6AHc()UvjwnpTSF8p2q!&8@Ag#%Fgk>2g1e2Pr zlhT-QGgIYPRR^T@z}Rz9w&RDpD_Xf_Tad$L-~2X!i>|I_ z%%XiOKn)$JWEU|8Do_{9RP;>y#XD{13ZiO2`eQ;1Rde-~`4bD-C2oEf6QJaQCV5h! zIhT=I*~Utk8erYwjLI?B)HGv~f$CH2KK=Iu&K;wI$|ByJqcKvE-&$4aTJ#5I7@`m- zc1a(wE%hfQ2@#4<9Ya-rrnp-;hp%6o)d!N5q}~1v=tuwEGpJS?fijWoUyG09G1{E7*LL`yYu?&RGNEs{04Yv>u(ThWX$U`DL&w66RR z(7fcjp*cXFir=|qNTA<##{bXn;+7wtRvS0CpXpv5q;_a@|k<|c=$|{8f zS_HTA>UZh~&q)h+e1TK|qPE_qo36Nw7?#FY;4@|va5~dsyvC$St4cZsKh-rQ1PY{G z|4J)V^g%ozM5gm8;t-3|B#oQ19q-K6+mYsq3<7C!O~{uI*iH6%f-l?1cs3=*f!e;s zO0dTq!D%cb>2hi~pTypUHU6pzE+h*RzcQNaPJyh{@Sw3O*GngVaoTGljdbPC*bTvl zSU0Qe6=sahs=M_a&omJw^6jk*)^?y1L)D#~Gtjfs2#FkP1UG+rYBN>38G8@^P=FV( zc8D`+x2(glF|YcrvuF!Pw28a=)Ay;x0zhP=Q2NKrrV}Fs;I8uVRy)`iTdKjxPlciC zeWC#!xQAFl`Y1^a9A4rkdKkrxs)xGKAcku939qQv(k;EfJX?Z6N10}IHhzUf@VPlK z#>b%~bG)>Kdi)lp+Jw%fUMAj2aee~)Pm>m#VbOTM@TnCwrI)0cG(M`L2@;O}_?ecgQwrT-+CMcsq?WB8|s!B*qt|Rt&UUH0>KBK2HGcCRqf^(nniPXFC zmcpdvKx(eAN|J)6TB&KEl2^*NEH&Izwjl%DY-NQ<44$DU{qMxjQZUoCXdwXWi)-?< zlU4&LcU1?zCrt^f?NhO{s3K~_<1A3p0WkX=k6f2dU_WO*tNaxL?=S$h4 zXDlS@6qPGcQ`A#Eo{+m8#-t@>++w<@Ap1R(zQZ6ri4H4dP-Kv5=GkJ+$@?g`j|qpk zx)gV7Qh~lqW^y$rzKr)$O^}_YfT{Y+y3e>r?snI)RZ7Uur7W6!a>nAC8DO$dL-O%y zF+TOO^E;ERbDS3|O$A&MEok8PeOK{|I&Ioi=2eX(%RKbif;hCk0nB|&kehhFASzuu zM5O9&RT)^Fkdw}JONRsOtKUy%LE2QU44X_ZvVXQ7^%3rfok7m!BrH~HkKobz){6gx}cukLn<^Sj2_=Q@M#)rbyu=iC_25^)F2vDfyCsZrr-8XTR z33+)!JcIz-6zNzN<^`53Pnigfec4^@z-u*hRq3LSyo`M`MJTxN&+Z9jZpQ{+Gj=2N zuGKZU>u7d{IM%%tr-hD}aUbZeqe;2aG2r#_T4Xn1xHI5 zOHNHcE#Z@x;A!dW-2X~8A2ewAd7b(`NYnnriuAYbm`;ZY&CW2BLpd>@^ z+2U@;RNOjc-c6^fROSz0yXK$j$+o2}2#?BCAE>X1ohc zp^GV=P-y2yKppkpN)%MX@C0(z(AC7-4i$(G5QH0o!JigdUR_g<*Lkmtxu?#bSYqo< z!g|6|5W$c&H6kG8%rdo3t82=f!jIcAY1P?5U8JZgg9=N9xyF?^DgwLK`&5n*GN|tT zFIr=9O$W%@<54qqtX4r=7Vpi#pA{tKO5iY5YVRs?9=j0~Nd4?Ry9ZVtx)Zd$Ixn&Q zMDlFo{s3W()V%t#$)!yw(h=!bhGhW7H`fA@w_*&>F<^X~w8nP6xY;EUb(pJ|5gu}ZOlI;l%XK+wviCHZCcj!m-(twPa?hFvEsFqRX@~7ZB zhIEL2PHMt=Q_~{1m{=|sSY_$Xcrg1Q#1I$sL3Jez6Se9B3)i$D@mAfE=wce4bPn`aJR!vfr>sm$?YLUW-zsEg~|FYeZ~PnZty7cS+O8r>K}+);o6q>$<>6K)wV zNNxbH=@9dFQQG6~VJk!6s%z2|(pZUqU7j$(s}T#eplDJml!rP<@9LO3zk9Y#^&ICw zIV4V7dA9_(co1i*t>F=j$jYNp;0M&vx5sM%XyMkFwqV*s^*e!*vXf~a6IPl*@)_z# z@G-?kwesLRfli9fP?#sBv~OX)+OCi$XK#{)>YDn&a0q4-9j-aJW5FApG+N(651@T3 zQh9bM?jg?MWj>@K3?mWE(T1I6nLGqk!^Y93vl)uJO_%<#^HYeHNtrO&?;)x!)fIGt zvw(?#)iw1w&{=?}U1l7N5zZ_mX8d=x6Cm06uui;dRvOow!F_gAwGxqvL|eh!tz0I1 zi<5{#)L&Yi*%pED+oaK!Cj^tybO9{I9k2SGDEw+2C>z$dJv4m663CeTh}g?Kh!ztZ ziE5X)xsUM*tFugz0fwYOmT>yq5F;=f*}02F+_b8l;K^##i$5wJRiuNIpaAN|$Cnvj z^@QRNKtOe-c@U|G%^u|~L1f07bw(;1ER|9JDHz}Dl`2#U0<%8QzcTbVZ_%^W>BHF7 za6zLLEsEU-E(1g)`9AAAc$2tgY8bt#Y9&FOkiHOzT8sz9GlE>RcFDNF>Is1~O+eJN zINyDwQCO3-`l!;?H34U;oL$F)FPR?-3X@)h{Zg&engtp|L|acsQ!*k&nnyNs%ZlHp zwSfMdE@r2fZpf0IBmqTOsI=%I#@MNuT;U|+3yigr9!CR=VEo11ZhXb4sXOg5AWC(v zfvFeqXJgm!7@fM1WX^7rye);nB4tIA+kv_gO9p5>*bo*p{$0b(lT0%GrqpQW2M&TkoR+=4k zY!!|wXx(%(z@-cpxc}#i-^Oe!&y_h)o-fH-jO!KsnKx6s(}n3_as_8@_oX2YYd-mh zCQMOa6#GcR4yuMsr#tOUD6}#nML8jbJF2vb@sI?ua2GrOx>@~(dP3J!%_*nmbx#>} zbiQ&}J;sG>AACt@c)!pE|hNl}oP~*%#LYA81b; zap~={45opx`*I#*hn4RWY3p) zv$i9XF*qkLqT+Y*HCJn(of#Hm-_o#46%Z6LkZj><$D1*fb_dmdS3eBK8QG139U7#02m4CEwS+eUst=&cjCYssd4%fpJLLWFd|Pb1;@pC#=&!>&!EGCt>@%EQ5edF zD9vr&($m0%QrrM#XP=RWvk4d&(C@I4Zz_A(-lO7#Uj<1AKG+dFwc>GWqoYD&rf$_Z z-pYzigy|weg+r8nv3Q^CSJHl(k+voFHC)|r3q9iz*-rUvb;yFPlu} zLSnU&F|lNbNvC(RPv^_PJK6rJbfMov;due8DHV->sXV(DZDy=CYoD7ClN*q&9<_Hh zRI9ty?G#WV-0F}!&vvUB9!q%9wA%5un|K$mwzhJ(mlcdIghXxWjz1Z;r-mff0zjhl zee*#PGHSHy=C!kI<7|jY9q%k=xYbTTc3R8Bb{R&_m0`Vy_;UID(e3&tBx=$I2@?y6 zz@$1IxQ$9kWo|$ZCod;&o?&iQA4=I$o%Wbg`j&_o{WV1}rvqbS#Q{A_vHOD3;Wh|> z4ad-sqTDy36?;5>>BUOel>@@!ZY3QiJ6=Yr8kF3-s%YYMk}eUD#$8SXJJxwnJV`cD zN2_V$h{2fjuvccUEmGTkoL+g)@q$A(uI_dl(|1bZ?g3CBs4?sr1KNu6U%M*W9Pl@G~YB&8C@p2t0y zJ03&+V}x&Rl`R`54x1)XB@{<#s_Oe3yi=k|iWPXVQ!wp0Z!_~S<`SObeS(SO_~L~& z&7cy?AY~1Zjhv2!b-A*6vWiAsmsq^D-w{56j1sK-U#a@SI6*1hv5#yDiw8_>PM?)v zVtY0uYo@OQ6Xkoa?5Z##(x4?VfObxYXobyW3S<1>P8TU@)9Y2C-S7tp21~Z)N~?gpDOaSPbJmW zO4KZ2PAS=`nPOE87)3lXDXQYzfeKMHO-0)2ECzp{kR0v+I(2;)v{EoA2E!vK;~K(h>MTYWrVW~^hjO{G%ubIV8|;m$-IBI z$x^}NxbtgCWc5~PP(%+rdRp#O0Fn0)Ekjkks%jQHmU(8bAr9?(+Vh(?bvQ737fps& z=vKy7pa}%qX)k2ji2RV;$GqzLi{}SMYKK_(@uo3}%y~jol^WdICMXW7yy~rx(ji#w z`d9cv;Z&d4$cRi8K2G7l9~M4GLzUk-yu)W@(k~qv%*R9%kkruKr`twHr}@}9u0mP# zNZ<)X>>M?U-|3q;Fvf$Bh((dp`+e(uDtv&~nZaAt4*cv6-F;KJc#_oJY45AS_GE|Q zO@q0r-?5(zT85#VQ^9b&-T+}LHIsonw0a9p!(EKm0FC(?Wx)!yYhHbyGcpW4 z+l)9(_C{=v?@9YZ^aYcuV!XdtwG28VXcC7=CD>T{eyB9#30VA26W23>FLn>RuWT5C zmRSxAsWra3eT(@<*oePDiYI_ozmr_=z&(TsM6mDa%o}S?HWYEJ1b_+#dR+WYG{|g( zGY1cEk*l709~}Cn=+#Qu1&0u-t+Po|a$BuCw}7x*tvvYIawzg$rzzZ>pQ%6b`#~Qe z=NE{J-XULO1ShA800!le3&n73jFU;&R@|*J`M@VcibUPaTCd|M1UDI00XWqmZ?-FA zPCFi6?C%+a6B?*nRdg}A1l^v;TeYB+w`n#^r>i1Z8oGz=cmdwrYbvUJoxXU?@X@eq zH7QyL-XP9MuQdPDUa!7v^yaX9xo5QZ32CI5jVjKwk_r~@lLADU01NB(kep$l;>OQB z^!t?3_)=gz6t9UxGlaX$VF^WpnzguFFuKZ(+2P)CNM$q!Dw>njSXL51_2`n202WN| zR$P-krH2zZNH3CXL1Ct$N=E2Z)c&Yej44FJ#!=X!R2It)CsmA8s3c24FSg&7@w7TivjLzPe=qCU+N1Lh!E6y?y9 zu-i98gtng2sdD;ShR2|4)lS(n!%%w>=c3Y}GqxNIaLpw>zL`^lhKm}BH2@vDyu_c& zj@L1e>zeeyhFROJI3276OUv{7i-11(cimrHEiw;#7N}hDGLXp@ajcsX#QR zarNP))_NVfK;{v!@ugg58!0O9+-)R)q4#89VN|d8zx$+6AX}h=2iopd z;VEzR3t%7Y(8`sj#)2QtT(|sYy&16uv_7uh3Qqfy^fZ&y_q|(uEN&&4I@R7v=F`B+ z;Wx3MFYlH~gLKVA&F-4gl-OO{AbQ#rnw7Bwhn+}>lNo=&bEBWYJ%-QQc&L-yBdR_U z5}Ewn3)vz0t>;Ri#%C%OOYv4TE9EAlP#+VlG&NccWyhUr1z!aDtE&ro9NXQb(uyU`_H+iQ@`U?00yF&3v3nv zpZDr+$(^Y`Oe1M1>~P=lP7tSB=+&T^gqJ}oB(L2U4rlW<)nA@;x3%stI?ysm?MVHUfn4 z0o%rQ;)X?1?9l?J7(^EJ3NT)gglHg3NTf#NC!?XbfiTQ@#1_BPAOguEcm>1~>`l@q zK_?35r@^4OT*>rE?;F^YIHVcPJ0X;Lv;$*Hs+I6i%1CMB8BRTHa^DJpD{WQ?aBen4 z>X5TAyTF!ZPsg0IC16pt()Y77*LTeW8ZRuy?$zD0r@^yKwUcM-D51@jouhi$@KubT zQMqg~BMK9{Ts0nwMpOeaBa!-U+@izI(p0?wZMrSE{8`ni$zm^;V?D2gX|_^O90$ zez*H_&FDdpT79Ia)wA_@SWgA9>Go}S81d_b)2Dl1yidwTOxTc&d?~6c>}13Pyjl+c z3$I$4iH%r*yJs6NkCr-GBVBLBg;i!Ax)Z3D$jlfx8j_QonvQ_C3W0}D0N7aE?eW2T zNa!GB6fJ4b=sUj5>wur-~KROMRD*Q?W+;%!Rhef7HBsKj;Rrcl_(P+>( z#p@Fj9Ns)}NeY~*+-9pttsjCQs>YRxiJF-nl@VIXY)I9%IuTQ;n#yD*3efhgP@?FdL%g$@98JZujVjT-#W-|VEoY!8BO6h_!c9yRraxGj z*{)g+3X2jGq<~n~wDE0q3dZ1pmF>FyA8+1z!5G% zsn4q(0CtJd5@b}n+97E3AfVIU|{$Q1#1Vs;C{T zxbc1ZT^WOoGVX)hIMJ%9POFTi78iD?dQOLoVLz5Ko8wXKczKpY6}o(FyoKN7l3ZDe zx5DUSj@p3I+_5PJ`wIgj5x+FURk`h3am;7JHM7MTj$`$$(DG3Elbb@*b7q6kv}zKh z(fle*3UBw&^E2+iigXjxTHeQ1PYYj+@z42xS3CanC_Y(|ylBRJE7;d-Y=^PtJN-fR zWpiW!kjUVa4OTAMP~sEW_xSdLZ}C>BH^@`hr$-$guQ$iE377&@pl7IdLR-mDV(*nW z9!9L;F|!p*rQ_6P@ReWd*cPGg|89@XX)~UA5#h=%4jDlS`-NgK)h$;t)g+EEtE0tu zqOFx&Aq{^lg5s?ln=#@l+$?uRMsXq%icWILo%POan7RE*TxWcBPj_ zXgx5R(5{_$sPaY@H+Di?W!dM(9vu!-@fdw62oPGXJwrLDx(WbHqlIPmNbzi8I$Jgf zJKu(^q^uMrFu)CEtX2xt>YR*b$oI)MlD33Y6~SSpRx4I=8^M>G$7d!P2CxV;iQyWv z0)I=jQpp+yAu4^#q^wY@Aar06K`yJ62=W-TJ1?|EO)6mC8i>+H>y#@q91x!rpT_T8 znM)@GkEP>NiAs65G9fq}AF1wr>UY7YL(l_3SJkpn(A>HmyKXPPbIH<7K9|Ib!DHnD z10h6J7izCX)d%?oA|fCBJ{<=$tTRb?o{%}jns(0q$ab)vi)V|=W8)wYolm}vJ$m}v zwFZ=aC`MVBslDsgM1C8aSiC*F`68#5#vhm`92>2vg98U8WARoPNJ??!o^yZ=N=5ZM z4}P}z#av|_yM5HOZ&5#SMOE6gBE>cBPR~U4eSX^Wr{Yzp&PE=oRuZYWL@=ntcqY69 zb;N1zANW3}hvp`*ATVLl@&0!X&iky?j#ENjgHs!10rjPU!Q88!5Rw!_9gtc3J~3)| zoJZt~@$0XxRvx_jX!H(@w{iOO<`e%~G||z)s0bU(bemOC>BPMPUy;*Mzx&kol0X2C zc#FhR{7wjjl)ae==d^Er2D&;SI4t#wv6<7)f_%kjuAn@Qz;`9B-qp$w=~RdL6^m6e}~eg4T71+NEBPDi=eMM!V|n9Xskk z5KUm4FIy>wEQrUX43^bZc^`rcJlmnv=R@g5XUux$v+A8xcN_Z@0-IgNi0$O0*DyA? z11?{zRDja%NeTLET6ydPgA8OlRkc0-g}#{SJAH<6Vpa)(h+ZVNRQZHl@xZ95&rb<- zHhCkrC?pxxuw_S6VQ)@A{#7w}kWQrLHOp34U2mEPmXK0BA%nvG)g~_s)HzpB06;t$ zQ-^<4F&mC$1iGfa?f%(9J_bfjG8d?8xXoRE1)JZ#pds{QiLt7?<=C*YWiayE@5Bfq zTZvcGQn_5NlsV4~uX2s#eId7yWoW(oMD@a|Yl2N#qnvdyhv)GkJNltfD&YL|I$(tI z1m7z
?pO=W9Jx1AeuJR5Akyj|7gq>3h5DF^PpHuZ-VgLQqw6Kq7JJsF?MJTy>9CVmRidF zgVbS;{q}^k&EV8|$s>L#)#-3b+uaWAKHlPMieETsXq1@f_y0RX+>LdMPFq8`eV*yr zOU*)NsDR&u3rtkBB0w?f#2JgY|pQ}^JiyJZ+;Le)5XC(jnsGUH<=m^S*E z1^VHd2fh{VD+fjsP0Y0v;~2HL@rR&id{~UK#nEBmReWXG@G(}m(fSx~o)68aR4B7k ztC<}x1pVNKAp>f0XbOVSdLm2%IE|{E5YhWV`xd{*L=Y$%kyqZQKBQ=-$IYkKhAwau zc<+Hwm5~qa}=w&=6S?zNr<3+ z3bO7zF7~a4My7MIBJDVZ@<3AoRC)SuY-`Gux#WbRsnyvSFRaxOzu^Q_{zXi1cRIsU zrUZS@m12io9fPy&OcGk{zRdY?B5;gpXBo~WC(`gghKRNgV?ba06)d=#Kl9U z23zzoVQ?mO0((Qy1!;Az79J?e7|0JTsv@|0pW1>vFp&AXYi7<&MsC0z6T_;vBI>9c zgWR=A4d|jV(=aHJkdV(~^*ayEFbu(tBRX2Xx+c|?=8!Lrb~#2|%OZ~lLK>Tnn|YM> zgVSEpW`F@TALLv2tGHVd3*KDZhI;1(wV;icK>~3-slM#kWElh?A?fmXC$Jq$xu9pZ zs%AWxy2HaM&g$LDbiIOI(DmBPm4e-;sl71~c6dLgUV)*W&_A(mNJK1h6E!LqlPJQ4 zPb=B<(4~m)8ICD~tDcaN9hNkskF1o7>C*WIi2fA5)k?=@Ec`Ohx81D~9%y79vHWCK zAlz7%!j(!huGCg))SY7Q9?5Ic^(cA(c+h$+AFI1%9ck0(@;1E#Z%qa+q}O~m$^NPgBU&;JD&U8%igXz1wnFlFno8-aYl12a zNZPU7TPIxQ=~&_Xx2^UqQ!eXh+LVvkecoc)w-E?wos_>btw#*jzFtu&gQ%2fxNK11 zDw?n#OY>8?**R%w0hleK+pCGG4yk@85}NNRVu!}2kb`54VrFREm)@`eSTajmAnKxt zkHmM!Lr@1p(Og|qeNLl%t&gZkNG}~>ZpC|JU!{L-fFUZ4J+z0TPrnjCdEiPBa_^Oq z>IXjWF)7Eek^{X(JqOvSq6wt~?&4;LrA9++XeiHclp+(4if79y6($t%aQ9Z6*;*a^ z$k4+0PE;##3RQF?^?mYq#X96;&cAEs*se5f+{;W7i#?MQEjwOr9??H^%&(|iysdOm zvk!LPXK)h)Q9cecm#^wFL*)+qowTtBo-6!MggJJgU4F}TL^6X?4bn$XsG^p z+0i03+Xu)zvX;$ge@PDrVP0c35*lLC%Hf~AWS5q?tb1RE5K6oI0<+vFz0<}$@T zl+wnz+kY$Zju|v5(0Pl9IC6eOhvT0`E3Lg)f2)y1WAkNEgRS7%lYX;W9g}t zR;}D(CVBfi{MOyZxFf7#{Ix1iKt|BkX!7nIW6rb>-f`wjt7405@;Cx88wa~@huHXR z`z0MrroCbU@}|=pVN)|z1zlcKI=W(Fg&f@w7o27#2o(eC`gP?aiiS;2WL~)XA(aj- zuVXh-PIaqYS^ZAH{n(h(9rr^;XD9mJBM2@dH8q(*eeu(1@%ETN7M3b@g<@SPDmk>t zeI$PU9!mE>Lt1}aOTN^!fiw?&D;xkkpYxuM(?OPOiZRyPXi@FkP~~E&XjXmRXWBay zc@gt%8Rb;pC);^Cn=~TNPNZRcY8jK}du(9ReRNIK&`ydT^Ny;cm^sz}N_aM(i0r=M zbv6(FB|XT_sXT9mJB67G`u%{dVh`!I9vBnosR1BDQRl8htVM+&*HskwXsVbX#S_Fd zXnSltof$x$K;*rgRCjxd-%B-&SRC|2A4gK1L2ryAGMl~lo%jd{0wD74eUi*L?p26M z6sSU~mGp=p7G(Ms6Xa7U+#*C|8cMrzCBGnAgKNGOQxqa0q_o(SD-Zs%wJHvMwxCET zd}J?;vy>cckj@o}`M|u7r!UvQ4A#snL^&7>2DeYxVeEbB07DSTckPsS5W+{(K#gS^ z$3)0dPUC&<|E=)V@#pBXabJUekOjf*w8Gi*#c7~inK|7P9&N!=GfXZcSR6vCTeMnfu#pLjSZFN{1t)U)qLHY-{o-OJFX^$yqaTXzoo5Sp z_Pk@ZO3P5}_)t0xU1z1S_fFuDdsx&I$0PU5Ou>$&$M+sOfk2Rgxni%aqlpFgOT4;B zEt>GGWJ{(FIjy{7c!3cpqr=WZlM+o#x766yLId$|VXdAmXfG^mQ*he8HIv$xgHs4h zz-ud4GGhTtL#}pT8M72$t@EOs!!CVS04Q)ZJA%F8o@DTrvcUVr%_y#^csnfDWM}6P zV;acwEWZ<0&h*PnM(m0V1Fx>hqZODLX-<1Ws>$sH$P+BN^x%-=5e111yR0ToRQ#{> zCnJ}rzE2?|gP4eryR1f8o)#$P2qsFUt<9ta$s5JV7(>{}i%6a4OwOkfTd8df6I=Od zaPSZW5=|y@MiRHAlCZnt3F*TCN^F~c-wwv9WyKWW)bD0(Cr^+s`dGBo7gFPL1_9NP zdrVf^KOsjcO2+Ak4T7dnwTIwce0Au1mMEJ+3jIz>5<^M6t7#R%G}I0}S7sO&&e{{> z?Ajih;R@)4sx0HmQPiIVzlZKy-Nb93P%^1uXSUPw&>hbJL5Zz7b{-Q3p1gom>5ys+ zK>-FWL;>(v;I|CfaVDIi^G@r93L!sLl*U{GiKB>MYIru6hF*1ZWX&%f zi}(H>=b+@iSm{KOZrKUl-Kr`Dm8FU~W=WM6Q-|Tc-zWB&ToJmYhR}nnu6ay&l~Jdm zjbN#8NTTg^@DkCis`)DfiXt2wT;OeQMMq{SGD#!(6qI=a?yZB8EoTj1 zO>wsj;V=V^kQvXi8jyM<%X(My0=1LPO7mo!y@DVdO-BqOCQORgN_9=wBc=rHb=SUfGy(OVoFoVcS%9 zi^~8avbO61G$exTz+Z)pSnYVpba;0B-8wd6%#V0P1DbVOs@}4n1UO+1!0or4yc$Sg zM_)kLPSuo#wWe#Pf1UACWvPxb)7fKASLy9D?+)J<(%8Qh-Xo^WX~-L>Oq5wXAuTo& zBh5`bf1f%Z&5}qPsagqG5z)1)`gp7EK4DM@K#c89^=w5;@kSUs-?zj3<53DH6EEV- z!P^sx&Leg#5YOsc!QD_iU}Pch$W8Rc>6r4BPiJ~<<=sYDgB;b2U}aL|kZ27dlJSZz zPb6F6z%zT@;!d_-_mvHHDkr`J9MD+>yYQ6_=bIREZ1}6>V3$*;`!0jj+M^Yz-0pSt zGTGb~M-`A6t8bvWXuBSowp|r(QPr@0;%D6|I#`r1JLXPtqOAD0v^9r5Td$vu69EV@ zO7eJz|8_((Ll&i?tIjgs*+7gf`dIS}RQd{|tcwgoA)l#o6BnS%^(4FZnc0}IXOpy% zWiXP8@6#<3Yt85gng+@!PKcveV(cn|r=siSv(Q|FbxeiVbQFz`J&B(}$b!h&)ioDk z()dsS>yibKVRYB)sdwuBt1~<1;>4<;_pBtSBkj>wk3vKzpuA=#*OH0a5xwg1lJWzwNyoB!Ag71{cLJVp)+@y*LSmIMpY06-?MQXl=OEXmfZyYEqbds|U z|En0uIy93RqvvP*kfV`mtBgaqRq^@Qb;1ErYAd4WC=Ex|oHp0A>5UEB#oL??n^>wd zo{`*CPbfy9KC~T9?P^|b8{K9gXYp(?yjeIdq4%{;z5L$bmWa zhFT`bJqAw4Gp2Ra`dt}^o-v8VSEeED4&=T_GTq;7?O3`O{&+9Hjv48?I_2x zDq{SG$zP@(dPH4Lt>z^rL4MQvM|!A!r=lp4qp#@N-8%l|I*1t61V(1A@Yje~y7xJ} z6OL7**{&~$_S@<*^ia74b{00Rld!nkxPiGSEWN7$j`YSo9FWO4GZBiFT2y8YxNg7u z5^o9NoQ3FX)%+Fwzs!I@LgPV}Xky%pubdy7BWYHtZ4mweZK!rThLzcmjHmr0yd{i` z;%+k+4pompqT?s5ka(RHv7scVuTBRiuD%u8NT>Dkd;}BQKtff!M>;Fjx6*^%Y*l!# zfn+R+nbDMt^G$$BLCY@cP@a6*?m@dBE<3GGq_lStzPD&8QH0Q-FSG-nt1_0gMRFZX3^O2(w1GK zAd2x0PL}6-&7?@UE2q`D!oPDa#oa})bfAXm=oA1Oe$+|2S|&BzX;mXUr`-t~;V#B| zLXIX}8`-$brg%bDa_~>W*&*C?Pjuw+cwZTER<+U#@XmKV*XFQ4$OjDyiMvmzV5D`P zttTWWQEYSFRq|A)eOxXv{$VxyzE5Bf4*@1*ee4T{AuEwFvh}Iz?0m&uJ7|y)H)xio z3jaP0R#B*`NDOIdg_#vDp#4g+2%H<@PCgaVO!41~bAq<=MX#^RHKSq5ylCYiqs(d#!T-%p^vAjgHoVTxfISAd*yG*% zWSl_FC)ot0j#W;@Taj?dh23Mn6JS!_=P{B3LENHxLcS*J&f-ueOQatt&w<)hYI0mB z*@T3scOcDM352^1W?1r4g$zYTIPnf#hnNzQ?TGZ)Omw`_s){59l31oi+z>P>A(};P z1JWxZ*{TBA#!O!Yx9gIyjq%7LwPF8J`7v%dRvs9su~{c3(n(6YGh2Qe3teX5@_^fod69={-5fhWV>@_WWCs zF%rHSa3hB+erH^Bw*>4vJYHtJmDw7fZI0}^`kfq_V_SwA+9nC4LkO2bOT$*tHLk8X z=e-C#*`2)kvTu$tIkou#-n%U*sJCwgrQYs<5(?Bl_Uf9aJREVQ9Nx(je3sD# z!F>5D5TBMS4TbP+_NPPkkS?qebS!7A-02jyA&x`P!BTmj>6)w@z4l|gri*Lx(2>`G z(A;ApnC6lBF~@!;ue_sb52-nbh3&n5$A`o1SK`O&hnLp`IFK0=G}J=-h=ZYI&2XL zFPbrQi(sad#>s~R7SHr@52;BEtjLtWb_#|Y1`sfU$k{DSRCkNNh{6_rOwO{E_Q4h) z#nX?qdZh`+je(kA;~2ZxV&66_0S^jMAK#?fefoNKpK6NNoM*eVotU;lZZb-?a%l20 zh^%NiOwnxLCnl?D7!wG+CT`U|KtWhcwODp_b|!~PiO3E-YErS{3CZD^;i+xa*`M(y2^pTA0#tW1S@xQ80UUpzPWi{$LkDT-~r3vxr;-g&MEoWiV zH!-8|qg>UdV0VN7g`FR{NAWwETq!@P4ZHUV>w{@%@%awSa;aiGDVw%6u7Jj#IK-bk zlyi1QqBrocy5`}}R*emv#L@(brqV$kkRVYv>Oz$#ucBt|k4O~UE8IlWD^^=h2GDM$ z;?z*ocrb7ZPMk3 zY$uWo2dS1qnJHZgjX+{lwyp@{_o0#COhf}A=-#^>*=mxoIZ@oYTGnTSO zm#B%D7-PLwiy#YD-=_+DMEM?Pfff_el0Hp_mLNY}oUCi(_afiwctK;(ZDU_u+7pWjp6H zN+9r3Rk>bR$r#6h#KSg&h&+Sg*L1`vAy-BVL>p9|f-tG6truUy_C5!9rSS(<4oST= z15{TTas+;6vJ#PXH8H`;n3qcV;nJQJPb#`mB`cTS+VTfR zOJgM^F$SR z_^i;K_P`!clz$|t@s(FuDp)3S)OT!(^z9w<%2_Ce*j-)I4;x_`%)pe{ePq^p03mG} z54$ezRu6_>i!-lBM2B}VGonq0L^^f;goaI9Q*bbz08js6W}!b#7*QdZ1M<3fhrqVbx0R7qVwb z#*WpcR_Dkgp{7qODuASX@Wp`6UA@BJ4kusK&AzIbM^^e$rcMUAn0kfaU%;ng2)WrO zRNd{t?-QZbBb)^Z>+&H(LNabt!E6{}bxln+9^NMB^ee;urn6DCfN_tD?!l>M8S`Q+ z)_$e*0%{DIaxnRNir+atc*j%y!uowsy<3ugl!M+dDtlRbsk-LD&sGAnw)^b3#+}r# zlEyEQ^u{J^Ri}g0N9vuf#d)P;&(9N8;?-2#?c~0hR2+TMjaI>Cenz!#8IT?r6P$TR zF~FM}+>zMl7_);iRTeS2!fGOlIPjW?0)RH0%M(^Pu1PJLhs70^lUwB|i*muE6eH@I z`g2J%#wy9^scjYGXMA<2M&;j)Z$f^_##tiH`VwSbaC*Dw^>4 zUNf|iS$eX`j7^JK5E|i0Xfs#Q1j?b8%pZ`NIQWpE3ub%}U3u7Lh3=yYr#0qo4dK@K z*Io`!01!r5S^Q3wl+ee(*!$dTa_H$?n^d*x!m$a4_p-H~&7t!8m=3w>ng+En-=6Q{ zZCF4~af(~HYBgb8BaS_r!E!rR7tMe6EaE$cbLB;=!=S|VM?ISMY*mK-ZG`i>0+kPU zR1#P<(Ln8q@__jcjV8Fty|gU@gPpFlOV(@2Sa{@8aod9YtBMJlUy)#Hwe4h zw-V~;Y??hvvNwGtxjp0&TwZ16!>&$;>sE5LAjiXdBi*Z5BZjJ8xTcjL0=WvOf{JH+qm{1afPxR8 z8kTS6x@)?kLAG>ehH~$>QglI9^>u>)_gx8WA!DEnEs%&C{Z8V|kwcfkLFFiW-Aa*~ z8#$K9qz!UrOclQUM_j~iW6iKFh2-Y+XO>$;T!AaNV3=a%t~EU8LkAY%xZ3M%?(#q@U=Kr z^&)TdI}vK2E@m)qD(vlsD?>OprH%bjm4n^jZiP_fl?A3s#VNe*nogt@%RzR;J%&XpPWaDJrk~ov`tA@?n*Txz#+^8?BUe+DJyv zYLV~pJA=nJn&8+WSmq`df2Wm5R-%cT7lm!VYa)$IsWVhfRhQ&OzY|EHRA!22tm_`v zj96MxsT(@lg6j8JiKWFR4viOW7&~IWmAd#)Ff>z*%so~@o3SJ0;W}YvFz&aKy4>D_ z-SOGkZ>1Lr^&W``m4^7bx8iP1x{bV1y)&(SoctSIGukp|z2mdO zjIUqmJP}VqZh(pu-M#Bp0;#M~U?J5&w)S|oN-dmawgd`yx!67{%^ovH1*iK6sc4@a zuTaCUh!XgOmSL}JD%7|qAd;;}x%SvYO-C1`lIh2U702-3nUyA9W*#+>;&P9#tgX~5 z1IsSbt=aFIN|vJ-s4X2#d#+TaF?vvamUZ@p9iO`es`KtX0n3i+dgVS@YF4iO!i=h< zgfHu|`{vYbrT(6QXqaggkMZJ;&q~%E>3wn*+b0gSmHI;ZqQ*g1vu$p4O^1q_GA<64 z8|ZZ_(>)+tRCLJYtGNd^TB&71f*zl#itTixl^cQ?**J%^%|36%-3li0`83mguYKF5 zN#O+P)M_H^aXR2;p+r;7V;IErWRD%6c?mSzb^{BNil1=Z6S7kMIkS~aVXwN<*R2#m z8W4f0Zg}`UamY%Ir;PgMe7H|thC+dxt%XJGO})6!HTAZA+B|ujgC*PPy5EVUXGQ~V zLq6`xY4y65sXY_q^|TGH+-LV;KPp(va^yQR-KV0%c+-&ry+XUZg9t%eH; zj$sRX#M|MH&ljJNc!29mJ%LKe`Fx+dO+N?F$zPjE=suOJRLDdO*nX5|d*#%4WC*~F z1u{;EbanXm$;@g*szX++{seCBvCh#F^rTSoHb;4Yr+#g*_rx`h;UY?v#~FW$#}pHOhHL33uVTggud z@0f=IpD+5fJ?=KVw_&Kj#k;kKoMkx(o%Y97MR#FkY6oOa|G32u6Y<2R(c^+HyXqlQA0dB{H;)0;AZQE;^{N5tg_S#*9;hd`<$?=GsT8x8|p0lkU6-8-y2v_q^j>|5kZ-u+IbdOAT3 zGtD5~wrVG!r5wnU5>yZ5F`Ai<1;J;=#<3NgfKFU~V{##-PPO~Usr^BNHqa^3t)>1v zKFN$g4JfqyVh>&L`HilFt{BT+AD>~;o-2oS6tBCcszYr~yN5Pc_5d!f9Nyi#xYAih zh7_l1gH_7z`wds7v#i!JlY5URuQ#DjONfy2sr*I<@E!taMLx5vtSS!m|y> z#es{blbOqvy75#F6JRHH*2$??ncj}Sh!Hf0y;b>;Axyj>u(9H~;0LlrI3@i;+C*0= z`C$G8xC`s3kJNEkobzHdmBi$r>aE~;xC*6V$2`I$18v79o0{1y?BcC>miNiy#UANx z_)gRGh4xr!$ICLLL{0ZseJdBQY4<5V{cN_JEV}o&rZZdh=^Z(M%UPVJ%--jBCfC$? z;%+vXE{;pA=Hg1Xh<%F*D|8wpGyHC~NW!Kh;o?(V&i}mbZppBqLXB$=}>jBq5L6w#6}>ssT+>R<8esSq^dzGJ$e z=-ihXNOgIi?^AA~+hsB$(@jJ0if4O+l>^yM7gr9?FfOi?Vd&e3RK1{~sLrw*tOSkE z)8sui322Ys>6Axs5#x0McKC4{w;@u_=aW_$h=tfo^kpA-fzRy%0 z2nIYH*hiFn>Km*K(}V;X$X%%$FJ3dTPutUG<`8Tm{O~8#6h6axbQkWnt%QGAZ1UMY z?=vewEsjD;La_6GcguFkW2MO?;oDrq?)n#jU$tS{ChUR4ukU+DR zts2P|o>lRL))&6Av?cP10U>>R3PKie)dPD~cw?^`F*FfUqyR$7%gc6q-t@6+Ekb&@k3sZOK|%I;_^ z2J&xjurf4vgdQ}7@+-S;CAKDmRy%8{w5zh33oDHu9U8$dtlXo|dvRszvKY^(J*73( zPPnj=QKwE0*Gc-jkVK0;gq?YyuEVpJJtOL#@1YftO1p+FR>@Cr3S7+ISZ31gFu@&_ z4CNcF)CC|d&IvlL^1h2J?LH&2=*A`_t0hPD;!0nc#-PqCXEmR zSH`1D%RBDGu)4gs{b+vq{-5s^`2fs$erZ0vI=Q4QJi4@8+`hat8sC1$>`oBX)!VDp zw_l#DZXc~KEiO-HmmnusE-hDA@3?g5Y<_iid3i-?%h&7niP5 ziu)_BEH7mq$LK1U;p!dNUi86`L<_Dj!IezL3f9u2F{hVh# z@$#qq{O>*U-#+Wfn_v7t?tJ>U{Qk|a`-;!KbkC>%ryu`IpSAgg554k_zwMo``1a5K z;m7~N!|(auU-i)!fAqEAbW?3L??>MF zg4h4cZ}{^M-t+nwyy&g3|Ijnu@%8`yeYgGb$+tg#^RZ8V_G8}t!N2gu|L{kicI)4L z$^ZJ5uX*?b9{MHk`IIL;;3sbTnZ=7ouU$RpQ{V9R-+k;~{3w&-u-o7`0Dq(>|cNHFCX9akazyvJD+{a zqi_00-|_u#8GqA9?tb6r-Shwa$sG@T?Qg&0kACIu-&(xzIiLN?A2>dG;Q#VXvtJ(l z^FRE}cfai6Py5Di`3rBp`3-M<#UDNOBhP!(=fCW4y!CM(_mnq%`0F0|fV&?0!_WNi zLyo`w;a~kl-~OmKeAW-oe*2zJ`!B!qC+~Uo(HH*XFZh+!e}C%tzv=T|^Lvl~_<#2& ze|qa%-~QCayT0tLU;CFn=E2|es+a%y$3Oak&-=6Ac<8gg?54-O`Hl0p{kJ#${`cK} z=_OZgdEaNf|K?x$-`@K3-*NM^U-X=xea-4CKH<*)?_d0|L+? z?T3E(i{AVF&;RIueB(1e_@l4=Vt>!m{$TpiU%L8x|KeYM&fk0f$1i{Up|AOkZ+q(# zzy8->_xz`Q)h+M5?c=`d{lETwPx z=Dq%kZ~0fh^aY>tr%$@;=375<#{+-hfuHoH&wlCC{^Bn@@&Ee6|M1ACfA{OY_9f4G z`J4XkWAL(@lSu-oi~5ym)`q<|NK9H^y#C}Xzw!SE5Leux literal 0 HcmV?d00001 diff --git a/main/res/drawable/edit_background.xml b/main/res/drawable/edit_background.xml new file mode 100644 index 0000000..f7c141a --- /dev/null +++ b/main/res/drawable/edit_background.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/main/res/drawable/flash_off.png b/main/res/drawable/flash_off.png new file mode 100644 index 0000000000000000000000000000000000000000..616f80ae5c9589ef1aab3f6794f7373b009c925c GIT binary patch literal 5785 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 literal 0 HcmV?d00001 diff --git a/main/res/drawable/flash_on.png b/main/res/drawable/flash_on.png new file mode 100644 index 0000000000000000000000000000000000000000..d47ef8a0c2a451105e6239745c1db27f61293483 GIT binary patch literal 4825 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 gNk^RUV + + + + \ No newline at end of file diff --git a/main/res/drawable/ic_baseline_account_circle_24.xml b/main/res/drawable/ic_baseline_account_circle_24.xml new file mode 100644 index 0000000..89199eb --- /dev/null +++ b/main/res/drawable/ic_baseline_account_circle_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_account_circle_24_actvite.xml b/main/res/drawable/ic_baseline_account_circle_24_actvite.xml new file mode 100644 index 0000000..4cac4ed --- /dev/null +++ b/main/res/drawable/ic_baseline_account_circle_24_actvite.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_attach_money_24.xml b/main/res/drawable/ic_baseline_attach_money_24.xml new file mode 100644 index 0000000..fecf031 --- /dev/null +++ b/main/res/drawable/ic_baseline_attach_money_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_chevron_left_24.xml b/main/res/drawable/ic_baseline_chevron_left_24.xml new file mode 100644 index 0000000..09598f1 --- /dev/null +++ b/main/res/drawable/ic_baseline_chevron_left_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_chevron_right_24.xml b/main/res/drawable/ic_baseline_chevron_right_24.xml new file mode 100644 index 0000000..fd2878a --- /dev/null +++ b/main/res/drawable/ic_baseline_chevron_right_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_email_24.xml b/main/res/drawable/ic_baseline_email_24.xml new file mode 100644 index 0000000..6943b4c --- /dev/null +++ b/main/res/drawable/ic_baseline_email_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_format_list_bulleted_24.xml b/main/res/drawable/ic_baseline_format_list_bulleted_24.xml new file mode 100644 index 0000000..0b66281 --- /dev/null +++ b/main/res/drawable/ic_baseline_format_list_bulleted_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_house_24.xml b/main/res/drawable/ic_baseline_house_24.xml new file mode 100644 index 0000000..c199d14 --- /dev/null +++ b/main/res/drawable/ic_baseline_house_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_house_24_active.xml b/main/res/drawable/ic_baseline_house_24_active.xml new file mode 100644 index 0000000..900d6cc --- /dev/null +++ b/main/res/drawable/ic_baseline_house_24_active.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_live_tv_24.xml b/main/res/drawable/ic_baseline_live_tv_24.xml new file mode 100644 index 0000000..4c6cd09 --- /dev/null +++ b/main/res/drawable/ic_baseline_live_tv_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_local_fire_department_24.xml b/main/res/drawable/ic_baseline_local_fire_department_24.xml new file mode 100644 index 0000000..adb2a4a --- /dev/null +++ b/main/res/drawable/ic_baseline_local_fire_department_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_more_horiz_24.xml b/main/res/drawable/ic_baseline_more_horiz_24.xml new file mode 100644 index 0000000..6439bcc --- /dev/null +++ b/main/res/drawable/ic_baseline_more_horiz_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_qr_code_scanner_24.xml b/main/res/drawable/ic_baseline_qr_code_scanner_24.xml new file mode 100644 index 0000000..597e8d7 --- /dev/null +++ b/main/res/drawable/ic_baseline_qr_code_scanner_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_search_24.xml b/main/res/drawable/ic_baseline_search_24.xml new file mode 100644 index 0000000..07b76d6 --- /dev/null +++ b/main/res/drawable/ic_baseline_search_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_settings_24.xml b/main/res/drawable/ic_baseline_settings_24.xml new file mode 100644 index 0000000..41a82ed --- /dev/null +++ b/main/res/drawable/ic_baseline_settings_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_share_24.xml b/main/res/drawable/ic_baseline_share_24.xml new file mode 100644 index 0000000..2f13bb3 --- /dev/null +++ b/main/res/drawable/ic_baseline_share_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_star_24.xml b/main/res/drawable/ic_baseline_star_24.xml new file mode 100644 index 0000000..3383294 --- /dev/null +++ b/main/res/drawable/ic_baseline_star_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_star_24_actvite.xml b/main/res/drawable/ic_baseline_star_24_actvite.xml new file mode 100644 index 0000000..a474b21 --- /dev/null +++ b/main/res/drawable/ic_baseline_star_24_actvite.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_baseline_update_24.xml b/main/res/drawable/ic_baseline_update_24.xml new file mode 100644 index 0000000..3b92302 --- /dev/null +++ b/main/res/drawable/ic_baseline_update_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/main/res/drawable/ic_launcher_background.xml b/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..a4f78de --- /dev/null +++ b/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/main/res/drawable/ic_switch_screen.xml b/main/res/drawable/ic_switch_screen.xml new file mode 100644 index 0000000..ea2eee6 --- /dev/null +++ b/main/res/drawable/ic_switch_screen.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/main/res/drawable/myphoto.jpg b/main/res/drawable/myphoto.jpg new file mode 100644 index 0000000000000000000000000000000000000000..47098b12a06bf3becb174d69c9a72e3a3ed20c5a GIT binary patch literal 49018 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�ttFMqbl&vq7~m z^?r38rWnk(Lx*!(6JsTj7IX-k?5SAox<{=aS%x0I?WN(5uPr>n*>AXH=ECKVC5!p? zx+VPru6nRAsjJsjZ-JkKMaGWvn*d)~__4D)0<@ucBU@x%7`DX+Hu|%g; zHK+IRm;GgYQs}Pb@B+89^fu$J4?(rp-2th&NJP*97netc;CmWl`^Z zyPLE8Nk>}Wc5DknqFO>;{nAz2&fyuHlJ_A+Z3>{d`HQ_WfBQK7u?&2y{gr1b@P}YN}ngj zg>P3KF^)0~k+6 zJO{9iL{6grf!UzUv^}Tuf~Lu2YBkjvU|(ap+_?=wul|z$=Hmjhn0IG;Y#CZ8x9OW9kZLcw-$d;`F(}{P z+P`S3=xmG0t`kz#JU!;j`j91Yi&Sg1I;Znq4Kqb&JUC*WsD%rj31!QO6YA)%D|x;6 z=9&~DE42sifyL-xp*x%T#3^``WyR3_eI+WW23kOV`gVz<9?C?5ddhd~d>^)}W)H!e z>$8Er4j)Qaz(TrVy~>^QulUw5+%csNv)Gxi!y_i6E*oE^=9a48yYIV3w%Y zXf}CXL5)IOJtE(-`=tzdV>o29W|piZX;PAow0XlhZBNqzMrbgvlv)E2}>vj++-CDDXXpyMOLLEOnN#(eB{Sjp zlb#xYL#mHZ*Ti>Y!CS(hT&bcjN(Mg|W|y|6hhUqI3%dqDBH7g1?+1e=Wb!*oDt%$c z4`T=i!8;oX;U|P^KKM0Xollqnz}NfKqQpD0qTHq?Agtu6Q-2eW&Ujdp>JNr6{YF$dpZs+8` zv|wJebYtnrAZqG+bjL}Gh4;Oe{?_KGBeDnkeKkvG?^o12Ft8HAMIvq;00}`^CP~Ef zYoT=~i)M>`t=z%ds3qxhL;hFx`M6eM+&zCV+{dWrv_lJ)TjVX;`wfpX9fVF*apHur zy*KnLul|CPmawAr0}FCV3ixM(Q{|~ueD|VW8_MOztv}5hWUcBd;pS3_t0?Em@HMiN z5*}^-bAvs>sNK7@jOwrI_Jg4r7z5uUcKN086{)J4BV32$RBqp8xY&n=FqV38ohJS! zQG+OrYIp%8cw*GJ=}K1W(-1L_syue}YezMz-?7)zDui9uy;Hm`6f8!zPYb95N)>Nq zH5>EpJZ5wSZd2gCKY#vbB>fx5+txM`A9|ri6EUfX`YuGfp$yGTXD40hp>hyW6MvmO#(D3f6;ssJ1!r{Z}F9B z3F-F-nirYXYXkjPopaq?H)If2*^hB%6p2`B1vIxls31;_=M!bQ#W}fwvhLoZ?dL@0 z@8=4Vop5XuK@JnJOkW-N<-&3@sPL|e;hXTmn$x^YY{#u?jet+mePl^QkEh&Bw_g~% zirZzPHtAks^2eMtDfM|S!{L3EY2%p;v=Lwht`)N-HB+48qUFDZm)LLZ+Frmt9aQR1r_)uG1Fl$SR%vAUD>Eab zH_S${o6ovG9H>;%vf!CIgJR{@EFzoMQgt=p zEmP8&+}IDMSmvjeK`O!6<-z-q=Ygx3&pY{1kA>kXF5d_2PLv|MVH3RJO<9~O+t*kl z-RIA=tXsz;IKA4EmjqVsZQ10m`f&VmvK*fh|?{RztF@2^*?B9u#d%1u_}=@PUjiWuYGKAgnZSLViUOM&w> z`YlJ?@j_oYE4Lqv`uaCVs5M1!XOx=}%vy@PdOasMZ7;3ZuXx5b-V-4hI_9H25BcP^ zhNNZtaME$y@jfd~NyndU)zmIJl{$Rijba*izH8Et2`QZhVJ9~tFH3ZMcS=rVsWVpT z%j32Nr%sC^;>+vn$C3yL|3sTX#AW~5s3fO=C z?sO}e2rC{gTuXVmP-R}aIlCNzIJT^Rb))xRa1CW@+|1M5!O{F+6{{ayG8J*-rF)~=g=*Mxz}4Uh_%z(K zU^Bw?k_BUoM2Y);h2JC@pVG2XH?^?wg00F#P%>heYS%Zu!L1L9OQBSL0$=Z`qB^!D z+2nRD?gwkVXiv6q3(*F3*o68VBKi>TYI*=-L-u{&@+7Jk;;<|~PP)3ndOXoIqE?Gd zTxzwYNS{m_A+6dJJnh4RIlT8OBL<5NDI#aK>Y}GilM$)y!KTIKDMY*m5`%e-kHTFVEUMWnL=`T;<&Ve~dO^D;O z3#lDeRW@ejJdLSVamysPiB;M>{aWN7C`15q zq=gee+{cuS6Pikk1u+-sG2mF@I+&DQ@bz)|X_H?0o{9lff3$jk=y?QV7zCQz)I6@) z*<`>tcY?_uwj4nlVPuJ5b3T2>i7n6*q4s6eg~TLIGa0iX*}*Qdgx0;FPXu;b(ADYA zWzm+PoTH@~i?yC0#&k$YOt`wNubtr2=hh4T!OZPj2F&2Kd=Uh6#bHaU=#1wUS6bzf zf0npfTFSza2V}LsN9L}8I9ZBsTINjilw(k-EVI=4tg1?^Tb#!z*|~8%28=70>Ipy)23Zs>$v{b|Y(L(3H*A6DbpB{*6Jj-L@-IaLSIZ6%pE?#ViJD z<>ewoddmVI1!@HIBG|OMNV4Z)nm{FGv)1c5EDDXelVTL;1%46ydCl4}#U37V-!;RG zLooBMJIeQ%IDWJ=ySc3tqPV~kz&%Q9c^w^B_`QvjmFvnJIe81(l6b(i(%f%b`2uJB zJ|Id4gG<9h)00*tVjbq6#x~@hL&^Pk->GqYu)W1P zz)it`k{m02uzHeaDvHieY*89}VTW2kV!KAw{I~xelK<=k$iK1u>_)Fh(_|eBF zSl2(q*G?of{PZ&<98~U#@~`n(x>V9L7CMS^0Nd^n1Y6)Sby5W@c{4}43loO>Z(P_e zcj$nU^}W)2*H6ypud9j-n||Jcd#VTE?qKb%z0YVrHXn@(^A64+UN`6lFE1T=EbXt$ zN#<+>*O5Y<13@S^b_#2rI)$F7*yM|@sdHWF+LM%YD948j?x@4B*Zf7u= zEYYEVkSb;u(rH%dULP=qul%M-y&Q4o2Pk5%RsfZ$>TgxkX zU9K&`tp(L#{q(ed;1V{(XL}V_HpKU7P9CLcd}c;<(fa_P*F;`r9`#TS-PlnJ!|-@f zDKQhIZblT9`0~+ae>_ugK{5y?T#2dh2|#k7ES2QUhB{|Mg!duzf|1kW4eh<`#t*VK zGRIqan*hZPXjWmgA=?PM?$(&>mu>4zIuo!#(~!lGxXdaxf8ze$hPMLx(ZIM_>F8zk z)}V1*ItDqh1=A_(^x27_-&EOltu5ZA?7n6=Yx);P0t(VseHlcI3`Pxn%!NphJ22ri~v6Xepg<&aM z!tTuhd28gPs(VWlxNCPwSn$)3b{o$!h>ocST}})DzoQRuWmKGt5n}H^asVAU#Xo9oR#(-MV#hpyTu=7`^k1yHWuWsD8hagL6GknEF1rI4$35nmo{80E!|F|a1cXn@aKv|_?)X;>faRXy9LlLj zSm?oNp{HTFd&q&X#W016J3iZ{Gt{7rR05ZO3up zQ49Y3q;Y|8IvLQJ)hYQg17W&7NQDs=!aA|JXHMh7Q48;Il>T7)7#K!;d@BUkVW)fiG zA4zhfNq@UgB^K>((>bFFkCUTMAT)5HvT$#<>l2d+0;#ygMqR3s_r-f4A*EaEX^s)_ zs6cej-dlsp7Up2;a^mC=3b?Ay{0ntM;w;VE< z{(+w0Q9Y*vUpHzGTQ&;twwwQ|st|4gM6EwW$!T_aWdY|g5?QR{ETIW2UY6T?P?nNw zlL9cl5~6CN(k6+Panfv_r=syVGT(99<|t*toVK!{1*OKEUX#sYFM4r+v}6euDaN{@ z8h8w6&qkAhk+xVTaWO)8 zwh{>2%3$@Q+|`8n@;NgfWU1zj*a^wlasCii)AVIqUU~;3urCsu{?e~olk#_h#YA}KJAH^!{e^I!G16lRh^l7#2a4eE%{0Ze0*!)v6^F>0smH{{!b5D4o1fN zag@1Rv3js6o4ASPm6VK$(K}Xiqw!Vye zCmriyf;Ga&hq3_GqLxQ^%t1dWS?L@MvaK3s76Cgor8G3S$;#!gs5KmZVRhM5TVmiGExBf z?VQYS|Me1*)T<3IU)sT4ri;<)UemhsPo!!B36q;)1Yb`qZD#YMO1?`-yl9p%&RQ@+ z1hfP@+SDSK2NKG~tO=g{&DP`GRadgzkjfU%iWGq+(>YI7U9ihfFoO5c{aKb-`RfGxwcpc_qKvo~* z34AQaMUAW*lsx~}0R87@8adB{0p1;xS!)LU`M571(5Gcx4*#w|i>gZ}(KL%GarWX(=hMsqolS z*KXCqW{XgM?Cph#+Pe>^WsfUng&ifH=Tajr_Gp)~6Dr>+0q4XCJuTxD=AsSm#a@unv0~>)FT8Rw<>up+;;g3 zz&{@P4t!IP=(;%9a!`6!`MB{xOvs&vy+y}@B=SS8Fh=qynE)v*0_#9e}TSY$ZYQy?ZV1TaX%DJJ+)w{(b)6F{e zf)RrIU<9D*ljFn*YWG*wmZ@7oX=J`KA5@blojdgsuAd`6z54s9TECxJt;xt{&Qr;W zGxE-Gu9a;E3H=$im(7RLCiA>?@t)bmrY1XsGtMe;D93#y(}@DEL_!x6X7J}ZxWF=P zD)C?74F-pGcAwVaJ*kyZeXmFgCcOK7diKM3g#r2DhO{w_9a||gE#O{sQuTYKy8gWT zX41@^?upZiq$6Bn!CH@R%?9^=GB9P2YFqYvqL(R~l|;<6{TsVCp=Z#=F!qwQmm^V5 ze0`05F%&V6!AXgfNx9IsnOgbrx*IA}MhjjB`e>zKdfY9iwU$H}Up_K`sq%X zHu9fOy#M_fi_L$oMzvF1;7{ed+YBI1gy$!^)PtK>=L?&|nDR69Wr(Y98k)4u7^`Ms zm$o!=A%+y}fZy~_*4SX#)h5+ zYQCwd$+mP;izb@Uz@=cpg4?vu}>7;2)WZ`Y788>z^ zf4f>U@ARo=(NgT|yr{==_FMILHe#%ZNCw*y<_`r0?SsxG z_I}sXVsB9f@o_-297Oy94Aq4qSZZ{-vxI#Ts-)I9?3nbsT$WZ!gq&1}c@rYh8up=YBA=RV)Bd(L|KT{`z*2*|5@}& zIexE4K=f#ba#SB_%G}CP9^3LNJy_q%{isDLOkI$hCWY&y08_@uHtV{7MIyj~Q+)8-u1<`^ikr(5a$!@B=QF&PH2W1GALt1? z*~=?8MerT}j)|!3XZbkPgbyE%JIW>Mn6>3y2r}g+gk_6C*XUc>pz|H>E;F@5)dRaa zeRH$a8os&r!&9RD5ug}-sM2t^Huc5K1>PfJDYtL5mh1Ud{}6W7@Q{C=;+`GrT_ujN zPd1N7=$j#wsLOXppNx3dZRUiEtf97Jo-6uL;ntRWR@xS?7Nh5Dh64|-0gfi|H^+$;Napqp>NQgKJ1<;?K@%FyK2xJ#o9a?t6^KZkQiOzK^-FF zyf%?{@F=MVo&o*O=lx_}(K81r0l$d?9$+i_{3A@HxbupZfl}*VJEBaOY$K2B-vbcD zOmB#Y5TO{R6F*cNZQ4GO(@QS_|7vGY_V)<%ZZqu#*NNJ9YmtgE8z@H5qF)mJF0GF) zq=qWJ7HH^oI6FM{J-(UAJjN&sX-NOLzJwv)-_L7@sfg99w#MF=cTIXm48o07 zH-m2Jt*u1yS;Ukb#yHIa{FwM&Qsk#Mabu&=mhQ^uMdeMJXXXYLKcfdCs1E1I>(RlP z)4u{`5n}ms4ko%F;~6`)kCOdsB0kCRE?3CPjepqw@tm%YPE(WV&RbHivNub( z@-?gKh{cQ_r$9x9h{6|HE9YIw)Z={u?n;I96aff$oyxR=hV#^o(EyD!bnYnXh^R4q6MGcPH0xbux3RlAm z7tN{I2;%Dg-APAgBv3D>l{QRPeq)zIJF`V*yab@y)wCz7P3ow6QXd>qCA`95JEm<(`WxwvNWzw^O)_ zTpaJO52xv5!QdAr&zZRK?^YKg@vAt0Z>E50@NZ^i_kCEAr`fx%gGV|Rh%cXQjUC|@ zT3*5ISlmvSeP{8w%gaFgZzFin5a!wU`x?P>{r4j&NpXo7{a6x|~! z2W!DXBMeuu$|HCDXU;t)RSn2EJ~#w;{HLl^6E;IW3rwa}bKQ0O@Q;ah_E3NRCv{y> zcE5U<$&QSh`F!V!V%a5T3^g-?hla z(*vtQdrZxv?kJk@6>2>hu3;)(+r40_g*P$SI=m3}roTj!;}hhRBoO2~!yf%@-4l{E^=mh} zX^WcQ3-4PxZ*b;mlQtg}fXJNvi-7~0MzBC#E#Yv zJ8Z!PWzM|~?g!+y1O)iCve;2Ybk+?<9&KPBx%Xaz+5*W|kb+4^P`0!(=SGE`rL=*QSxz%H#gBs&TqGZ~O_^0QK|@W9!0VEu2##g&N@`EaA-Sj0-0nV3CcIz z)&t=be}695OPeTgiRu*&t@oys43ncu&37ao1WD~_k)y2qM<$;BohjtD{~9cW=J^^e6N0vwuOe6I3+!Ns{{Q(33eYPRP)5}*~KDO;&h=B%G9-b(zD_i2ASt6{J2VuJpv(J&?}yj|XP*)Fky+;g(T_pUr}I!SL7-qHpyPS&jydwg0Y@mD^u z!(77DwaPprdLe#)bR6+7IKY2<#65%vZw&*IYG&g1)gkWpISOIZWt%%ti`XAr%+k#p zcD?ny(U7)vHL7>_A9lmOti;AyY3ot*oI5La@C|eIiDCny z821ax$OWan%@z(rIC}Xp1m^Wg{y;915%{q=O7OA#p~5?{lWGkmSvijIC*M_@6w3ns z`0f)`tr}Q6KAI3C^sFT=qsHzT+iKO*{6KM)b7-n>k*jKx4rX=ANA71X4)kXWO*Jo! zDy_y1L14dqb8S<-%-gmG@~q!3l9q@0jcSXvp~2248)WpAuZ(-SNOUl(J*+K(VBpOy zZtnCforSHojRTc9Kl8S=yfm#PjV-1Ca0biFv$}v2T#?n+>%iK)2i7#;1c0Mb+Xl@4 zdCdCP-j*IH-mhte+DFrECVSEQ$vh7S(H)b%C8z_4UBHkWi#Soo9-N$x7IK&|wBmum ztlsMe=cbr}iFv)e!c6$*6Ku;ah!&~nminp;zg3%qk-iskCC;K-7b%(%sP`1;uHng&})C0Oh8>*xCvu?8$P;qno@h{&_I| zrTgDJ`!=#J6kIs))M2{y?#hH+*;ZubG#qRT4n>7Ag=4it8+4o{Ir4u9IwU=rySb6zq0t4XCdp&$TgW9hfezx`xJ)((^f)}T=wj5zIpEt zY)oxKzE8^V%M~}wUl`h}3iVNOL`LBj9p1=IG(OKd;osU5GEBhMu$Lp_m);!_=Vitt zSqJ^YEDZo)R@MU@x9-o6U3Lrd0IGwxdm)Q&r%}sYoy-R1h2^eTuaTMNpw?^eP*?R< zlFVMC&%Ot?-I5sD9;dL*bvNWCSNBX~mG@y`ncr?oQ$hNAX`QJzpJf=^K7rkJv5z}1 zV)IDK7^OhI2)X#+-ap3u7#QH=7*GoBtoKe1rVljcdo@!wRe5aBRHSDZ0>lvJsf&g| z$?}&xs5E8w384FaFO9fuKp5TY$pZ&2|}#{ugL+I|NWHT&-$lrOe^trB{->4}lP<8W$)IlJVLyxvYNtyfvb8-IZZ z*|>}q)9;fW52{u93rEhuWjRkY+bS0dHyM>ZscFZA+?-1W_}qx zS#D2rucAIk)bndr;t#G7$?)348OK|;Q-?xq8}p){lbW3;{11}ZQ8N|X$^r<7Gaj1Y z`gNy5wm@L^45zj{VV`i70C_LMbNjPAKuv$CmW z4&c$xWUSH$d&Wbq(~B%>g~ApYc5(7F5KPH7=-gcO9oP*syIMV%baOmDgT2wQ`1;^~hmj))raj2snd|W}Yu^b?R z4HSsOfVGnUMDcg5)|H!V<4N(o!u`YeC4Hm7T(v60;)QIJ?7}@*!)1DAx^06x-15Pm zmN8Os&{akkqld7N6}RDWd**KIa1W_a>~?!VD6b^sl+m=S$3N^=*Tv456d#wIECXaU z!yaW?Pr2Uv{?}O&_*_R^^OgU@Mo#nR=+QYm))&b0Yxgcji|nj1#2Q+~1BTZ~zwGIy z4BU2W_6>Jb22$NJUxIQ1CbMJo0$T=((|s4fm6P8SV>htT?_5dyS_)fN0Du}R2`17M z;l-BYoOTy(yR9W5qUkbwYc%?$R@@e>XWuTb1G8T{8}Ebb$;@U{*R4-R-M9;P5g5U_ z>>}PVxD_*)nTqsZ3vkcgZSet*an04>V18L1qUnvdkF) z`I^aO2`TbwZ#9dQ6y@3?Yv0sc7(2_Hmz}Uk-EN6SDSlT4xCo9@?;aVe^pK6L0cp)` z1J2s^^~ux;-eCH9H*Es;)g=FAfM_`QTjSl(6sLiItIYVHc6(~0vm|fqc8w%yrB-*c zHYeKrp>os15`)M63ZERtWo|YJEN1~U#6SN`jxlPc*@fonzdB(+vbOr_%}^~bpe3=aaY1k>;($j;w`KV3Abbt9>Y;kz^ha2vyv_yT(ek9K ztAwW5Lo=bhaWQZ2ikrQGG`5y;FeXf;=4n6b*W;t}IQ=5MA<;6k{%oTic?Yc{N&3ep z4Qn9v_mzvbTO(PZB1gMXn5)0ZbsFZKgYlNaYs>f&p7-`~GR9b7hmc!m|eprgt-gr%!eT z3h^xG5k*wKFjHlX46w=X5t;g84*nuUzU^SbQ??2^is#+v1}w&!Rs=DM7cYfd3Wrz51psa11{XwydN8)^BP0*Ni;Q2e-a_A9;oTaOj;xd3&nmedvn!>e-SO& zehGRjVO+Z6wdZT6Q)TT^l0>-_d*Z$SH12=z`V(KM!4xMU^T3&h@Tr*{=J+x?d*rBv z`g=>2`US_(K;eh8Ged|Zn6{oTwn7AuboFxwdb@d^WAtC8uu(>1rzy*9cFa13M5;dL zAT&6v2fobNuBoyjd?f_<^taMaw-N*8+I_>fp=cVbIW=n$>KrL?9hzB}z z5^@$l3&SQj4`fydT}_%jDfM-VDpwLdi~=No-P$F3@@nW&!H{+M=uHgc4kpo5k=1!I zYvl)*D3+?sUvn={yYF9Q+Y^)+$FKZ3TWvM(ItThQK7ds0MQ4Un>f zRE+e3+1(C(%?rFqjAr9T`)tKy$24*d0t4k+%_4mx+s)O{j_>_Ur=e%&vOuCg*Vo~s z8?P8>EfjyPDzVJ;Rw(ZJ%aM%H3avmC5J!tpN|9&upqUFL6M&JQNT@L0`n9&sI6=a5 zQO^UWk-Yd}pdV(GX@R{HmsXqt4r0(nZSzsn3w0~Yjh3P#4P*I!_NB)#zTz;Pgq~sl zdjiLO0}-DO|HNt|wb-sL+<`5<46cf&FzWtmb^yr{Lp!n`6>)( z8~0PTt?=@xblL5NH%|%u;BsFwPy1p%9J`yIpa~%lVIzjl7TJaNz{_Pwq(4`_KVRD% zvr32)MA#MY&F#}yK+0+%YeoDuXJ$qk9m7{$si`1avQDXxF%EuD&>p6(uNPoFADH}_ z7r@DNih5OJ{8#Rv@qbaUND>3~oAz(1QckUvS!4p@YMkGH`R04Ry2d)fZn{2zHsLU_QPAF5BrSM1+*z4{ zn`$+vYhaL;y|xeXo~wjMnETg!7xSpmxKL+|aY40~p_& z@M(@7tGno|Sw^O7ARy;-^J%23dx_g^-G!Wk2|b1Kk@n|V0L&a(0?7Zo+dQijm%Fn- zf1`?p=Rf>%6wh{2<#AcH-!iIjzSipLt`83ABc+U#`YuqD#QRM_R-=(iqWlh3mW6v+ zD{juE^VIwYSVT7Tmy9sMcpD$l!zlx0N*?5*1ZteWF9wv@M!Duk%EJwLN)wlyQ zv5_~Z(m96Git|lzHOw@YyIg;b8^vQGZCpGQg5Cax2hPSO@-+t8X+6HLug{C|Vd@Q+ zlM4pxaK|pGIjg3_*ZpESN5q9hTCVkpL$aQ#c#0h(GDfvxEl6A5C|651E-Ytq3_!T? zXM8U6Km)a>GtvE|wCLUm&*_`LyAu0?J9TD4K20|3g!CxWz*SL|1yeZQQEx2n z`2xemy&c_YKAUFE&i2-MyW!7|lL?bv@f?mK(pNQ%Jp!76)_(~T2>gjf)`HF;3-3W= zmuGZyuUS_ZPQ5u%HMpJDFeJ6^IJh4fW0Vqa`7{L#sQrqXq<-D=)+}eb_U?*ecW_q8 z#7q^{>&DNl2}=2fN2I${km1=Tlver_3Bw~;fJN- zevt3A*d3AX$K&c{`U+Th`5h?XrE(ST;lMysG{rxg7|K(7PTC5*0UkyyC&=|mfO^%_ z14===TJ%2m17XY@a;|z|=;Y4IzVgQWx<;-lIm-lW*$Z!J3Sk2*+=q!-Gw8^NVZfK@ zJDXG9*!h`Z_-5jz;TpGV7Vj32f3<6%g#DJHf3_Of@iZ8~X9%75ARgU13)yB#w8En?~ny2M^KJjXG@q1{`fy&{PQ&jDk7%>lh2@7}3q0kd(Y`=AkItzGMM zgmu?EE+T6oW99q$y6N|D>3zo zZirc$WmRw-BJM-u)!J8wW+k295~2lL^3r8^BhBNFlKiE<7`mxR$)WA^kn|s1>uJ&D z=dT5Nj9i{SH>$M(Ui7tL)z`6i4|PCjg0i_|!F$;dgVg{;ZF0_<=dQ&;Q-qOeh1pj? z?=xAqaJZL!#dxl!ho4l_lq<66EYV{b`Ze_kL6CRq4E-1dFIX)iH6NTR<#*RaBQWZ3 z8l}@@eX{_LSe$)VFL8M5x^7xA1|1l%d$8B#c$=Uo{rajZoe4W3K6pN`5WS^lPXB7Gra=8IM9BB?L2#osDESH0WpJ@SNmiS6^+Twai= zk~umZMY=Rsz5<>ID@SeJI-K(-78kJ|)`(-i4(Vt7Q3Y^Fvc}K5X{r zRa40BZ}fEQq%vqHT2VTxQ*8g#^rOAou3eqIx74ta!**6MfErx*xakC5k^zP@5@9Td=Do5^E4CFSR^ zQrH&raODe`gR3nix8RhTR`dlO*`1EMUUv>Ynrx7Vo;JypZh4K$T;hMz@Kw}SpB_0& zPmRk)ydz-SxhWfE67q42VzSZV4aO=PyS5pG)A};A33;l=zOQIc?l(W7dE?Ru_OFK} zM#VpC_l?(Qy)}^8kV}b7gtP3v_6MG$N5fhH*2)pf(VbMhN@~gUtI8u7B(Njw{LwgvcvGE9-b6% z^R{uJ9C|0gUyiVDZ!XK83b?%{RS;eAQvcCE1M%OV_>==Qh2i zdkG~|6oziJvyh!~0XT9qUOrGt;I|X`Ke$}0PyXQAQp-R5R0q8WhED-^Ktg5E;H?th zmOEe6UUHDeiMWf6#oqvdqkiELI@j$Pr2D7+tf*U&X{2rWhgbN8{e{Z*ZzPBOG;JuC zLJt=0``>t{|Noo+<_Pd%C`ffRI-i)^eF?$+b44fJ)gf+V26i4lK==C7h*DsM*FP+8t$SU^8|S8y)Jd2--h9n6Ji3w_xKXIeE_`s3b>g{l`I4*U@1Ro+(J}osAr4UADqms(a*0&Fm6rS z$ju_;-wFKUdBDU3we@s|mXS*-!FYy`i>;KQ8MlP6+HT#}A%GRWr*IY^b?I(Zm|tGH zJ>!yZ1+$CA?A#O80&Hdn<4PxRH!FKy((kxTGe8+bJ_&S&1vyBQqJ z*9ld_XE5{C#T@g!H`5sbnyRedt4~~Qn$LN@FsV)iA?_2!)t+CUi8#oWmmZRYl z_ijtbsN__nud{p_Oh`oy-&d~S4fU;UJ$$rODj3h?qaR=U_9boE8hX|%W9VUNlZxrD zCD!dq?KGHacTKIK4}NLyr%%VTT*X||P3#t40@HX+Zj;`*|dan3e&qbsZ77wm}D z0D5H4cfXm!*#GI%35@zc7HMI2$awwob2PD;x;Rh&#uJHAWFe&&aYP23#@Lg z9E5w9$5`G$%2aG%gD7mF!w(LE(<;3pu^^6K@`q=r#G#e;*LeH?)TjpbUlL!qE})r^DL{fs|-G|U*0!xMeQ zS>sCmb4@}8ohrbrHb2nZqVxTWHd8%mAM6S?tElrYSz9GO1nnkT@f3}2lzw`Br&Fj;cf1L z)xSYCilSUI&CJVVi&Pg^21ZTT-|zS|1kzp25vG^gu%ner=3wuk{_l6%T6AaAB z<@MuNm(awPlt^excdsi##`AM%#{)CO{V!V_6~fY|^Don&bVF6P)`CG~1322fxT7I( z+QspV$E*01lIKu$%=rEx(jR}jtCN)Q2qKiPE?_h12M#90C~q9|9Z1{{$T*^s)QHQo zscSF{nH&nR4K+{A*|{LlOW?d^hstzpg69RByNO`Y?B}c_VZk3^c+elKAubvd{UmsvYeM9P+I81l3c z6wnu%Y1M*~tMl77kNuXl{7gLGLO-wa?V%izc9`MEsu1gc>0=^3={M5VFhaE-CKWPI zg${8KwM?4)*#*4G#{~oLJ+RMVm+suG4xDyHwk2 zbm_GiHL+VI2Z1|ku>|s0N;wN)nnz4w@yE?yry{ zUBM`IYWt$cO7a+5olRXc(qkz9bVD)8UYCKz@oRsa6IN6~n-!V`tz`R~$o=3th|!&y z8$|hUK!(!X@Jo@yOJnihPMj@|lySWtDrL))?GKgfy{Y#di`s;4M7sAzr82x}zIj}& zo8eA>OS8{+8i9jeQCBfoV#y%UiHc4=%n>m{$q=)vzvQSd&h85VeV`l;!m|j`& zxu2fT?iz5U^5k&nA*`XgvfLgA!cqK_$36alonfjaltGr`EXw~+A_N!LkbS9sud=}N ziWX&cwN7gw?yT&3_u?u?Uns|-WGNv0FB^Vw3G5a~3f=p=%v&Y&ez?bLCXC%032yur zPd2kGrKbD(**EfX4T5suaOMOC&^k4 z*Rh$e%cFfMo35t}r4OAHW9 zuyU%{cA{U5z9u--XLujp8|22NjQ^%-bre?TfK|7(%OfK>p_m!Q|210)?||8M^O|>I zy%tl+nVG+ywrvRNM%)V3|G7Nf-m*1zrZHYrjsuiwMqb>`6U9m^#=Zt#<+a5mTsTFJ za=K?9y%|;zIJDacG7s<6ZhOi#+;+Nk2YUTU)3Rv4jXIttSIgq$QBJpoRECTpp{QEV hq_XXC@0BH$8)qMX4;(BUW(3M{=)perTo-@P{|}Vf%X$C+ literal 0 HcmV?d00001 diff --git a/main/res/drawable/search_shape.xml b/main/res/drawable/search_shape.xml new file mode 100644 index 0000000..89c5bb1 --- /dev/null +++ b/main/res/drawable/search_shape.xml @@ -0,0 +1,15 @@ + + + android:shape="rectangle"> + + + + + + \ No newline at end of file diff --git a/main/res/drawable/star_select.xml b/main/res/drawable/star_select.xml new file mode 100644 index 0000000..4ce6cf2 --- /dev/null +++ b/main/res/drawable/star_select.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/main/res/drawable/thumbnail.xml b/main/res/drawable/thumbnail.xml new file mode 100644 index 0000000..ea2eee6 --- /dev/null +++ b/main/res/drawable/thumbnail.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/main/res/layout/activity_bottom.xml b/main/res/layout/activity_bottom.xml new file mode 100644 index 0000000..49319ff --- /dev/null +++ b/main/res/layout/activity_bottom.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/main/res/layout/activity_main.xml b/main/res/layout/activity_main.xml new file mode 100644 index 0000000..ca0c0de --- /dev/null +++ b/main/res/layout/activity_main.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/main/res/layout/activity_mid.xml b/main/res/layout/activity_mid.xml new file mode 100644 index 0000000..ddfaf4a --- /dev/null +++ b/main/res/layout/activity_mid.xml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/main/res/layout/activity_movie.xml b/main/res/layout/activity_movie.xml new file mode 100644 index 0000000..2e8498b --- /dev/null +++ b/main/res/layout/activity_movie.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/main/res/layout/activity_relative_layout.xml b/main/res/layout/activity_relative_layout.xml new file mode 100644 index 0000000..4fe216b --- /dev/null +++ b/main/res/layout/activity_relative_layout.xml @@ -0,0 +1,33 @@ + + + + + +