From f8dd33287618fbe96375fa116e2be6775f214c24 Mon Sep 17 00:00:00 2001 From: Ewan Sinclair Date: Mon, 16 May 2011 14:07:05 -0400 Subject: [PATCH 01/12] Bugfix: fixed crash that was happening on an HTTP error notification --- .../securitycompass/labs/falsesecuremobile/LoginActivity.java | 2 +- .../labs/falsesecuremobile/SetLocalPasswordActivity.java | 2 +- .../labs/falsesecuremobile/SetServerCredentialsActivity.java | 2 +- .../labs/falsesecuremobile/TransferActivity.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java b/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java index 080b361..492d81a 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java @@ -107,7 +107,7 @@ private void performLogin() { Toast.makeText(mCtx, R.string.error_ssl_general, Toast.LENGTH_SHORT).show(); Log.e(TAG, e.toString()); } catch (HttpException e) { - Toast.makeText(mCtx, R.string.error_toast_http_error + e.getStatusCode(), Toast.LENGTH_SHORT).show(); + Toast.makeText(mCtx, getString(R.string.error_toast_http_error) + e.getStatusCode(), Toast.LENGTH_SHORT).show(); Log.e(TAG, e.toString()); } catch (IOException e) { Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT).show(); diff --git a/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java b/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java index 86eb795..514521a 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java @@ -78,7 +78,7 @@ private void grabAndSetPassword(){ Toast.makeText(mCtx, R.string.error_toast_json_problem, Toast.LENGTH_SHORT).show(); Log.e(TAG, e.toString()); } catch (HttpException e) { - Toast.makeText(mCtx, R.string.error_toast_http_error + e.getStatusCode(), Toast.LENGTH_SHORT).show(); + Toast.makeText(mCtx, getString(R.string.error_toast_http_error) + e.getStatusCode(), Toast.LENGTH_SHORT).show(); Log.e(TAG, e.toString()); } catch (KeyManagementException e){ Toast.makeText(mCtx, R.string.error_ssl_keymanagement, Toast.LENGTH_LONG).show(); diff --git a/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java b/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java index a289276..360c74d 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java @@ -77,7 +77,7 @@ private void setServerCredentials(){ Toast.makeText(mCtx, R.string.error_ssl_algorithm, Toast.LENGTH_LONG).show(); Log.e(TAG, e.toString()); } catch (HttpException e) { - Toast.makeText(mCtx, R.string.error_toast_http_error + e.getStatusCode(), Toast.LENGTH_SHORT).show(); + Toast.makeText(mCtx, getString(R.string.error_toast_http_error) + e.getStatusCode(), Toast.LENGTH_SHORT).show(); Log.e(TAG, e.toString()); } catch (IOException e){ Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT).show(); diff --git a/src/com/securitycompass/labs/falsesecuremobile/TransferActivity.java b/src/com/securitycompass/labs/falsesecuremobile/TransferActivity.java index e5ca272..02f5586 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/TransferActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/TransferActivity.java @@ -181,7 +181,7 @@ private void performTransfer() { Toast.makeText(mCtx, R.string.error_ssl_algorithm, Toast.LENGTH_LONG).show(); Log.e(TAG, e.toString()); } catch (HttpException e) { - Toast.makeText(mCtx, R.string.error_toast_http_error + e.getStatusCode(), + Toast.makeText(mCtx, getString(R.string.error_toast_http_error) + e.getStatusCode(), Toast.LENGTH_SHORT).show(); Log.e(TAG, e.toString()); } catch (IOException e) { From 899322185351bf40dc85ce5e1d554f5e5c83aa81 Mon Sep 17 00:00:00 2001 From: Ewan Sinclair Date: Wed, 18 May 2011 16:37:07 -0400 Subject: [PATCH 02/12] Bugfix: Fixed null pointer problem when clearing empty statements dir --- .../labs/falsesecuremobile/BankingApplication.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/securitycompass/labs/falsesecuremobile/BankingApplication.java b/src/com/securitycompass/labs/falsesecuremobile/BankingApplication.java index dccbea9..4cee7a2 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/BankingApplication.java +++ b/src/com/securitycompass/labs/falsesecuremobile/BankingApplication.java @@ -337,8 +337,10 @@ public void downloadStatement() throws IOException, NoSuchAlgorithmException, public void clearStatements() { File downloadDir = new File(mStatementDir); File[] directoryContents = downloadDir.listFiles(); - for (File f : directoryContents) { - f.delete(); + if (directoryContents != null) { + for (File f : directoryContents) { + f.delete(); + } } } From dbeb73d1b07aa86be22bde2b15cf7aa1f2af97c8 Mon Sep 17 00:00:00 2001 From: Ewan Sinclair Date: Fri, 20 May 2011 16:39:39 -0400 Subject: [PATCH 03/12] Added menus to the setup screens --- .../SetLocalPasswordActivity.java | 52 +++++++++++++++++++ .../SetServerCredentialsActivity.java | 52 +++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java b/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java index 514521a..cbcd4b9 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java @@ -14,8 +14,12 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; @@ -95,4 +99,52 @@ private void grabAndSetPassword(){ } } + /** Called when an item is selected from the options menu */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.optionsmenu_reset: + resetApplication(); + return true; + case R.id.optionsmenu_preferences: + launchPreferenceScreen(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + /** Creates an options menu */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options_menu, menu); + return true; + } + + /** Resets the application */ + private void resetApplication() { + BankingApplication ba = (BankingApplication) getApplication(); + ba.clearStatements(); + Editor e = ba.getSharedPrefs().edit(); + e.clear(); + e.commit(); + ba.lockApplication(); + launchLoginScreen(); + } + + /** Launches the preferences screen */ + private void launchPreferenceScreen() { + Intent i = new Intent(this, EditPreferencesActivity.class); + startActivity(i); + } + + /** Launches the accounts screen, doing any necessary processing first */ + private void launchLoginScreen() { + Intent launchLogin = new Intent(this, LoginActivity.class); + launchLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(launchLogin); + } + } diff --git a/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java b/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java index 360c74d..3627e6b 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java @@ -16,6 +16,9 @@ import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; @@ -98,4 +101,53 @@ private void setServerCredentials(){ Toast.makeText(mCtx, R.string.toast_loginfailed, Toast.LENGTH_SHORT).show(); } } + + /** Called when an item is selected from the options menu */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.optionsmenu_reset: + resetApplication(); + return true; + case R.id.optionsmenu_preferences: + launchPreferenceScreen(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + /** Creates an options menu */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options_menu, menu); + return true; + } + + /** Resets the application */ + private void resetApplication() { + BankingApplication ba = (BankingApplication) getApplication(); + ba.clearStatements(); + Editor e = ba.getSharedPrefs().edit(); + e.clear(); + e.commit(); + ba.lockApplication(); + launchLoginScreen(); + } + + /** Launches the preferences screen */ + private void launchPreferenceScreen() { + Intent i = new Intent(this, EditPreferencesActivity.class); + startActivity(i); + } + + /** Launches the accounts screen, doing any necessary processing first */ + private void launchLoginScreen() { + Intent launchLogin = new Intent(this, LoginActivity.class); + launchLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(launchLogin); + } + } From 02f74b08978d578394e4eefc6a520e55d58cdba2 Mon Sep 17 00:00:00 2001 From: Ewan Sinclair Date: Sun, 22 May 2011 00:02:50 -0400 Subject: [PATCH 04/12] -Reworked setup process to allow back-navigation again -First run now only gets unset after sucessful completion of the setup process -Login screen now always sends the user to setup if landed on with first run set --- .../labs/falsesecuremobile/LoginActivity.java | 8 +++++++- .../falsesecuremobile/SetLocalPasswordActivity.java | 11 +++++++++++ .../SetServerCredentialsActivity.java | 7 ++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java b/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java index 492d81a..d9aeefe 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java @@ -66,6 +66,13 @@ public void onClick(View v) { } + /** Pushes the user to the setup screen whenever they land on this Activity without having setup the app. */ + @Override + public void onResume(){ + super.onResume(); + checkFirstRun(); + } + /** * Checks if the application is running for the first time, and sends the user to the * appropriate setup if it is. @@ -73,7 +80,6 @@ public void onClick(View v) { private void checkFirstRun() { if (mSharedPrefs.getBoolean(BankingApplication.PREF_FIRST_RUN, true)) { Intent i = new Intent(mCtx, SetServerCredentialsActivity.class); - i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); startActivity(i); } } diff --git a/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java b/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java index cbcd4b9..f711919 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java @@ -64,6 +64,13 @@ public void onClick(View v) { /** Grabs the two passwords entered, and sets them as the local unlock password if they match */ private void grabAndSetPassword(){ + + //Take the user/pass from the server credentials setup screen and set them + //This must be done here, because we are about to call the unlock method. + String serverUsername = getIntent().getStringExtra("username"); + String serverPassword = getIntent().getStringExtra("password"); + mThisApplication.setServerCredentials(serverUsername, serverPassword); + String pass1=mPasswordField.getText().toString(); String pass2=mConfirmPasswordField.getText().toString(); if(!pass1.equals(pass2)){ @@ -92,7 +99,11 @@ private void grabAndSetPassword(){ Log.e(TAG, e.toString()); } + //Inform the user that setup is complete and unmark the first run flag Toast.makeText(mCtx, R.string.initialsetup_success, Toast.LENGTH_SHORT).show(); + Editor e=mThisApplication.getSharedPrefs().edit(); + e.putBoolean(BankingApplication.PREF_FIRST_RUN, false); + e.commit(); Intent i = new Intent(mCtx, SummaryActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i); diff --git a/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java b/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java index 3627e6b..d5090d7 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java +++ b/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java @@ -89,13 +89,10 @@ private void setServerCredentials(){ } if(statuscode==RestClient.NULL_ERROR){ - mThisApplication.setServerCredentials(username, password); - Editor e=mThisApplication.getSharedPrefs().edit(); - e.putBoolean(BankingApplication.PREF_FIRST_RUN, false); - e.commit(); mThisApplication.lockApplication(); Intent i=new Intent(mCtx, SetLocalPasswordActivity.class); - i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); + i.putExtra("username", username); + i.putExtra("password", password); startActivity(i); } else { Toast.makeText(mCtx, R.string.toast_loginfailed, Toast.LENGTH_SHORT).show(); From a8d52bdaf9feb0a00529a9b29592c28f8cbbfd62 Mon Sep 17 00:00:00 2001 From: Maxim Veytsman Date: Wed, 6 Jul 2011 11:31:32 -0400 Subject: [PATCH 05/12] added license --- LICENSE | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e170fcc --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2011, Security Compass +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by Security Compass. +4. Neither the name of Security Compass nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY Security Compass ''AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL Security Compass BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. From efb07f346860c0a296ef41166b4dee2fe084d936 Mon Sep 17 00:00:00 2001 From: Maxim Veytsman Date: Thu, 14 Jul 2011 19:50:01 -0400 Subject: [PATCH 06/12] updated branch to have correct application/package name --- AndroidManifest.xml | 4 ++-- default.properties | 2 +- res/values/strings.xml | 2 +- .../{labs/falsesecuremobile => androidlabs}/Account.java | 2 +- .../falsesecuremobile => androidlabs}/AccountsActivity.java | 2 +- .../falsesecuremobile => androidlabs}/BankingActivity.java | 2 +- .../BankingApplication.java | 6 +++--- .../BankingListActivity.java | 2 +- .../EditPreferencesActivity.java | 4 ++-- .../falsesecuremobile => androidlabs}/HttpException.java | 2 +- .../falsesecuremobile => androidlabs}/LoginActivity.java | 4 ++-- .../{labs/falsesecuremobile => androidlabs}/RestClient.java | 2 +- .../SetLocalPasswordActivity.java | 2 +- .../SetServerCredentialsActivity.java | 2 +- .../StatementActivity.java | 4 ++-- .../falsesecuremobile => androidlabs}/SummaryActivity.java | 4 ++-- .../falsesecuremobile => androidlabs}/TransferActivity.java | 4 ++-- .../ViewStatementActivity.java | 2 +- 18 files changed, 26 insertions(+), 26 deletions(-) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/Account.java (97%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/AccountsActivity.java (98%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/BankingActivity.java (98%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/BankingApplication.java (99%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/BankingListActivity.java (98%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/EditPreferencesActivity.java (91%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/HttpException.java (91%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/LoginActivity.java (98%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/RestClient.java (99%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/SetLocalPasswordActivity.java (99%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/SetServerCredentialsActivity.java (98%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/StatementActivity.java (99%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/SummaryActivity.java (98%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/TransferActivity.java (99%) rename src/com/securitycompass/{labs/falsesecuremobile => androidlabs}/ViewStatementActivity.java (94%) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0be004a..744d921 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,6 +1,6 @@ @@ -26,4 +26,4 @@ - \ No newline at end of file + diff --git a/default.properties b/default.properties index 0b9250e..510b090 100644 --- a/default.properties +++ b/default.properties @@ -8,4 +8,4 @@ # project structure. # Project target. -target=android-8 +target=android-11 diff --git a/res/values/strings.xml b/res/values/strings.xml index a00591c..37a9036 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,6 +1,6 @@ - FalseSecureMobile + Base-AndroidLabs Username Password diff --git a/src/com/securitycompass/labs/falsesecuremobile/Account.java b/src/com/securitycompass/androidlabs/Account.java similarity index 97% rename from src/com/securitycompass/labs/falsesecuremobile/Account.java rename to src/com/securitycompass/androidlabs/Account.java index 4e35744..60cfcf9 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/Account.java +++ b/src/com/securitycompass/androidlabs/Account.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; /** * @Author Ewan Sinclair diff --git a/src/com/securitycompass/labs/falsesecuremobile/AccountsActivity.java b/src/com/securitycompass/androidlabs/AccountsActivity.java similarity index 98% rename from src/com/securitycompass/labs/falsesecuremobile/AccountsActivity.java rename to src/com/securitycompass/androidlabs/AccountsActivity.java index f776ce3..2128a4c 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/AccountsActivity.java +++ b/src/com/securitycompass/androidlabs/AccountsActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import java.io.IOException; import java.security.KeyManagementException; diff --git a/src/com/securitycompass/labs/falsesecuremobile/BankingActivity.java b/src/com/securitycompass/androidlabs/BankingActivity.java similarity index 98% rename from src/com/securitycompass/labs/falsesecuremobile/BankingActivity.java rename to src/com/securitycompass/androidlabs/BankingActivity.java index ac995f5..81a73ab 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/BankingActivity.java +++ b/src/com/securitycompass/androidlabs/BankingActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import android.app.Activity; import android.content.Intent; diff --git a/src/com/securitycompass/labs/falsesecuremobile/BankingApplication.java b/src/com/securitycompass/androidlabs/BankingApplication.java similarity index 99% rename from src/com/securitycompass/labs/falsesecuremobile/BankingApplication.java rename to src/com/securitycompass/androidlabs/BankingApplication.java index 4cee7a2..bd548de 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/BankingApplication.java +++ b/src/com/securitycompass/androidlabs/BankingApplication.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import java.io.File; import java.io.FileWriter; @@ -70,7 +70,7 @@ public void onCreate() { timingHandler = new Handler(); foregroundedActivities = 0; locked = true; - mStatementDir=Environment.getExternalStorageDirectory().toString()+"/falsesecuremobile/"; + mStatementDir=Environment.getExternalStorageDirectory().toString()+"/androidlabs/"; Log.i(TAG, mStatementDir); } @@ -426,4 +426,4 @@ public void run() { }; -} \ No newline at end of file +} diff --git a/src/com/securitycompass/labs/falsesecuremobile/BankingListActivity.java b/src/com/securitycompass/androidlabs/BankingListActivity.java similarity index 98% rename from src/com/securitycompass/labs/falsesecuremobile/BankingListActivity.java rename to src/com/securitycompass/androidlabs/BankingListActivity.java index 0ad6125..bc25e10 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/BankingListActivity.java +++ b/src/com/securitycompass/androidlabs/BankingListActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import android.app.ListActivity; import android.content.Intent; diff --git a/src/com/securitycompass/labs/falsesecuremobile/EditPreferencesActivity.java b/src/com/securitycompass/androidlabs/EditPreferencesActivity.java similarity index 91% rename from src/com/securitycompass/labs/falsesecuremobile/EditPreferencesActivity.java rename to src/com/securitycompass/androidlabs/EditPreferencesActivity.java index 0c46cce..195ffda 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/EditPreferencesActivity.java +++ b/src/com/securitycompass/androidlabs/EditPreferencesActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import android.os.Bundle; import android.preference.PreferenceActivity; @@ -22,4 +22,4 @@ public void onCreate(Bundle savedInstanceState) { addPreferencesFromResource(R.xml.userpreferences); } -} \ No newline at end of file +} diff --git a/src/com/securitycompass/labs/falsesecuremobile/HttpException.java b/src/com/securitycompass/androidlabs/HttpException.java similarity index 91% rename from src/com/securitycompass/labs/falsesecuremobile/HttpException.java rename to src/com/securitycompass/androidlabs/HttpException.java index 0514e1f..d93b965 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/HttpException.java +++ b/src/com/securitycompass/androidlabs/HttpException.java @@ -1,4 +1,4 @@ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; /** diff --git a/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java b/src/com/securitycompass/androidlabs/LoginActivity.java similarity index 98% rename from src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java rename to src/com/securitycompass/androidlabs/LoginActivity.java index d9aeefe..cfb8233 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/LoginActivity.java +++ b/src/com/securitycompass/androidlabs/LoginActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -129,4 +129,4 @@ private void performLogin() { } } -} \ No newline at end of file +} diff --git a/src/com/securitycompass/labs/falsesecuremobile/RestClient.java b/src/com/securitycompass/androidlabs/RestClient.java similarity index 99% rename from src/com/securitycompass/labs/falsesecuremobile/RestClient.java rename to src/com/securitycompass/androidlabs/RestClient.java index b582908..6266e5e 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/RestClient.java +++ b/src/com/securitycompass/androidlabs/RestClient.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import java.io.BufferedReader; import java.io.DataOutputStream; diff --git a/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java b/src/com/securitycompass/androidlabs/SetLocalPasswordActivity.java similarity index 99% rename from src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java rename to src/com/securitycompass/androidlabs/SetLocalPasswordActivity.java index f711919..5de171c 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SetLocalPasswordActivity.java +++ b/src/com/securitycompass/androidlabs/SetLocalPasswordActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import java.io.IOException; import java.io.UnsupportedEncodingException; diff --git a/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java b/src/com/securitycompass/androidlabs/SetServerCredentialsActivity.java similarity index 98% rename from src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java rename to src/com/securitycompass/androidlabs/SetServerCredentialsActivity.java index d5090d7..b51ce9b 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SetServerCredentialsActivity.java +++ b/src/com/securitycompass/androidlabs/SetServerCredentialsActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import java.io.IOException; import java.security.KeyManagementException; diff --git a/src/com/securitycompass/labs/falsesecuremobile/StatementActivity.java b/src/com/securitycompass/androidlabs/StatementActivity.java similarity index 99% rename from src/com/securitycompass/labs/falsesecuremobile/StatementActivity.java rename to src/com/securitycompass/androidlabs/StatementActivity.java index 8395b7e..588bf58 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/StatementActivity.java +++ b/src/com/securitycompass/androidlabs/StatementActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import java.io.File; import java.io.IOException; @@ -157,4 +157,4 @@ public View getView(int position, View convertView, ViewGroup parent) { } -} \ No newline at end of file +} diff --git a/src/com/securitycompass/labs/falsesecuremobile/SummaryActivity.java b/src/com/securitycompass/androidlabs/SummaryActivity.java similarity index 98% rename from src/com/securitycompass/labs/falsesecuremobile/SummaryActivity.java rename to src/com/securitycompass/androidlabs/SummaryActivity.java index d7c773b..a396f78 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/SummaryActivity.java +++ b/src/com/securitycompass/androidlabs/SummaryActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import android.content.Context; import android.content.Intent; @@ -83,4 +83,4 @@ private void launchStatementScreen() { startActivity(launchTransfer); } -} \ No newline at end of file +} diff --git a/src/com/securitycompass/labs/falsesecuremobile/TransferActivity.java b/src/com/securitycompass/androidlabs/TransferActivity.java similarity index 99% rename from src/com/securitycompass/labs/falsesecuremobile/TransferActivity.java rename to src/com/securitycompass/androidlabs/TransferActivity.java index 02f5586..17655de 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/TransferActivity.java +++ b/src/com/securitycompass/androidlabs/TransferActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import java.io.IOException; import java.security.KeyManagementException; @@ -320,4 +320,4 @@ public View getDropDownView(int position, View convertView, ViewGroup parent) { } -} \ No newline at end of file +} diff --git a/src/com/securitycompass/labs/falsesecuremobile/ViewStatementActivity.java b/src/com/securitycompass/androidlabs/ViewStatementActivity.java similarity index 94% rename from src/com/securitycompass/labs/falsesecuremobile/ViewStatementActivity.java rename to src/com/securitycompass/androidlabs/ViewStatementActivity.java index 19035ef..f1905d0 100644 --- a/src/com/securitycompass/labs/falsesecuremobile/ViewStatementActivity.java +++ b/src/com/securitycompass/androidlabs/ViewStatementActivity.java @@ -2,7 +2,7 @@ * Copyright 2011 Security Compass */ -package com.securitycompass.labs.falsesecuremobile; +package com.securitycompass.androidlabs.base; import android.content.Intent; import android.os.Bundle; From 535054e3c1d9cf3f700c3f57ca10a339e63fc485 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 10 Aug 2011 10:22:06 +0800 Subject: [PATCH 07/12] updated logos --- .../advancedencryptionsolution/Account.java | 68 +++ .../AccountsActivity.java | 129 +++++ .../BankingActivity.java | 137 +++++ .../BankingApplication.java | 511 ++++++++++++++++++ .../BankingListActivity.java | 129 +++++ .../CryptoTool.java | 230 ++++++++ .../EditPreferencesActivity.java | 25 + .../HttpException.java | 28 + .../LoginActivity.java | 136 +++++ .../RestClient.java | 446 +++++++++++++++ .../SetLocalPasswordActivity.java | 165 ++++++ .../SetServerCredentialsActivity.java | 151 ++++++ .../StatementActivity.java | 231 ++++++++ .../SummaryActivity.java | 86 +++ .../TransferActivity.java | 323 +++++++++++ .../ViewStatementActivity.java | 41 ++ .../androidlabs/{ => base}/Account.java | 0 .../{ => base}/AccountsActivity.java | 0 .../{ => base}/BankingActivity.java | 0 .../{ => base}/BankingApplication.java | 0 .../{ => base}/BankingListActivity.java | 0 .../{ => base}/EditPreferencesActivity.java | 0 .../androidlabs/{ => base}/HttpException.java | 0 .../androidlabs/{ => base}/LoginActivity.java | 0 .../androidlabs/{ => base}/RestClient.java | 0 .../{ => base}/SetLocalPasswordActivity.java | 0 .../SetServerCredentialsActivity.java | 0 .../{ => base}/StatementActivity.java | 0 .../{ => base}/SummaryActivity.java | 0 .../{ => base}/TransferActivity.java | 0 .../{ => base}/ViewStatementActivity.java | 0 31 files changed, 2836 insertions(+) create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/Account.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/AccountsActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingApplication.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingListActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/CryptoTool.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/EditPreferencesActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/HttpException.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/LoginActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/RestClient.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/SetLocalPasswordActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/SetServerCredentialsActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/StatementActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/SummaryActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/TransferActivity.java create mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/ViewStatementActivity.java rename src/com/securitycompass/androidlabs/{ => base}/Account.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/AccountsActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/BankingActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/BankingApplication.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/BankingListActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/EditPreferencesActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/HttpException.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/LoginActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/RestClient.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/SetLocalPasswordActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/SetServerCredentialsActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/StatementActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/SummaryActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/TransferActivity.java (100%) rename src/com/securitycompass/androidlabs/{ => base}/ViewStatementActivity.java (100%) diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/Account.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/Account.java new file mode 100644 index 0000000..3df0452 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/Account.java @@ -0,0 +1,68 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +/** + * @Author Ewan Sinclair + * Represents a bank account */ +public class Account { + + private int accountNumber; + private String accountType; + private double balance; + + /** Creates a new Account with the given parameters + * @param accountNumber The account number + * @param accountType The type of account + * @param balance The balance held in the account*/ + public Account(int accountNumber, String accountType, double balance) { + this.accountNumber = accountNumber; + this.accountType = accountType; + this.balance = balance; + } + + /** Returns the account type + * @return The type of Account*/ + public String getAccountType() { + return accountType; + } + + /** Sets the account type + * @param accountType The type of Account to set*/ + public void setAccountType(String accountType) { + this.accountType = accountType; + } + + /** Returns the balance of the Account + * @return The balance of the Account*/ + public double getBalance() { + return balance; + } + + /** Sets the balance of the Account + * @param balance The balance to set for the Account*/ + public void setBalance(double balance) { + this.balance = balance; + } + + /** Sets the account number + * @param accountNumber The account number to set*/ + public void setAccountNumber(int accountNumber) { + this.accountNumber = accountNumber; + } + + /** Returns the account number + * @return The account number for this Account*/ + public int getAccountNumber() { + return accountNumber; + } + + /** Returns a String representation of the Account + * @return A String representation of this Account*/ + public String toString(){ + return (accountNumber + " (" + accountType + "): " + balance); + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/AccountsActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/AccountsActivity.java new file mode 100644 index 0000000..3281870 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/AccountsActivity.java @@ -0,0 +1,129 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + +import org.json.JSONException; + +import android.accounts.AuthenticatorException; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; +import android.widget.Toast; + +/** + * Displays a full summary of all the accounts + * @author Ewan Sinclair + */ +public class AccountsActivity extends BankingListActivity { + + /** Useful for avoiding casts when a Context needs to be passed */ + private Context mCtx; + /** Central data store, state, and operations */ + private BankingApplication mThisApplication; + /** A list of the accounts for this user */ + private List mAccounts; + + private static final String TAG = "AccountsActivity"; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + setContentView(R.layout.accountsactivity); + setAppropriateVisibility(); + + mCtx = this; + mAccounts=new ArrayList(); //To avoid null reference on network error + + mThisApplication = (BankingApplication) getApplication(); + + updateAccounts(); + + setListAdapter(new AccountDetailAdapter(mCtx, R.layout.accountdetailsview, mAccounts)); + + } + + /** Updates the account information stored locally and refreshes the display */ + private void updateAccounts() { + try { + mAccounts = mThisApplication.getAccounts(); + } catch (JSONException e) { + Toast.makeText(mCtx, R.string.error_toast_json_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (AuthenticatorException e) { + Log.e(TAG, e.toString()); + authenticate(); + } catch (KeyManagementException e){ + Toast.makeText(mCtx, R.string.error_ssl_keymanagement, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (NoSuchAlgorithmException e){ + Toast.makeText(mCtx, R.string.error_ssl_algorithm, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (IOException e) { + Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } + + //If the account list failed on retrieval, use an empty list + if (!mThisApplication.isLocked()) { + //refreshDisplayInformation(); + } else { + mAccounts=new ArrayList(); + } + } + + /** + * Returns a version of the given string with the first letter in uppercase. + * @param input The String to capitalise. + * @return The capitalised String. + */ + private String capitalise(String input) { + String result = input.substring(0, 1).toUpperCase() + input.substring(1); + return result; + } + + private class AccountDetailAdapter extends ArrayAdapter{ + + public AccountDetailAdapter(Context context, int viewResourceId, List accounts) { + super(context, viewResourceId, accounts); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent){ + View item=convertView; + + if (item == null) { + LayoutInflater inflater = getLayoutInflater(); + item = inflater.inflate(R.layout.accountdetailsview, null); + } + + TextView accountNumber = (TextView) item.findViewById(R.id.accounts_screen_accountnumber); + TextView accountType = (TextView) item.findViewById(R.id.accounts_screen_accounttype); + TextView accountBalance = (TextView) item.findViewById(R.id.accounts_screen_accountbalance); + + Account displayAccount=mAccounts.get(position); + accountNumber.setText("Account " + displayAccount.getAccountNumber()); + accountType.setText(capitalise(displayAccount.getAccountType()) + " Account"); + accountBalance.setText("Balance: $" + displayAccount.getBalance()); + + return item; + } + + + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingActivity.java new file mode 100644 index 0000000..85ed0f4 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingActivity.java @@ -0,0 +1,137 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences.Editor; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; + +/** + * A superclass containing methods and variables that all Activities in this application will use + * @author Ewan Sinclair + */ +public class BankingActivity extends Activity { + + /** Central data store, state, and operations */ + protected BankingApplication mThisApplication; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mThisApplication = (BankingApplication) getApplication(); + if (mThisApplication.isLocked() && (this.getClass() != LoginActivity.class)) { + launchLoginScreen(); + } else { + View v = findViewById(R.id.root_view); + if (v != null) { + v.setVisibility(View.VISIBLE); + } + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.optionsmenu_reset: + resetApplication(); + return true; + case R.id.optionsmenu_preferences: + launchPreferenceScreen(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options_menu, menu); + return true; + } + + @Override + protected void onResume() { + super.onResume(); + setAppropriateVisibility(); + mThisApplication.registerActivityForegrounded(); + if (mThisApplication.isLocked() && (this.getClass() != LoginActivity.class)) { + Intent i = new Intent(this, LoginActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + } + } + + @Override + protected void onPause() { + super.onPause(); + setInvisible(); + mThisApplication.registerActivityBackgrounded(); + } + + /** + * Checks whether the application is locked and makes this Activity invisible if so. + */ + public void setAppropriateVisibility() { + View v = findViewById(R.id.root_view); + if (v != null) { + if (mThisApplication.isLocked()) { + v.setVisibility(View.GONE); + } else { + v.setVisibility(View.VISIBLE); + } + } + } + + /** + * Makes this Activity invisible. + */ + public void setInvisible() { + View v = findViewById(R.id.root_view); + if (v != null) { + v.setVisibility(View.GONE); + } + + } + + private void resetApplication() { + BankingApplication ba = (BankingApplication) getApplication(); + ba.clearStatements(); + Editor e = ba.getSharedPrefs().edit(); + e.clear(); + e.commit(); + ba.lockApplication(); + launchLoginScreen(); + } + + private void launchPreferenceScreen() { + Intent i = new Intent(this, EditPreferencesActivity.class); + startActivity(i); + } + + /** + * Called when the app needs authentication, normally due to a session timeout. The current + * activity stack will be cleared, and the login Activity brought to the front. + */ + protected void authenticate() { + Intent i = new Intent(this, LoginActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + } + + /** Launches the accounts screen, doing any necessary processing first */ + private void launchLoginScreen() { + Intent launchLogin = new Intent(this, LoginActivity.class); + launchLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(launchLogin); + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingApplication.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingApplication.java new file mode 100644 index 0000000..ac350f9 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingApplication.java @@ -0,0 +1,511 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.List; + +import org.json.JSONException; + +import android.accounts.AuthenticatorException; +import android.app.Application; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.util.Base64; +import android.util.Log; + +/** + * Stores session keys and handles moving the application between locked and unlocked states. + * Instantiated when the application loads. + * @author Ewan Sinclair + */ +public class BankingApplication extends Application { + + private String sessionKey; + private String sessionCreateDate; + private boolean locked; + private String cleartextServerUser; + private String cleartextServerPass; + + private int foregroundedActivities; + private Handler timingHandler; + private CryptoTool mCipher; + private byte[] mCryptoKey; + + // How many hashing iterations to perform + private static final int HASH_ITERATIONS = 1000; + + /* These variables are used for anchoring preference keys */ + /** The name of the shared preferences file for prefs not accessible via the preferences screen */ + public static final String SHARED_PREFS = "preferences"; + /** Whether the application is running for the first time */ + public static final String PREF_FIRST_RUN = "firstrun"; + /** A hash of the local password */ + public static final String PREF_LOCALPASS_HASH = "localpasshash"; + /** The salt used when hashing the local password */ + public static final String PREF_LOCALPASS_SALT = "localpasssalt"; + /** The username to present to the banking service */ + public static final String PREF_REST_USER = "serveruser"; + /** The password to present to the banking service */ + public static final String PREF_REST_PASSWORD = "serverpass"; + /** The initialisation vector for the encrypted banking service password */ + public static final String PREF_REST_PASSWORD_IV = "serverpassiv"; + /** The initialisation vector for the encrypted banking service username */ + public static final String PREF_REST_USER_IV = "serveruseriv"; + public static String PREF_DERIVED_KEY_SALT="derivedkeysalt"; + + /** A tag to identify the class if it logs anything */ + public static final String TAG = "BankingApplication"; + + /** Setup for when the application initialises. */ + @Override + public void onCreate() { + super.onCreate(); + timingHandler = new Handler(); + foregroundedActivities = 0; + locked = true; + mCipher=new CryptoTool(); + } + + /** + * Returns a string representation of the server we will be making our requests on. + * @return A string representation of the server address. + */ + public String getRestServer() { + return PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString( + "bankserviceaddress", "10.0.2.2"); + } + + /** + * Returns a string representation of the port we will be making our HTTP requests on. + * @return A string representation of the port set for HTTP communication. + */ + public String getPort() { + if (isHttpsEnabled()) { + return PreferenceManager.getDefaultSharedPreferences(getApplicationContext()) + .getString("httpsport", "8443"); + } else { + return PreferenceManager.getDefaultSharedPreferences(getApplicationContext()) + .getString("httpport", "8080"); + } + } + + /** + * Returns the directory where statements are kept, as a String. + * @return The directory where statements are kept, as a String. + */ + public String getStatementDir() { + return getFilesDir().toString(); + } + + /** + * Returns whether the HTTPS setting is enabled, as a boolean. + * @return whether the HTTPS setting is enabled, as a boolean. + */ + public boolean isHttpsEnabled() { + return PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean( + "httpsenabled", false); + } + + /** + * Checks to see if the given password hashes to the same value as the stored one. + * @param enteredPassword The password to check. + * @return Whether the password matched. + * @throws NoSuchAlgorithmException if the hashing algorithm is unavailable + * @throws UnsupportedEncodingException if Base64 encoding is not available + */ + public boolean checkPassword(String enteredPassword) throws NoSuchAlgorithmException, + UnsupportedEncodingException { + String saltString = getSharedPrefs().getString(PREF_LOCALPASS_SALT, ""); + byte[] saltBytes = Base64.decode(saltString, Base64.DEFAULT); + String hashOfEnteredPassword = hash(enteredPassword, saltBytes); + String hashOfStoredpassword = getSharedPrefs().getString(PREF_LOCALPASS_HASH, ""); + return hashOfEnteredPassword.equals(hashOfStoredpassword); + } + + /** + * Peforms a bunch of hash iterations on the given String and salt and returns the result. + * @param password String password to hash. + * @param salt The salt to hash with. + * @return A base64 encoded string representing the hash. + * @throws NoSuchAlgorithmException + * @throws UnsupportedEncodingException + */ + private String hash(String password, byte[] salt) throws NoSuchAlgorithmException, + UnsupportedEncodingException { + byte[] passwordBytes = (password).getBytes("UTF-8"); + + MessageDigest md = MessageDigest.getInstance("SHA-256"); + md.reset(); + md.update(salt); + byte[] hashed = md.digest(passwordBytes); + + for (int count = 0; count < HASH_ITERATIONS; count++) { + md.reset(); + md.update(salt); + hashed = md.digest(hashed); + } + + byte[] b64Hash = Base64.encode(hashed, Base64.DEFAULT); + return new String(b64Hash); + + } + + /** + * Returns the shared preferences for this app, with permission mode pre-set. + * @return The shared preferences for this app, with permission mode pre-set. + */ + public SharedPreferences getSharedPrefs() { + return getSharedPreferences(SHARED_PREFS, MODE_WORLD_READABLE); + } + + /** + * Logs into the REST service, generating a new session key. + * @param username Username to log in with. + * @param password Password to log in with. + * @return A status code representing any error that occurred. + * @throws JSONException if the server returned invalid JSON + * @throws IOException if there was a communication error with the server + * @throws KeyManagementException if the server key couldn't be trusted + * @throws HttpException if the HTTP/S request failed + * @throws NoSuchAlgorithmException if the set SSL encryption algorithm is unavilable + */ + public int performLogin(String username, String password) throws JSONException, IOException, + KeyManagementException, HttpException, NoSuchAlgorithmException { + RestClient restClient = new RestClient(this, isHttpsEnabled()); + int statusCode = restClient.performLogin(getRestServer(), getPort(), username, password); + return statusCode; + } + + /** Performs all operations necessary to secure the application. */ + public void lockApplication() { + cleartextServerUser=""; + cleartextServerPass=""; + locked = true; + } + + /** + * Performs all operations necessary to make the application usable. + * @param password The password to try unlocking with + * @return Whether the operation succeeded + * @throws UnsupportedEncodingException if Base64 encoding isn't available + * @throws NoSuchAlgorithmException if the hashing algorithm couldn't be found + * @throws JSONException if the server returned invalid JSON + * @throws IOException if there was a communication error with the server + * @throws KeyManagementException if the server key couldn't be trusted + * @throws GeneralSecurityException if a cryptographic operation failed + * @throws HttpException if the HTTP/S request failed + */ + public int unlockApplication(String password) throws UnsupportedEncodingException, + NoSuchAlgorithmException, IOException, JSONException, KeyManagementException, GeneralSecurityException, HttpException { + + if (checkPassword(password)) { + mCryptoKey=mCipher.genKeyPwkdf2(password, getPbkSalt(), CryptoTool.NUM_ITERATIONS).getEncoded(); + cleartextServerUser = mCipher.decryptB64String(getRestUsername(), mCryptoKey, getRestUserNameIv()); + cleartextServerPass = mCipher.decryptB64String(getRestPassword(), mCryptoKey, getRestPasswordIv()); + int statusCode = performLogin(cleartextServerUser, cleartextServerPass); + if (statusCode == RestClient.NULL_ERROR) { + locked = false; + return statusCode; + } + } + return RestClient.NO_OP; + } + + /** + * Returns the application's state of lockdown. + * @return The application's state of lockdown. + */ + public boolean isLocked() { + return locked; + } + + + /**Returns the AES key currently in use. + * @return The AES key currently in use. + */ + public byte[] getCryptoKey(){ + return mCryptoKey; + } + + /** Returns the salt to be used for the password-generated AES key. + * @return The salt to be used for the password-generated AES key. + */ + public byte[] getPbkSalt(){ + return Base64.decode(getSharedPrefs().getString(PREF_DERIVED_KEY_SALT, ""), Base64.DEFAULT); + } + + /** + * Returns the stored username for the REST service. + * @return The stored username for the REST service. + */ + public String getRestUsername() { + return getSharedPrefs().getString(PREF_REST_USER, ""); + } + + /** + * Returns the IV for the stored username for the REST service. + * @return The IV for the stored username for the REST service. + */ + public byte[] getRestUserNameIv(){ + return Base64.decode(getSharedPrefs().getString(PREF_REST_USER_IV, ""), Base64.DEFAULT); + } + + /** + * Returns the stored password for the REST service. + * @return The stored password for the REST service. + */ + public String getRestPassword() { + return getSharedPrefs().getString(PREF_REST_PASSWORD, ""); + } + + /** + * Returns the IV for the stored password for the REST service. + * @return The IV for the stored password for the REST service. + */ + public byte[] getRestPasswordIv() { + return Base64.decode(getSharedPrefs().getString(PREF_REST_PASSWORD_IV, ""), Base64.DEFAULT); + } + + /** + * Sets the user's credentials for the banking service. + * @param username The username to set. + * @param password The password to set. + * @throws GeneralSecurityException if a cryptographic operation failed + */ + public void setServerCredentials(String username, String password) throws GeneralSecurityException { + + byte[] userIv=mCipher.getIv(); + byte[] passwordIv=mCipher.getIv(); + + String cryptUsername=mCipher.encryptToB64String(username, mCryptoKey, userIv); + String cryptPassword=mCipher.encryptToB64String(password, mCryptoKey, passwordIv); + + Editor e = getSharedPrefs().edit(); + e.putString(PREF_REST_USER, cryptUsername); + e.putString(PREF_REST_PASSWORD, cryptPassword); + e.putString(PREF_REST_USER_IV, new String(Base64.encode(userIv, Base64.DEFAULT))); + e.putString(PREF_REST_PASSWORD_IV, new String(Base64.encode(passwordIv, Base64.DEFAULT))); + e.commit(); + } + + /** + * Sets the local password, accomplished by storing a hashcode. + * @param password The plain String version of the password to set. + * @throws NoSuchAlgorithmException if the hashing algorithm is unavailable + * @throws UnsupportedEncodingException if Base64 encoding is not available + */ + public void setLocalPassword(String password) throws NoSuchAlgorithmException, + UnsupportedEncodingException { + + // First we generate a random salt + SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + byte[] saltByteArray = new byte[32]; + random.nextBytes(saltByteArray); + + // Perform the hash, getting a Base64 encoded String + String hashString = hash(password, saltByteArray); + + // Base64 encode the salt, store our strings + byte[] b64Salt = Base64.encode(saltByteArray, Base64.DEFAULT); + String saltString = new String(b64Salt); + + Editor e = getSharedPrefs().edit(); + e.putString(PREF_LOCALPASS_HASH, hashString); + e.putString(PREF_LOCALPASS_SALT, saltString); + e.commit(); + } + + /** Generates a key using PBKDF2 and uses it to encrypt and set the banking service credentials. Also sets the local password (which will be checked by hash before being used for generating a key). + * @param localPass The local password to set. + * @param restUser The username for the banking service. + * @param restPass The password for the banking service. + * @throws GeneralSecurityException if a cryptographic operation failed. + * @throws UnsupportedEncodingException if Base64 encoding is unavailable. + */ + public void setCredentials(String localPass, String restUser, String restPass) throws GeneralSecurityException, UnsupportedEncodingException{ + + Editor e=getSharedPrefs().edit(); + byte[] salt=mCipher.getSalt(); + String b64Salt=new String(Base64.encode(salt, Base64.DEFAULT)); + e.putString(PREF_DERIVED_KEY_SALT, b64Salt); + e.commit(); + + mCryptoKey=mCipher.genKeyPwkdf2(localPass, salt, CryptoTool.NUM_ITERATIONS).getEncoded(); + + setLocalPassword(localPass); + setServerCredentials(restUser, restPass); + + } + + /** + * Returns a list of all Accounts and their details. + * @return A list of the accounts returned by the server, represented as Account objects. + * @throws JSONException if the server returned invalid JSON + * @throws IOException if the network connection failed + * @throws AuthenticatorException if the server rejects the session key + * @throws NoSuchAlgorithmException if the algorithm used to hash the password is not available + * @throws KeyManagementException if the server's SSL certificate couldn't be trusted + */ + public List getAccounts() throws JSONException, IOException, AuthenticatorException, + NoSuchAlgorithmException, KeyManagementException { + RestClient restClient = new RestClient(this, isHttpsEnabled()); + List result = null; + try { + result = restClient.getAccounts(getRestServer(), getPort()); + } catch (AuthenticatorException e) { + lockApplication(); + throw e; + } + + // Log the account details + String logString = "Accounts:\n"; + for (Account a : result) { + logString += a.toString() + "\n"; + } + Log.i(TAG, logString); + return result; + } + + /** + * Downloads a statement and displays it. + * within this class. + * @throws IOException if network communication failed + * @throws NoSuchAlgorithmException if the algorithm used to hash the password is unavilable + * @throws KeyManagementException if the server's SSL certificate couldn't be trusted + * @throws AuthenticatorException if the server rejected the proferred session key. + * @throws GeneralSecurityException if a cryptographic operation failed + */ + public void downloadStatement() throws IOException, NoSuchAlgorithmException, + KeyManagementException, AuthenticatorException, GeneralSecurityException { + RestClient restClient = new RestClient(this, isHttpsEnabled()); + + String statementHtml = restClient.getStatement(getRestServer(), getPort()); + + CryptoTool cipher=new CryptoTool(); + byte[] iv=cipher.getIv(); + byte[] ciphertext = cipher.encrypt(statementHtml.getBytes(), mCryptoKey, iv); + + String timestamp=Long.toString(System.currentTimeMillis()); + + FileOutputStream outputFileStream = openFileOutput(timestamp + ".statement", MODE_PRIVATE); + + outputFileStream.write(ciphertext); + outputFileStream.flush(); + outputFileStream.close(); + + outputFileStream = openFileOutput(timestamp + ".iv", MODE_PRIVATE); + + outputFileStream.write(iv); + outputFileStream.flush(); + outputFileStream.close(); + } + + /** + * Clears all statements from the download directory + */ + public void clearStatements() { + File downloadDir = getFilesDir(); + File[] directoryContents = downloadDir.listFiles(); + if (directoryContents != null) { + for (File f : directoryContents) { + f.delete(); + } + } + } + + /** + * Transfers money between accounts + * @param fromAccount The account to take funds from. + * @param toAccount The account in which to deposit the funds. + * @param amount The amount to transfer. + * @return A status code representing the server's response + * @throws IOException if network communication failed + * @throws NoSuchAlgorithmException if the algorithm used to hash the password is unavilable + * @throws KeyManagementException if the server's SSL certificate couldn't be trusted + * @throws HttpException if the HTTP/S request failed + */ + public int transferFunds(int fromAccount, int toAccount, double amount) throws IOException, + NoSuchAlgorithmException, KeyManagementException, HttpException { + RestClient restClient = new RestClient(this, isHttpsEnabled()); + int statusCode = restClient.transfer(getRestServer(), getPort(), fromAccount, toAccount, + amount, sessionKey); + return statusCode; + } + + /** + * Sets the details for the current authenticated session. + * @param key The session key. + * @param date A string representation of the date this key was issued. + */ + public void setSession(String key, String date) { + sessionKey = key; + sessionCreateDate = date; + } + + /** + * Returns the current session key. + * @return The current session key. + */ + public String getSessionKey() { + return sessionKey; + } + + /** + * Returns the creation date of the current session key. + * @return A String representation of the creation date of the current session key. + */ + public String getSessionCreateDate() { + return sessionCreateDate; + } + + /** Informs the application that an Activity is in the foreground */ + public void registerActivityForegrounded() { + foregroundedActivities++; + } + + /** + * Informs the Application that an Activity has entered the background, and sets a check in 2 + * seconds to see if the entire application is now in the background + */ + public void registerActivityBackgrounded() { + foregroundedActivities--; + timingHandler.removeCallbacks(checkBackgroundTask); + timingHandler.postDelayed(checkBackgroundTask, 2000); + } + + /** + * Checks if all Activities are in the background (e.g. the entire app), and locks the app if + * they are. + */ + public void checkIfBackgrounded() { + if (foregroundedActivities == 0) { + lockApplication(); + } + } + + /** + * A simple helper class to perform a delayed check of whether the application is backgrounded + */ + public Runnable checkBackgroundTask = new Runnable() { + + @Override + public void run() { + checkIfBackgrounded(); + } + + }; + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingListActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingListActivity.java new file mode 100644 index 0000000..f71b6fa --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingListActivity.java @@ -0,0 +1,129 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import android.app.ListActivity; +import android.content.Intent; +import android.content.SharedPreferences.Editor; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; + +/** + * A superclass containing methods and variables that all Activities in this application will use + * @author Ewan Sinclair + */ +public class BankingListActivity extends ListActivity { + + /** Central data store, state, and operations */ + protected BankingApplication mThisApplication; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mThisApplication = (BankingApplication) getApplication(); + if (mThisApplication.isLocked()) { + launchLoginScreen(); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.optionsmenu_reset: + resetApplication(); + return true; + case R.id.optionsmenu_preferences: + launchPreferenceScreen(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + /** + * Checks whether the application is locked and makes this Activity invisible if so. + */ + public void setAppropriateVisibility() { + View v = findViewById(R.id.root_view); + if (v != null) { + if (mThisApplication.isLocked()) { + v.setVisibility(View.GONE); + } else { + v.setVisibility(View.VISIBLE); + } + } + } + + /** + * Makes this Activity invisible. + */ + public void setInvisible() { + View v = findViewById(R.id.root_view); + if (v != null) { + v.setVisibility(View.GONE); + } + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options_menu, menu); + return true; + } + + @Override + protected void onResume() { + super.onResume(); + setAppropriateVisibility(); + mThisApplication.registerActivityForegrounded(); + if (mThisApplication.isLocked()) { + Intent i = new Intent(this, LoginActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + } + } + + @Override + protected void onPause() { + super.onPause(); + setInvisible(); + mThisApplication.registerActivityBackgrounded(); + } + + private void resetApplication() { + BankingApplication ba = (BankingApplication) getApplication(); + ba.clearStatements(); + Editor e = ba.getSharedPrefs().edit(); + e.clear(); + e.commit(); + ba.lockApplication(); + launchLoginScreen(); + } + + private void launchPreferenceScreen() { + Intent i = new Intent(this, EditPreferencesActivity.class); + startActivity(i); + } + + /** Launches the accounts screen, doing any necessary processing first */ + protected void launchLoginScreen() { + Intent launchLogin = new Intent(this, LoginActivity.class); + launchLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(launchLogin); + } + + /** Launches the accounts screen, doing any necessary processing first */ + protected void authenticate() { + Intent launchLogin = new Intent(this, LoginActivity.class); + launchLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(launchLogin); + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/CryptoTool.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/CryptoTool.java new file mode 100644 index 0000000..e104352 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/CryptoTool.java @@ -0,0 +1,230 @@ +/** + * Copyright 2011 Security Compass + * */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; + +import android.util.Base64; + +/** + * Suite of tools for encryption and decryption. + * @author Ewan Sinclair + */ +public class CryptoTool { + + public static final String CRYPTO_SPEC = "AES/CBC/PKCS5Padding"; + public final static int KEY_BITS = 256; + public final static int IV_BYTES = 16; + public final static int SALT_BYTES = 32; + public final static int NUM_ITERATIONS = 1000; + + /** No-argument constuctor. Doesn't do anything. */ + public CryptoTool() { + + } + + /** + * Encrypts the provided String and returns a base64 representation. + * @param cleartext The text to be encrypted. + * @param key The AES key to use for encrypting. + * @param iv The initialisation vector to use for encrypting. + * @return A Base64 encoded String representing the encrypted text. + * @throws InvalidKeyException if the given key can't be used + * @throws NoSuchPaddingException if our required padding type isn't available + * @throws NoSuchAlgorithmException if the encryption algorithm isn't available. + * @throws BadPaddingException if the padding was bad + * @throws IllegalBlockSizeException if the cipher block is of an illegal size + * @throws InvalidAlgorithmParameterException if the algorithm has had parameters set + */ + public String encryptToB64String(String cleartext, byte[] key, byte[] iv) + throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, + BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException { + String ciphertext = ""; + + SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); + + Cipher cipher = Cipher.getInstance(CRYPTO_SPEC); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); + + byte[] ciphertextBytes = cipher.doFinal(cleartext.getBytes()); + ciphertext = new String(Base64.encode(ciphertextBytes, Base64.DEFAULT)); + + return ciphertext; + } + + /** + * Encrypts the provided byte array. + * @param cleartext The text to be encrypted. + * @param key The AES key to use for encrypting. + * @param iv The initialisation vector to use for encrypting. + * @return A byte array representing the encrypted text. + * @throws InvalidKeyException if the given key can't be used + * @throws NoSuchPaddingException if our required padding type isn't available + * @throws NoSuchAlgorithmException if the encryption algorithm isn't available. + * @throws BadPaddingException if the padding was bad + * @throws IllegalBlockSizeException if the cipher block is of an illegal size + * @throws InvalidAlgorithmParameterException if the algorithm has had parameters set + */ + public byte[] encrypt(byte[] cleartext, byte[] key, byte[] iv) throws InvalidKeyException, + NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, + IllegalBlockSizeException, InvalidAlgorithmParameterException { + SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); + + Cipher cipher = Cipher.getInstance(CRYPTO_SPEC); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); + + byte[] ciphertextBytes = cipher.doFinal(cleartext); + + return ciphertextBytes; + } + + /** + * Decrypts the provided base64 String and returns plaintext. + * @param ciphertextB64 The text to be decrypted. + * @param key The AES key to use for decrypting. + * @param iv The initialisation vector to use for decrypting. + * @return A String representation of the cleartext. + * @throws InvalidKeyException if the given key can't be used + * @throws NoSuchPaddingException if our required padding type isn't available + * @throws NoSuchAlgorithmException if the encryption algorithm isn't available. + * @throws BadPaddingException if the padding was bad + * @throws IllegalBlockSizeException if the cipher block is of an illegal size + * @throws InvalidAlgorithmParameterException if the algorithm has had parameters set + */ + public String decryptB64String(String ciphertextB64, byte[] key, byte[] iv) + throws NoSuchPaddingException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, + BadPaddingException { + byte[] ciphertextBytes = Base64.decode(ciphertextB64, Base64.DEFAULT); + + SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); + Cipher cipher = Cipher.getInstance(CRYPTO_SPEC); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + + byte[] cleartextBytes = cipher.doFinal(ciphertextBytes); + String cleartext = new String(cleartextBytes); + + return cleartext; + } + + /** + * Decrypts the provided byte array and returns plaintext. + * @param ciphertextBytes The text to be decrypted. + * @param key The AES key to use for decrypting. + * @param iv The initialisation vector to use for decrypting. + * @return A Base64 encoded String representing the encrypted text. + * @throws InvalidKeyException if the given key can't be used + * @throws NoSuchPaddingException if our required padding type isn't available + * @throws NoSuchAlgorithmException if the encryption algorithm isn't available. + * @throws BadPaddingException if the padding was bad + * @throws IllegalBlockSizeException if the cipher block is of an illegal size + * @throws InvalidAlgorithmParameterException if the algorithm has had parameters set + */ + public String decryptBytes(byte[] ciphertextBytes, byte[] key, byte[] iv) + throws NoSuchPaddingException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, + BadPaddingException { + + SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); + Cipher cipher = Cipher.getInstance(CRYPTO_SPEC); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + + byte[] cleartextBytes = cipher.doFinal(ciphertextBytes); + String cleartext = new String(cleartextBytes); + + return cleartext; + } + + /** + * Generates a random AES key. + * @return A randomly generated key. + * @throws NoSuchAlgorithmException if the AES algorithm is unavailable. + */ + public SecretKey genRandomKey() throws NoSuchAlgorithmException { + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); + keyGen.init(KEY_BITS); + SecretKey key = keyGen.generateKey(); + return key; + } + + /** + * Generates a random AES key, encoded as a Base64 String. + * @return A randomly generated key, encoded as a Base64 String. + * @throws NoSuchAlgorithmException if the AES algorithm is unavailable. + */ + public String genRandomBase64KeyString() throws NoSuchAlgorithmException { + SecretKey key = genRandomKey(); + byte[] keyBytes = key.getEncoded(); + String b64String = new String(Base64.encode(keyBytes, Base64.DEFAULT)); + return b64String; + } + + /** + * @param password The password to generate the key from. + * @param salt Some bytes to salt the password with. + * @param iterations How many iterations to use when generating the key. + * @return A key produced from the given password and parameters. + * @throws NoSuchAlgorithmException if the PBKDF2 algorithm was unavailable. + * @throws InvalidKeySpecException if the keyspec produced from the given parameters is + * rejected. + */ + public SecretKey genKeyPwkdf2(String password, byte[] salt, int iterations) + throws NoSuchAlgorithmException, InvalidKeySpecException { + SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, iterations, KEY_BITS); + SecretKey generatedKey = f.generateSecret(keySpec); + return generatedKey; + } + + /** + * Generates a random initialisation vector. + * @return A random initialisation vector. + */ + public byte[] getIv() { + SecureRandom sr = new SecureRandom(); + byte[] iv = new byte[IV_BYTES]; + sr.nextBytes(iv); + return iv; + } + + /** + * Generates a random salt. + * @return A random salt. + */ + public byte[] getSalt() { + SecureRandom sr = new SecureRandom(); + byte[] salt = new byte[SALT_BYTES]; + sr.nextBytes(salt); + return salt; + } + + /** + * Decodes Base64 encoded Strings. + * @param b64String The base64 String to be decoded. + * @return The decoded String. + */ + public byte[] decodeB64(String b64String) { + return Base64.decode(b64String, Base64.DEFAULT); + } +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/EditPreferencesActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/EditPreferencesActivity.java new file mode 100644 index 0000000..5ba1edd --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/EditPreferencesActivity.java @@ -0,0 +1,25 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import android.os.Bundle; +import android.preference.PreferenceActivity; + +/** + * Simple interface to allow the user to edit some preferences. + * @author Ewan Sinclair + */ +public class EditPreferencesActivity extends PreferenceActivity { + + private BankingApplication mThisApplication; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mThisApplication=(BankingApplication)getApplication(); + addPreferencesFromResource(R.xml.userpreferences); + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/HttpException.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/HttpException.java new file mode 100644 index 0000000..aabc5e8 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/HttpException.java @@ -0,0 +1,28 @@ +package com.securitycompass.androidlabs.advancedencryptionsolution; + + +/** + * Exception that contains an HTTP error code + * @author Ewan Sinclair + */ +public class HttpException extends Exception{ + + private int mStatusCode; + + /** + * Creates a new instance with a given status code + * @param statusCode the status code returned by the HTTP transaction + */ + public HttpException(int statusCode){ + mStatusCode=statusCode; + } + + /** + * Returns the status code held in this Exception + * @return the status code held in this Exception. + */ + public int getStatusCode() { + return mStatusCode; + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/LoginActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/LoginActivity.java new file mode 100644 index 0000000..38132a5 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/LoginActivity.java @@ -0,0 +1,136 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +import javax.net.ssl.SSLException; + +import org.json.JSONException; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +/** + * Graphical class which allows the user to enter a username and password, + * then perform a login with them. + * @author Ewan Sinclair + */ +public class LoginActivity extends BankingActivity { + + /** Useful for avoiding casts when a Context needs to be passed */ + private Context mCtx; + /** The button that initiates the login */ + private Button mLoginButton; + /** The text field to collect/hold the password. */ + private EditText mPasswordField; + /** This application's preferences */ + private SharedPreferences mSharedPrefs; + + private static final String TAG = "LoginActivity"; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mCtx = this; + + mSharedPrefs = mThisApplication.getSharedPrefs(); + checkFirstRun(); + + setContentView(R.layout.loginactivity); + + mLoginButton = (Button) findViewById(R.id.loginscreen_login_button); + mPasswordField = (EditText) findViewById(R.id.loginscreen_password); + + mLoginButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + performLogin(); + } + }); + + } + + /** Pushes the user to the setup screen whenever they land on this Activity without having setup the app. */ + @Override + public void onResume(){ + super.onResume(); + checkFirstRun(); + } + + /** + * Checks if the application is running for the first time, and sends the user to the + * appropriate setup if it is. + */ + private void checkFirstRun() { + if (mSharedPrefs.getBoolean(BankingApplication.PREF_FIRST_RUN, true)) { + Intent i = new Intent(mCtx, SetServerCredentialsActivity.class); + startActivity(i); + } + } + + /** Grabs the username and password and attempts to log in with them */ + private void performLogin() { + + String password = mPasswordField.getText().toString(); + + int unlockStatus = RestClient.NO_OP; + + try { + unlockStatus = mThisApplication.unlockApplication(password); + } catch (UnsupportedEncodingException e) { + Toast.makeText(mCtx, R.string.error_toast_hasherror, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (NoSuchAlgorithmException e) { + if (e.toString().matches(".*SSL.*")) { + Toast.makeText(mCtx, R.string.error_ssl_algorithm, Toast.LENGTH_LONG).show(); + } else { + Toast.makeText(mCtx, R.string.error_toast_hasherror, Toast.LENGTH_LONG).show(); + } + Log.e(TAG, e.toString()); + } catch (JSONException e) { + Toast.makeText(mCtx, R.string.error_toast_json_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (KeyManagementException e) { + Toast.makeText(mCtx, R.string.error_ssl_keymanagement, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (SSLException e) { + Toast.makeText(mCtx, R.string.error_ssl_general, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (HttpException e) { + Toast.makeText(mCtx, getString(R.string.error_toast_http_error) + e.getStatusCode(), Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (IOException e) { + Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (GeneralSecurityException e) { + Toast.makeText(mCtx, "Crypto failure", Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } + + if (unlockStatus == RestClient.NULL_ERROR) { + Intent launchIntent = new Intent(mCtx, SummaryActivity.class); + launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(launchIntent); + } else { + Toast.makeText(mCtx, R.string.toast_loginfailed, Toast.LENGTH_SHORT).show(); + } + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/RestClient.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/RestClient.java new file mode 100644 index 0000000..fa4d226 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/RestClient.java @@ -0,0 +1,446 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.http.conn.ssl.AllowAllHostnameVerifier; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.accounts.AuthenticatorException; +import android.util.Log; + +/** + * Handles HTTP/S communication with the banking service, abstracting it as a set of methods that + * can be called by the rest of the application for any given banking function. + * @author Ewan Sinclair + */ +public class RestClient { + + private static final String TAG = "RestClient"; + + /* + * These codes are used to indicate the status of transactions that have finished, mainly + * representing error codes returned by the server + */ + /** REST operation didn't happen. */ + public static final int NO_OP = -2; + /** No error ocurred, transaction completed. */ + public static final int NULL_ERROR = -1; + /** The banking service rejected the given username and password. */ + public static final int ERROR_CREDENTIALS = 1; + /** The banking service rejected the session key. */ + public static final int ERROR_SESSION_KEY = 2; + /** The account referenced in the request doesn't exist. */ + public static final int ERROR_ACCOUNT_NOT_EXIST = 3; + /** The balance is too low to perform the given transaction. */ + public static final int ERROR_BALANCE_TOO_LOW = 4; + /** Operation was forbidden. */ + public static final int ERROR_FORBIDDEN = 5; + /** Permission for the operation was denied. */ + public static final int ERROR_PERMISSION_DENIED = 6; + + private BankingApplication mAppState; + private boolean mHttpsMode; + private HostnameVerifier mHostnameVerifier; + + /** + * Creates the RestClient and connects it to the state of the application. This allows for it to + * modify the state based on what happens during requests. + * @param appState The BankingApplication containing the app-wide state variables. + * @param enableHttps Whether to use HTTPS. + * @throws NoSuchAlgorithmException if the SSL encryption algorithm chosen is not available. + * @throws KeyManagementException if lax SSL initialisation fails. + */ + public RestClient(BankingApplication appState, boolean enableHttps) + throws NoSuchAlgorithmException, KeyManagementException { + this.mAppState = appState; + mHttpsMode = enableHttps; + setLaxSSL(); + } + + /** + * Performs a simple HTTP GET and returns the result. + * @param urlName API Service endpoint. + * @return HttpContent from the url. + * @throws IOException if the network connection failed + */ + public String getHttpContent(String urlName) throws IOException { + String line; + String result; + StringBuilder httpContent = new StringBuilder(); + + URL url = new URL(urlName); + HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection(); + int responseCode = httpConnection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + InputStream inputStream = httpConnection.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); + while ((line = br.readLine()) != null) { + httpContent.append(line); + } + + httpConnection.disconnect(); + } + result = httpContent.toString(); + return result; + } + + /** + * Performs an HTTP POST with the given data. + * @param urlString The URL to POST to. + * @param variables key/value pairs for all parameters to be POSTed. + * @return The data passed back from the server, as a String. + * @throws IOException if the network connection failed. + * @throws HttpException if the HTTP/S request failed + */ + public String postHttpContent(String urlString, Map variables) + throws IOException, HttpException { + String response = ""; + URL url = new URL(urlString); + HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection(); + httpConnection.setDoInput(true); + httpConnection.setDoOutput(true); + httpConnection.setUseCaches(false); + httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + + // Assemble a String out of the parameters we're posting + String postData = ""; + for (String key : variables.keySet()) { + postData += "&" + key + "=" + variables.get(key); + } + postData = postData.substring(1); + + // Send the POST data + DataOutputStream postOut = new DataOutputStream(httpConnection.getOutputStream()); + postOut.writeBytes(postData); + postOut.flush(); + postOut.close(); + + // Now get the response the server gives us + int responseCode = httpConnection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + String line; + BufferedReader br = new BufferedReader(new InputStreamReader(httpConnection + .getInputStream())); + while ((line = br.readLine()) != null) { + response += line; + } + } else { + response = ""; + Log.e(TAG, "HTTP request failed on: " + urlString + " With error code: " + + responseCode); + throw new HttpException(responseCode); + } + return response; + } + + /** + * Performs a simple HTTPS GET and returns the result. + * @param urlName API Service endpoint. + * @return HttpContent from the url. + * @throws IOException if the network connection failed. + */ + public String getHttpsContent(String urlName) throws IOException { + String line; + String result; + StringBuilder httpsContent = new StringBuilder(); + + URL url = new URL(urlName); + HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection(); + if (mHostnameVerifier != null) { + httpsConnection.setHostnameVerifier(mHostnameVerifier); + } + int responseCode = httpsConnection.getResponseCode(); + if (responseCode == HttpsURLConnection.HTTP_OK) { + InputStream inputStream = httpsConnection.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); + while ((line = br.readLine()) != null) { + httpsContent.append(line); + } + + httpsConnection.disconnect(); + } + result = httpsContent.toString(); + return result; + } + + /** + * Performs an HTTPS POST with the given data. + * @param urlString The URL to POST to. + * @param variables key/value pairs for all parameters to be POSTed. + * @return The data passed back from the server, as a String. + * @throws IOException if the network connection failed. + * @throws HttpException if the HTTP transaction failed + */ + public String postHttpsContent(String urlString, Map variables) + throws IOException, HttpException { + String response = ""; + URL url = new URL(urlString); + HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection(); + if (mHostnameVerifier != null) { + httpsConnection.setHostnameVerifier(mHostnameVerifier); + } + httpsConnection.setDoInput(true); + httpsConnection.setDoOutput(true); + httpsConnection.setUseCaches(false); + httpsConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + + // Assemble a String out of the parameters we're posting + String postData = ""; + for (String key : variables.keySet()) { + postData += "&" + key + "=" + variables.get(key); + } + postData = postData.substring(1); + + // Send the POST data + DataOutputStream postOut = new DataOutputStream(httpsConnection.getOutputStream()); + postOut.writeBytes(postData); + postOut.flush(); + postOut.close(); + + // Now get the response the server gives us + int responseCode = httpsConnection.getResponseCode(); + if (responseCode == HttpsURLConnection.HTTP_OK) { + String line; + BufferedReader br = new BufferedReader(new InputStreamReader(httpsConnection + .getInputStream())); + while ((line = br.readLine()) != null) { + response += line; + } + } else { + response = ""; + Log.e(TAG, "HTTPs request failed on: " + urlString + " With error code: " + + responseCode); + throw new HttpException(responseCode); + } + return response; + } + + /** + * Logs into the REST service, generating a new session key. + * @param server The address of the server to log into. + * @param port The port number to use. + * @param username Username to log in with. + * @param password Password to log in with. + * @return Whether the login was successful. + * @throws JSONException if the server returned invalid JSON. + * @throws IOException if the network connection failed. + * @throws HttpException if the HTTP transaction failed. + */ + public int performLogin(String server, String port, String username, String password) + throws JSONException, IOException, HttpException { + // First perform the RESTful operation + String protocol = mHttpsMode ? "https://" : "http://"; + String url = protocol + server + ":" + port + "/login"; + Map parameters = new HashMap(); + parameters.put("username", username); + parameters.put("password", password); + String JsonResponse; + if (mHttpsMode) { + JsonResponse = postHttpsContent(url, parameters); + } else { + JsonResponse = postHttpContent(url, parameters); + } + + // Now parse out the JSON response and act accordingly + int errorCode = parseError(JsonResponse); + if (errorCode == NULL_ERROR) { + JSONObject jsonObject = new JSONObject(JsonResponse); + String key = jsonObject.getString("key"); + String created = jsonObject.getString("created"); + mAppState.setSession(key, created); + return errorCode; + } + return errorCode; + } + + /** + * Queries the server for a list of accounts, and returns a list of them. + * @param server The address of the server to query. + * @param port The port we will make our query on. + * @return A list of all accounts the server told us about, and their details. + * @throws JSONException if the server returned invalid JSON. + * @throws IOException if the network connection failed. + * @throws AuthenticatorException if the server rejected the proferred session key. + */ + public List getAccounts(String server, String port) throws JSONException, IOException, + AuthenticatorException { + List accounts = new ArrayList(); + String protocol = mHttpsMode ? "https://" : "http://"; + String url = protocol + server + ":" + port + "/accounts" + "?session_key=" + + URLEncoder.encode(mAppState.getSessionKey()); + String result; + if (mHttpsMode) { + result = getHttpsContent(url); + } else { + result = getHttpContent(url); + } + int errorCode = parseError(result); + + if (errorCode == NULL_ERROR) { + + JSONArray resultArray = new JSONArray(result); + for (int count = 0; count < resultArray.length(); count++) { + JSONObject accountJson = resultArray.getJSONObject(count); + double balance = accountJson.getDouble("balance"); + String accountType = accountJson.getString("type"); + int accountNumber = accountJson.getInt("account_number"); + accounts.add(new Account(accountNumber, accountType, balance)); + } + + } else if (errorCode == ERROR_SESSION_KEY) { + throw new AuthenticatorException("Session key invalid"); + } + + return accounts; + } + + /** + * Queries the server for a list of accounts, and returns a list of them. + * @param server The address of the server to query. + * @param port The port we will make our query on. + * @return A list of all accounts the server told us about, and their details. + * @throws IOException if the network connection failed. + * @throws AuthenticatorException if the server rejected the proferred session key. + */ + public String getStatement(String server, String port) throws IOException, + AuthenticatorException { + String protocol = mHttpsMode ? "https://" : "http://"; + String url = (protocol + server + ":" + port + "/statement" + "?session_key=" + URLEncoder + .encode(mAppState.getSessionKey())); + String result; + if (mHttpsMode) { + result = getHttpsContent(url); + } else { + result = getHttpContent(url); + } + + int errorCode = parseError(result); + + if (errorCode == NULL_ERROR) { + // No need to do anything to the data + } else if (errorCode == ERROR_SESSION_KEY) { + throw new AuthenticatorException("Session key invalid"); + } + + return result; + } + + /** + * Transfers funds between the given accounts. + * @param server The server to use. + * @param port The port to use. + * @param fromAccount The number of the account we're transferring from. + * @param toAccount The number of the account we're transferring to. + * @param amount The amount to be transferred + * @param sessionKey The session key to use + * @return A code indicating if the transaction succeeded, or why it failed. + * @throws IOException if the network connection failed. + * @throws HttpException if the HTTP transaction failed. + */ + public int transfer(String server, String port, int fromAccount, int toAccount, double amount, + String sessionKey) throws IOException, HttpException { + Map variables = new HashMap(); + variables.put("from_account", Integer.toString(fromAccount)); + variables.put("to_account", Integer.toString(toAccount)); + variables.put("amount", Double.toString(amount)); + String response; + if (mHttpsMode) { + response = postHttpsContent("https://" + server + ":" + port + "/transfer" + + "?session_key=" + URLEncoder.encode(sessionKey), variables); + } else { + response = postHttpContent("http://" + server + ":" + port + "/transfer" + + "?session_key=" + URLEncoder.encode(sessionKey), variables); + } + int statusCode = parseError(response); + return statusCode; + } + + /** + * Takes a JSON string and returns an int representing the error code in it. + * @param json The string to check for JSON encapsulated error codes. + * @return The error code the string represented, or a code for no error. + */ + public int parseError(String json) { + int errorCode; + String errorString; + if (json == null || json.equals("")) { + return -1; + } + + // First see if this string is a valid error message + try { + JSONObject jsonObject = new JSONObject(json); + errorString = jsonObject.getString("error"); + } catch (JSONException e) { + errorCode = NULL_ERROR; + return errorCode; + } + + // Since it is, encode it as an int and return it + // String is of format "E[0-9]+", e.g. "E3" + return Integer.parseInt(errorString.trim().substring(1)); + } + + /** + * Sets the application to accept all SSL certificates. + * @throws NoSuchAlgorithmException if the SSL encryption algorithm wasn't available. + * @throws KeyManagementException if initialising ther SSLContext fails. + */ + private void setLaxSSL() throws NoSuchAlgorithmException, KeyManagementException { + TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + + } + } }; + + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + + HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); + + mHostnameVerifier = new AllowAllHostnameVerifier(); + + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/SetLocalPasswordActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/SetLocalPasswordActivity.java new file mode 100644 index 0000000..b68e540 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/SetLocalPasswordActivity.java @@ -0,0 +1,165 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +import org.json.JSONException; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences.Editor; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +/** This class prompts the user to set their local unlock password + * @author Ewan Sinclair + */ +public class SetLocalPasswordActivity extends Activity { + + private EditText mPasswordField; + private EditText mConfirmPasswordField; + private Button mDoneButton; + private Context mCtx; + private BankingApplication mThisApplication; + + private String restUser; + private String restPass; + + private final static String TAG="SetLocalPasswordActivity"; + + /** Called when the Activity is first created */ + @Override + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + this.setContentView(R.layout.setlocalpasswordactivity); + + mCtx=this; + mThisApplication=(BankingApplication) getApplication(); + + restUser=getIntent().getStringExtra("restUser"); + restPass=getIntent().getStringExtra("restPass"); + + mPasswordField=(EditText) findViewById(R.id.setupunlockactivity_password); + mConfirmPasswordField=(EditText) findViewById(R.id.setupunlockactivity_repeat_password); + mDoneButton=(Button) findViewById(R.id.setupunlockactivity_donebutton); + + mDoneButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + grabAndSetPassword(); + } + }); + + } + + /** Grabs the two passwords entered, and sets them as the local unlock password if they match */ + private void grabAndSetPassword(){ + + String pass1=mPasswordField.getText().toString(); + String pass2=mConfirmPasswordField.getText().toString(); + if(!pass1.equals(pass2)){ + Toast.makeText(mCtx, R.string.error_passwords_not_matching, Toast.LENGTH_SHORT).show(); + } else { + try { + mThisApplication.setCredentials(pass2, restUser, restPass); + mThisApplication.unlockApplication(pass2); + } catch (NoSuchAlgorithmException e){ + Toast.makeText(mCtx, R.string.error_toast_hasherror, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (UnsupportedEncodingException e){ + Toast.makeText(mCtx, R.string.error_toast_hasherror, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (JSONException e){ + Toast.makeText(mCtx, R.string.error_toast_json_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (HttpException e) { + Toast.makeText(mCtx, getString(R.string.error_toast_http_error) + e.getStatusCode(), Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (KeyManagementException e){ + Toast.makeText(mCtx, R.string.error_ssl_keymanagement, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (IOException e) { + Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (GeneralSecurityException e) { + Toast.makeText(mCtx, "Crypto failure", Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } + + //Inform the user that setup is complete and unmark the first run flag + Toast.makeText(mCtx, R.string.initialsetup_success, Toast.LENGTH_SHORT).show(); + Editor e=mThisApplication.getSharedPrefs().edit(); + e.putBoolean(BankingApplication.PREF_FIRST_RUN, false); + e.commit(); + Intent i = new Intent(mCtx, SummaryActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + } + } + + /** Called when an item is selected from the options menu */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.optionsmenu_reset: + resetApplication(); + return true; + case R.id.optionsmenu_preferences: + launchPreferenceScreen(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + /** Creates an options menu */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options_menu, menu); + return true; + } + + /** Resets the application */ + private void resetApplication() { + BankingApplication ba = (BankingApplication) getApplication(); + ba.clearStatements(); + Editor e = ba.getSharedPrefs().edit(); + e.clear(); + e.commit(); + ba.lockApplication(); + launchLoginScreen(); + } + + /** Launches the preferences screen */ + private void launchPreferenceScreen() { + Intent i = new Intent(this, EditPreferencesActivity.class); + startActivity(i); + } + + /** Launches the accounts screen, doing any necessary processing first */ + private void launchLoginScreen() { + Intent launchLogin = new Intent(this, LoginActivity.class); + launchLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(launchLogin); + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/SetServerCredentialsActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/SetServerCredentialsActivity.java new file mode 100644 index 0000000..6a71079 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/SetServerCredentialsActivity.java @@ -0,0 +1,151 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +import org.json.JSONException; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences.Editor; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +/** + * One-time setup screen for the user to enter their credentials for the banking service. + * @author Ewan Sinclair + */ +public class SetServerCredentialsActivity extends Activity { + + private EditText mUserField; + private EditText mPasswordField; + private Button mDoneButton; + private Context mCtx; + private BankingApplication mThisApplication; + + private static final String TAG = "SetServerCredentialsActivity"; + + /** Called when the Activity is first created */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.setContentView(R.layout.setservercredentialsactivity); + + mCtx = this; + mThisApplication = (BankingApplication) getApplication(); + + mUserField = (EditText) findViewById(R.id.setservercredentialsactivity_username); + mPasswordField = (EditText) findViewById(R.id.setservercredentialsactivity_password); + mDoneButton = (Button) findViewById(R.id.setservercredentialsactivity_donebutton); + + mDoneButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + setServerCredentials(); + } + }); + + } + + private void setServerCredentials() { + String username = mUserField.getText().toString(); + String password = mPasswordField.getText().toString(); + + int statuscode = RestClient.NO_OP; + try { + statuscode = mThisApplication.performLogin(username, password); + } catch (JSONException e) { + Toast.makeText(mCtx, R.string.error_toast_json_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + return; + } catch (KeyManagementException e) { + Toast.makeText(mCtx, R.string.error_ssl_keymanagement, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (NoSuchAlgorithmException e) { + Toast.makeText(mCtx, R.string.error_ssl_algorithm, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (HttpException e) { + Toast.makeText(mCtx, getString(R.string.error_toast_http_error) + e.getStatusCode(), Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (IOException e) { + Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + return; + } + + if (statuscode == RestClient.NULL_ERROR) { + mThisApplication.lockApplication(); + Intent i = new Intent(mCtx, SetLocalPasswordActivity.class); + i.putExtra("restUser", username); + i.putExtra("restPass", password); + startActivity(i); + } else { + Toast.makeText(mCtx, R.string.toast_loginfailed, Toast.LENGTH_SHORT).show(); + } + } + + /** Called when an item is selected from the options menu */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.optionsmenu_reset: + resetApplication(); + return true; + case R.id.optionsmenu_preferences: + launchPreferenceScreen(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + /** Creates an options menu */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.options_menu, menu); + return true; + } + + /** Resets the application */ + private void resetApplication() { + BankingApplication ba = (BankingApplication) getApplication(); + ba.clearStatements(); + Editor e = ba.getSharedPrefs().edit(); + e.clear(); + e.commit(); + ba.lockApplication(); + launchLoginScreen(); + } + + /** Launches the preferences screen */ + private void launchPreferenceScreen() { + Intent i = new Intent(this, EditPreferencesActivity.class); + startActivity(i); + } + + /** Launches the accounts screen, doing any necessary processing first */ + private void launchLoginScreen() { + Intent launchLogin = new Intent(this, LoginActivity.class); + launchLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(launchLogin); + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/StatementActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/StatementActivity.java new file mode 100644 index 0000000..c8d023e --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/StatementActivity.java @@ -0,0 +1,231 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import android.accounts.AuthenticatorException; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.format.DateUtils; +import android.util.Base64; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.AdapterView.OnItemClickListener; + +/** + * Displays a list of statements, each of which can be clicked to view it. + * @author Ewan Sinclair + */ +public class StatementActivity extends BankingListActivity { + + /** Useful for avoiding casts when a Context needs to be passed */ + private Context mCtx; + private BankingApplication mThisApplication; + private File mStatementsDir; + private File[] mStatements; + private File[] mIvFiles; + private Button mClearButton; + private StatementAdapter mAdapter; + + private static final String TAG = "StatementActivity"; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.statementactivity); + setAppropriateVisibility(); + + mCtx = this; + mThisApplication = (BankingApplication) getApplication(); + + mClearButton = (Button) findViewById(R.id.statementscreen_clear_button); + + mStatementsDir = getFilesDir(); + downloadStatement(); + readStatementFiles(); + + mAdapter = new StatementAdapter(mCtx, android.R.layout.simple_list_item_1, mStatements); + setListAdapter(mAdapter); + + mClearButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + mThisApplication.clearStatements(); + refreshView(); + } + }); + + getListView().setOnItemClickListener(new OnItemClickListener( + + ) { + + @Override + public void onItemClick(AdapterView arg0, View arg1, int position, long id) { + Intent intent = new Intent(mCtx, ViewStatementActivity.class); + intent.putExtra("statement_html", decryptStatement(position)); + startActivity(intent); + } + }); + + } + + /** + * Clears out all downloaded files, downloads the latest one, and refreshes the list. + */ + private void refreshView() { + downloadStatement(); + readStatementFiles(); + mAdapter = new StatementAdapter(mCtx, android.R.layout.simple_list_item_1, mStatements); + setListAdapter(mAdapter); + } + + /** Downloads the most recent statement */ + private void downloadStatement() { + try { + mThisApplication.downloadStatement(); + } catch (KeyManagementException e) { + Toast.makeText(mCtx, R.string.error_ssl_keymanagement, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (NoSuchAlgorithmException e) { + Toast.makeText(mCtx, R.string.error_ssl_algorithm, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (AuthenticatorException e) { + Log.e(TAG, e.toString()); + authenticate(); + } catch (IOException e) { + Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (Exception e) { + Toast.makeText(mCtx, "General Error", Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } + } + + /** Looks in the statements directory and loads what look like statement filenames into the list */ + private void readStatementFiles() { + File[] allFiles = mStatementsDir.listFiles(); + List filteredStatements = new ArrayList(); + List filteredIvFiles = new ArrayList(); + + for (File f : allFiles) { + if (f.getName().matches("^[0-9]*\\.statement")) { + String ivPath = f.getPath().replaceAll("\\.statement", "\\.iv"); + File fIv = new File(ivPath); + if (fIv.exists()) { + filteredStatements.add(f); + filteredIvFiles.add(fIv); + } + + } + + } + // The list will now display with the most recent at the top + Collections.reverse(filteredStatements); + Collections.reverse(filteredIvFiles); + mStatements = filteredStatements.toArray(new File[0]); + mIvFiles = filteredIvFiles.toArray(new File[0]); + } + + private String decryptStatement(int position) { + + CryptoTool cipher = new CryptoTool(); + byte[] key = mThisApplication.getCryptoKey(); + + // Get the IV and statement file contents + byte[] ciphertext=null, iv=null; + try { + ciphertext = readFile(mStatements[position]); + iv = readFile(mIvFiles[position]); + } catch (Exception e) { + Toast.makeText(mCtx, "Error reading statement file", Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } + + String cleartext=""; + try { + cleartext=cipher.decryptBytes(ciphertext, key, iv); + } catch (Exception e) { + Toast.makeText(mCtx, "Error decrypting", Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } + + return cleartext; + } + + private byte[] readFile(File f) throws FileNotFoundException, IOException { + + InputStream is = new FileInputStream(f); + byte[] bytes = new byte[(int) f.length()]; + + // Read in the bytes + int offset = 0; + int numRead = 0; + while (offset < bytes.length + && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { + offset += numRead; + } + + // Ensure all the bytes have been read in + if (offset < bytes.length) { + throw new IOException("Could not completely read file " + f.getName()); + } + + // Close the input stream and return bytes + is.close(); + return bytes; + } + + private class StatementAdapter extends ArrayAdapter { + + public StatementAdapter(Context context, int textViewResourceId, File[] objects) { + super(context, textViewResourceId, objects); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView view; + if (convertView != null) { + view = (TextView) convertView; + } else { + view = (TextView) getLayoutInflater().inflate(android.R.layout.simple_list_item_1, + null); + } + + // Extract the creation time of the file from its filename + String timeStampString = mStatements[position].getName().replaceAll("\\.statement", ""); + long timeStamp = Long.parseLong(timeStampString); + + int formatFlags = DateUtils.LENGTH_MEDIUM | DateUtils.FORMAT_24HOUR + | DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_SHOW_TIME; + String formattedDateString = DateUtils.formatDateTime(mCtx, timeStamp, formatFlags); + + view.setText(formattedDateString); + return view; + } + + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/SummaryActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/SummaryActivity.java new file mode 100644 index 0000000..096d5fd --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/SummaryActivity.java @@ -0,0 +1,86 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListAdapter; +import android.widget.AdapterView.OnItemClickListener; + +/** + * Menu screen which allows the user to select whichever banking activity they'd like to perform. + * @author Ewan Sinclair + */ +public class SummaryActivity extends BankingListActivity { + + private Context mCtx; + private final String[] optionNames = { "Accounts", "Statement", "Transfer" }; + + private static final int LAUNCH_ACCOUNTS = 0; + private static final int LAUNCH_STATEMENT = 1; + private static final int LAUNCH_TRANSFER = 2; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.summaryactivity); + setAppropriateVisibility(); + + mCtx = this; + + ListAdapter la = new ArrayAdapter(mCtx, android.R.layout.simple_list_item_1, + optionNames); + setListAdapter(la); + + getListView().setOnItemClickListener(new OnItemClickListener( + + ) { + + @Override + public void onItemClick(AdapterView arg0, View arg1, int position, long id) { + launchSelectedScreen(position); + } + }); + + } + + /** + * Launches the screen with the given ID. This is necessary because when a ListView item is + * clicked, it returns a position. We can't associate a listener directly to each list item. + */ + private void launchSelectedScreen(int screenId) { + if (screenId == LAUNCH_ACCOUNTS) { + launchAccountsScreen(); + } else if (screenId == LAUNCH_STATEMENT) { + launchStatementScreen(); + } else if (screenId == LAUNCH_TRANSFER) { + launchTransferScreen(); + } + } + + /** Launches the accounts screen, doing any necessary processing first */ + private void launchAccountsScreen() { + Intent launchAccounts = new Intent(mCtx, AccountsActivity.class); + startActivity(launchAccounts); + } + + /** Launches the transfer screen, doing any necessary processing first */ + private void launchTransferScreen() { + Intent launchTransfer = new Intent(mCtx, TransferActivity.class); + startActivity(launchTransfer); + } + + /** Launches the statement screen, doing any necessary processing first */ + private void launchStatementScreen() { + Intent launchTransfer = new Intent(mCtx, StatementActivity.class); + startActivity(launchTransfer); + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/TransferActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/TransferActivity.java new file mode 100644 index 0000000..a2a56dc --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/TransferActivity.java @@ -0,0 +1,323 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + +import org.json.JSONException; + +import android.accounts.AuthenticatorException; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.SpinnerAdapter; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.AdapterView.OnItemSelectedListener; + +/** + * Screen which allows the user to make a transfer between two accounts. + * @author Ewan Sinclair + */ +public class TransferActivity extends BankingActivity { + + /** Useful for avoiding casts when a Context needs to be passed. */ + private Context mCtx; + /** Central data store, state, and operations. */ + private BankingApplication mThisApplication; + /** A list of the accounts for this user. */ + private List mAccounts; + + /** The dropdown selector for the 'from' account. */ + private Spinner mFromAccountSpinner; + /** The dropdown selector for the 'to' account. */ + private Spinner mToAccountSpinner; + /** The button to trigger the transfer. */ + private Button mTransferButton; + /** The field in which the amount to transfer will be entered */ + private EditText mAmountField; + + /** The adapter we'll attach the 'from' spinner to. */ + private AccountListAdapter mFromAccountListAdapter; + /** The adapter we'll attach the 'to' spinner to. */ + private AccountListAdapter mToAccountListAdapter; + /** Holds the currently selected account to transfer funds from. */ + private Account mFromAccount; + /** Holds the currently selected account to transfer funds to. */ + private Account mToAccount; + + private final static int TRANSFER_FROM = 1; + private final static int TRANSFER_TO = 2; + private static final String TAG = "TransferActivity"; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.transferactivity); + setAppropriateVisibility(); + + mCtx = this; + mThisApplication = (BankingApplication) getApplication(); + + mAccounts = new ArrayList(); + + // Set up the dropdown account selectors + mFromAccountSpinner = (Spinner) findViewById(R.id.transferscreen_fromaccount_spinner); + mToAccountSpinner = (Spinner) findViewById(R.id.transferscreen_toaccount_spinner); + + mFromAccountListAdapter = new AccountListAdapter(); + mToAccountListAdapter = new AccountListAdapter(); + + updateAccounts(); + + mFromAccountSpinner.setAdapter(mFromAccountListAdapter); + mToAccountSpinner.setAdapter(mToAccountListAdapter); + + mFromAccountSpinner.setOnItemSelectedListener(new AccountSelectionListener(TRANSFER_FROM)); + mToAccountSpinner.setOnItemSelectedListener(new AccountSelectionListener(TRANSFER_TO)); + + // Set up the button to make it all go, and the amount field + mTransferButton = (Button) findViewById(R.id.transferscreen_transfer_button); + + mTransferButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + performTransfer(); + + } + }); + + mAmountField = (EditText) findViewById(R.id.transferscreen_enteramount_field); + + if (mAccounts.size() >= 2) { + mToAccountSpinner.setSelection(1); + } + refreshDisplayInformation(); + + } + + /** Updates the account information stored locally and refreshes the display */ + private void updateAccounts() { + try { + // We can't just replace this with a new list, as there may be references held to it. + List tempAccounts = mThisApplication.getAccounts(); + mAccounts.clear(); + for (Account a : tempAccounts) { + mAccounts.add(a); + } + } catch (JSONException e) { + Toast.makeText(mCtx, R.string.error_toast_json_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (IOException e) { + Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (AuthenticatorException e) { + Log.e(TAG, e.toString()); + authenticate(); + } catch (KeyManagementException e) { + Toast.makeText(mCtx, R.string.error_ssl_keymanagement, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (NoSuchAlgorithmException e) { + Toast.makeText(mCtx, R.string.error_ssl_algorithm, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } + + // If the account list failed on retrieval, use an empty list + if (!mThisApplication.isLocked()) { + refreshDisplayInformation(); + } else { + mAccounts.clear(); + } + } + + /** + * Pulls the currently entered information from the UI and performs a transfer using the set + * values + */ + private void performTransfer() { + // TODO: Check status code and act accordingly if an error is present. + Log.i(TAG, "Member Accounts [" + mFromAccount.toString() + "] [" + mToAccount.toString() + + "]"); + if (mFromAccount == mToAccount) { + Toast.makeText(mCtx, R.string.error_transfer_same_account, Toast.LENGTH_SHORT).show(); + } else { + String amountText = mAmountField.getText().toString(); + double amount = 0; + try { + amount = Double.parseDouble(amountText); + } catch (NumberFormatException e) { + Toast.makeText(mCtx, R.string.error_transfer_invalid_amount, Toast.LENGTH_SHORT) + .show(); + return; + } + + if (amount > 0) { + try { + int responseCode = mThisApplication.transferFunds(mFromAccount + .getAccountNumber(), mToAccount.getAccountNumber(), amount); + Log.i(TAG, "Response code for transfer: " + responseCode); + } catch (KeyManagementException e) { + Toast.makeText(mCtx, R.string.error_ssl_keymanagement, Toast.LENGTH_LONG) + .show(); + Log.e(TAG, e.toString()); + } catch (NoSuchAlgorithmException e) { + Toast.makeText(mCtx, R.string.error_ssl_algorithm, Toast.LENGTH_LONG).show(); + Log.e(TAG, e.toString()); + } catch (HttpException e) { + Toast.makeText(mCtx, getString(R.string.error_toast_http_error) + e.getStatusCode(), + Toast.LENGTH_SHORT).show(); + Log.e(TAG, e.toString()); + } catch (IOException e) { + Toast.makeText(mCtx, R.string.error_toast_rest_problem, Toast.LENGTH_SHORT) + .show(); + Log.e(TAG, e.toString()); + } + + Log.i(TAG, "Transferred $" + amount + " from account " +mFromAccount.getAccountNumber()+" to account " +mToAccount.getAccountNumber()); + updateAccounts(); + Toast.makeText(mCtx, R.string.transferscreen_success, Toast.LENGTH_SHORT).show(); + launchSummaryScreen(); + } else { + Toast.makeText(mCtx, R.string.error_transfer_invalid_amount, Toast.LENGTH_SHORT).show(); + } + + } + } + + /** Updates the display to reflect the currently held account information. */ + private void refreshDisplayInformation() { + /* + * Simply calling notifyDataSetChanged() on the adapters here doesn't work, as the + * mFromAccount reference remains set to the same as it was before the transaction, E.G. the + * same type and account number, but with the earlier balance. Clearly the Spinner's + * OnItemSelected() method isn't triggered when calling notifyDataSetChanged(). + */ + + int fromPos = mFromAccountSpinner.getSelectedItemPosition(); + int toPos = mToAccountSpinner.getSelectedItemPosition(); + + mFromAccountListAdapter = new AccountListAdapter(); + mToAccountListAdapter = new AccountListAdapter(); + + mFromAccountSpinner.setAdapter(mFromAccountListAdapter); + mToAccountSpinner.setAdapter(mToAccountListAdapter); + + mFromAccountSpinner.setSelection(fromPos); + mToAccountSpinner.setSelection(toPos); + + } + + private void launchSummaryScreen(){ + Intent i=new Intent(this, SummaryActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + } + + /** + * Returns a version of the given string with the first letter in uppercase. + * @param input The String to capitalise. + * @return The capitalised String. + */ + private String capitalise(String input) { + String result = input.substring(0, 1).toUpperCase() + input.substring(1); + return result; + } + + private class AccountSelectionListener implements OnItemSelectedListener { + + private int transferDirection; + + public AccountSelectionListener(int direction) { + super(); + transferDirection = direction; + } + + @Override + public void onItemSelected(AdapterView parent, View selectedView, int position, long id) + throws IndexOutOfBoundsException { + if (transferDirection == TRANSFER_FROM) { + mFromAccount = mAccounts.get(position); + } else if (transferDirection == TRANSFER_TO) { + mToAccount = mAccounts.get(position); + } else + throw new IndexOutOfBoundsException( + "From/To indicator int out of bounds in AccountSelectionListener"); + } + + @Override + public void onNothingSelected(AdapterView arg0) { + // Nothing to do here + } + + } + + /** Helper class to present a List to a Spinner for selecting one */ + private class AccountListAdapter extends BaseAdapter implements SpinnerAdapter { + + @Override + public int getCount() { + return mAccounts.size(); + } + + @Override + public Object getItem(int position) { + return mAccounts.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView view; + if (convertView == null) { + view = (TextView) getLayoutInflater().inflate( + (android.R.layout.simple_spinner_item), null); + } else { + view = (TextView) convertView; + } + String accountNumString = Integer.toString(mAccounts.get(position).getAccountNumber()); + view.setText(capitalise(mAccounts.get(position).getAccountType()) + " (" + + accountNumString.substring(accountNumString.length() - 4) + "): $" + + mAccounts.get(position).getBalance()); + return view; + } + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + TextView view; + if (convertView == null) { + view = (TextView) getLayoutInflater().inflate( + (android.R.layout.simple_spinner_dropdown_item), null); + } else { + view = (TextView) convertView; + } + String accountNumString = Integer.toString(mAccounts.get(position).getAccountNumber()); + view.setText(capitalise(mAccounts.get(position).getAccountType()) + " (" + + accountNumString.substring(accountNumString.length() - 4) + "): $" + + mAccounts.get(position).getBalance()); + return view; + } + + } + +} diff --git a/src/com/securitycompass/androidlabs/advancedencryptionsolution/ViewStatementActivity.java b/src/com/securitycompass/androidlabs/advancedencryptionsolution/ViewStatementActivity.java new file mode 100644 index 0000000..ce09bf4 --- /dev/null +++ b/src/com/securitycompass/androidlabs/advancedencryptionsolution/ViewStatementActivity.java @@ -0,0 +1,41 @@ +/** + * Copyright 2011 Security Compass + */ + +package com.securitycompass.androidlabs.advancedencryptionsolution; + +import android.content.Intent; +import android.os.Bundle; +import android.webkit.WebView; +import android.widget.Toast; + +/** + * Screen which displays a statement file. + * @author Ewan Sinclair + */ +public class ViewStatementActivity extends BankingActivity { + + WebView mStatementDisplay; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.viewstatementactivity); + setAppropriateVisibility(); + + mStatementDisplay = (WebView) findViewById(R.id.viewstatementscreen_webview); + + Intent i = getIntent(); + if (i.hasExtra("statement_filename")) { + String filename = i.getStringExtra("statement_filename"); + mStatementDisplay.loadUrl("file://" + filename); + } else if (i.hasExtra("statement_html")){ + String html = i.getStringExtra("statement_html"); + mStatementDisplay.loadData(html, "text/html", "utf-8"); + } else { + Toast.makeText(this, R.string.error_invalid_statment, Toast.LENGTH_SHORT).show(); + } + + } + +} diff --git a/src/com/securitycompass/androidlabs/Account.java b/src/com/securitycompass/androidlabs/base/Account.java similarity index 100% rename from src/com/securitycompass/androidlabs/Account.java rename to src/com/securitycompass/androidlabs/base/Account.java diff --git a/src/com/securitycompass/androidlabs/AccountsActivity.java b/src/com/securitycompass/androidlabs/base/AccountsActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/AccountsActivity.java rename to src/com/securitycompass/androidlabs/base/AccountsActivity.java diff --git a/src/com/securitycompass/androidlabs/BankingActivity.java b/src/com/securitycompass/androidlabs/base/BankingActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/BankingActivity.java rename to src/com/securitycompass/androidlabs/base/BankingActivity.java diff --git a/src/com/securitycompass/androidlabs/BankingApplication.java b/src/com/securitycompass/androidlabs/base/BankingApplication.java similarity index 100% rename from src/com/securitycompass/androidlabs/BankingApplication.java rename to src/com/securitycompass/androidlabs/base/BankingApplication.java diff --git a/src/com/securitycompass/androidlabs/BankingListActivity.java b/src/com/securitycompass/androidlabs/base/BankingListActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/BankingListActivity.java rename to src/com/securitycompass/androidlabs/base/BankingListActivity.java diff --git a/src/com/securitycompass/androidlabs/EditPreferencesActivity.java b/src/com/securitycompass/androidlabs/base/EditPreferencesActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/EditPreferencesActivity.java rename to src/com/securitycompass/androidlabs/base/EditPreferencesActivity.java diff --git a/src/com/securitycompass/androidlabs/HttpException.java b/src/com/securitycompass/androidlabs/base/HttpException.java similarity index 100% rename from src/com/securitycompass/androidlabs/HttpException.java rename to src/com/securitycompass/androidlabs/base/HttpException.java diff --git a/src/com/securitycompass/androidlabs/LoginActivity.java b/src/com/securitycompass/androidlabs/base/LoginActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/LoginActivity.java rename to src/com/securitycompass/androidlabs/base/LoginActivity.java diff --git a/src/com/securitycompass/androidlabs/RestClient.java b/src/com/securitycompass/androidlabs/base/RestClient.java similarity index 100% rename from src/com/securitycompass/androidlabs/RestClient.java rename to src/com/securitycompass/androidlabs/base/RestClient.java diff --git a/src/com/securitycompass/androidlabs/SetLocalPasswordActivity.java b/src/com/securitycompass/androidlabs/base/SetLocalPasswordActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/SetLocalPasswordActivity.java rename to src/com/securitycompass/androidlabs/base/SetLocalPasswordActivity.java diff --git a/src/com/securitycompass/androidlabs/SetServerCredentialsActivity.java b/src/com/securitycompass/androidlabs/base/SetServerCredentialsActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/SetServerCredentialsActivity.java rename to src/com/securitycompass/androidlabs/base/SetServerCredentialsActivity.java diff --git a/src/com/securitycompass/androidlabs/StatementActivity.java b/src/com/securitycompass/androidlabs/base/StatementActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/StatementActivity.java rename to src/com/securitycompass/androidlabs/base/StatementActivity.java diff --git a/src/com/securitycompass/androidlabs/SummaryActivity.java b/src/com/securitycompass/androidlabs/base/SummaryActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/SummaryActivity.java rename to src/com/securitycompass/androidlabs/base/SummaryActivity.java diff --git a/src/com/securitycompass/androidlabs/TransferActivity.java b/src/com/securitycompass/androidlabs/base/TransferActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/TransferActivity.java rename to src/com/securitycompass/androidlabs/base/TransferActivity.java diff --git a/src/com/securitycompass/androidlabs/ViewStatementActivity.java b/src/com/securitycompass/androidlabs/base/ViewStatementActivity.java similarity index 100% rename from src/com/securitycompass/androidlabs/ViewStatementActivity.java rename to src/com/securitycompass/androidlabs/base/ViewStatementActivity.java From 3447cdebf1bfb5cfc6ba15f0a4c3cac2448b032a Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 10 Aug 2011 10:32:13 +0800 Subject: [PATCH 08/12] added jpg file for sclogo --- res/drawable-hdpi/sclogo.png | Bin 0 -> 24744 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/drawable-hdpi/sclogo.png diff --git a/res/drawable-hdpi/sclogo.png b/res/drawable-hdpi/sclogo.png new file mode 100644 index 0000000000000000000000000000000000000000..63c1ce96766116aaf6ac8d1953663e5c03d3eb8e GIT binary patch literal 24744 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 Hu0mjf-eJqM literal 0 HcmV?d00001 From 7200bd852d4ef1ddded0a40753045b6fdb377bb5 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 10 Aug 2011 10:38:59 +0800 Subject: [PATCH 09/12] updated strings xml file --- bin/FalseSecureMobile.apk | Bin 0 -> 74854 bytes bin/classes.dex | Bin 0 -> 47232 bytes .../androidlabs/base/Account.class | Bin 0 -> 1461 bytes ...ccountsActivity$AccountDetailAdapter.class | Bin 0 -> 3070 bytes .../androidlabs/base/AccountsActivity.class | Bin 0 -> 3551 bytes .../androidlabs/base/BankingActivity.class | Bin 0 -> 3739 bytes .../base/BankingApplication$1.class | Bin 0 -> 768 bytes .../androidlabs/base/BankingApplication.class | Bin 0 -> 9802 bytes .../base/BankingListActivity.class | Bin 0 -> 3630 bytes .../base/EditPreferencesActivity.class | Bin 0 -> 845 bytes .../androidlabs/base/HttpException.class | Bin 0 -> 503 bytes .../androidlabs/base/LoginActivity$1.class | Bin 0 -> 897 bytes .../androidlabs/base/LoginActivity.class | Bin 0 -> 4616 bytes .../androidlabs/base/R$attr.class | Bin 0 -> 394 bytes .../androidlabs/base/R$drawable.class | Bin 0 -> 514 bytes .../androidlabs/base/R$id.class | Bin 0 -> 1523 bytes .../androidlabs/base/R$layout.class | Bin 0 -> 804 bytes .../androidlabs/base/R$menu.class | Bin 0 -> 450 bytes .../androidlabs/base/R$string.class | Bin 0 -> 2274 bytes .../androidlabs/base/R$xml.class | Bin 0 -> 450 bytes .../securitycompass/androidlabs/base/R.class | Bin 0 -> 783 bytes .../androidlabs/base/RestClient$1.class | Bin 0 -> 1179 bytes .../androidlabs/base/RestClient.class | Bin 0 -> 11289 bytes .../base/SetLocalPasswordActivity$1.class | Bin 0 -> 963 bytes .../base/SetLocalPasswordActivity.class | Bin 0 -> 6188 bytes .../base/SetServerCredentialsActivity$1.class | Bin 0 -> 987 bytes .../base/SetServerCredentialsActivity.class | Bin 0 -> 5600 bytes .../base/StatementActivity$1.class | Bin 0 -> 1163 bytes .../base/StatementActivity$2.class | Bin 0 -> 1970 bytes .../StatementActivity$StatementAdapter.class | Bin 0 -> 2358 bytes .../androidlabs/base/StatementActivity.class | Bin 0 -> 4876 bytes .../androidlabs/base/SummaryActivity$1.class | Bin 0 -> 1358 bytes .../androidlabs/base/SummaryActivity.class | Bin 0 -> 2785 bytes .../androidlabs/base/TransferActivity$1.class | Bin 0 -> 915 bytes .../TransferActivity$AccountListAdapter.class | Bin 0 -> 3164 bytes ...ferActivity$AccountSelectionListener.class | Bin 0 -> 2217 bytes .../androidlabs/base/TransferActivity.class | Bin 0 -> 8352 bytes .../base/ViewStatementActivity.class | Bin 0 -> 1559 bytes bin/resources.ap_ | Bin 0 -> 50997 bytes default.properties | 2 +- .../securitycompass/androidlabs/base/R.java | 105 ++++ res/layout/loginactivity.xml | 2 + res/layout/summaryactivity.xml | 10 +- res/values/strings.xml | 3 +- .../advancedencryptionsolution/Account.java | 68 --- .../AccountsActivity.java | 129 ----- .../BankingActivity.java | 137 ----- .../BankingApplication.java | 511 ------------------ .../BankingListActivity.java | 129 ----- .../CryptoTool.java | 230 -------- .../EditPreferencesActivity.java | 25 - .../HttpException.java | 28 - .../LoginActivity.java | 136 ----- .../RestClient.java | 446 --------------- .../SetLocalPasswordActivity.java | 165 ------ .../SetServerCredentialsActivity.java | 151 ------ .../StatementActivity.java | 231 -------- .../SummaryActivity.java | 86 --- .../TransferActivity.java | 323 ----------- .../ViewStatementActivity.java | 41 -- 60 files changed, 116 insertions(+), 2842 deletions(-) create mode 100644 bin/FalseSecureMobile.apk create mode 100644 bin/classes.dex create mode 100644 bin/com/securitycompass/androidlabs/base/Account.class create mode 100644 bin/com/securitycompass/androidlabs/base/AccountsActivity$AccountDetailAdapter.class create mode 100644 bin/com/securitycompass/androidlabs/base/AccountsActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/BankingActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/BankingApplication$1.class create mode 100644 bin/com/securitycompass/androidlabs/base/BankingApplication.class create mode 100644 bin/com/securitycompass/androidlabs/base/BankingListActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/EditPreferencesActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/HttpException.class create mode 100644 bin/com/securitycompass/androidlabs/base/LoginActivity$1.class create mode 100644 bin/com/securitycompass/androidlabs/base/LoginActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/R$attr.class create mode 100644 bin/com/securitycompass/androidlabs/base/R$drawable.class create mode 100644 bin/com/securitycompass/androidlabs/base/R$id.class create mode 100644 bin/com/securitycompass/androidlabs/base/R$layout.class create mode 100644 bin/com/securitycompass/androidlabs/base/R$menu.class create mode 100644 bin/com/securitycompass/androidlabs/base/R$string.class create mode 100644 bin/com/securitycompass/androidlabs/base/R$xml.class create mode 100644 bin/com/securitycompass/androidlabs/base/R.class create mode 100644 bin/com/securitycompass/androidlabs/base/RestClient$1.class create mode 100644 bin/com/securitycompass/androidlabs/base/RestClient.class create mode 100644 bin/com/securitycompass/androidlabs/base/SetLocalPasswordActivity$1.class create mode 100644 bin/com/securitycompass/androidlabs/base/SetLocalPasswordActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/SetServerCredentialsActivity$1.class create mode 100644 bin/com/securitycompass/androidlabs/base/SetServerCredentialsActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/StatementActivity$1.class create mode 100644 bin/com/securitycompass/androidlabs/base/StatementActivity$2.class create mode 100644 bin/com/securitycompass/androidlabs/base/StatementActivity$StatementAdapter.class create mode 100644 bin/com/securitycompass/androidlabs/base/StatementActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/SummaryActivity$1.class create mode 100644 bin/com/securitycompass/androidlabs/base/SummaryActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/TransferActivity$1.class create mode 100644 bin/com/securitycompass/androidlabs/base/TransferActivity$AccountListAdapter.class create mode 100644 bin/com/securitycompass/androidlabs/base/TransferActivity$AccountSelectionListener.class create mode 100644 bin/com/securitycompass/androidlabs/base/TransferActivity.class create mode 100644 bin/com/securitycompass/androidlabs/base/ViewStatementActivity.class create mode 100644 bin/resources.ap_ create mode 100644 gen/com/securitycompass/androidlabs/base/R.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/Account.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/AccountsActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingApplication.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/BankingListActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/CryptoTool.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/EditPreferencesActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/HttpException.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/LoginActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/RestClient.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/SetLocalPasswordActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/SetServerCredentialsActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/StatementActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/SummaryActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/TransferActivity.java delete mode 100644 src/com/securitycompass/androidlabs/advancedencryptionsolution/ViewStatementActivity.java diff --git a/bin/FalseSecureMobile.apk b/bin/FalseSecureMobile.apk new file mode 100644 index 0000000000000000000000000000000000000000..4a5847733fbe677d5e8921537a6df79297be80b9 GIT binary patch literal 74854 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 z zbUbE&hh|etS8RiNlST@o2x%mSL&B!5 zy?y`ikbx#1`L+u_UQO0^n--2%EF@kZuRXNvQM^ibi0g8_XKzCaW#|gijdr%u?d2$5 zgKkO4$jI1K4TwoaN93jgerKFHh-u$26!lUZT7>KbSJ(?L-Js)LKgIn}%p=AKOVnz3 zlNb=DJ)}QZ2p(-zrd^9l6D7n6lLpRuP7Z&stK(teAkq&L7C#qx$QRCFX=1D}RzI4j?}afWW5aU)qt6{MmL!+ZdEtHZKU zZqRQJ7#|T#solA?4L!OSm&KPhMSFp!Jn~>eWy-RE*_4Gz>W1i4BGCk&$2jW z0pw#zD4#17Is(1;^2Q&2eb!0^SY#Mu#$bJQ4p=#UVT+SJRly63uCU{TD5;kH*~+4d ztKM$Xjb|{pW~O1VPjXnSO>R1E+=I&SdCx^6@;QnS>t`a9M5z?S6U(%}*ZLxJ;bmk_ z$=w9ONFFqQZ>;6b&|Gu(mL-|1?(nvEO9f3eLMCwB?avhYX_cJtX3R)sbgR-iL^_#b zUPfe9MnRtS{#DG`Si4@W5A#SHQ=Wy)#WK~=6UU3lwK&QLVw%+lHF#c`=WE-T%Hk18 zgKOPFw%FkBgHZ{bmuZ=LB7Jqgx-ULlQ

Bby>LRgsN7Ve*Uu|I_G`wN;D+CdBQ|2 zQBAy_6P)8<*G}%)wNY$GQvUO`E~GI?QD4agDK^SSNG+wp2+nXMaH{vh+cEt@&R70( zK&@)_hiWn#W2@soyr5s=v`#b>(`M{{zmZ~6>2Ysp>QDcowh#KM#mSWu;6ZiBG;!>K zl8I=hSs&M8D62hi^`^py7<=TvnNDw71u7(^?7<*dbqiz(_qvGp?$#Y1D;KC$vaC&D z!)p*d>%H?Q9>^xsn*k@;lqSZ>f#!33Qr4F+?K~XPWN5-%2-Sz}%wd!KbWv5*tLt}# zrsm*rZ6Tph9gmsqmZba-0d>wB-|Yj#S1#X-K|fg-K3)Cn6G#}%V@)N(zGJ2Vd!$U} ze{|1(5TrVJVW_U&9$ZtC0MBc0b$)Ksa{lr6$W@&fGOB6)g%{(_9BZxHCL>j4R?^&`y-BDiByDM6{Ng}j&73E<#36d^rFc)iU z>*1R~6C_m4>7Ja*t>bF)F;VlM`*M{I#qKubN6e~(}OjDG=Ab04YQ>RqryG%_)>FjvVT2QL7HOvVWV z@z*r}_c)vcfPr{(Yhp?M=gR;2!bY4}IDB?@w{++HV(GKp=^LQ)?@sbL+uwRbn&%Y~ z=4VPIyE&CP6h?MnPg<=N;Ef$s(wkQbRz0Jke^60SmfoExmmOhYk&@h)lr7wI~YOjCb0wO)?m;SA*c)~`a$ph5hz@it?N7l)#ZyToQVrguw^Xdg>U@MPC@o}jxMElxXpgUNNhti7Gyyh%1xN^N8s-deN7i&UW7j}OXc+k# zsT&{x(+_hZEEj^e+4k zq(_Wf%u|6=yi*p~oQe)02H7sS5r($*ZteA&nwh8zz6*s9k`Nl=SF~&KFl(tDvKVR? z0T&u>WDEf2n$;TjDbgwB8uHq>)Q;XB>I5`OkO4R8bY+Kj=4!G*jQy@gx| zhYC3eqXVx4xdT4{?Taa{Fp?$ACm+oKhaKG`RsF`jy0|&c9c=C}l&{2XZ5M^Tv;dG!p;t1hA zBD<_YI;3dLFkB?KF%2+Kf-R-kYEf_TTmV8yVnBp;seJHn8BUoJT5&g#E>XwO(14aw z!Wx*PXgkOw!4$Q4b4Up5A)TPc0pgLkkhqX*kez|F0EBfZBijH>FcdT31d;>53F#U+ zJa_+Ep(A_=$OVu@3qpNF9&GzwO3n?S zKvh8|1H3^rjnsv$mQn~y4E>Sn7WtG57Kj~yl#j88dWnn%lnK^^G3LL{!2b)xTvJ;6 zXvTHQ=z?=gcxsO@`Yr^nH^-Kb!-@_Cx+4(9O@Lkv5CG012?7^`AA$!En4AqZMWO|O zfia78Z22sRQt@KY-UZLY%*`+-a4ONeaF5VGAxQw9@gf%AJ4q2v;8S4zr`O?!^-GBp zpy?q~22(=BVNbB$|6w~wH(&#APhtX>0wo5?3J@J!4D(wPF%vzdaKS;ileo)&K)!;x zjQ$b88_c}Mv-aAI#f89!!iUg@_?BX@1KSh$!Hn$`a7yNabQ(x$kIGG!fijB5iDrbD z?g2s2gRLR@5W!$mAQ(-=k>xdx4svubK`ojAx&siQX#hTwIx-iq1}KRx0gyl)h38Yj z@KcaTVRA4LL^(LOq^I8bYfiTUFm^h?U*ymKDSwUGOwff3;VVQwG(MyV?BbsKBfx_V z@q(2gjRBdFbz#!^IGURfCA0S$*v1&fh%WFiFdgv03{wN24`H9T6BvBJ&t|Ux>6vTS zM8*bRv6WoNi^2Hm@oO^(IUx+v|UjB$egt24nL ziTy6rGNU$>C{4C!O3uIzLmAbi;s&3)8Kpsy+Y?1wmYW5|T`FTLbYDJ$6UCFIl;uMw z#(}g3cF!r%w{SYIsUJUbV4P-xwdix$N606@6Vz*DbcJK>6LdVJa0na;|8xZn0ci{| z6e?62G#Vhyb|>Dc&?(9(<0;80-zm;1`zh6_7@{+vM<|Hql;|{Y&2kML#)dE`K4SEt z1xli=0D`a({y=$)daAqzhIm6vfp7$tyHQurjpyt=fo(uJDervr31S2$$&^ehU%uIh zuvU5~>^+=`h*3RaQSa~(d-@>tBzyS0?n(B%{aQOEBa_Z67fuPwEAKTP^Ux?!>;2q} zH@oN3ptd>rXecte&Hi^CQ$+QfT7yRT_ilx7Vi8qnRREqTT98z@;6C3ckpH>kdUcb4 z$FyTcMepnzG5K)##P;R%{w^|8W%!zDelL1&IqvSlz0j)OENauKIq23LB=p5zU7@+; zV>s>f`TD7Q+vCTaAShlpm7Xu9=gPduqe#z%$E{;1`QB-Jn+hJ-0XuKvO5nh+>XZ(Y ziP?0T-c)Px-A+BZN?f(6i*Nq2XkNfe^H0s>^`O$URr0tJ$Pdq&OF8T!y-c9;=l-}I z=w8{;@{?2Y1=_Met|=w|YE|!2P&}S{CJyyUa2t;v@&mQJ`R27mddaIf))8~7{6ILpEvm72BF&;c_@hHJ19387<5)Rms zR@j1z!{D*sFK>DfjY#X{5_lFBxC=1D20JK&d&r)rI4icxT$(ttow335DOeXRpl$Wq zq1tecK*>;1(7xm2`iQpg2;tcD`p`(K_)3u{v;uG3Fc-_z4EsXt-Nd@GLx2;g0FUM8 zvuW`ikb33Irn^6T(6n3ec$TAImtnke?5AjuXJ&&<@ zKFZ5#p9fRm+l;oMgh%(c_#O$+kPpI7t*r0>+nd+>GOF?R_lZzMBGdTHXWePAa$Cv{ zhVGbdlG6_`25FunYn#gSc9PeR!2IGiYRgQ#4?$de8n2lb`Bl;-Rhq#RR|PnV(Qmb< zRECpuwrPVO|4C2I^5cF5)9i5ZqH^S zQF`($^Ebb$%>r~^Nmbvr&1jlGv-;nqmMYiurJE`ky1$zlRIuO8S2cS)U%5}F+HB|7 z2%WX@tAftj`gKB^?d}~_o9*wZRq^foWT(UV0u83+`2tn6(_ZfKxq{QC4a&e4u97Jv z)X@F^RNpTb%E14W1MN=N*@qkK?JEBAz-_f`%^I|*RTum;!~3a(62Ft|{L}t}&tAJN zYY?;T2saH;i|9O?g}C~*-5!_oQk>+LMtVkqKCHuiVqs(6Ltq`IZ~=V@0TNO z!6FcUbictHJRkDFtw2gr<+h};nX_FRBlFst$|>IMOU^*})SZb)xALy{{v&73Dg&s8 zFa0AnRAygMadx61$s_w>zJdIK%719M2MqCp(oe3EIq)Kn``NcWQ z-hmTl+CLb<(QG>@i>~5qrKU@vY)m3R?h|%zNQc4cMTioX zqLGRy)3Nf6vfacRMbKL(*35*TVVtu!lsG}x`3E38?A6sZYXX^KT8hal*?l)7`ixxl zcE+$gx;wT#!#f&8#ig6UsCsB>%}6hP!L+lFp-@K*ah8l+IdNPGa$~tdlxd}X^xomg ztE9B)8bOB^V`1M%6uI7)tyy!GuO51I&)5rBhg){abL;xK7OORX z7;s*DsxmvsUrxeHy=du{7;hfSjOHiBeeXtaNKk22kVNtmZXTNeQK0+)enal}J&*3Xm2{a$ zrf|iRvkQmwr;Ks3#20;$mk8}XeECQDh#EjN34_1 z_!ZAh@y=3@#(n6Y$8XD2g#nXG-pXtt;XD% zQ=85^1-U$0M$m@cs>hY?+FhS_Z&_O5 ziJbgK*K+LcC0i-zg>nSMkNIx_`@z6VbQmb}rE3Qfq>fwW)TTZ#l?Yc(xeB4LJB8~~ zr7yy3-`UqfcWJFCk5bmLy-Rnis#a`Uwx^4YWG2j~A*2GA$-CR4I`bDD0Uu=*gDQ5= zJERv#wJ#R=y3xk!^`ZLexwCc>vq=`4&J&MDZx~k*gY>M;v-xL*F68ZtCsonE?u+I= zA{Vu+m8WP4yr7@=8dU628!l_B%|1vSsc#KPbjcE}F$9Zoqc38I(cmIlqfr&7XBQXody+v!2T4{>jRn zNc25{BJY0}FnvFX027|nn=A#55uU|=+a0z=Zg#Ku&7j+49R?P0EO5BNf(NXl=~|Ms zs=kfBzDwV0Lt{M5glN?-u~($#Uj9ti$W6Xd9MpVq39lciT2X2Jn&nq1fhMUOmm2OD z!DGj9kz^|SD5zzpBK%^lFdMz7h>MWKf3J6}cYk7?{mIs0NKIlh6nr@TL!!Q4y19kS z5eGmBe|JaI%W6Z?thU$ny1whPXzH{4)BLF+{mP#ut^<1GLwZZ(LHql2w=kJme%F%v zo34%wZ@PHVj_NTUXO^u$eE|+vLDAMl&0D5bD^>3<@ddWfwq?4-&X@H67^b=ZQA6zC zzu8f^bL`b^yq)^#S|Qig#bd&G{;@-F?e$*oKIbM?pbjmnWt1j8TvADG9_>UOW&1k8 zKKgAVnD}lYS94F^?>o%_j_hNIrV`#=C|2s@$h+P1oMEy?u7R91uHwAeqo0@VAx9;a zy-sts^V}s(pOsFUPjrIpD)RDPe;E-f{fSYTt z;*0k|^3lByW9ckFM)B)zLIP7;Q6=hfx3>7^)%L?E%vi9fHilp6@0e#&TXRv;hkp7v ziApI~T`5`W$&JAp(GlrE{ zdyYeFWmAuOwsDtJnMcLq8A_`UeEXoIeYjFFmzb*kz{0e%hJ8l(z=UrxD^K{xcShtK z#svdk2X=4Ow$x7ksQ=XUNqnTp?$0}R!toJBV5b>XX$Dvyb=WYhvP=M@oV9r&ejUAXBu_jhWp#( zghch1;~AVB{Pup{%ZB8k`N!E5)$GQR`ba!mV)CF^)ef84eTN^sw#0`?0br<*$SK=nCuI< zb^ZD1_l!;HJ5cRGDg44GFf}pbvWf`WhbErQ)U-b0@3lY#kvR-9e-;>zGZ>|VI>of3 z3wW!Z{ZdR0uZGTfi*)-X+|w6A$c1xk>>CX*YRU%h-Uj4a_F$T_Y?yG)aoLhly5dGF zPB`W59f>*NRG|$`r-UihvcV-EVFTV1( zDaoepptrVJ=Jg`Zsj^N1HSLG8N?Ti4F27wH76^<(+$91uZ8Y-{R5Wf={Fo)qN&R(cD#m`H}aG8`x z2JOS;(B*@`-{$V@Zq>5wyg5~t@_Sa75?|XLCaj><3iG`>o5Nltl%>ZroKsn#59HDq zh9{)YWg9xVW@_l_wT%v?8M{dwUAm1voCnlzeH_Twf_|PdsJCVSPADYMFLSv(nPh6L z{~RwIP987sT?)7K(=40EJDi2o_sg9|SgicZ*qk5B5R9w);}Pq%Ev1h(i3P^Yk@JmH zQ@b&y5yj6zwof<92^QCRuKVP^oVGgbf9KHruYtbVW>vXxi~m}u!9YIL(EQI?PW!)= zuZxaK_|?2UBgMxi>)XVFD~gW_B(F@iOE2)~;UsT^AS5P9ZrCFA9-s=O0_8Kw3$hsSuIp_4jzK|Xyfon zdF202uYWq0^^n*qf6TC>DusO!=R+Qh#!S+Ke^x-+shR9K`_E^Y`ujw5hm5wro)vq50xMf)%JS z*1ZlKoL%b^{BM!sF^)x3UJ8a|3T|KV3;RAf!@7Nq>7(FJ$z{nj#M{YeNj$a2?s z`X*>dKaJK0PBVgkc__iUy0u2bZ(aB-F;&ym-z3QXgL4Ze63~$Lz41h%UcL$uX+)mm zK-(R`=SMV$N5$>A*zb1cXzZ&_5{)ZVsc#nka~kZr%DHIW_)s$BHCuEB{=NmD(b9Ln zF*(Ij{0Om7AcoH1n9DRCe!aZ}YjL_&W0+M<9(R_j303p85WQ04Uam zQQO(czzZcsB2gGwV>h@|-w@YDF+}Yyo z7RK*|bMvxy)lP$?XYhRP9bS-F>u~QzSVA(mF?oMux+uXo-QL&4vznE1x&ZIlQN274 z!FcmdOts=Sw6T0dF|{pU=HU77Q;`va0X+1fC%B5Znj~@1%5@&^{nq=sQ+(;Xyi=-n zmm0q`qARX%-KL-BTh@ok!8t9^|nDATb?Zho)RUweFyeZ|{RY{W^tN&k2`u=X2N;#H7U zO{4l6kNtYAiB0A2Wnz(Wdn6e*IzQ&n`3Ta>)z#tE%`)hSx~5hZHhgMcU9AYR&^ywxMpnCP+79R$ zqqEjgBPQMMpkD&Bj%nsvGF$GR2i!$1!Tn@&w;8rbw#f!h^)cLI#>tYiV%`p4vGf`% zL-dkF1vgB9(YZP8J&UXvMsI!4b~L46JPxCL{kQyxV&x<44B8_Y-Afm@byT3Rk&V6XniTn<~)yhDZApG-#as@G`=y|ZEJ@~wev9m$hjD)K|& z9p$&r^ykV!SsddNzF@Cnq3FDSid@NiQT~6OzwE;0O~o2@wt{g4$^BDs>Y6NTao`DV zzA^RUa<7!WdDD$vS`LjUpV3hs$u0MfpO)JZGLti(6ARD8Vd9y=Jm%z-$^Y+lmS9iElm3G-&IZ05tVOg_bK=q}YA z!}I$m*}<(Y57J5QbQX#H%DlduR0-~%v-rtJCwB;j-Op&mWh9R6iZ)dEMJ9f+)8w#} zvW{@buVJSA@&MRq>cum1?R4v;^x$2e{AKm+-twS$J7+FGWYYg?XmV`p9B+`Xa1vjw z*ZK{UdM!#c&olcW=kRNp@=t0v=!WUNdN1^I!C&saAJtJwafQ>3JO2DOHdOnY#i!;T z_jG>%{d$YMmgSX`;(YE>#38e=x&A)kVy1vO==qSa{ai9;?%Q_qW?emTr@6!H|{&0n*OowB>B-_4gRHtgB`18YTshDIrVPYS_J-lH$}!ai|a9V zPV&kE2`V;~(h#w`v9j?--rVQA4jpDA0Qxw@4cc{ZoV4`glC(z)bA0ugb#a4Hf=$D- z^AcQCJ@CbZsm374H18>GwHex*>jn$5S8qitymeSuaou~qw5BHme@S`~9~z(W@2Ok6 z@UOo6?xt=K@oGH~nENJgIuM^N3ICZ8F3Y}R6TOQeR*xreiDd+tAax^uo0n=qKE&b| zEYImU&g(1w`rSB@``gn&%M|!YnKvyP?=5>RRhgSY+F>^pTLG3yq^DZ($>N(vmEg{A zY@Pzra@Dc)dU{gnUrKp#TfOC;X`C9paogHk{;u#xOqmv*=$vb@q(2a;^%k#g)+uqh z<YV?bEv9l-_pM3gSvC1vu>9^R_WDxLU_W|!j>+#Y=NW~`2prc8YVPG@ z0Bh&7mo#YFVyf0L4wMnyD8&J_dK2`PRoCD2TJUkKQXEE zvc;-Q-`srWmsfDp2+^J|1qo{4&-%=Vv{uuzR5}|<{OPYY|B3Z#iOqLv$76i`?;Ynz zeW;j2;fSVI;stG*rR!NXj^@yrj-UNZ_|pD<*3mw#N-;bz^OEEG(%W$VZeG0$WLTYN zzU=%GpbV04R58Ns&jY z`XeI{85SS0wFKUlx?l1hY<-E#exNKOE8cn5jTle5xKmwZU&V3qLO)@45iNH0J#p?^ zTE*bVfV938YL7jcQYqv;I0yb&k_Ut7V( zx%Xwh#X_`%#W^+BtJbNF{DyjHLQ4bHH)YPfgULs4K#31BcPFa&g+_Tc*u(%xeT8|F616x5=!o8L_=kgJwK^d5f5*PhB|BuS8qsMRbP}IX}L)b zI6t?V1pC*d@z?ICxwbdZuMlcQM~ek%qL>P334k1i)&ieMd~OY`B*efU-pz*d%tm28 z*?f_J@5%SZ4<$2w>;R{^-q9rUpgdOAKZj}=cbe>K4Bc?Fx2$(*cT+ZQOC0*HG*9K? zf6Ci3&HLRgJhaMur+4SgJn~X;JpVPH`lbwSb|-@V&WD94jVJ|G z{UDP2UvmZ1DI&4TaZ@;mdc(bcbe;Vnxu^-N8HNWqK^J0IHw2M< zaKAF2wrV6+)U1_|y&3k1a}$XiUk^A?4ffW33aGx@4?GAA(Sy@Y=IOyrx7t;c6|W*2 z>A3ene~m6ARQI$+*Nw0MgfFYxyp)GI<>PSeRe}1IGB+hr59zM|qp`C9ZlhWDy)lj% zW404BGjq($95XXBe`a>f3^B81W@dJ5$1*cBGd<;=ci#v1+*5BZoVcXJCIaf`1y0CC1|(7 ztO2sUE;AWN)PX6D@$wirX4edRK@5Q52btg}3>+c*lExEu9flOX7vIY3H@~qvjj7(D z6~IYmEk~0QvXTDPNSd(5Ie2NKe21RTwPk&eow5&=S?Cmx%$iSdTl|#Io57%fe50rQ z)v8`4H>Pt*eyuQp+7cPTjGBwY*vwX^$eFsC&o_qZm|9(I;+*|>{f_2OyElUxYw7r7 z%LTXBNYM|nJx|vRgba$-GXBPIlIXkcw>8o8gFEi4YdvRrIrxBOgWJ|3zPe_%v~#2# zym;@baibbOE==3ahK||#d*9t5=;|xL#naC0TdG_1OMp<-ihPM%=Xsl+4~Jd-z7pK8 zb$?yw6rKZb@ef+66k2nVa<^(6Lr$9bQ|I&FPl{N`e*bkMA{FjJ9XAkK&SFbis z!CmlOe3rH9efKAG2*t$89ozicXZvPX7T^2SJxIHYMLsol_{Nd&cp#yeE3l31SCvo+ zwj!Ge5XqiKJh4PO=KWrLZxIfp z4id=5*`@V3yATokH+;>c&)O|ey4v>>uZ0!SUM~C zn!{uAYOUPz)^asoB~YPZ79|uTwYo1*JSlz@|2={#EXjs-Z-{jKyHkAEn1(mwt@hNn zF+Aj=E&=_@*9n-)hIiXj^b%%6n96n66RGEkp>$F|y_r3S@uxtb*L-lV=lN2ZmsRcA zn&X+)x$}zs#e2?uP37xqOyJ$?#xLa)nCDTw0^>2Z`5(d(dK6Q2p4C%7C-$ivafM#v zw;*4oBf9h3cC;+c>YHXFf_wv;2AFLTn z#RaAk5ZncMb2s$zfS*p~RiQXj;R9X;cH(vOcxwB+|#-JluGG>v$DOKJzO^dbPW~ z6S4MdeKDp;n6*FQUyiYcK0miqIoly*BWdVjf$~Z>wVd*>qV_qTEwHO8Okq35ztgcq zb~vPRE8W96QEG|d8P*j~s>CW@Ds+sgu>ffbT&c`F^r;^$JM+RU-1B6xX|cYbfXapB z-6}KfSQ>36d>~tgKk}7$)diY;AU_j)7S|^)f?3)_^9M&vo6L|ojA?*Oi&PbE{-b2pJo4c_ioiMJtyY15|LRQfApORxT#=W= z7o;@qidiI+i7`b8Abd|TK|szop`wJ6ooJP(-r0iBR`Tzh#p>RT)|diYbYIJ*&ZLt} z4|hq`JuPJKW^ASYb*^l@d9^qlNvwaG{X{Y6g)8*7Mj@RepGco+2^1x+e0il9o7DA^ z@R^^d@b>ZH_k9j=gRwn?#*{v<`hEl9Myx`r)E3xb(be6Y@lYwZM&mqdF$v*@+`NXg z;uWWSI02=|W8k*5%IElY-3ivJlItA4o*G22x{}bo9N5u=urq@CsrrG$C4zKHrQQ2x zU6hUD{c5T6N?(%IM1wuJ2M3+ASZK(=`Xwh05C!1jBEr>8?; zEuXu@t8YpnZovIXoD#v8$pG4CqoEu-=j7XLL?po4YN_iQcz;%({9_G63r@#zl&cwT zepGhBna@>n8wn>g)`Lh#Lr>D*C4+`)0G9604zU$xWk^3(?bbPIc|@ZoXy zf+=t>@SFETY0rl|NPO2^N8GcU;OF@2v-}hYe)J5qLsnRiG~xGad)fs*(gJu-y=@Ia z{&FkVgW;R*eDObQT0A|2UtYbpa?=Bzb+)g**1O(=E@@*Oc^yBGzEmC+`5$@B$u`yl z?_(aH=PDuRI4bOLN;-`?JbyeTvnju|JWYZ=0h~uvS+Ca>Q1F>gKSbvi=vr<4d}H5s z$2)iSw(ELthbZ$|{!Q){X2WNNel_Lvj3994+NbDx7gTZhmrVS09@g}f}@?fI`@`svtqu@(;FvJMR{7`$77+-o=~ zABwg(_7N|)E8PRfwvp>k!Xc5QQS=JIDiu)2UtjODNo*@#x-XH0lRFt4LPA-csb1@;I=EqcKZ8B^=0` z`W3is%zR(jM=B{T<#z+)nzE6qXH^y}okS~^E9{XFrp2{2N1_i;i7&6`TEdP|Fty-C zl?nPLWG*gdL5vyIpAurYgQMhXyVxQ;MIaTUXp%o_Pr&bu9eypDn2_(?-ORMJW%UmI zV^e~YDW+e8xtqO*G&Jgvm7g$TsBcw^k zN?6wJ;+DBh_uj2fmb$VfTq-$Vd+>20?44*TY)!xAUbBo?1=GZOnsC;HwASyJkQ>V( zu)~nt5@8y=_3ImZaL%M=_nJ9qX=U`?3RY#pabKxy2@w!2XRFEF6_`WO$sr(BSPb-M z$qepTQkP_M*xj|aMo1=@PUUfrP-Q5a#%H&6GqUl`WU@4q!^u;2;%2e#s5?uSYjIRtxwKg|DY8V| zM3|F_0<*U{^h=OyEsg-Rrv`4=Q(xSNGcpy{D8Z;k(ESq9UnW90Ip1buWY6j&(k)zO zA(O7DAxdgP;EJIkoL*{vMl>q$Zt6t{BC|c@qf$C>#DwQCk8;q(nOAD-e72Mw(UhSW zx;dPs*ye_OGL-?4J9)aWwK#ycrDuNJAS6s=8B3Qf+wQqV&Rir*4- zU{4p1lE{;#qP4TIg@Xz5ilmuCJ~)S!TEGnoA+l#34sl~dN9T6FbDd%zWy)Ygr^p3; zU<*CD4b;TZ#EB6lp{srK_8PDMLLn}@PufyBQY)=ISMcP0H&2m?69t9W(j8#TjVVEO zPuU!#1?1r~v|t6I$t22!EN13>lE1*DR%K35H)Pnu2HcvxJ~ot(OH2BKqxF-hkuGkdWvS8!%1Yge!IMM&%y8Q~NkF9l2367$8Kym=;FoUQf~*@tEl&L_eNi6`nYD5gD1^a7^%q zOuhqZi|}3@%#!a}ZM(5?eN7){)ecya?b+ILM-&Mi2OA1^@q`1XXy@B~dqf~SS$1R+ zIQj$1e^E1D$kYYl4JsU_k=rK2cl%AhVYZNFIy_#AAUrXKfK<^!=IADjN_G&G>vH+) z5-;}kw`wx4QIH?)SfXeYPC09}KC9nf(A%+PX z_to-P)-lV=Oox7Y<2cKKxK>VPcHJD4JkAKR??oQU_+zf$pF%{lJSH2Hll85mJC65# z@-xk>TOd8(tpSdM9OFw4kh~##FXy92)m%K=(DgpyMkO!f%(d6{5va6PwjbF62n^yO z60Ah?oDVOz6Vsd(a|Nat14t+H1!*`^tfB_yURlJ`&UY5hL_Tt;0xZ93MJP5_C8m@~ zOJO<00>T?L!kUx`@*!nw4$3&&zO|#$A&PJQq}vUyGti}6=ys%&8r080$y`k~w~_uu zYMA?l_d3&fC6N(8`)F|wPb5#DD;>|{(`cjFP(#wl+?Eqz!&YR)%-lh=M!GKL;Tq2( zfM#c96FsXa7RWZsn@b8gJ#HK z96s_$#yn9%`+3VS~|+0 zPRGk{wy~`F^ebOy6c;IIujix4^zz%O;jwUy$RVkAuk>OiqKk@Ui)`{UHM_!yLGp=3 zkNfPnzLldhDf)A_hC(*a&Qf#c;!Fss5rVAw5Y_v+EByk|6Hj6+d)yG&kV4T{tJ!oi zEdk;z#WlrJZpXnwH{=-qxx_gom@S7e3S4=S0J>c0T!qU=G zxonu*18g%qCcmMDbo19M1w*N7Lde=8qX>Ah#Au}crLFKCf9Yb@&x9<4zU46wA*$j= z(S31?aTV(ReoFpn0%*Tk_#;!xN; zT+u)BXvJQg0bFa9PR$RLK`_UkLF~F*;FnmzB#-Xeoa-t1@=(YXvOs=Pb||gNl>>U% zt|ofanJKAVu`_1yCU*(1-DM-YSWGEGyVWinq;!4e+J`AZAQUwO$AKq@oE_2bh8bwS zuwk=(jCBXkAtcd|mD4VoQV5#8jAJ6kB)K%C<}So5l<$c%W}2a|%I?8hnUgD6S#sqU z+h0h8i&sziA1_eK#*X)c zLUIMv3^IEV1XvNH3NzV+lT)pn=pWUHhpk9Y;!TdVBm9EOKsToKf2}p%*FuY;{odyu zbi7%~-p{zS1M&ScGmf-jqUL97L<;?mEh0xC2Xr6mQItu(?_(wCkbF9CBxIgp6!rUmay665VMG z>5~fWd}RB9tVwi;B@GDBwydVY3irTD#E6G~hR|?#91UGgBpM-=OD7BTgm6vbaPhn> z-4>szT_cQGFN=(vH-J%tf$8iFcXCmysb+8y9OEf$$Eb^IYVI+mmZ+)jZy?n%Jjx?R z^N!bM{Z~1@&q7MW?60G`xG}8NXtLTY9saXI-;I76?a%D7j~7>^CJ;$~ zzdb@7w4PG@Ui%=4NrPij>Se;nU5;l?Jap_oy48e6Tj_8;kx8lk{cG*w;Ebvj@J?2eHb-?L6`$l;~C79}PHU~6&QPA-BZT14%Lzlzufd9$rx-ReAv zxu-Fz3qd?TH6HcK-dz^LXFql&rz{p1F^D`g`NMKLIzjd~r4QnxtK}yPI~w&a%;XW7 zt(i5BY+__+)>S2VU1 zcXH{uQHIREzM0U0weYyYu*Wq7O?a*7$@!@aBn4R9lHUZ>xHL2OdRr92xe=u0aMcf$ zm*j$K(-K%sTJCt*-LhEo>F9Zqi0le$_ele>mo*fmgsQ^uV-0WE1_Pw2i4iX>6NE0h zV-IdVPHf#EHPZbG2GpgfHL}D#Mod_uTUOH&m@un1^^wUcLyiUltC@x^l#UAS9TMk^ zl^KxNFM6Wk2DpT66M!5v;;sog;B#5b2Z)J8=f<$aGBJ#ph|JYw!w5}Z0WIso!vty( z!r9e@f=Ir|VONi%az2#PKsY@SZj&8^I!|S_g`(Z6YT%o__GE~ZP6q`(VDB<;AH|gH zKIoP_2jAL>Dgp3qLUzH)aWeq?OFowb*F;aFgpcx!_D=Eoyo5k_?I(5lVpI8N*0wrRntd4-7psJf=$9L>tkJ@3RR0j-=<2+fJ$oom zIKMBsnd}@4z-yz4U!`gHCKbX;n@UX%u0@UxZ7a4sIulZpI1|%iW9Z3t!DIyELLTKE z(l}LG#5vmerH!ctz#@m`3X7cSczk5}$OgVK+tOI+jYRvB7XJhdIaAj$(!1Ydc?=p-+xYZQ2`2HsUS=mB`PyV z*ooRij{>VGi*>YWwNCDem8H{NM(Wn3a^Nc)D_6K0@#Fx+4RlwHQ0cu6&#@+rPv`I5M!`22F73t>|u=L1Ob>w_Bl!?>5XoFW@tCDvwNH^U_{hdWP zH9zRh5g)~jdJKc#n!phD*^};)I=v`uZ~c1B~cu|FLl~+zr9{uZAUHJg*nj3MY0_ zREajchdHxq>^{Cp;|C*3t{%cDcmoUZuiHeY#Kxl;QimL##v1fn%>ALWI~$V1a-B$u z#*`HGYDzQ(JDIDv5j8wT)+$w<(o2Y;%=eW*$5EoYqX2XCP$2~#3Az-!lkBj0LsE4J z4ky#P(#Ej?NIQ1a%J1w6Bc{CQDFwp8)!$B;6D?9e<#-9f6JWO26()eAL%9V-G<9=` zY+r|EJ$1W3#UT~r^AeC@EfQYnJbI{Jb(7hs1BqNCCguxQG)l-?nOR}+R>+2fbrfiW zMvsI)O-$^l2%jYN^N;FB@K{d~vO}Gri#Pj}sw9-revf9?j%Oa`9rC??NF-T~b*Nvpq4wtQY?3jtwX( zVwta7bCk+z7EKu|mGw@tQ6IH8Z#ec!%6DAcjiOu09#7Y$69&eW0riuhJC|4WNVJl? zamNCeE>%?Sl-s&?Vyxy9SPa1^pbK-)FwDeRsT7l494GeaNwKa7!xTxhbIOQtcn*#Y zkB>aSZLRzIdwLhse>ioryFjWLpOR$WHozt{o*gHUb%b@!6k11C&pIwO-g2uFYbAJQ zQu8myE35g}G9fC3<6jmXP;2*DX-;oX0F&#`$!%#}6jrGobzfQeXK%>tj^lYA+exR` z=RpHgaNwKW_X{fhxBh^vb)h$CT1XfJEO$@@sy=U zD$6Zk3suPGLZ0UhwJ9l5NfIIA>`P<1Sn%b<&6GHuH)U9Ph-F4p6_8Al(h#(#nL9GV zQZI*T1t;J`4sZbpDaH-d7*i8`^MI3nb9K1Vm!Z(0eyv*5OMu{42#8oF+YrV)X5_Bo zYYR{=h`V*O!7@1QUuuG9woo@tL83DD?*LuBwfF;a#?BzEp{IbI(yt~T(Vk(eQIB=KxQ&UtJW6WS-y4e zZcgiV%Vwuh7-T{jqv0%JzQ>sy29kcrFdP}50Ru_tf%14Yd*fljccb<_($H-pqd9q~ zhu!)WZ{TIj<&VCs*=6UqQCeJlb^-ymwh9;S##GAk9d`7Fq!rs4!TcT3*_WT#Ut0Iz z{HhK{1!zQb6}8neZd%h65NLHyfXq-$zOlbYRJ6y17zH$Tn3j!RXfU~8u&_)9!JNpl%w;sRFWcxxF4}rYll;^ zL<5_&wMEdCo3NA^Y_~K609bha1#<1t@uC3j1m8{byvrRzW9K#RTU?SAr)o(*R`xKg zdoIZj1Wl@k3aleqaR@pW#E5FA$lnRtO^+AWsXeUG?g+`PXEa@<4z;so4A6&1!Uqfa zTqw+qTg{)Euw;`kC)`ElmqgGduqM#j%%M1bEf^u?y^;$>mZqL_q#8v5=(R-eVYgw2 z01D^KvzG-%bssbKbYg&4SC+HxBP+B)i~|4!qe;U=Q)|q@C31?S6#2qaZIwBVR^>4H zAMQU>-3VkOWw$vfAqd>3tv#nPhQ`S~XJc(phoYf3-X|A`KTI95FR;qt!cXpZb)8MN ztg^1VM)8<(+q$xc)3dpZ$~*)bG%$QGTR+Q0OI54?eoK8{kH<=ES6eY6qeuyez8Mo+=ijZQcI0|+Yz zVbFOLrkWO`CrrC-nm%|h^D*2POcIzbCn0kRc6l(P*QBqc>&{_w}?EA}~hNH|oIU%!mEXD&DR*6F)?O>KPFB!zl1uW~_Ncvy z(Fzg{o?`y7Dx~_5K|ZYIHCU}~t4I8-eY#xe?0`w)EZLT5ltQJ&OE&@o`zixxMqiQp zqPDIHx8E6KS((f=)?S_u`RnktrD<%4H2V6Y*%+X$qawopgFl;6le3Ydu@T z8q>Epig?U&;$~+x=A4)iB3cyd(+Ah1$c-l2G6j!OGe{HX;I9{YT*@r!mYf|rd>mV7 zWU(tqV&(*}BCX2zQdtSmd%q?->QEQFWW!QL>fy;^a0Js&?@!-y$aF)5`mF{+TRjpt$V)hl9h88Uz$CqXHnTB4jt{ha0@RTa5 zzHtHLf55`V=*#NkaA%!Whd-_w?}W$W7ZdFsh!l46#(bvb-q&SI)3eiwOL>ZMEMUnvY_56?52|H@Nib7&Kd*PXemVGPybZ0FqV?HRWJZL zs$`S%h4$>Nuvz%<6kFDFCL{KqZZX#+hL$X(Pv?>~HHRTz((Z<)rxvn57qt%#H7eEl zxwS`Sl6rF~Uv#FZSo^+(Nu1*=y?cTh5ufopMkYqd;|HfXEyFv0XRK`Kl_V_j*JGejv*qH}5PZ4=`Ni6& zAWHsV(9l(-U&Ro44bLyLG3Zh~Y$=B^l} zR3srgxVXWb{h5ck&X)cI>0^XU@$vljLXq$wJrnzF?G0bY^;hLSws6epb=W0C2 zlx@<%cQ+&|+-t#5jObxkT$h8^vDh9HdZUZ4t(aN%AIW&RBfS_U?#i@XEHjDyFeBE; z3cu!rIp@4X8r-*dOfqZ*TUak(KLpfNQ=Ck&h|RW;^Vx*8jFsJ~WFTS7^if0 zHob_FG?%1UyiI=$PPw=WRJdup^5JfV_#he_60x=7c)S;|JeuQdxc0G7W@)NUYB zo)cQuWEY!+&GB?PR2_iR<~h;n^_l$>Gp4R)b2Xz9XF;_plXfr`u`AJne%V$gG|mWwO`1$W zBxML>Q!^FotX(K}oxN7QGMiD9rC8HxOk9E}HGX68dUf!-H9Qth=> zW?1hvoH%9-HNK8}XW1R>9JV61^ewmHC1zQb$Csgf_%)&Z?4d4Q=qW8pth`HR^U+SE z8VbM8FDyEQ)X{09R%Mv&6~oIB-eseVaM^Sc8UeQ${qU`y>M>;$h|6T6pSw=B-@q(q zgn2bFUHM@}yhZT{~S z&X9hZ?fwGXYu)Q4b{hiBKfC>se)zwC6omBq)Z8Gx3X-*r9L{dvW5!|t2O z5Ap;n<`&NcX|@*fgk#ng*92+C78R$gua@(zbqZAp8DSuHng4rNuv^d6Y6F>-{h|pC?*ZBC2Q`KI(aw>>;ZVw?_u*&?z4yqzG`*g; z_vIDYcLv)|&WEk7$OML$T{nsD5eNszz%1I&6l1+3R}Q0hJV2A~MK{i%zC(L1gdz2q z1ZY1@XbO=Y0g;~lB1qFkgH#g4oYm@k@>gQRgC>?!xxVHG8l5`nWB!5RtI@*>-q_#B{_Ks#SxXP zZJcp=@PaQr^T!@4m^L_pJ7^T?LGBz;MRe#fZhy#*AzofO62-7PDYG;_9?t{Zynn8I z0XDg>h&7E9Pfxr}Q3S<3VF{5fYqby7Bo}U#etbgY#r(7-y|Do&jQ<_>(hXTwM}DNVvSLqXi_?ehLWq4r5}GjYJ)7+Z6@ zHyyp3_Ef+tCjF3Ix5@Fu@WU?~?Q)H}iFb_oryh_1QPgFY5U0-GQl50e(Jews7r{&A zTfQ4y%B3(=w2|AkVi@=tn{0W-CVE-cBScejZ zjRe)%v16E<)5wr(pM@8U;C3q?<;?-10rv5IL{qNEeO^8Kv%{jt*W`9+viA__x0^rQ zu{v7i9h(B437v9UZfal#%u-pA;b!f_Gel6|+dhdt z^Y7;g_{73qP zt>rQsx8=5+CpQwar6<-V*Wz}5asXiL*ui7<2EnuD6(aY9pM>}QXoah_f+f$A=%=`;f|4=7o7xjis6vX~D?zkW%uRVKlwab{@+F@K#k_Z91!#)`d8&hhJRF!!~j)}loeGGq?42rV~`b;lN1wGR-u;_t4xx%E9b-?xKDZ_ zXw5{m%z_Cnn4yga14p~^wG$iU?C;?<%upA2Eo5?Pvm(va}v_QCjp0KjvkIccnJyqYz&6!hrlv#+QzSPB-<6Q=$( z3~D5d(kfLvG^%w;8_&6$2#3LdG;2B6NTRWDor&**(}B{9=Or41HnwPL2U(mSjP?HE z%z+m4sJM`(#4P1;^W!4M!43xmS6=3@9s!t@dMIH+lQe&XMz&qY@gegI&l1qA=9|$+ zb$Tr1+|L_S+#N*&s)X`B%vTCII;BxgpDd*-+qAXqF310owh49nHB2E>thWyWZImV8 z8rKrDRYCxV{5`0~gWH;I=2$Vs(c@X4pA(Z+ES7w3;5yXko z!*;bYO=aHy8Up8+Gg#=j6$VAH+MqK$kqJd>=|}t>8B8 ze68;uv<)MSJ4KFs%B40Z+{I2a;p1H2JGy(dF4{WcO`}#t+nMc{pfBzo=#LAPJoeC1 zf|+4QFq?jUbe87Jea}!Mt|1h{s~1VI4RqZW$yC1A39tIzuIlz}7=qt_Wal=0tya9T z-2+&2yT(C3hKDZ?!1MU+s~8n-Z`kuZVHloTrQJdx~ume^|=ND(Tmb@ zVyD(F0{#576cDh*0zF>u1l^FQ}PG)yY!#Hx-$MKcrA?WA4I+eQcnoyGon{aK?u=uN* z4YAuZI)vDlF2DfEimoWZ;Cd{aGc0F?>AQ+d zQ$=B+6qk70Whjpnv~ja(s2iEp!tAFr6KJ{X+H}umoq?EEH(_(3upX#oV{@u6s#NKo zx)}!cb)9pDZYweeHP%T>H~HNdN>Pjk{9(07EzqA3-S}&sF2POdD-@L@BIXMOHqZpxpD}+hsjVN{c9R&_5q5 zGFsMxCbjF<*UV=ZGxH&}0UJg`!|WWTM-sR=nA)dTwdnKT48%9f53wcJj6b-xPdF=U z+!wQW`CM}s*U_L*Av8F$;brv+X_eJ<5!eL9v34;0aouk{KGs5NGO;!B=K0e8Ly^pB z_VwWChhdfz$>DO#%puebhpV(7VKhhz$X#htjN>PuaZ5<$jdhC64ri;QLcN;ooHqu% zk|)-hZ9jN>K%?%+xcIr{UI*h7{uG(cnYEl3?--=^`A^pxmgBEWwBwpoaL?X;rUv^V zHaMSiDM^D416U4;ZUt!{NhomSE(hPtynR6l2J>lG`v<)I2gqDqBKupKZ zfv8!BFeMiwC&v_s-d0C+-?YTm^#3;AL(UjlTMf$+`~eRR`@)}7yZ0o` zjv1TPm6?s5xuRjSy*^O-%{EZ!4-!CYysYWvak>*55zStgY^5Z(5_7}osLN>b>gPq5 zoYA)$xy(DG`Ngznv&n_+)Uf+OTtE;s!WM}JYqPlDM z#jWyszwCNzwqIFP)eqg9tuAgkH3x@yx37#eY1e?afHUj%JI8!2zBG2bd)KDM7qtxC zyoa}e04l6NXo?$mXo1#C(U*Q4_&1~}61!BbXLTHQekOD8k21&~?u=o0S$)2cQT#I3 zx3H!>w)yUcdBk*p#+80or?Am?!vfnCqz$ju(!ik5n7MSM#PqzSc02DWO2!9|k2|0I z$yGBYvX)Ro&0cA8DvNBgfBoc_WLF}`%4Jm(Gn<*fX{pSPxnEwIw~nZK%l^;j3lC~~ zo&o;RYe027x{Ia^onP<|;}XtmOJVw~`6quYuX3GU@ZX_%NG$qM8+0!C2ntUHX>bS( zusab_?uGO}~Abv8C}Hn6aEaT_D+hV=7nrr3nT73tB5_zp+O~m6^&qhniocQSK?qY21K6I&xtq56Llz&x>7j((s)tOgad2f6f@Hi!)dCTMHyXlG$8YhY_( zYU1Sl-vBr;xc~a#@1po<6&Q32WT12cZJ@#WOA7%d1jr#f7subJ6Ipv1PLx3@L>C+UCpEw=I>q^ruB!E&q=6SBw7p=>9u){<>iPEvWEkgYEsByuxn-{=4Jv z_4Hqt55L#be>PzZ@PE6y{wLwD^P%6%j6a(#)?Wz!chT|B-hVx1{hl-Z+17FY*&8&2 YQjmrQ9mB!Eut5(X=$R+M?}Od{0XOI7eE@AoX(NDd(o2-_i`1_crbC`ecWgvEqKasWxx7|4MHl5;|G!sf!N zxYm8Ww(eWiy40=KR;|=)ZEfvtdu^-Lw%XciTiR<|Z~eWWnfaca1oYD0*YA(t>v!Pu zeP*6{W}kWHnfcB+X^C&osi>T$vY)K|&B7o5;h%rL=G>jbmR>b=)CV2U#!sqVu=^>c zI+aq}S5Ga3=+DDXD)l|r@Gph)RIXC{pzjP&>hsXNBBic#lsbKwQscybtWt+AQ|i*= zmD;+Qw7}V57q|#~7CZ>P4897U2VVy-fmguy!Rz2H@CWceAlRcYX zW`l)b88{WJ0uA6SkOVux0q|My2>2%WA$Sw~8RT>*H3UombHQ5B4fcTj;6iX4cnW+I zybk^XvJ#XBYy{iERp3GJJU9qm2Csr2fS-V0f_K4t-~(_7xJl{L3pfYd3ce101+van>NqeToB?)#i@+`53GfQ|EpX3Mst8np)u0WW z3$6iQ2Csr&g5WON4wQrW;7rg3t^l`!r@?o@-@wq_O3edjflI*c;7RZb_&N9hOxdGU z477kA@BsJ<_yzFxDm5C+0!?5KxB}b>egfVH*-Y9fs01g2grT1K13@z)r9aTmh~J zw}LN%FM;R5H^6tn>)?Ix50HB?;|`nvrh(~THmC*lparypZg3vB1l$3h2R{Pu0{0Ty z2}}mHAP)9}+rXXRLGUE_Cin?>3;Y(imnu~VMuVxK8k_=71E+&#&;>34H-LM=21pW!KE+Z{a4o(KOpcQNf7l9kW-QWx0OW9IOJHK^NEs4uI>yZQvg82zU~_0A2#Gf**jl!QVmFl}Zf; zWneB?4LZPHa22>0JPe)!Uj^R)-ve)g4}fzO`UDh#v0xUc2W=n)&I6Z%>%m>%8Spjm z9q=>oSCD(PQlr4}U^-X~R)aX$4$cSHg4@Ak;5qPP@LTW?5WWVR0F;1HU>ukLrhw^S zKBxn$KodxTJ>W`kC-^cr2)+$|4t@vz1`4l5Ux5lx1r~!9;0(|Py1{v1Kez;31#SlS zgD-)X!K>h>;BD|n;9f^tfsx>NFcr)IHDEbt0P8?I*bV*z+zVa=Z-c)8=X&}Llz?$y z3YZNRf_iW!SP$C3cCZgz4(;SvK0dN(#13U`80$v2K zfFFam!3V(mEa`wKC&xBLhlJ!@)gUl zVhL3&iHfC5vD7G*3WeHNsB49~Rj5scs#B;Ug*s8F1I3h9Oh3hRQ4Dv*@Kg*h#c)v! z3q|)Tx<}FM$~Kj{758o6c5nx{6Wj&v2KRt_!F}NK;C}D`co2L6JOmyFkAO$P7r|rT zaqt9q5gFrsw4r>>> z%DUUFOqS&@gNj?yS!3N&28o*u3xBP3r*JR9ode_}>5Kau_%Z9=Z)GC**{lAfKf`+%LhGxZ;+$%dPuW+$*j7HQcMM z`wiTZrpUjS;XZ_0@)f@1>$@jp$VgxKaX-p%2R51Vv=Y}ZkGTE1h+EQG0u@~(A4xw6 zgfH$b)-5tUKtAH$s$E7#+Rewop1Szapzk1iVXK@8SVh-`!Z)`@QX6| z<1*Z>$Q0N#J2T|Z$#9QAK4N9|XYjAUU1<3?WbkjzaNnEZemKMZREE1fBmL(x_}{{v zXVd>d24DKf=f95IZ=bg_-0x+`AIflll;IArkoj$um*FnTaDT)=^JS#p{k&vs`1}zW z^5bw1vSpr-!JmrTk6VR%pp{vGTlDdMGi1~d>s|rhcb}HwmU&ccWzNdrOWB56zUVX= ztLFpZiyjmA{tUj9$LF`=UPAZ$Yne-9-6VTwU=1)=sp%c(>LMK8+eiG@OjQk|x{l?OFEPdC~-&*=R zOaEl4vOmQkSdJ z)}zvvzfz4+*@RcBQkA1=j>^^4q%)29b>u7bRZE)*KM{W=exXw>oo4CxEd86Mf46jk zjW^NK21^fEdZDEkS$c`3ms)z6rPo?|i=~fR`k19pTKXkRzYRT!a!#fkLQk~xLreGD z@bfLb#?qTCeb~}hpwo$e0(1uSB;pI5V`;agDNB1S-D>GJOSfCP!_u9Wo^9zlmY!?r zk1Un;l>DSUh5p0R^|m}0SSsx);nJQ$r9FjSY^k)X_@!NiO1lb`b`|;`mfmdXXDxle z(nl=)qNR^p`h=xVSt{*+GU>ettx~h}_?v})3gcU7rKM9Xoo4BYmY!tkuPptwre+?_ zVtjv0{bym3he>}H8Yc@nTg}n=%(3Hq4&&N^KgW*uIgEEt`^|WtW9P|StUj5y)iz$W zm9Mt))pmYVTY2#hL4F?ApTwJQ=>kh@Y&tbqivL47Ye+{7!y21z4H_w5`&X#~P0f5; zh}9_REuwu+p}sG#1J!E$+3fPxYC1?Q()>cT1e!zmX81Ym`mWQoQaugLqdz|j z9bn5f0IO;)@&njSo(j#k{Cr#90yS9OgnY!d$3Vu>1^5fuMV_VUd8z|Ch?;M*^gGZZ zH9~zKI)t7UTFfB23pz}dsJ)slQv1knIPLu>{G%B)($1slVWCl5jxkuhJCQ3Tg=df( zhedxj{$oh*5&Xws{U)@3r8-B`Me020aqN)yK+Du9Rjlb~OKa3;@Q-KYNj~FA=L*sp z&%Y}*W$&u#BGs_X=lK=nPq5`Zfth@a_Lr+;Eq|e=Q`9m| zbJf+F4psMPYQ~ksPm=x#%$zNnu2S1Itx?ZGC)o6bN_rD)J5Eq0y$Q7JeVSjReq-r7 znws<{*l{<(jyp+5#+^_ZcS2*9N;$;8Rnw*FO6Wv(JW}6@@Eh?@f{I^gJ^4&RpT#t- zQEM!1)pVA+O4B@bji%$(1D1Zl(uXX4*wRNW{i3Er)MJ_!smCqF+^!ps!esgTU&$0b3;nL4@Y&*`e z?KqdyKPk^#Tb^oLo@)3~o@!g3YFnOaJKm~oIYeH@olwcY+U8$v^RKq~OSt4;ZSxnu zjQeU^j(MCwN;&4)a?H2>`Rq={BDa9kNeN%TQ}kU8|HNOTcI$H1u!4xbt5H#PoTg{0 zGAk$ZM&w&HHRG+u)~7}pJy@egs(W>~(N`j0N4`RrSt|3R#+JW^QybBbHMaZ<)mgec z3vGE95hCSV#A&Lu<06~B@ZZ+{Me1EmYt(No{k^6pf02{?7TNq3+58sS{1&TqI{n4A zy_Q)25>9j^-zCh)8%a-AnVU5|R^6#-wq6H?FYR~=r@SJ63gsS0ey6b0I|f>7%U{cg zk@DAa5-ja2RNA)|O(5-COTObZHTtQRc_QmftsOVDww-HjJJ;HABkBK6%bEI$zslyj z)KaN`t*w8pt+&WM2fxmiug>OEXXiQ%y5SvzbMr`sa83OlEn@KwbBjHRE~beH<0rYSXC$20nGHTzJBx7wyJRMKBf zy5B)=jn$KDu`@;Pbn9=z$ecoW6Dzyu(X)sr;mx)@>#zi;!e2)_O89y#tZAA~)c&}Y zk7KFaKzPAf`SUO&PUi-(Zr)~H* zG@Y!3w%Yt!ZTVW++0G^1R(6brPPf#wOB)vDnS^g5UR={sb*rXh)%}{f>OoCARX6Ex z;*CN|(++j6_3wplw)t&l=QSRG2jfocz=UnbBySkj;ZL%Yx=mB;1mu#m$FtB*E4Rg# ze~X%_<+cz$itujBPg&YS|361MJy?7r3ExV4PRGBMaIu52rqyMdR;iz9>Z;4N+#Yog zbQ>0-gl|LRy{T!LS_pqTE04(UBpqpwomiUE9y^t3kDbh8X^)+hybJlAlw8_HsI<#Y zYTTo#X&>QB`<#s?m3p7e4(ka`yVVb&=h%Ahvh~_++i^FV^=`sJyve74d1KS z-@@O^_`6-xDSEvg&)CAN&ygXN-h3Q+8N%myL$IsON96Z!z>c%w<@hCj$OL0Ana^w+ zega+z7diPz{F{lto$wl7yiC9^;Q=5Yk(bY{HvUB8)#Z~jJn=t9{MT%_6Y&JqH)N35s816@v{D#&m}f|iuK2#awhu=Xb}hDpS9t#mzVfb z5BW&Ad>$tJEb^B<{y-q{7AHIO_e-PeHxSSRA z504RE`55nt2$%Zy4{ss-RKg>V$hpVi;VHtK2p>YYoaOb8zn}2O34fLFnMVk}hVT~% zmrs=;y8d~z-~0IQB>X!zT-saO&u%i3%eyN1`0f7}+~XJrHIHjHtDA}M zj~@w_PXpoa5`V7t^~V2i{8Nd4vyESkU-I|kOSpUXYLe`UkvEJi+(zr1gd@PmX8 zc~Y}k-%bAh_?Pgv39lslZ{%OsFT99w`P^jVd$?bIkawWqbs)jNvs7Ntia#5QN>oFk zqb+Z|rBf}ffr`v&&^F84Y3W5a>;|aB7r9%YcW1aC&2WD;!~JrG`$rk>UuL-ffLqG> zcgrhysJEO$a7)-|OOJ<2{*};EEN_+Nt%L5cybCN98Iivd>X-e74EHV8E$!&L?}jIN zJ^~f~*P!13Kd}6_EdM>Iq$%=}$06$%_eUaw{*d_M&c{6rNSLHM4!7hn(bAKlLH-Hv z^jplk*UrddymGqK=sK#wbFuMUEy4PajHJCX!h0*I&+oMSSj5qK$FuT1mR}!rIZG0G zDGBSReBj!)+` zmsE18)oISwtiE}jr3MCNT**J~ozgDScAb$Np83Qwef1vvTsWoJq9dFN)mafyQ6~|- zk}=`;sl@*fxlzzWHqXJ13M8Tf3Gs9H%Q*a~<;_SgL%x{wlhIr?hTPAmB&NiTlraVpk!^(M zu%ZWb>CCteP=1+5mBg32C!={-(uv3gQZL>}hISu0i;d(E-HGVLo<7K7*taDf>rf0H5na?jop7Icz2oy@v1kX;38w#UCM=4-a8Rk!%A1Bn#i`CQUY?tX ztfbZRT$yV^Wv($kqAQ$f_+-A3k|Xm~#>+s`lR4t3`$_L2Nw28Ti=7&#jW@x~a~e+# zD&zNCI$M=G-SqetQjk#ek`s=^P7SFdw?qYZZK*g}jqxOpDpDwM%1BF2x+zoiIO8nC8HN{u26)e$EaFCUne5Vc{VNxF*;3~ zq0#5ce5`|S=j+@st+^6^DZ8gwb%^&v-mcjEpz5rzQFF&6qNfrjb5&-KwAg=>pBYC| zvflaf5&TcrIqN8KuYAsJN7jo*%B*#g-w@=CUR=#s`PcMfXXG^E^yWE%w2r2XK}ssM zn}Pg9Xfo=tvrR;F30Tc0sm94!tgXyX^qkQF`M8%br}LZ> z$V8->XDlMMGdj_?JGLTsg0x2@OuHr`XYn+xpmk!O_7F{(*&cm$WQCKt8m-g4)T<*e zBA-khxhg|PX14kNrXz14olG6+r_*0YN^d*V>n`Mt-IGo4i9Klaq=Y?W!(x$aYR0DB zhRHa2f-qU*J83hAnKTitxt@{M7%9|!noa#g?giv3p(Vi}`n=9rgVj_L`~drHlM}?& zNkld?f)deoXCKctXFi&v&>0kb$D4ZU096>=5H|2Sib^P1y0 zWxwiO^Zri0vJS3{3{o@D8e%obikwZUMEAS5b8jCimIgKwWjf@P&=6e}!&NMl=M@IF zM2}$xpwTOO)B$ZX`jUUnl%!U**qu3nf`E)9sqV&2<%}wjh*Yw6ycP&JWq-{f4JqGT(pVvBc(aJPm2&3R@OLUQQBukK)+s_j0teE1g4CxY+hLreJ@;!+X zm#WqHXE;&fR5^3u&Lr(bMBY|Odz$sEy%k+KtvhEySk5`;Rx2vLr+h1bI`sw`Crn4$ir1h82e*?a(y@ip}2{G%M zi~l$9r$LkGCYLcf08KO!e`9ngnsaS*ki>`<5z?x*Xw51%&2*W8j*J_j{@zh`2WIc+ z?+Y8FgQ@WZ?9;(|B#J#MccVRRe;gw3A^1xH+Fro za_(>*3w%A5^<`q@WEGHrZ@cd&9a&ow(T&)PIo@<{2xU#$p6U?F$-qwD=;Szsf3BPy zR)yZ_^RX)j6?lbjm2nNp*n#(ujJ=Ln zi;SS(Z-yg#JyY%<5@yO>--rLxG@k*Dyo^x~*BkJMLSxlqREfLKDI6s8b&MzbzI=KE zJFt3`8sSzmmLkmKMD$M5&qs5bwcvf?52R2-3R{TEc=s12lUpzdw zvfulqC<^*}uvoZn8hQ`rr*UPkyuZuppQqksS^4p5$H%=f#@KyR{~RvOsO@-lRysy$ zu$7ahVZ=&AZ{fXcUPv^aoEM44i_=cm)4MsG9<9YE>vE&4tHCW5GgbdQZa~s+(eY|h zI*+2DznkkHL+|F&^%(rIY3bs_>M&jn|JbY%GVYx4=_ho~-Qy$@7dYqK;!J+ZStGCQ z=~*+!PQTNu=g8FN2yqp(PPeu(E6N|MLvsc5s=;B9oik#=MA63Emp%A&}Q-%y_<}j$y4%@8PglyMYx$`#)kIeZTkfN zIiJAa^9lS5K7oJ9C-ATM1pc-C_`W{63BKr~MyEYPw}>|2eFS0B7gAqeZ+{_!=j*Mf z;K|xth&B{CiSt!>W}hJK(&%her@Pz9;c1(mzb<|gx$zRWaO{{%IA1CCs_2UcvA~yl z4%W;+(P|et(vK3hg%lF9Zx7Ix23pbzT~L90+}!WRN*(WIPbDHLVig>v3CDc z<>gC=tlQdpAfzB2Qc{4%gD+B&ON=+z;erG|=TJbpTOu1Bp}vI7zopMd6M7yh&I-6~a@x0_b_jPr~t%;H=R%Pc2<>N^GOkxKGkq%LJQ z=~$%kMV&_3&lAzhol9w}lKfNHxm@l1Qsst9@}EJ6UyGZ4P<{pcYjEdyrTODk=bBk+ zc1u^Z$N80dEi20@d!=wv<-6bgxHR8WB?W&bcfQ}Pj?2%b=cVtHcbRvZrEV*|uv+>f zycwyua}Tq1gPccmny?A?Sq`TN!9iIssmk+Z=X@sqJg=1dF{N2+i80%m&hrFkH(?W` ze*-fDIk?Y2PTGsH5E_UMYjEbNviJS`zfAts(#M~g|4tRVf%^qnVNDa!3!FWqxwl`5 zb{}Plb{(-qVw0IYaL(OIokf{ewQN_@12NVr##wb~z>G6$9h7kv)8i$j_o8Nm#c)gg z_G_LQXTmE9nz1GBSX|x?Y+-z(r5RO1C610uE3wjgCf^aH{}}J950R0&>{TWlo1xf;ppX#zN$jFg6WxpQiX6ZiWdl%H_cDD@n z^tu`#&4NIwx0jx~ic`yyKqsT=TD_}JMCzr_0)>O+bX3Z>C9;6>pdL_Fna-PH40JIyLlQSb{8gW-R2Pt1^kdYQ?lCe#jO?0j$q{69zS57M= zB9rt}&(83mY-Z>6Ym}aq*=q^avouF$=Y4v1UI9qA|LXU@*z`ZZs7!svjUUXi~q0W^_0%5>}B8X8*{I3_w7Ir8r#+1Qyy=_ zVv!wKM9zbd3E*DF17JRwqT9l*rghSC`k*{GH=7mba zUuQ)s#6FUph|inh^8&FacA-PhQ>$^EhqkGdlL_?9SfOt0iL?9j=!se^c{xku4dWB% zsG{&lyZhLhE$_3dh?!3a=|<0GB{Z%*taC|xScg1v^xS)Yw?!m^JOkz#cgT2`M1 zF|s87h_KnaHirj?%-*$`d|u%sqwK{2q3~HEBYW4o^}BT`3ui0TLGL*^u|1BKD0}A9 zB=s)Wm%PW9EDHNO(cW5`l=V*3m%rSXFAcLx%rd*ggZ%CT_Xe;y-Q^E zT&vHJWxUF50@)?@&q41JZ4TqrnIHRk6oviWuDMCjTU))`O~fCkuH5d%{Ig_7v5`T8qT|nn|Xk+O)^uzPG zOb(6FU4&=p{p)jbCXxeAg7{;c**Y)4a{hjj2 zUN0Fn@8w?5IUV_~Le70kMUnlq_j2DPzIiYApT_l9B47*ly{lk$k;6%kC7hiiJDYy` zXq*j;MRuc)zKc|^-kCtyk@V5zH2-H>-X9ky!TYJaJ$ ze}uO}aCnCjH0NvA?o}f~bCjIjof;|$qJ1lh)T!($(7ED5^ZwkNv<1T}Vn`Q-e9aQi z5*=MdN+rR+lBU)yoFgB{ou{&QcvoZP{aGL9R#c|Ep7p-`qrLL}Ib45vtrLCun|yh> z8&woGn(K#HYW;6ISO1*00aExXVzLh;_D4-tVm8!ni;8U#5>U=RP;inES6Y_8Lp~(!$@z<TI8J~yU zQ|f&u|6jy6bN|Q2^(k}zZ=`4D{(-~hzQ@6hyw{F#?`uos9b9sYuQkni7nhXVw`=l{ zH)&m%PAeOZ==dRojf3iw?8z6B-fz(9a*Lr(&x(j!;#}><_-Vi`kzY&w-G#1;-7poM z#qOCo5^-b1OGN)lJUKTvcL=AX^Sp>VgcbS@p=f#0OVxzUg-*{aSK;U6=3h7zyXPXE zgRH6x!{OXSWSU-KOR}O)NjCfHisjCMY}wZ@WKWjs6|q<2mV%D;8%`q`_jAXolZs?V zKLa~vpiVIn`GXEC%JTRH6znW+Cz48Nbm%x$_MiT_b4#F2Dl?e^12M1D&fls(^@n#}n^um6oI ziKl11pC0R@q@(9`AQA2y?VYq{p`7=a_y6Caj^$FvaBSb@#63~$e0Cz{)Y0Wlij$f; zb$}Y%eSzwV?!;D=JD(S*#(kfmr54JaMMi?03zdY%a+a`+Q~I3X^k5L_9?l!}O@TK| z{z3Bjfc)gXL1*N5)TcA@N1mm8-z276R7OE;{%5$|^p=`Crg82iykWeAvHKUK@|h9l zPSxK?Lr%8+J5`*zpob12lZgD8XXAp)aQz;a)kbr#K*Qu~4fCGmqG9G)IxWbQ{a&b|EKC|^v{<9x3(`U_6=jHQx@ysz^sm3NuZH#L7MYq^YJGg=Go_vikV z>A4@)HRZjQ4U0vto~$|thmnRE4!en#Mg5w`ailn{=4v*@a6r#(Kpxf=IjKkXA;o>V?*?ozvo(n zY!Ut$uH2^jh>~#=GE%91|HN1Jx58+p``;gTMm`qbpZq*lAC^bWVR`tn>kgBxJxo@{ zh14a1?D0@LE_jP1fI+eAjx4-t0htbv7r~AuqkIQUWjNQnV$PlJoZ@g>M@opgAWJ)Ran#AP$ zBZQg02s8SOev>(SC;VJ!EOGb(rLq<4EmBic#86)(Np^9^$vpV*dJ|37O>^G@v82h5$CM(0L5-q*S}F-Ehjj+#RFiL~L$=uOyGmE3!Y z@m4a%&v(iw6P+r3c`EDJXm>nXY>*Qrww50Aze^V(UG{D%-y105?6fmFpZRf|?Pb1~ zMcy(`L?`)c`9^qpE=A1!0pBKQhi`0!&sm$mjDar8Z**?c>6j73cW2W4yENY)Tf5=Q zI@TE->Ws1D$56XF# z+?9P0`6fzKlrutXhGB(SB|+CQ-`aSan#i{{Vo%=2Ok1F>F`1F_&5M$7DJ!~h$DX|F z2;pPW;W8`b#7XYL#Z~O_+c;mkOI5}>)q4C^c4fouIaTkTgHx@?Zz0V}%9!3Kx^gp-bsp5#@UR#oRBHcY|6_wO-|jd;^7>2g?_DmZ)+vzK?^BW z-_rHU1@yV4y!SZG2{}?@-YTSPY;w~%kdA4QP)4}4h%JE)@0(9&WE|h=G4&sCSpB&J zM(B8T?#BZ>kr7MouJoRjxgz_!dK25XG~-y<{vOrkMp3KiT)V$3yS7)}w>109cVx)x zoNW%7yVMcR*+<-^9_c$h{dcKSrW=@Newp}weMT*gv`dv3v-*^3%Ew1)jo<#0b&#Buk>a56e=6Q|tZpY&7_1%r!9V#~ecKZ56))X0hmq zO7gv%{JBXKjCJ2hZkwb%+*tSLSi84UQ@KUT-prHtU9>50ikS&oavPF4yqn@pT_nox zDj(UDv<)`Pcoj>L0yZ_ffVT#C;mNUX=2gHy?Jz526)CXx(xz96?&V(aacaIQ`);qi z-v|BWXJyKNN#spBqTBp*5|Ls`RrdMb)ckQdpIgW>F8$nFGgG^&SKc3&{pC9{ zANRJ_cy->#qNxih$5^Po56k&P`I<#uQzFrM0ea29J9i0ff0M{Mg<}f~<@Swy)aQ=s<>!>r6PaPNT2od#0MY#!|HzOX9nOJ;N!C!+fWjo$*QJArfgG?+1ieMEx`K zmfg#}NZyO&Vsu>)tIF&+idfw;B{_AOdkc~>`i$i`wSqT)0^@I^SdA$XY*KHFCU|h#W^4cQf6q zsofwohWF9a-I3hX6MrFoz5|Jzd5g3w<1G@SKEu+R#4OAwkJ9v>*L^lVv>{q0b@H27Md43Hlne$MSbVU&4Q`_3wth zhkpo*pU`K{_!cn?u5q5dbw zIv#;`!haNc4fKo9?a;?8eH?l#{wJZALZ5=}hJMLXxi2O0<#y}6(1$_h=b3)~m-_jC zVEumI{gTLU!+Wov+(-TVfe9uTKi-EnUXkVdWr+6kPq2Q!eF{jR3Z5LmEQYQCewvcT z=YWhO;cWmyWiKxDJWJ&culSF(bfl#+wq!oZe3OslxsiXerxa@V8}%F%zu}p*B!-M_ z6KB6pA)NM`bMJ$(({p%l*y}!kTV%tm>=IYzq0n4Qhgmub zD!OSDb(GU9kr``w@>{Z!s_-TONpBLrXDR+lAas_ca)vGbY9Q&!?@2o90?k{5U*ayp zCscmx(a`ahF41zU2$M8Uv$Vm|MoZ7Ibcdy)D@1<3rRPH>-HT{JX`hREtGUI74Ysrx zDl!{*3Y8X?G^D+_X5wOMXGN>muTSW7^lLMj<2t;n{>PiPHIhcaB02VCeW=0ls6|@ zx{_@z?ak}D%T=hnJ-M+hp>oQ*Q_ZP(N1SqGm#4a#6Wtr)T`FsG#iWW!QzlJOf$0^~ zD|k+wTB#g<&XilwRmabssY3D`zZ%+>XiLpj&Mf7^_F$@j4jC|~JKo*hmP|Blj_;VI zvTSv!i*-%f)V#G>6P}*I#pb=a^>=sP1W<~FJHAR*0gMS ztf}U-CG{~i*aXb0uB%=)zosd+e0fvd@-=FpVb5P#v!G^KY)N%py(%!Qh09mYTe1MI zpXQ31l}ne@*DqPVtO@RtngxF3`WnNnty!x^)U>pvR&>Sb_c)Ev-M8j*7BUXYW65Y+ zqD5-X5N%7OqRAexA-awM+|mulAIyjMO~K;o`o&F4Vl^wPV-%!b4P6|It%!ETxAerj zQ_&4{db}l?OfZOtNl5n*g9;a?Qk^y1*T*}h?M-VsOH^RVk|hgxp2A3Um((e5NnM=^ z^MGBaf;jMFrMagp0d*?xlQq5p^{Qp_7yGSWuOgOFAFGblETw_d zBC(a#%jy@_tW<6t9apzRdE_DwzVyqZ4jvgnJ+g--p*+bMhR6sTXM-AFXXj#idX`uB zq*@smriIh>oT-NNigtFE`&~0r4eQJA9hNgyNuQw1L6{kBy%~w+dPHtd%~V6v(fpt# zdaTY=#~&6_-`d<2Z^;-l<75mayJo7f|GVr=H7G5V>@J_j2x^aK<`1(bv9+x$nGm%! zQx#>3FQ)0*TRlHKV5KXbE0{pBv_o5OU1XR%B4ol>!f6(`vz=C zc6BtT$`_zESEbt8yJxDwX@MRX<@1`m<0np?sS5kD>yjI1s*!2l*0%Vz^19|7%%mlW z4eg{x8G2hr2QQ5$dS6nYUl0BW7A=~2XHn*k9*TmPEIK5@u*4DByo+`IWTS8Sux&ns>QYI;Hzj9Un?=g&~ ziMRAtX2hpN%Iw9%3!zuE!=ra~HSh2jpWcr1qi2N9REI^DL15!%4lNsbUQa5OOk~bS z8z7@D#_&5rih3rSyZhK0>u3oym$r3gs=9wkKD`)?vkCOE5@xEC{=L*@suPbc zqQAu3ReYwJ`LD(6)yv~1&r~!1-N-Z5$^TMRJygY?IU&ZUcww)NAIW~%C=%cnk` zs!OhKZeM{C+Lr8U$sAa7{%=X}lha3?Kz+PxYrJbdHj>zM&F#HvjM~rtzbA9l`k>z5 z++{YzQR$B>w_`juf*yil07tsEto2jaft|($W^mcuENh+;tX>Q-zwi!bq zkz}l}r^Du7-=6G7Tg`80_KE@fDKbmrsn#TlcGMAsmWZ`u6B%=a@TKvNbygrwJ|mAH zQs1^Q(VXh(!ul^cLU63LE4huRL+j)Sqr5H2E@p%5pIcVOn_I-xDoKa1PiS7=lj`hA z)u+1R%~9B?DePw^+ry~9}*in+g;52v1@{A2(20M|F=I~zWUbbJDA?d)r1&O5j zzT~lK&Z{WT<_m(ZFG`#Nm=y9WQZ;6kxpNz z_ih;}WtMIEx=oxbrTarCw6Z6WFzbJ&Bt5BD)nOSK7~Z^|wst)L`iSq~oQjSgVZ;+` zkHlD7wX%-gcfy=yrH6%t5|SQV)}JY98_$O5?vW8=JI}Yp%WLC1%;r|M(HV6fX^N4S zTgovVTi^w48(DB=@z=vK9lR`A-?P58x_x7kk=fdjk&vxVTC!et0r8dW(38}5e7|(o z$GcMH^LeywkYkQ`MnbkidiPu{`zq0TvOCo!(d@;|-K|TT*@N2IqM7U*yW~h}CWkb= zq7s>NoW6{iYHmNyQED)M=fdG;^sp3k9!!5dk&&=dTNjSf_9>Pw{j`iEU{o2e9%^<_ z9nK-$%<5s|_(j=XE@Pm(yS;pIvOAS%?uf6BchS5u8cKCS84`@R?tVkgXsKQq4v*94 zL8f#2gk|)YX^K9f^~v>{*f%{v{40@EpJ-BLgg%5Rae)f&s+pf=Cvy5b(^T+`o+}~r%XFhW#O2-V&$?$Di0T@$4ydzdNrut9MeZRrspJg zYjb;BiyHb#mb4oANg=kR1b?FWtHyjcsUe54Osq&R-@ZX8>Sx3m zIWJbdNO>{N%m?`AxlIdKE?=s0)85!}mF3$zD&o7+B^cbFV-g5uBi5?{(yI-+ zXJr4tz7s!mx_Le2oT0okm{tSMY^<0#mtw#B-rtbA!@pz)i`q!BkOlssOgxkc2e?o9dUKjc0?nc9!*I8+Co0*(j zH+7r6i}IRVS}0jdi)oS)T)n5`-SSokO_A*BS|3NMyn#GbBp%t2mdwx~dJ*G66-@|?_*(-)HA zWruFuJaNeuS?mE7UU%YDS?0B)zPUZ6+;z=(Y}*yC_khfxqGuJ)J$_4p~oeK9H4m% z+q$|_SbR3#k`28v(=z_af=$M#IzO4<`u2EpmnzUCt&zGZ4m%rKjpNadwv-C9h)G|m zTpSz}=p$Bybkm0!IJ8EK8i+B)8@W`hts}m)t(|(QK#R0fs3k5T(;=&9O_Tb0|A+?HrhHn%Kj>msi8q${AZ{9`c1 zcSHhl&Zt#xT-(KB$I=a^vsD4bm0eJ}kwWYXIQ~#U{c>AnYcgL7pR1jA0uIrhCcF4F zb+aQBn^lc4d^u8<)12-mHj7QXd|BU$`K<<-P|TmEX5Tth1ACbp<=t>|yDIKwvBY)g z_dPoK!6qOjC)rJ{j6CgEwltPa1)B_iXr{Or5>1_5Np>?Gs!s?5GnEb*Y2(;~fpit^ zJR9CGxSPr4>kQ>=P~ia)W47nZTy0LVLygNIQ@O@(6viOqVI)ep?WkP2mEez>uy|G^ zC3_s{V!Io-4aqAYRluWqU3ap*Clz1OoZ|Pag@Iz{4S&m$?(Uv=SGS57o(z4nMN|2` z9IYgBd;JtyJiR(c4esmLqn(MB1KU^r+MP@?Gx>c`;qORMcX8=60^`zCZ#cXK@eR#A z?Wx1waH?zx)Vo(*u?1bp&IL>qX>}zLYqrxXiRSit%wN5mlDWtP)J2wQVrQa`t*4F8 zkUA~t-L)&J@R9_RfDN?@X%Ck(43$|C7AG4@!^1(J4}d4eu36gEK)ik5E$UQdXQT@( zU9&XfJ)%x?nP_$i$vh>{AuBis&><`t`qjCf!XgSIm7eWV2w@nd=toGcLTT%vTTHnB z+DMoUW6#O))O`dppGL|KeG(RU$2Pb(9Kx5v8#Dqb)p5UHr)tWC=x4=YniC| zfan%ASf0x_)bvx4MTRZICf?#}I+Y__TaJ*pSrEdq0TN}9FAheJJvvai)-P8}RF-(; z;KsPRB|?Gls9!opp3l%xjL#_a7L~2TbP7%zf9+^JHj~SiAg8T^aV_fpDiw4@;5^$tRmIaGVQjVY_$P3!cVYlhITP3ffPHJm2%I{Z}ypBx$Gk{G6%1i7EZA@i)warDT z(-N#_86J^0fmRnqI%2JD-I-mM(-BMhRUF*w&aB|TUbbJof)0O3*(&68h)y<5nbpy} zId0UNwyani-3}%nHRw^Hj?FC?6MR)z)`mbrv{|-1%_163>LXKru{>#RmZ&ToT7#=W zzH7O@vehlijmk~--u6)W#^X;QH87c2mQ0Chmu3xSs+;JtUZmM%x1yQxCE2my^ia0^ zBpZ?p4VRnL@nlWIKrx=~CS9pw>k|)#TKeJ}1u%K(fUYY6E&xZ-FK=6Qj5WK`2kTJ=VJhAa)56BZ83 zKM^z9B?~(@m0X`}SDvWx93Jz0g9^7MMo6vHvE zTVIKd>pg%9F}K-Os(eFN*xi%wm#MF(bB+m@p+-q`9MRcopuM-7VTuu~tuwL1BFqb` zgM5pn?tjOz(jd0AT3i=vOeY%*8NIhD|l3Gt^562YiH~S?&tZbu>B$QDkX@|oSNtfh^ zSx|3wBu#0dKzD0$8#B9YC(8h54|>?LEDq>SHFq&F?Ae@njTx|5ZsHfFy-n=j%}#z` zn&;O?jYzYsX{Aq+e4{HzLal9J-Rt#1P`7>`$>{D`XPpK17%-jkNXxM4Hd_nXPkL0} z;B+zk@P5%#{&|M&>O892X_Z2^%9g_|vr#DYoh$8OBRVX=8qcyRPY!sqQye|ir zTb6cOoj3pn=77EPi)h;T3FDL(g({dzuHXnFE0wfya#P7w98Px4=h~slNhQZEiDMzh3m8b&8$Ey0u)QH(E0Mr7?y*@ zpC0(>ULM|uZM&1}&pM6ZHo2{#ax^ivn#T<~RpdS7KJ0$e4d+))oH&s`j~mYCFURv3 zFOO-?LxfCJW1WXJEq6q6BHwBvFdk6<<-WpCJq5n#Zu`Cize;WPo(;V2J{kz;kM@E; z^GYVRd4V5#gLei42Rza$yUruGGX6H>18&(1p7$H~cxOm~6D@Ft$QMvaG|6MTr(X54 ztN6xPIKRzPFT3Sc#QvR|Q^kkBD6J)a<7GEg@pZ`z&v55WGOjvsV3w+N{zII#p8BCz z+@QueKl8#Pcey*)){d@qcaG#Imk6zDQ1yl$Fj+Rt;_I7JO_DDKOC}yTvxJ{#(K(3s zbiNfv5&79po@erHDM*v^8Yw%Y3Ow}_e$Hf$3QuqcU2xG3w{7G^PyNo_>%4GRP-$o2 zx?1Z>rg>Y^uG3yn6HWQsW=-62;jCYp_Si3(Q94syj?~hvvkCX%t#fW#g4XdH-I;*PcJoiQK0*Ajo@Zc^Q*R3RXHOIwyW7y$l%No)*;t@(|bdv^+ffK>s{>K6Z{H3lkb7k>bxw;`CZ3kRZHr@R@(T< z08c4Y)iQoQ!$E`}zvBDTb`Cc1&DQIKRA?e!q=avV$H^1a9Oot24JsU{T@5BGNxPd zg~u%O+_YHa+(E18OlvVHEJIg7W8XdGMY1e17nW$256N zmj`b<&Udk*` zR|e0ye#Z`mk^AewSLw@!Ku~MbyS$ti1Fg>Z0%zcWrQU$A1zWeD?d76kc6ix;a$QDj z-cJL2Wa4BoaooJtU>3i=v|(g0JD3y94GuUploR52+(Nm>gt9`}p*;HSLH=}2n-}_~ z%QNt>+sd$ch^S{@FhA%9y-sV~__~U?E zTkCm0@z&nusc*Y6C*TGC=(SeRZIVK*7ovpd*I+25LS87K?sxpeUdc%8Ti)5VjsH$^ zulUWxyp`q|TX4rko=4-MPL;dm0y8Ls-l-uc#LsSpTsLQbAI84 z^Y3!=N4ncaHlR?veNLz6{@HDHcf27DVb!*%B+?qiJPt_LnAy193rW6X3Zz|H>8wWr z+kfmdG}f;0)Dk9yOOz^`Dy{scM=Lu&cUwqZ13dI2(Q{epwy&zH-8s<Ugrf523A#7&93#rbV^(ds zcy!1#841!Q!C<(}V}7@~1D&$`AU~T%w*<+waG-=wzQeI;siA_Q@PC3%4H$i`;>URF9llL+|sYP%_AG!A!}b?M2kigRf8gGaO0;)E_yUKfUib0dvDyO~R z=6(@v+pl`t`_``Q$hCWpKRj2XJNCK;t8u>pYehgEbe|1;&kF=za7S+s=YP*rKlQSm zfdvh;o7kqe1#e|2p>;2I(q`$zQ@zl)f@Mxoffu|hh{Evh40^LY=R(h=&KG&DRc_Zv zS_Wr4Z!!VGmf{Z>`=W`mlXHV7|#{Cici-fVo(&HI{dg7FhnMY;uC z(*h0JW}NL5<*Jj7dCKUQmHcfnr)N5ENpnd)SGcRsjs-ssheu=sPh77Z2qWgQGPJsOf9H-!EIhU%JY8b#@p7( z@`EdRUDaLIxdr3JFsC@B1y#Q1wCk$A9AtMx-ZGdj@!Uh z+9Z>jx;Ze)T`7X@(9WT!8)tCno}p`oCWcNP+G!Y}p{EnN1~yEST(CIXW;8N0l80Qv zFakutGt}$ro$M|nyOLW?F=m=#47)jS(gLT~-In3Trq>l08OBuFUE=n-Z^&?emmQH* zC_HrP&}lJ=tXYv?+`;w97c8*0#LP&^4xNS+wKx#Xq1GpXcAG;^%$Q zHB?@=m8ToXwuBLXzBs3Edl(s8d6%~EObK2x0A&lacrhRrJOE*@6gSv=P? zQH`ml^!q=Ii0Su-=y%)23v^=qdWWH-922v)H|Drr=P|um_V}&QY+o;Zp51}hPMhs~beiK_v(|AQ00+VA;1IY}ECk29B3gssdkqVn3mcW=We*GN zbzt0jM#y~%ym1Bw!UJap0 zIfwY6x;NS=+9oIPI@rJ2b>7?TIFGeUQM0dzuHU^o@OFEPv%4cJ><-H*afW67;|ET4 z&CN4TCO3CP+=Cq(oM#f$8$6YCoR7c*TU_UzF2{MPo3;S=rX1%7;JuXV?C)`$J9}K` z8R&ap|5nGj8Qic98F0;Z3Iy)m;W%%D-8)HVrxdWny-J$yinFgJ^lae_cdrx9>t|n2 zqiN2FE21|#)Z&VBSRx-d#|Z@7ktL&SvHwGaUpj|Yd*d9({qUTi`_#F&(j0q9>e7Au z){vv_5|Ib?@iT;u8mnu6w{Q;bbL3C!9^0oqGTY{G_dU8~`yBb{@v6h(-7BGoFsccy z8FrueF5T}OgKyzsvWKUAbezvis(0?!d2AkbzxbZnuWR{$xPO3~0or~=^g(H{_x3wq zaGVRzr!8)l$HV74*`Ax-(Z4t)TXkzbB1s%X#(nR6=TXObRgTUcyGR}v^LXhJ9yeUZ zOYc;|8+7hcWCd4|0Q?j2V|pOIYOzQOqleSD+i1Vi4=lC#qT?5mRg&G0XbK6WDq zT;Ia!9{e1SL!V4io2go$el|WN+`# zeN|Haf0{afmIR|HjC-yofweR`IYi%}j}Y_`8k{3&X=;|Td@HF8qM|4%BQvEJwJ?%e zDlC@<2L~bh2M!GmLIn-|&UGl|J@@h4d!KWz_g>!XJ3MBoaY8ry9Q_(V6F-2ocp%0^ zQc`E-9YNYjW0J>~IR^8SGPjSV$*3~c>)?G>Z#g3`9LBod1-!2s#XXTXwlt3({JpX$ z!KJ?}#Jp>ZMppCaSR2nNPFY*dkxDJcz)Pp3mv*Jic5!Xc1oWR8w3L@GHcei<#xH9U z)b~0e2ELWL&8#>fw*XP4px>LCY!Op0N`#GgX4y7in=`Pr&SV}h|9~N;XA^JC%tU<2 zbEYThE1%1Pks2T5M@{?!Q&dyA;8rDOiwVzxdkx@Husw@jIHC!E!z_jV}E)S+@!s**O+tcuk> zMm~&f)qQEn16t1%C50!>RYG`8HOXeVTK(J)C^KArh`sYe(ZhoEgb`&^&ALJL578b$ zV%2_AEk+5U`3D|DH_s1NJ-X;Pe%g$Jegfm$wW;A zjVAs8f0Xgu+irsmKA0uFr?=-k=Q+=F_UG@<-vCxn$sxtCVELzJXj_fIiOwmm^Ds2I zR||Zn=JIN2R(WWf70dD)UX(+Ip>V>_xao55*xaw4*jB{Q&*Sg!8mCn|U|_opeaYS7 zdEI6h-fLGKM1kWSml<+ZPB0dIW;+bo4aak$O@=XTw>x`BKVrzd@oTn%GzL}lp}>&V z^rK!7yow%VMKr1+hrEbNDte(X4DLCe9Wy)RRacVnE$$xiz!C4sWhVOQgbYi2|04(u zF>q{0i9GSBqnh4LpYp^cRI4&aNL?5D454$4hz?uj_Xt`!6e_#xZAMzKQI)jWA_vaG&~Uw zP37^FAvLXun^hHScuqd^dfoPF42w4j(1n(;D(CT%{MOf}1y)&LZ7@ub7PnT2#7z}* zm>>lY{6=8eZyn*kn)tOO6u=DaN}B!=X{5vwQIrxZBu`o(I`fp#2bG@v^yX4#51pgN zcMKTg7Z@@YE-+%~7bt#}Rb%ul#W~2JNNZTa0LCzaJM;q#x}|#D#XUMjB>FNLiOwk* ziQZ|t9mhn{*`!ls^%&nU@`ZvFfg&lLl+c1CB_z-clbA}1Hz`{HXN`Gc+a{{W+gYl4 zC=p6=R*PI#iXj@`$8>^aQcjad@pA_e{YD})c+et}mU?H6xoe8WL`)*Gd7hh7F|F+{e(7R$db$I84XwhH`J5$QB!H|PvzQN2;*zu1%W*)I&}M(=Dk#>%9K!_4i(y$ zOuUS-MzKggY$&;{c7x%z%E@%&49*&Og$3H$4otj?a{>`2MW9bP5uTSVr&fo?YLMd|52xNC#X#;U1U9;c?j-u1_gULg>*14*zk-C5YS_O~*(HX@FU z?Yi%;)avTsXzK*z?bf`iNLV#`*L1(9X#15iUmcA}!nU@l>88L;1yyw2@|-~^l*cx&lcv9nR6WJWy^e!Nsj2<+HA{{i#LSn=5tQ;_No^H zR~@7ni1EKI+{Mw&e+5yV13e>$e}y?Rx<46xfS#X8iD0Lqhgu|g=CBfj5^tc z-TbRnANr|Rt@dDVDA9u?o+94>sU|I}vn2MB!j$7_era8ls8^v`9vzD&qko})uHxjQs zz=dS2j*E3%uH#xAGs!M>pac~Cork#j5Ei)-r8;cQVuZ3~E$h_b>4WG`1ltJA3AzQ` z=5B#Obr>v{&U&1$K6_ojk+6uXSi(H+;s@05BR&p;H^;$9hnvA$MwKB`0a~WSQW(Z% z%G9ViLaC2Pi&A@>@}DqVhwueH#b;cdB>z3Gx@c=2_qj4?@j5;yM+{$5V+`US3>X~5 Z5q!mc2fo(H{|4W3AE#ZxQuz)Y{{bZUa|8eY literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/AccountsActivity.class b/bin/com/securitycompass/androidlabs/base/AccountsActivity.class new file mode 100644 index 0000000000000000000000000000000000000000..93833d1843d4fa3cff609f1f80bd63bdc7e91fa8 GIT binary patch literal 3551 zcmbVP=~vWN6#qRy2FHjNcWp&mL>Sb#Z%}o>ZE%2E5UZ_A$iyL%Nya3D+SX$C+P$@# zU9`&wzt(f=;Hl^I^mG5Hp8j5vSp<4qJ}`NC?=HW4@9*6k{`vRMzW{8;Z!y#eY}1{b z>KS^$HT}z6=QYn$H9O-vX2#M+Jat6#3^l3iPQmuQr0$#J6pW!xVCN&Lc5C*SX=l@> z=a;kv>T*5)C4pt>$djr&wr|+J+9RKr{7!-SxuH?hOXl;IscXLJ*aExKkK?gQmF8yW zN-@xM`n)!-sRiG(REbL-51Lt9^9!yauy4w7*Q2?O?04>=x!R%RA%UjQkfqsKbDq}}h&TjRD|i;q2{d|!9~6|qn#M(j(Uy`50&5hs$}pBvf^~A8JYoCB zu<4m2rbU9yrcj%LS*VX8A+VrQu%zp1mu1!BXvbnHw_d?)#HCqP!A5MN<7{BI!kiUt z?Pc&hk~6ltj0n@7-SlQr4hkyi{E9AIn zW|;oqVnukVOn!RWxRFT(+}DjkKj74YGJp!D;_OWa6&%80fjP2}QSYG%RzMWE)A(Tmd$)N;Myn z2FkXE34KV26pU(77W}`sD7q-L`Cu^IpUWGdkM(K!s8h#vEpPgoWqK@j>kP$?s9(*T z7~T+A5~R3lySrdo8N-d^D&C6WP10(rgo3y64riWM81aI!B%6DR#Gfii(qF}U3f`AI zp5r^m@_EDU;Rk`-zoy_rd?XMXmxFBJ+!WXYBj*j>@0`)-6?`H)*QZR+Op$U#T*c=S zb7KL2 z7jj4CQ}8(}F^NTY0+A*Bl|sNuEak5f3Sb#cfopzR@K-9|pvxLQ4FmK-EBrQwjzP;+}(-&*d2gd90G{I5ej;ECb-MVAHo#Zm?;VKmh`!`hy#Rl z8*iio1gYA4=q=)fruiL34Bo?ukqLS^g>kOBg1w7e9S>HQxN?KlWv*VOjire7$1rp9t eddcvgrs|w7=}_iY0P<)262Rm?N3`%OYW@QTW3np% literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/BankingActivity.class b/bin/com/securitycompass/androidlabs/base/BankingActivity.class new file mode 100644 index 0000000000000000000000000000000000000000..d16b12e8575beaae59f2c368fbb62717a2e0f2a9 GIT binary patch literal 3739 zcmbVO>vJ2`9X(f)y|#Rv*s^1c?a;g{%MUdvk0wfi*u+#tPEs6fl2Xb_y0JH2?~2`( zA*B$YK%h@r3N3xV7-l+r=}hZP+L=y2@u7bc)9JbUkYu~GNk2&YxcC0f`JLbS-Mjz% z*I)k*-~>J}kP^7J=57>yRcm@yaEUx0%5@i|>&$z~ z3>beTUr91|{o-8HsoSbFxvWVINeo~x3xRzSBe+Xo&#DTxX)&IkY%LFk>&Vu?-2xB% zpIY@2bzGtg-C2xczr;QG40&5VM*hghbo=B8P+O=q=uzIs*F0*NCy z$^|4mZ_@+r)jXw~^mPMi zJ!M8>7DWMh#d7M)mU?dPTA9>G^5wQ_n|xi=W2G#P=h1P<7 zP}WjCB5_u$Ip8Vg*x@lf_^8B}^x#M&^#xB|QJ&JNhI(tSep#Y~(^SM_V1c`~rM#ASR{z_6lcrjal2PK4dbJU2q#J4&fp>GqBTklFa|^(|iEKJd8m zn;YRCRF!xJJv!04gwlGCMy2rF26vx8wVkJXa#dnYPnz)5s^wFLq&XH`zVTe{B&u%U zD#c9_uDMR2oS;|^FIiZy^}fe?&9qIGOq$n|pASmAns#zIo#B?Rmp3Gy1+(li>-7cO zTxFY&cQ#iND*|MP32^g|h6khm7f z_@cy1S|Ldp%g(0mTbolx@v_7#|53U*c3>i%p7XZj!V+<=3Yn?PxSPYKIjAziN+H+A_y-0n6dkh@U z@CCQ-n8-6RkzAWdZv@{~HA=5a*cxH$?6B1ixLgaauLF+pKfxg37@r?MG1?7YwXbF< zqwdBE%l9gOuiwI3^xyO?{6JuZmml-O_dlWJ`L@nc7hYw!b(YMgt2daV!_Q%tPH)in z&xXVz1J1<6df1yk3pWjZ=i}%2MVK-_x?)m`u>l7od;L<|tL3Z6>3c%f0kdzi{Wm+Z zAB;iz2oQNF!<{Dy{bU?^^uIW_vzJ~Z!b|L<>m>Se2g+y*r9VbV=@0ZcfjdQcjVP}Z jJKRF~v z!3TKo2l%7JYF#jx+cp%{^;OqbuYP>Ge*mzCITs~{EnzOgOo}2^`7gS6d6tD-$Ei_q z!lNvVcqYSrt~*M%_PX6f37#vX>#Hux48b|S^)Om6l(N zi%6zFU+b?mjo`^CPnETMVA(dsu-$Jl^;K%hNek^^64NfG7&iKxj*l5z{-|h6(K$Zb z=c3a}O`&5MGk8BtkqUXF>?S7vU+1#j7gCOd#a=uV&3>aswofq@9mN=FhH(Tv umUYtBS7}_szs1Bm4)zBw`}+?^rN`l5mZD1dgwLeQG*jRUiLK7^(Rl{xw89bq literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/BankingApplication.class b/bin/com/securitycompass/androidlabs/base/BankingApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..187c230920c3352a5434d3469af4fb3781b32462 GIT binary patch literal 9802 zcmbVS34B!bo&WukxtKfx83-6aIV6xwE(nO2Ad-Xxg2@mwArMe;GV_uQnaqTlHz-=q zYPBA<^{5qZYo&*03kek0wtKYQZgA(l>LGs#3MHkfM| zjOFx()>wKpnI3K#A5SIYF(a8t`^m$!)Y{k(8y|0Qy<`gJ^jr?xuGEh+g}RQ!j>Q^M zvGj05)X0KRGgFzhqb;k)41Fj5WAddk@lid�Qy{3}v$Va5j@qC-g*1+(;fv8c98e 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 GFa7}sS=o^Q literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/HttpException.class b/bin/com/securitycompass/androidlabs/base/HttpException.class new file mode 100644 index 0000000000000000000000000000000000000000..cb02888fdccdc18e55ea812b57eb246f1e05befb GIT binary patch literal 503 zcmb7AO-sW-5Ph4bjZM=JTR-vSt?i);#hcf5B>mu zlsFrU)T4);nK$$1@peAH-ah~gap1vW7)I%mYZ>L4GLKZRgw|Xn^DI^KScIB~LQ8&S z%oT)^aa|X9N?#(FKk&hB; z0Xzf@rEYIl1w$i185M@+L?!Y%UxqTf5n)U+?MWJmcqTGs@w(}nTcsIJCja+;%HZn_ zoAre>o3_aj8TY4Yo<(w`3JZS@FtC5eF_|vWB^ey+oGOQE4_g$gghqrN%6|Wi-q9=S z&jqJRu~BTc;9{G&ZM3Mj_rs=6n-J}xL#lK|>|l4T$qNjW`!A?J5y^p-vozqakO_*q Lyp~}kYgzl>aoK3v literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/LoginActivity$1.class b/bin/com/securitycompass/androidlabs/base/LoginActivity$1.class new file mode 100644 index 0000000000000000000000000000000000000000..915578b8d1bbe3ef00835b02484db6e56320747a GIT binary patch literal 897 zcmbVK+iuf95IvKmabgTjQwaA);z{On`KKUG?l&j^o)Cm~p$5?T|J$u0<|19<58Xks})7d=9A z=mM5wrRBT%ULuPRBFQD8ADdLh4APE?+7Bc&U!Pkmg# zB@Y(~o5!zJfXna+9g(KeRu!iOVf8yFBFH-qh)mjfU{J!fnm*kaBb7PgBy_MyT z$pYNOEoNs4g%l;1=zs=eqnC4?<&rfJf;XBwKgoHxr1fxzuyRB!Cpa`IxWNr-@>&A* zdah4AxD8%i`0PE!))PKEk3YKi9l_`a&U~$6R-CW8ap*Dnd=41nysJ3NJK-D#HOm(7 zj-@mDhTtd8ALe+@xwk5g!G2uL!3bQzRYo^)jqwd!=Qjf_ZrU0`w)*T_!fo7byJ4%o Ef27yoaR2}S literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/LoginActivity.class b/bin/com/securitycompass/androidlabs/base/LoginActivity.class new file mode 100644 index 0000000000000000000000000000000000000000..1b3f988e2b338bbfd8e7e3757c88178daf7f3741 GIT binary patch literal 4616 zcma)9`F|AU8UMc7;Dlv>xRE;ufq=5ocugP}rl6o7rI+R;H3_5p{dU^t(z_)BT!jWcIj5uP3myOtmDyFxYSnTQ@v% zh;+5yClE^=)&{kNrP+OnwC_?Mf~Heo&)00fTeI>;4Q}Pp2rCKPvemRr|1OegYVM}$ z?M}vsB7)f}VyF|CnKEsoBcJUt+%B!hG9)KQ*Q{>MHRXHpu-fl8De;EXq%1x{2Fh9E z*zK;N`J_I(sjRf)(TsM+GFqCurAW7{Sb+Me5Lm2Y3T~0RB`TJpQJ^;4MFCoKIm^^F z-;_StJULlP-XFf&62)>fDY!#m-ZSRCJ)O277tl zD_!X3?P=&jw}O2F4JG?c7!xY?<3WKa1FFq&EJI^}GgZdq{K4jf3JwxBnqo4jU$qW=j^b{ZDh^{n zK%og`xn(7;NJd%K6EbXNO>3EkEF1;2aXAM@AgIXU2tDaLVW}0kjkLx%L)H;bg^#?z zt$EvW^nno-YSuUoY)(dwPr>a`4B(Y#A>GKy z8XLt^c)x=8vHX^V%=@M#8?lO$_<(?5MZaSlEyvobIT^)i$^2<%W5B%B?-LzPID20Y6ld@e1s|p?qy3=bqxcvxvzpHm$|^jr-49B;FOrY> zQ9LUp`4rR0ar+X7J;zS$N_TdYIZLd?Q9LKHK2tJQS>F4NW4kq5>oc-Un-O;!qBtk- zydW@NN;#CUIV*Ucm7oq~Oa-4~Ngb_4Ti&!XhAUamlLh^PiZ9@zz*N~|f`%^@qpL?> zq?^y+ODevMuh0mCauVq54NBfHW@pb~L-$+8y?h>Dld1mo3GBw!dDz0%#(Q-M%X1}T*Ps5^VsOWh(GN^CJ{P>o@ zu8EVP!c6U)xzfgwyd0=nCeD>haHR3)MsZX6@H+x^fdQE$$O%^|iNishWi9v{{k*`4ydERytg zsPF$tXg2*~vX+B+qU0m$+|>BlK~RxhnacPnLB#q%uJQAL;7QJtBSMPTW|g(A@C?sY zOUv7Of7mpnfpw11UgH{>Prp~uCktUT?c`nE*kKlD-HLCD)zaUjlC(KA1Rc%r6#S*4 ze@{3(DEJ$DK&eWW(Kug^nljKpSt5*tDX5Y|E_YRO*a}t-Qo+i}kn4O*#|&c649;qa z%lQO#eBQ>B1XsazO8hEjT@Fy@@F|gi#hA;d8X{mGNr8J#*L=#$&!d`bfnwx)o!@p$YV1>AWPTdrU$U+xNC?!JOnVsE{H_5;M-Uck;_ z0hV(d1lCZuwbW)kW?=&bxD$&wpRUAa{`;iJfD{KQ?52o94pT)@TY`6B zDmisZ$%a|Y2n@NCx+H19T@^Y{Et0H~qjiyxRn&PYMPCtnp!zz}5uC;B8#r))M~hOX`O+erh150!gN%BEn_>wSW3+{wt6nFV zWW*M-X)U1tIxK-y?c3Y<-avltwu|^zM)Bw$}1(&za3s#5K?=!lG|a{kVAXGE=0M#;)f8BiD_bCFE+elgsrKd$n9&WdD`xYwTHa{WoiQ=*Sby z3E&`8>LEfNCZ$7ksD?Oa)s4`xi4MG%F6^S;G?=7(7!C&TC@fOXlAq+|kV6g^a0D;G zB^QtMef$%7avH>2;Aa_zL==yRnVjDi;xW;P$HhuKAvWVg5I8x0_AwGDo6O1SVin#9 zlDt;L@e}-%akG$tcM?CN+?$v_C-HOcoZ##i+?@_~zvS*hu=^EvHyPz8@oVnh3eJ9m z2zk%MZ>dit2+206|E0Kv7v5Uk#vhmNDWu3o&0_&~#YRlF<+!l1Cq-ZL{nv&?2B$q0UyC&7as;75s_ z!4FUZRbAb5QfI8}94`&X`?rE@}>+P1oGWa&gHof7kX>Ag)6 z5yngTB1I$3qqr-Vs`7;7QXB2B2*bmp1tFTXwaPHWdX5+gVN__NZo5^f?1L;DMVJ(A zC7Xq`I_TeK84)%TkC|F(c literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/R$drawable.class b/bin/com/securitycompass/androidlabs/base/R$drawable.class new file mode 100644 index 0000000000000000000000000000000000000000..726920c41907cd0cf304998c2e9d406e41fa9d2e GIT binary patch literal 514 zcmb7=%}T>S6otd6bU#UkIwhTvOrp5*nOq4jd;lLx zyb~0<)Xlx~4d)*2J)d9i9{|p#wOr^lH!96UYcBZk({Xj=$fOhr~o|HT6sYAP|>y&0)( zl9`!tL^}i*N~_|M!9O~ll5l8J8NtU|6D_nEI%B2fb-9RTe&=>z=#5PxvZ=_GoVxoMnj?48Fr!GM4YA8`_%~~Y#&2F2(CIz}?xT-7 z0-}(}LxXr_i6i3GC2o?El0=(ohbDN%K>g$m-Pg*ZN7WgEWb0Jj2nn!(P3j)Ds=AFG L>QOb`#~%9Ms~d5` literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/R$id.class b/bin/com/securitycompass/androidlabs/base/R$id.class new file mode 100644 index 0000000000000000000000000000000000000000..77c04488d1d1c4d294eaab1e870ff85b69e4ec5e GIT binary patch literal 1523 zcma)+Sx*!}5XY-ob{CfAT0lS!k^4|a@D{{_#Ds)sf@WVQJu?M1&USCQdlq@}Gx=oV zgCD>TWvm_-?I0*Gz5Sc2uCD%9)qel+^&0?e!pkyrFj$FIBQO|eTG&(CH@PtZmx)#) zNqJ;~h#L$J=0#G5P6h+Vyv2i*%cI~;bd0fOFwNswWzw3^#2QhCZH_p(#mIo|G3eb@ z(pWBSou?TVKIL~$U2;-pjR>`K0tOS8IN8%?9)~fghz38xy1liMtX;F<`D*izFDI|>kPvTy0ua^ zY*7~OLxI5(*$nCyYSJY^X$4OWkF98t)M26|{>iDA!NNb?{UodZbI#~m$s4&oJyaoz zoHa9+TV36 zGnlcOOGApc&(LYqyy4m_JQSGbH5z0vd(Q7rt46y|Lemsd{%W88zav_8f!_dWbS~l< zdI{I48C`kLKkNjfv#Jj<)v%@=BdS=dMby0tI+jg}ZQ%LI1vx_&V?KcRWgI zK5F|a=4qX4;kf;=)4msm!P@?n=W~k&;jPMajIV?XTRK>G!^)t#=k(Z3sm;-p;W>lF zs|97yArjc2AuP~8#x)p+B9w?|E};Xuh`T+m5chaoCGPdOkGS9C0pdZAYs5ny4-=1g z?Cu}+c#L@5+&v`sgyx{R7@sh{O#48@J60doDi}<$3 z>%@V_cZfGU-Xvw2>k(S-lfpsH0L9fW@ZfVU`6F6g0RU?7nAU2(FTxYp%I(|v`V@BP Mw~`-!1}|XzCx%3FJpcdz literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/R$layout.class b/bin/com/securitycompass/androidlabs/base/R$layout.class new file mode 100644 index 0000000000000000000000000000000000000000..71e597739fa241c2efe821f11f93d864210f2b47 GIT binary patch literal 804 zcmb7>O>Yx15QblOlWZGO`T>Qu6v{^_r4p>*3gQw8sZs<|LAlTF4#kyYBioxQCw>zr zBo6!leiUMM>A^@G;4=0zW50gK^W*2Y?*N|TD94h*lgiDCz*XaQT*&?tg;0>Kz0!28h7r=|EM~b9uMTD>-c3nYL+C3~mRG##LlmXBW=bX+2ZelX_r3XJ2`)*+xy~ z4`FeOfq?lgrE3AcPHY2}C(*rRWJ=ySqeVWe|w%W%2s(pl5pGi zYQk5A*AiYA-bi>;_*%l(g|`yEA$&98ZE>O`w=40MI4U{@`o~|f_ocIVM`CLjIL5xj ZQMd2oF79>p`(1p116haN^@n(bonL>&w_5-J literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/R$menu.class b/bin/com/securitycompass/androidlabs/base/R$menu.class new file mode 100644 index 0000000000000000000000000000000000000000..fb91fef64bcee6f2618b4307aaf3fb44f69b50f4 GIT binary patch literal 450 zcmb7A%Sr=55UkE7yBaqp#%Jy#KF~$Mlj0>H1QvxTxytNj&i0i^Y#7l3E&Jn5gLS}+{_az^Qu(th5LoDHW7MS8Z|9MW|K@6~b0@T$h@z6gYX}g+OQn^&A_V&f z6GC%nrm~Fyofyk#6S}F=@}`<+vb+~rAqoA|YdK55|N8rnKZ)oT{Zyt?g09CVt2!0uHt`2|Z%OB> zQrE3X>Zz=`YE3#--ClFvCc06kenF#qa$in_s9N160-6OjealAwvU$GJ3;X~W=9%`8YOg2s-dhSJK)GzjMf%^V5O z)Ilb-Y^d(fo)a|Hmc5bAM@{LP1&6iEhY@!~?_1HKIwxqBFWqxSM=fh=sVYL6@6oNo z{!E`0wA5K|rFOgOC^0e%$qpebBKJKehkQnzdIZaYpvgohK9Q+YK5wBeajcvR+A3m5 zO(W5rx)twHE%)B&p!Z=d*Son78k*;rmOEv;wG_~Ln#w0WE$X}`=o$indtX_!OC1#s zvB}sc`)I-_HhMQ{4W6w0@$UpJVFZ%=}=Jf>w(x<~lX; zvy);T5w!dw>+w*>(bq3>@d!s>@}tO*lIWSvK!l=Yt23J& zM|XOe33I-D+;q4ta}7MVmGAcIQ8h}Kz4m|`_}@0h9_<^SZsK0v z%~6R4KxNP=8U&waTmhe9JOmzQd=@;ycoaOwcpN;zcoICtcp5yzcosazcpkLCcoDqB zcp1FH_#F5=;|t(b#%thp#uvet7+(foVSE+*3gc_w>x^%JtBhX--(-9X{2Jre!EZ2r z6Z{tA+u*kuzXQI*_%8Te#`nPY8NUa9pYaFa4aOgWA25Ch{)q9%;7!J#fInrt1^$fj zBk*I!pQDpRm<>Fiprfh<6P2$1PEUU;T5Jc;&~QYz=_@>kiuV$IP2Uvyx5e{2`W~N^ KV)+jg(cC{X0WdoN literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/R$xml.class b/bin/com/securitycompass/androidlabs/base/R$xml.class new file mode 100644 index 0000000000000000000000000000000000000000..19c0ea9c2a910e574cad299f51ed6f5e624eafd4 GIT binary patch literal 450 zcma)2O-sW-5Pj36jn>rG`q{gPmSWJW;-w%Iib9p%H|bQjq?@vvh@SjSo&*p60DqJ? z3I2dy-n=)v^LF3-{C<4{xWrL_8lj(L%gAw3Se?HKUn%DzWo9{bCnRX6kJFwPZmn(p^k>sKvWGI!l+CoxFwya o(m=iciSVPkvMpE+0CThj!;06@!A^DFt#B86QcD}cJ`U0Q1Kmz)5&!@I literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/R.class b/bin/com/securitycompass/androidlabs/base/R.class new file mode 100644 index 0000000000000000000000000000000000000000..aefb64621e86e7a8b9dd99f5178c64ff8865ab3d GIT binary patch literal 783 zcma))+e*Vg5QhKhX=|;v)?+;%YH1Y>da2?~K@f^UmELcXrEWAJZjlpccEIO;|xH4DAdq%}hM*7ud^cszs(1!{!jbQK#i ziVXLkKwz0*rOb1Ue4P$f{Fef2gm%h&?GiHD71$u0q|EW;IEa(ap9+EP^mC4sAM>0E z1oqOu8Ae9?1AcQV1R8{+l>NSqJYEpCI0FmbJ}@cS5VnFnYvKd>qYo6{`67c7+awHD yvuw)~ooCKX;`0+*L6v#IMHV=|h&q;-E6i19ozFURlexv*VeT^bnFq{6)PDieWYW$6 literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/RestClient$1.class b/bin/com/securitycompass/androidlabs/base/RestClient$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ba93d61b488334562539622d5c9a7699c04105c6 GIT binary patch literal 1179 zcmb7DOK%e~5dNH`O%nnQ<^3*@(xf1^;UNJ+A^nYPndUw!7sJZ?v=ok`o!qQra++;hg5>V=?aRNDI<^B z3QDL7E5c(4!35nRQ&E zO@GCUF0bx-Haa%8h-=K{KRk|cIP?~nQUj@tz`}{L3(UyW4Z3^7tgc7>Gv;!jZPaFm z+RB|cO%$zZe;l(%efZD^V9TmeQEXYv2Dw2T7O@}@OxRl$EczxWS#oW;+v&6gD(l8j z(u(*tki|SVO`gXTM78RBhc8fpM+s%Np5oavW%jzlz6JKWnlX9Jt2_^J zL|_!+TNYw|v^fsp(_hDpEGb`K+~RP8KI=D literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/RestClient.class b/bin/com/securitycompass/androidlabs/base/RestClient.class new file mode 100644 index 0000000000000000000000000000000000000000..0ed315409fc88fd05f988866dab1ac3907f4d47a GIT binary patch literal 11289 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 literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/SetLocalPasswordActivity$1.class b/bin/com/securitycompass/androidlabs/base/SetLocalPasswordActivity$1.class new file mode 100644 index 0000000000000000000000000000000000000000..673b9ee70c7501b4300af46f34ceb681a38a087a GIT binary patch literal 963 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 AV*mgE literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/SetServerCredentialsActivity$1.class b/bin/com/securitycompass/androidlabs/base/SetServerCredentialsActivity$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cc0d3c8f2c8097d25c1ce1c176fb333152ac7963 GIT binary patch literal 987 zcmb_b+iuf95IviuabgTjQwaApuDf`QM<)mBd=q`XCZ+= zJn#X06k^uR18Na3!P0tX#xrMb$3K64{{i4BMh+SRVUiyQhLU-q%8x9+m&OEAr$w&P zOvWaNrJ-O-<&=twim;%Rbg5)!wv$p-9OQ30XbJR=WF>=4>VsfEKBA;_&=wdjpn^)# zhhWApe_w~0O5R1vl%%N;XqSh|_)oZ&Xz5}m47a7UDqjffj{XDQ#!R3U<|%a{aNdK1 zj*BK%J#^6%XpXGIYNRyn&5vU$-pV*5fqs-HGMmXlS$$z_*+vC+mM_cSJ84P%$T-h96S(MJ2MJS zaEf%e!`p1~S%K*F>{9ucXz=O6W$QVXp0jQ(?)cFcc;m0Q@TvA$v$pz+jedqc>mJ8g z>pCv-EpQ2g1uq;KXl%!4bHDn;hN5Esk&CHrEWac%?)5 QEcMy8g8O*bw#=-b-{-ppUH||9 literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/SetServerCredentialsActivity.class b/bin/com/securitycompass/androidlabs/base/SetServerCredentialsActivity.class new file mode 100644 index 0000000000000000000000000000000000000000..98973d41bf2ff3ad121acfaeb67dc62b989f24e4 GIT binary patch literal 5600 zcmb_g349z?9sXW+lSwyINYnIgp{;32HffimfF-4ngtjasO=UwuIi2jjCe!TBrn9qY z3uq{(3aDJ7cp)eS#iL3#Emg!@@xlX7yz#{QLQ#(I&CKpjk_PhgXWN}OZ{B>JA#SANDXU$aF=+DLajhu`nq?3^Lh_pLw znUa=c8tGhH(lJMPNJChl-aisEhKFOt6@f_R{G7Bmn=+jeSkzhEwA)M#NGG-_WjZ}_ zkJBn}RAw6)@6OsOe{)UdtgI#5^Ny3X1Qtv_>MihKIMd&;k21F98=L--#H_-+YM{Tv<3o4$uZQ^wnd<>bEh$4#L|W}5KA~VcX4SpndThB za(az)URI+{VChSlPM~UoX_?MOQf+MNr8XVel#C#R1v=)UUf}3X(~?{BnSN>a82xFf z7-y44y4SExHTOS;9cn1hF*CJZN+fDgowev@!y&WzjU~fpbFuckl}gLjrd}oCu{xGw zS!gtba0CJ?b-V%%bYxCCuIXt6Q|_ipjq#@5S=_N&M+7x$Z=;STM7ftB2-sF&Nn=xq zp9`e2&ssIK2%P#qx=rz4t3$`^(5U7Kae|H$agu<(!?aRL)b_n`f^qd69rf_5cAlZ58nZOC(S0-0?xnofa6$xU zqC69{|7uMZ*Rb69b0fV(MR`oTOEv~p-wZ$K$A8-TSiIAVhxja5jE4g?_|9YCR@^)64((mqff^L*iN_%OM6Gw&U9u6OeT`!8mDfb`lTrz8m+|Q z2rkB@8ZHT>OFt9#WR0Ao<1)OO(qxPw>1lRS*|3w-T08*LAdyzZq+dr;Wsh)fFuOYf zsf@6L*v{Gmv7NcB6+0)-)`q#Rc1FoHqs)L;tK7Ezja%yf(@>KIZ=3#sH^9)YDO zWd#~s8x_k&>|D9G%dm_AnPKKF(N$-TjlfoCn4DHmJhL^M$R`Ke(gRsmp21A%l!iPb zZL$yA^JY3FZAEgCN+El6?8W5*vxtJC@8+q{oqUk?xDv0`@EU42c}>SCt|F2~RJQJ> zfe7UCp6>pgGU>D)k)(sGRg7IjUtPq z?#fFmDO;z9+I2`Mmn@9n4&~*y2+Va2Xl7&a?vg?(e%`9%ZEitJXOlyLq_5%a1ZEL; zMU=X(i zn=N-pTZK>}X-mmO8^Y&x9K<1}W|Jg?jqL>1)PHWV3-i@df~)qVWRlVWs-h@=MaP%$ zm=fb_I=+s_**sEmS6^#Knx&SNdRd@Umd?lh<<`(>71*PF3r}eHHtT9JDyQt!@g01Z ziPQ8>QjNy=k>pYxElUFBE*JR{G3r?D6QE>Erk*d!rSiv*bo|)OAIY?2YErEODLXl} z_EQ}{!_U2bGQq?pQ_AuzIjaKd7DKPR!E;THUBXlNm4;smtSD+c?PeXn#&4*V zWhV3+)HNq-lg;n&dks%Bs9u(he@4e26t_xOXLbHhI{u8mF!wVlW|RcHHqiM3f79`I zWu7@6^4#vk1D!xcKQmRdWZ!9ZD+;RNUjiFuly;SBWt0c5gwM{j^0|^0^IRy*o2g2* z&*^v`FAyL`Dz!On4A7TLf{l4m2d_>LNi_kz)v;t!=5h_k(=;Na<6LE$NFtlJlXA1E zZc!^(Fs8JZMKRW@8pc*HZn3@XQ1w7kfGW?AnwS*;ii_r6-Vi4DyPBw>H;RrfZDUYQ zYK*ah?h8@xDpaT|1m7yu-N7AsGjK;AmoO!mNe(dKa+6Rlfbz=~*e46CBi z0*-qW&0|;-jn>5qIQ~(r8^bA_ys|i1&q=F0*)WEU(TA|{FwWdgG1?2*RF-75tJE4Q zyOwGlPc=@U94DcX-Tle@+m2J&x1ZrkI^UDVmy~iLj&mq$h4QH`<80b6TFQvo5 zrHoqIk6r%a@Px%(-eQlpco@$1Xx&HwyAR@uaqLr+uPxvW1-y~m-c;gtt9R-cpX6;5 zM7iA+Wm(1DSf}JJ;LgLiYr8A+JI3*@)543wb?<2|;NCvI?59@u_C*z=2lk`Z-St7A z+yPo<8ID7gmjE?xVhgXvezxUm9A%@b#xXW9f&7%de;H z&!Xiwp_5;`czfDPO5I3d8+OrWqx8={B(R?=V>ln<=w(6dV>P+}kK-ad!9Mg!T!N=@ zDbv+uc#ij-D)fuFq@ZxQgTYTf`re)`G~D9?eKDTJ{d}vSG|%8e_%LN{;fW!9gm~RT zxrcCoZz=cfqkP*(Oby{eQ7J;b-CiLx;i+;8CjKvcg##ljlM=1Tr!)M$_wYOpTW zVDoofUc()WPgcRglI;h`J_?}%WNq^yJj{NLuUN@je?5OHfadeJl#u^q_(48D%_jrt za}V;XXWqqbWSb1RAuLB4E9sEc$P)a!0)Ssz0{mKh0beBVaZ;#6XlZ37C#>_nIG2*F zN*?u!&6oQaq+ji7srv?@@y)PeTH*S%jyeN-$a*g$?sC-O3YXb(?`(-#J-&zUlX49s z^auE%t17!4pVti>6|XgZD(EDaC;9uyA^bw1tK|@WE6~T`j~w{@P8#5^<*;AL|K|X% z;&UGp(ABimHFW2-Xdna|aXlS+LqMoCzEIUzg?|u?Y<;kRHv6Y56uT^6s4l9e{4vK3 zkh*6W9i34!f1u3xC|Bwmsnt!)H8%&$JjZ8JL(3>+sJy~5>XW{}C%w=k{clCOx$Zv& z{I_os2hYB@ki)IC?QInF_5hcKB`&j>m&v8JS_sCGmvL8d^wYJdC=2bS>o%8+(yu}& g7gmT$28^lzA$9{#39V|Ds1^~SSIxqi{LViw0uMs#ivR!s literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/StatementActivity$1.class b/bin/com/securitycompass/androidlabs/base/StatementActivity$1.class new file mode 100644 index 0000000000000000000000000000000000000000..114b4d7295394f1e958774522aece77b2d878d7f GIT binary patch literal 1163 zcmbVL+iuf95IxhRabrw#DTF(;5FkmRZi@sJK}c!TR!E_JD9ZcBS+(0b>&WW_@mWaR z!~-9|MSS+5Ub<^@B6|SU+8We zsctAb#_tFt{li2gvL|)Y2og19&oW1+3HcK-6n-f5k$=!RkwM}hLs*%_`$Hw)`)&S| z4|FqB!D&mGL~0omGRd(r<#kS=HCqOC#(1T)N?sG{m03ZmZ9=*kb!8TW%N`soxJV)A zA&WdARk04ameO*6(Cf(fo#=#;P;5nk2-_l7_B=7BZApZeGv-p>;F6qZ+$ch+(wb^x zz1nth9XB1^AUvO~Zys*pHeo>ofi$MPNief_?_#BH3w^5eQKR2y4TwZVy6)mGmL1$9 zytq&q(-0n3EJL{Uvnk6TX4ziY3p+UwlQz-yZ00D48#U_eQhgn;{RDG!A@1VTxG3 z;GYS>G7B=r?>s1khhVyqM% bv+o=#sPdX-I%;@o@!2+yHLPdssEwZA0>L}? literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/StatementActivity$2.class b/bin/com/securitycompass/androidlabs/base/StatementActivity$2.class new file mode 100644 index 0000000000000000000000000000000000000000..55bcef39bfe0edc40d4b2ad7262faec3440beacd GIT binary patch literal 1970 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 F^9PD`ZJz)D literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/SummaryActivity.class b/bin/com/securitycompass/androidlabs/base/SummaryActivity.class new file mode 100644 index 0000000000000000000000000000000000000000..10a1bc3a47e646cf3d7970c12c7221c523e5a6ca GIT binary patch literal 2785 zcmbVNZBr9h7(JIjHiQ*vjG~5GuoOdl3BJ~fRznJ!HUvu|Ew!!PY_7PHY|`Bg!l(X^ z&UD6ae(p?#nL6zc=#T33+|4e@py@CsGk5pyz4tulInT@e=ifj725<#C8U_TenaxJl zm1f(qydA!`4A;#XcFk#8wYpJtvsJ^D*>bzlFr1y7=~-Lcr(saw=Alk581|-RZxk)p z3r`CSHuB!Kz^P(jC~G!tPugBKub$i9yue7axR9NEqe|T zx#wsx_o$SA@FbVduRJPM$^xPwaD*VPXV~7FQE$r#eTBeSu(e#tRTh^QOBMB9bRjCM zxl(y)aaDb$D$(1PZF!#yMAEZsG3*YN=o8perukWdV#1Y$YUY_@IBjUgp4 zT=oo4Ht1OlA9Atc7`FRVI>Ti2kq!+p#lW&cqr8m#EV+Rns(liWFv4Qy{~)I%`UX6peRkzXQ+#>p|G<2)`1 zjJneELqkz5`GSI^3+jNtB^_BL1Ws~CuGMmyEwc9Hn&nzmtIkwWu3pwLgs6tA0;w?K zFRa>z^s+g}F?Mn_qvc5_B8Cx(Gc#`}l|L1j>k>VfAcfw9SgAgjrsumL@R^QVpu>u@ zpLHE@3f@HvjQ1=Dhwte49Cw+0GzAQ3d0f}Xt*yhen8yN104l?$+%OI6}!NM%-1b*Q>{u{Is#YUQYMIq@^JbcN2nIl z)HSwbt>D+1Dg8`mq3#RSO)Y_ex*;&Jztp2)V2JTb){VApJ}b*QV<~H8(~;6vDfYFF zRh44FhOof88!9>;sSU>igs|qiJHFBJZ4X3PhMf(p4c9kTsIhs_4|8+bX!&KQ;d{y! zsv72C!S7WXeiXQVsKAGm!v+|~WBjDzPE{^;wGZ+AN@El3X?giN+j5Yjrj8m|#z$Pw zaC(|*>TRSBQ$Jdx9dSY`tl0f2^Tcf4_zH$*t%db!!)Jq zPR|M4de8C*+Eh!&ifUx>a-JCHhG{+UQ!)hKrh&=3SV*QYG|{`g&7bwtxikn zR~;JIAy4-|!zy`4O<{_;uCAXU45)U=w}iSO_&kkas7e@7mlJf(kMzt(IX~JnALA*Z zt|^Ykc%no!!RJI~56MjQFPvD9BuqCi&@@t&=-AA6}IO=mqVi4mVJ4GE?_xHyi;J1eYs|gDmG#UYm`hyacxDgRmopc3 zag*z}-{9Ul=`8GGv1>X*CxA&pPSMq~bZVLeW^e}QIGf==&Fd(`_I}N$HQ6y8&>{(Z zg(8W~;5e4)_5lBkdO&sCp952=UlFJ6hp%ulHTcqhFTaAG8hQzh-`5nO2x)+ZHIDPt z;x-B0!5A-xaooiO`}QOjd=e)JOVE81Q&{(7@g2WXn~{+iH?V&NEFKa}9Z0^x}nC^IvDdQj%s}XKl`Htm(K*}9=5O@ K9mYM*`TGw-^R9{j literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/TransferActivity$1.class b/bin/com/securitycompass/androidlabs/base/TransferActivity$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8377ef8af7e30e6588a6f55756ce3be78f7023ac GIT binary patch literal 915 zcmbVK+iuf95IvKmapD@9rVz@Vwg%Evswo0-DMCO*B_u;1sPevEZ<{Ud8hM={J_`v1 z;(-s~qY$%c9#G0tEUkBTcFvhSGxPh;&tCxUqwAqUcqH?a$SOH1borU>kHXqWn6$`s znu)|liLfdIQWx^aq`^mAArH49UZ3>UZT78NJ{0sL@ zKhyFMgs0s(IW`A`T0c)!6NGaCJT!b%u@s<* z7NOd80ZXwq>fPuhQN@8sGDT>|xfIzz6xyAq&YBZMcrxEp!W|am<)>95bh`1G8t!fm ze5~S%hs%VAa}_PXRrrL4kWyJ2J|NJTu=1Z=1pj?LDx})ePVvRr{%^a+b8TK5ndMfS zqqnLY=4pU+Y;Xb=QYcX}@*gF+jb4pRnkiO72;LYTgnq{3rmTlMgyl1mIl;`};1+kP z%4-4CYPp8-C|7tj;j?#2Hs4MFca&VQN2EIZ%i#-S6m`5Z9Dc~@|Och-r{ zl;s8Qj-}E2ir@z>&2k)a?%{-^a~e10U<9t=I-{$&!T1Vp@|%Ggw{8s~TW$6&;5P2o I-PBFKza(Mk#Q*>R literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/TransferActivity$AccountListAdapter.class b/bin/com/securitycompass/androidlabs/base/TransferActivity$AccountListAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..a8628a63e8b8bd6caa69e8910d0758c89ab86eca GIT binary patch literal 3164 zcmd5;YjYD-7=BKYcAIn?N`XQsmnx;E7a9dhu>rIsYemm+6hs8}2b!rhGrw$jsc9;2?zamZtlOV2nwCY_Duh70w_>^jFAGd$Te2%n zh%=^TdglZtlPzKlEeb?t?7R_$K$i*y9WjKlLq!zb0^y`Qup?_)#+A})&TtmAT)`0N z$=bSBSkxR-t^;92IwWwZHB*| z(=v0}+ge#ml{~YMlBtpI#3A%6I4ls~zN6v=^pa-Ryie*BdX({uRe?Rp%up4ipjpeQ ztGU~TUWGZTVh~5@GSAZ5qV1ZVXs>G4omRl~8GWuS2?{)hNt{)2P6n%+ zo(JM;;>YkhrWH()6hFFt$TF5^EE|rB8O$%Mq$sCCmobdGrJU;ru><5iGBnvgAS1J^Vg;r^ zjFFkv7<`?(?2fb2q&w22g1~{~Y@>Ty7tg_xnQ|$H(^zyeBPNaHnotWyA3^TVPj{x}`fs%`s%B+}F5WEh0K3n}R@M^F&?Mux7g19A(F4 z-d6)4+kJhkd9G{T)AT!+wPMizcaWM{$1cv=YnCiP*$AQn4_Z#g=c?W3c&$lbjIZ10 zGR0yH;k;dPbmP1!AF@65`eV{l0W~Av>X`z+5DdO)JwY$1`368gF~j_|L3DS^hm&6# z{LGM-P}<4WNv=X1W5XjqLmhsM_>WwLu#^AoJVQnFaIVTZwRT}QM;e9R0AYfo-0K?t z3F-#+KEXkO?L|eJ0jN#EBx5_!Dgkn})#0 z|IXhh|5N@>lD~2CcZ&RtlfTpCZ<73_$=@0Bcb5F6$=|vEl)r9C=BGgt4>Am4(%U{f c@)(~ruS;3GA$;Nge~GU+%F1Sc#RG)?2Kdh%fdBvi literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/TransferActivity$AccountSelectionListener.class b/bin/com/securitycompass/androidlabs/base/TransferActivity$AccountSelectionListener.class new file mode 100644 index 0000000000000000000000000000000000000000..30413410348d336a2353af5dd4549910744fe813 GIT binary patch literal 2217 zcmbVNTXWk)6#kB{iQ~A5LqaJraoqs6TdF3c1aL@6b7>u1tBfqi3p)?I!Br( z%$_U#XFTs3o~IeMGmBFs7grqkEFMJi?CiBEB*?b*pRmLHwl&Em^P}VCLy-%SYi@{OKD6Zl|mG= zX-pwYh!#stwenUPNldUtP1>T~J8B8{z-V;@AzO1yqti58ss0DTn97ataJ;BOPli*T zv_@6TIA=;uSS!}T52!L+JLcok)R|SP`zrs`?o(5A6$HE_-XmNaoqg4|#8bWJ>xXw4 zE0#CZGYxJW}e3W&&X+f0b5hSPIRu_qP3%>SRaZz?nrc28BZ&(NbLJD*AjJFAjbZRY&# z4&NDq+rLh@63!u9$S|6}9CrT5Gk-?;jU&Pj(S>ScvhPQETtg-9*^z6}-zP z7g-kLzZ{l$7U7VTyFYj(!J}UO0dukMkmE6<-dDJq`w<^T@EbmQ1?@RBr4bL+`1m=d ze@5<`>?ber>8~o>SP*VO<%)mR#eo75$`rv4#c-eE*ypiMi6HznPDo{c626WKHaJ`* z`vRLmayss?HB}uQUt)_r+~v8doRUzz3N`-Evhg?`Ku;+51w2ILKkcYs82|tP literal 0 HcmV?d00001 diff --git a/bin/com/securitycompass/androidlabs/base/TransferActivity.class b/bin/com/securitycompass/androidlabs/base/TransferActivity.class new file mode 100644 index 0000000000000000000000000000000000000000..fbdde776069ea538b7642d8b80a6250df067b559 GIT binary patch literal 8352 zcmbtZ33y!9b^edGk;l)nJo3K8vSW-qG9K(06C<<8vW3T%ENlty2A*b~rDxB^EM7>! zkU(hCHe0hags>%`qzMU5tdWfy0wie@plL$eltN3IHYPM}NxGzMN*m`tZo z9oinvw+R}PeS>zcJ(Ee;F*9$cQ-ZZ!|EJT+TS;zGvON|{7gG5gNp~GI51Wxf-cCfi z?3|u9sn;GznfXH25?nWCdfmj1_2{=mlqIT|P);jUBUmx9GkxU>f@QjbDSg}9xAt~!+FFRqT1|q%rEK%B4kGB&e zW2F?-t+P{h{u=IVS+;{1?nuY2Aga+~U(i-@tYzkTz|58sBGS3Y`a&w6u-caGP_8aFa2ZxqAFoCr z2*EoHti~0BhMbjmjEwrRts@kpC8`_9kb!rq7_+&8W|vK8$adb^Vdw0AJ3)h=#6?#b zs70MFUuWQIP#Fyb@+d2v*Rrg{l$psyDkj?kxQ+*1q!sJ=>kR}@AHW9MSlNi%vsv?) zqAZ9GwCK9)4NO9?`gj0SmD$Y(wxEmPJ7A~cD);(hQJTq2%3k92Foz>LM=rN=&Ua0t zZB>ciU|k z1Jf}>d;1K`#0=H!O$KgO)HD<_aiYbu(_9eUFb(u0MvGNI`95ZG8L^`k>#g8X0T9_+ z|6iKywGtMesdP#~VbS>p5yyb)b5PKBvHEljr5gtg972LlmU8u^qIoOn9%se<(*$eI z6VsDV0k&lPT@+n06$&6t_c;cBuBTVs-)f){(*jT*a&byp8AKKZ)y833^u=mJy+#U0 z4IIO5bajq0I`~*0Dr;eBSqmlWqVS_uc~VoL+xftak=lQ@RPN&jLTH+dyYSus-b2Kd z?O#tca5wIuJImR(5k7R$QN`fB27XK3oOeZ1^x}8wdIQby1#fJ@i1Rv$gqyDiJ zdW7g4NAumL5`E0T$CaDfSi&;1I`T;azmHGR+1q@Y&3u~A^UP6ui92VU`#+7(1aLp^ zpiJ4HHSho)q*hXV`vuc|3JHDgdioF2Na*bz7A&6-k~}$-zt0-@93G{j&3K$>ZK-%h zJ-W;GC}%?kK94U50)u95tHT7ZW>59;TFedNOZajCkCU%4*WQ;l^+LabC#Zm=dC1bx zg>P6HPGjT6XoVy9{E9=QO%M61fv>4{YjT6>BS8#fB!D9Ina&PG4(8IS$mZUjts9TV ztcg9q2l1@3_D%n7v(u4iPl>M}zOA!=M56wIriZIYdm%r_@Y!ahoX%G45PZkLcU5-7 zEHAP2wB{gQP3GhTTmesW(UEp3rs-&9!G-GCS zmOFF-&1_KC=2IzBXGlO_g~qZIb^~W15tpE-PWq{)!!GK1+R`Ei%1 z2;=N*3(72+6Oh@X6ya_$WUkDkx({o9({q5>uDoR5`<}-PNiL9u0ePEX)r7qLrhGnA zGGs%VRgqI1#+fMR-0bH|vY38am@sX=uyd|prDM>{_FA_VtW?ZuyP(gO1sJK9r995J zpsW>dUZVPDvh_1rruyD+VSU$2E8~Oa1I)pjJ=f4&FPG8pH0RT$5xtcudMlS3vQm9y zQ^G8yVuQVfWYWwY>y2eCD;1D;2o{zv)`d@}6C{+B!x-0e(r*|3b?ygIyg{(2Li%wx z(~%gAKpd2*Qdv})Sl~YDe)!OJOPe9<^pm%;h)p(O`VhnJ@>)@x01x&8OwEO6f(q4CxkTZc~{3XBl(3Wh&iQ3fac&(lowY zlo>P0OO2Ts`mKbW3C6n}#T5991meX~-^( zI40-QH_~lqJ6LT~GJBK^okgvk$`ly>)Db0x1UvP_w3W*(xm*yv=;+<$rLqR*lU*qo zyjZdmL$3GA@xIH#tSWbDar-Ztf%8;6p4N#Lz9%=xw(_B?6+(js{zg4Pus2=E#;i_T zt2i@!C*(tFg`PpHjcQrXL9RtZO48PSq+c-G2?%q$Y3D6t@n}q16c9%IEB%FDNc+|~ zWI%|Ixfk9>Ada7WGJEiDMU$ygx<1<*Eagsqa)(8HqqUOOfGRBsX-!Q_GfvCW3uh-g zeS_nymNI~wt!!6tN32X?`DS^ zcYZMpu4O@vze~9z!dBSUhDUJe35Uco{?<8zmmti(Zr}p6VmVv7EUe%!H%p46RUCUI z+&Y3tIJB~eRpBDmgu}yF8)mQVX>k0!VRVMWp-n|ZpGNmEdib%;|Jcq& zeY?Xlf*r%yUHP$>tnCk<|>I>pZV%7c$A|jSsrtPl-h_GPDWpWtac)UA`tPvem)?Bw8Mg8R;$9l{;DX>I5as!!pIMVtsN zZY|>EDLlDz2r+l+>B^~R+^J1n&cbi$7w`Cwhp@(7{9H{1o#)-f^W3TLRZjh>v(sVw z#rqIcH4nik@qdEi0&B63si?L)nfGa%WrnBi-OS9ieURB!jdL~qjv*YSc^#wa+(sR} z3zxH9huc|&y#t$ZoK)__F5CqR?;)l4B1by6;~xILkH7cgqr9XC@qVTXAHd@*evIHl zyrvK1JDm9eKIUA}cE^BU^scC$CF8$vO!*Q5;)mp+il@zDcKesSqg_t#CH8VO>!yX<+&}9>Y%>YyiW10(h4H zzP&Ag7ubG(R%1QSr+el+ZL_+bTBIK36QRXt@apc+-;Ut#sN%Cl{IrPIL;u7de!k&- z{(_%H{Oc+F+fH4iGmoK(&Dzj^cn}y8MbRBa{O4)BDd=j5ww}VTqeGZ}RgErek{WO2 ziI#>>J|NRL*v@}vi&D$x4K^)Bsb5p$GSnmnIhs*Zlm_qMA$-uK6e|oU}*?_?xac@Zjxz537wLeq|YTX-#w!Glq_;Uu47AFbT05{mSL_m9i01IUP3D5 z`_d*M)>UOH4=Faua$kkcx34|dS5X@)JZ*$WBr*imMx}~)H+yK!{j!Rf{Q|2nFF5UY ziD~_QjWIr3{yyuupGVL_T-;CB{Tce<`-$%d&_={=!NbJbBc%2@I+sUT$bAfH3=!j> zC-S~XDvuLDU#2s8oE5jP@T4dBb%Ir#uQFf#8p|Ii@jNZAONo)^G@#-_Fl&-u3O8$qb_vDUgDVA#tH=A z#Fle(nAK_?GOJpDS2gmlwJ+?WCF~2xg2S|qId7upSA1Nnw3O*u1?8`Gp5<-4j-H}i zwT|s}wpUj^IAdO)3%)$_^o`*D`E1Ki=TcPw9YZ}`LL=3>fTka&H@||WejV!soA4vt zfFC=`YId0^Ih3ee?Y!NMXqRi)tKwhcn0tB5@1X+pxt)7Pu2q<~k4Q&XYm;;q<@%lB z)}m}Fa}nZN;3sq~XZcFK##+TsofF+xX0CUlLD%$4=^_0p4fnirVxE!~sX4V)(_E;c z9j-yO@{5nKI*ab*Pwt(;(@pa+WVVo_??e1AuvBw;L&l_X+TvM^9Ut;H< zGa~V^yuDGe=Kv0Sd&=UB$iUcR?(?@$6SnG44$2|6Vbn@OQj)2gB)3XV3U!lc!|s25 OjJ*$2+&J4KsQL|o^CLW326g_Pz9$6V@k(1bjB;dpZX<}z^60=w)U^xkh$Y!yvki1YWO~-CLno-S+ zygd0k_yV4(0-1s;if7*VABy6%Hk(8bt|_&8yXT&J@45ZgzrXzf;2vIB7!g>khYdGY z^;V>l1J0W=j$IjeQK&s%)?&9NW93%0+FMU#q8chlmg|Y$2U~qh zfs2g++#?+~eR&`-Rq6S4_f&01C+;&112S0!x)skscZ}$z;M{B~na=z?J-fa~Qj& zR^a)nSg0Cm6E-g3V(Ku3OcuOpV-iyW=VFztgh9eQ8hpl*FB=1at2W*=u}tyCa$3ERmZxfedarLXko(KykX-lye(kA)PZMEN(W`nkSP}ibauJjDO=IPO`Z);?HJK! zY@ETU!M$zcUE~GEwp3E?P$aATF=oBX+wGneGjN#axG#(EUTR+jvcba4;;x0c6JGys zX~V^P%;UC&sxvT~8uvrC4}jfbQA2j|a>fIdukAmb=O;2P}C| zSDgkHm>5XzxB~=)KH1NGr#<12TVE@tQC|yOV4UFfomJWFHEwo2Y(;hTgq5Nshc@P2 z1H+8*jo|Yp_@k;hj&RO5g5wxhF8@1c&JnUdb&hS0qn*tQ80XyXUcfn==Sr9^=4g!n zMw%Z`b?zJ?=j1N6aoK6(4adn{YvcN#nEnN~xbe>FY_8D8ogXmMnar;_KjYT#Sa_cM z;0PbhwXxL3r)@m?5#vtov(&Hnyp1)(CPnXngDl4@3}6yxF-0C%agEVr5qc+^ypze!tldByE|L6RCPtc9~n&VSYb??Wfed7CKxgzahRr9cK43n zzIVCp@yDlQ)I!Ah=itv1!tJh-g$z}4rV$>R3Wh5R}hf?MZRG-*)1 zhMQdNN%Lzo;{=K}v%Qy{xZLaCJ8ZXn-ZOu7(C*1-y84`;9Wmi%yc0|BGE^{Z%a2m0 zoXI?^rZ^^8cYRoo!yey!I=R>@GSBXFhr%(*e>Zub*z0-cN7g;2XZf)k;*K3E$kWeI z_g2KdAgcam8f2pi*DnIo7=?$yDF35rxEhLpF^MVW`DXv<%jT2wGGJzixt`G|Y zWdjN0b7blT9-8)0HF4hjLQUM_R3k}WV#=160mOUA+JUACOw@RzLf$)#{X3hR1fSj| zMAf;Q70UIFIzD)8M1*C8Oh3`a`s_JlxlM&$NnheDV_d$Oz;dR%TiYtywzj&9S{B}C zQCo742#;4bEV})CPvIFjgYGJJxeC4xNVrgz`9|zj%+p6hl0GCn=vno<99?X@pWeqh zEqa=6g>ZxmHiV3SYr0C#S z$J#e%?+h{`?>K%u&psIww~btDsEMml{U!9?Ywu_aUrdLf5mEmBvS}-8ew|)7UR~KG z?}?#mwc)`-S#lh)gXN4{!wFTJ77t{zvQuLWcGpRN*L6bj6Zj^e=b>{j7}@W-wsW+! zcKA)v8r2SX64-t|JNq1Uc$w|+i~)%>n!&h{;kRR`(CDtlx8zISMilNt?W|itM-E0o zLdusd%oRU^;rqh9I;Sedgp>n^n-80cS@X^KaF@x)du;MjEsvwc8V3U9Aw{ke+~$QD zk-HnOwEJ=!_6|~O7`G%OC@PDX5&0p|{?)mA@26AyHh4 zdyY1v4(;XchQLl28@q>1>?4F8Mvrm%ThwP2w0786y?ZXGdPLi$Tz=EJS00DC@Afj? zt1`h_UTjpiL~C*Fi&;*;IGcM3!%P>lmi3*(;S@O`@9W$nsZUvL&~fwnWOXx&?@q== z-bwzDJlKXoyR#lp77^cMyY-gqZQ)aU9n#nKjTH&YQt3o=GIG;p+H-I2-*3ueFEJbZ zVpyo@VG`j>bY5`x<9N#PY&~|b<~3oBYkc12KALwDr{XW!P)%T#TqJuJK;~#9{3Nh$ z>+?M;+t;*$sLxcJo_+IC{d8_4VNcGNQ7cK!QLvf%7EW`7{v4}wO5Kx!A+n9=Lj;r1 z32w_`To#w+7Q-0pKJ)!#g)hf1o>5r7&Pox zFNs`rIUdug*>ct7A=MDGr%F zMb;k|ZZnKk(9rEGeqhwz-8wE9y`%`fw!w$c5~R$UYg#P=(Dm^d&nGz zYO#bKiki}x%o_%}N*Vo8HYq)H6QZv$4?^dq8e8WN=juPks$vs;O3O%lHr`dnuI(G! z)|2UDxiG=Ac~`(|YlK$K?e3AlASzl;XMW{=tvIGOG6kGUfMpBo40#p08U8h-dK5Nz zj{vwTq-Stb2v1uYhzF5oga+V|#goT|iWvB;vfy>#(~U-|ZDMqY#agToR+K)`s>wPM zRLe8gMeZxCT%Z(-oIp zuWP$=M&i)VehhWin0^xYWv^*1PHj41t;KeRbsbJyRiRP*kZcd`2(d2UVhd*bC$1uv z7RD$s_#8Mj>GaugnJvzBs=gs)fZru}Hxbk*=(90RGlTlYKv>=XEhXcojMY%*N z$MI&W67R{_^84qJgeZSk3*bwbfo#@0t#g~3%}zAskNw^0k?XDTGfMYTZC z+{8CJMl4gR+AWTiBd>LDN7J$+Kg@U-$|c1cbc1L^c1F@ng1X=C~uk~R+6op%hP<`q^YR>s3G-YI>o4E#)W|0p(d+33nM`>HP!q(<;N(jH^a zV}uMEO?$@@kj7gp=*^`2w(FDoR@c+`GN+6iZcTD_3X!{}NfL0pr50-g5pf^$cYbbRM-Cp8BYuiD}GhEbTT&^+#39{j}xp4?A& zc1?4kxJrM{bT-Z3gpSoJwgWT;RrPY)E~Io#k~mMl3WV z(XtSEy9SGc{otay4Xd^9ZaIaUV_q?15hYuH)HlE$#y~^G+aM#u99iHXV{keJs z+RG~B-=+jN8#{+Deb|#hdcHIkzi_)q$@Uhtjoddi$<2pDE60W^{U|DTuvB)rlF70y zlxMBKCT0_wIxJWz=DcZLtZ7^Ht7V+)7d(hdN0)Jx-&r{S#eyu;Wy^WaaX|R1PX@ts zfyq+zp5U^-@(tgu<~^d{-5@KuAlegbH4717FseV?z|Gjr+#cBfukk-x?WuB`ICkb8 zym1$JG+ZP}<`QfLCLDTqIwov(M3iR>N2(=AH%CnbwoQvN=;-gb`=f50!LAu<+l9y?wY}w zAL#4Jo5!Z%yi0v_e^7HN%_Lmu;U2xfUF*IQ#R0aD8Btiow(*p6Q9g?HG+*uXUkZ+G z(Xa?bJ$%3e$5Gd=&>Ov%uk>-PD?0k+Bnu_$L{8q2@P>>CPGviK^@GIQrKa-A=)TTg zYIiR0%iej*n%nrYpKsGT%XID`(FkT(W*KXnri-%RdPmcQT?MPTAA8@*K}zcEmfaiS zmzHJe?_Q1A-R$>zvsrnN6YBav?|f3V>1xTSdcTX&fw^yQ&)gCB)t2&a*?h~ola$c*$emHJ(Xa zL0&pu_00ek;%jE!a6*o*C0rbi!Ku~|7Wts!FQ`l`*~5EUG!I_I5(PFRk37Fpg}U=xcpWD*sB%Vl50!#=31<{eb_Rn@ zjcY)c{Np1Q(YG2tW6#Iw#oo%%4_5_9$Zu4^bEQHU&jP|&PI-rx%U(6Lxy9p4_fo0-#ZUy7)yUd z+Ee#bHp@~kld|51EXAwhty9UOV(HOnHqLu`4i&iT;}w3){m0Ko#yAXmZFO&s=>*oT z_h4Om()Shf?GD*&!ePm>y068X`!qAx7q&`L-`rO<9N(52)Ti~kp`LN>QN-Q(GTzQH zo8Gn0&0l=`t^2;dX+H8k;AjZR-Knc#-F_iN(nNYJinq~gczo`69~SF)>|}qI!u*jg zy15uTxLTOI{Av!5G(;Ui7L&ET??N;l)~~#$ijU1F{hCH0Uk*S1wv-e)^7#8;)0|bZ zbET@(rTB?Q!My7T*qXP*(O9IqE{cn%t>1jMOsa(?ASbwNy))I**OMVyDNF5#6^_rY z{#42>Es~L7nSO@93TZ2VdYuGXxGuvR2CRt}W1lx`K@kAUm`V%RI%e_f0B(iiD}L{7 z;80U9-;{khouA@4j&vAahm$bCqpe@N;JG_vYx)S&Fhs_)JCITQJTcAP;&v`6xEixj z(R9yORpj2!(+ax0G2i)2Op8kGywjCIdU{iM;<;|<1nRC~;H1PorJnxMSI_%v#XgAY zj%Lxw><+`%&Jhi*_Glp>-_Nzy~sV7m)ca`t{K^*7#399TD+`+rnTK0If7-78LGHp+sTtET0TKhpC1B}!A?s;RS}fS+@;2-LG7`#Pmgf?dH?_s~9AUsS@pv=Yuzs z#42ziefhS?BG#^b4P&|eM(9BuYYeiFp&r4}T;ieRCoAPaXYR5Xr%aW;CKik4_glvM z=8F{7N0^J*>R66zFQ$LD)bX2mf}cUW+5)kQ?)SI_opQPUrxiy(PC^-80$bXjYeq4g zf$oXXb5!k??5Z!=aaCM2h$u|K*1Q$(o!InTV6lO=ev{(FPlPUN9{X#0^wYg^B^tFS+cf0J;T_f5D>qz93gdbBg6S(q+bmYU|8h9HJ9 zT+9V#^PT7zzRk`)i&QtAjdXt2w^s!=llt@?6gP)FZMQ9`TUaapcgWJP=956 zpu;yL_JMh6!g=n)5YeN6a>6a#BOG&=7i)w161(wgVpXs1`>-J8e6!zGXnvNg_i(I1 z1*zAv@+sb1(OwXrS(X_`M;%#xY@JX?!4cNrKMAVQ9&deCvei_M7 zy$@fDd!JjV1h3Sk<&w<4k`Tq0i0TmJ97KC=a&Odz%Ec{ri^Cqimz@HZWU3h-_kHwl zyx52~qg={*^2z%8^rtvDEuQ-%JEQswYHzT({A5=yd}4o}Oqxzw60+>9fLhj*Ut|yy z5qQ(yR?`Sm*bU!$d$zK)Q%vItA4P3TBiBL%ict^iJncL>ZI4K@`%Vkv+lR`TmS2`H z7>r=-5?o%w?G5U)$Y;LM`*65EjfBEqG@_#KW=|U01nJvPn?gLZgoSr)5BCuTJ0FXZ zWi5s$d>r-J7j!IHoXN>9^Is>^_Lt~zedqEaYSE@o_tnJ@O(9(yOOFrXf1k#iL;@CT zU>X&{YE61JjbPF)x`Qmk$;BLmXLAQrb6030vl5^aCVc5NBjI;!ww*WhRH z2;HW+Rw%9@B@t+5C!34d`6ZpnE&QTf*L793bvR#STyo4K7*gh?p0NZay|^2bS!su> z86K85>+VTC#q3&2?yHc$^w6#{-x?L8xGtc3WkJbq`5x zq;g5sw2`(TufZUQcA@TT;;nn|6#?Y7t-7yxO?-0$r}8tGFBH&rB-i$NO8VY2t&!pM z*brGv`;>Pe5)#U3+9+|O`1;^(I0fEvo65#8Be%@k=BkQEb=e1dfxFgUL!a$>j`u96 zRgiDhmHDNrA9TAY?!JC2P?#>Q{IdFGz{)kJYq`r-!XKY#L?-ErmRjLWE-r70P^X{X_=vi?<2-_NwN8UDo?qW;x39!ibZ1eh{T=_xQly{7U}*=|=wm-e;WrBn zk33igcR4n8KZm)l3R}Hu$k}qS?{`hw3e(!X6d`z&75=zxRi&!7zU>~@?zUV4qLQc; z$skF)%W|~qEM-7hkp!c^!?*hAmf@D|mK%oXx8AbwUA@>v(8zlw+TuMux*nkyYQyK+ z@v9e?&@R3sXtWD`k`bSxHKUW_xj(7zZT(>VbiC?Fg#!<5)NiAj@D*M#tzmN=B{oh_Mxeyf_DwS z@r`w!Y8B;DDru0(s*r-FX#I*RuuLqLvsdHAi%{n?+@1b%;iM2gK zC;W;`8>QRKC=m z7E&q+#-V@$B_*MJEcSU1%BW_`tWQG=*-WXT3*jb1@XhE=FGRB>hUk`8UUN0JJuuPf ziJfl@YNEhT_sqX6lzVxVW3nKl-oBWUsxDeCgH7exiz)l|;dtk8%k$OzkNcN#pSnL^ zqppZyN%YTj7Y_I8_VRPOlW(0j*>cFGk^XU?$~T2|D?Xye*|C(L3zf5}L+D z*KC?T4cNXa@1>ffwk5y4oLgffZkAbg{WD%kI8(?9`_Sk@{8o#mAJ?1maark49;l}F zl8ya__+{p~pX%}bT+1zW7xUS@;hQxL9ypiO1>%r7(@UWfS$XlW=>$#jd}M!Ps*|T= zrDwc@!o~7d>f*0cgoy$hPW%=`EA(Lj1-T3d3h^F3jr&oq&i@a;A80yvX6jk!Q8Ir zqeIubsiYZ)$yM;0Zlr!YM$>pnzJ_iZnJ;YfI}Dx3oB7NPn#~r_-h*TcSK`4KZ7@YD`A>WyX)S{1j@tM-7GYyE9=rzn37-9P z{O1-!TuYh+>e8t*y_Gj28C?|)7(HW!^(40rpFIsdc#}^#yw#g`+02x(^HDm!rD|{k z(;A}ex5)P$q0Se!HL`7AFM2b);Bg7GOzg*%6{Fw2I478AT_oMzsL`W;c`}UaLIf9Y zGgFRBOr3Z77o}%j6$X;?wQ$~ogWcBNQz9ujU!tCWxG%c-zR!^R{n3Y_d(Rf)G1lcm zwo(aVZ}id<%*10YUBiyOy%3MJ{xWzg6)#q>mlkh^3-5IS6NPlIDMJe_>FWYI3i@7J z(wTVlrE7$-H4E|R>o3E$io<24H`i?%e4o4CYdEYc-nfpi^ZD6ck1go;dZim`BhsMm zz}7P_4#SPi?a(lfZ=_!lPW=_Q=E)m8+;V*OQF`#21_0|ct~%) z1b!GCc(ovf34?J%q-WRr?;pTj1i%yEA;1a%9U#&JNClVzpaQ#lJ%9=T6c8a40ipo< z07$^*Km#BcAQhk-;0Zt@;Kv-a;Q)0GFiSArf1s!3=T$tF#9-&}+!=v-?k6Tu->V0cwbY8|dvPho58kox`cb)<6nKqW?_G z_&2?~o=6RGFa^|hz@ChO^sYd1M?hir4;)$lkt4*{1&jguZFyv)|X`EDl z%Nf$I8{lJq#_R9LOYyfn+yS*c;Nt>x`}g#JH(PFi4)Q-&n8nH1{+v%cvnqgvo%rBj_6jzUiR>K7r^9lK|!Ko(7^P7!_nokaba=$ocab zE};2+j;Kx~vp>-So1y-(8?&^RFvH>V=yZ&q5+%N&yB^W>84}Ag)2>8Z} z>Y3J{xjP-B1F%YKz}FpU0ID+v`03kJfAMY@>>L;^6qzA9mlK^M!lX`WpqZ!nqmNS$ zKGphZ9E9|Lx+2-0$N=^Gr>8^n_0w9YKwqa(@^l`kP9$&#a+(1-7{UB}pD+89$O^^s zQ$L{sQ3se_2Z~-oCnJEy_d9n;_oudV>OD}8zw-MY zf1FPA06l@uh_3)CzRUM#6rck998b8M`V6G`Uu_H8-N*y#o1oqfjKK`FgJb`=8~8c3Ju1*YWaU-y>I(7U%^J=E;PvLK6uc5J7%53P65{s@XYP|cs~FAT;2qV|8bW5_?K zfCP>p20^s$fYa$(3+)7;_+s~?A1Izc)&&DA>R(r1sz26WlM_1i6WO4+eY)#Ajf&8k zb-Eve)(=jwLU94E7fyTy$`c?zZ~%Q>1adin@tk^{E6ni6lb^dsKnPC;7fuX=`Gb#; zr$Ms}d9o?s@V(#D`tQARoLCB!jW`0{W+&P-0W=&ZF(0D+|LR2s2d#Y|Uj%nCaEJ2C zRB(stzFz|0KY%+(&%msLtQ7!SR}=uW01$zOpqL8nTu^|9e$U&Woy)I#br=lcM?QcI z^a#jqE=Fa^Mb1cR9YQ~<03 zD1cly6<`5C04UD@;4VNbzzzT>$ax(AN&!Xz;6eV&3!noK2~Y-pw&NR zJ!>IA4TBN<7YazDKUQ5{AU6bE+V)(~w!(g(b;Z1C3^rtc4e{!ny-!(-4zu^7XsPw<#_E)_z{x4+v&zi&mR^bTj z2#ODezeL4f^F1hD{@htZKKPRYn(0&8-}42?JN}Nw3UF`(R$=%{i+}3F2J`?~HDpP@ z<|L3u{ocp#=RA-fo#x+$e|R1g&HtGa^6{V9IYj?!c24#i^`G+uMSmzWfHe9uOaH#F zBlwN>S6xDxw=2jqe@X_uwftFv#^Va+2$JT{%oGMA`j0J7bG-kQ;X%8F|HK>00#A2Q zP%nSZ44md!pV$pF6I$Riw8w(-JXD~I(>3NA*+BSJ;C{j$Dnsm{GF0*3`^W{YPOpE{ z#~JS*eLyr&ACR{GejMv(JwUnE?-w)$^e5#rIt1wLH`Mlw4&glb4A~t% zxI;3WncK-cDgIIiz4!jNpv zQ~;a+;sB}uMgUF#0RV9Txd2rFEdT=mGXU!VkixM6r~o(t!~s+Ri~yVf0s!IwasjFU zS^x$BW&qX!AVU$3IN&o>KAU$0+_N$?@1Pz5`t}m^9Q&*c*#T5O zqeCD#E1%IJ5T2FK=n#m`%4c*4#AoF*It1v;kPyE!Is}rl@);ch^esE+`5E00{%3Ru zP&|a5pV1+ZpOw$(5TNhWL(k9JAwb`%hRSE{evI#|9Rk(a^Rspc)Mw?hdIXxY@>%^4 zeVx_+;75Df?gu?&E1+M5v-%S|hstO5;KcXzIb{Eke2i!1vwHA$^z`{z{n^b{cd$zMO^nL?+epU}oa!<==^(VFqJwK~I*%v@% zPSEaqe1KvQWOC32`3n>uzSsRv;{!LKh4@4J4~V}NxI-}wvXlR(E=Xp`XTJ9n2Riz{ z>EmGh;7#s{9w7HRu?uLO0`))2e1DYr|0tjN@sIXre*B|+>5ujTf0WPsg{g^~Lr)D*8AqopvSlk8}q}LZj@q zmdAv*Qj~>+QOS{bo-irr>xbODCZQjR=FDliIX2O~skbWhNJHTk!#DrchGa~d^@GNF zxcY-sm5O`2M@XbnAj(t5v{v{ee>_^674@1DBo1*R_dXK!7s!6GDq=C8*MGh-flTO5 ztz~z7EpLwAL=$~~<1MGw+E$aVJCm&6#*b%STBt2d=LnAk&touCCQoqP6Y#q09+J}3 zs=!1~1`GITC-i}?*%Gycg>5@Cc*|dz)GThau3VM^r;1b%!=!6x7gxscWuzG=kP9R&=R^2A~vV>J6vI^U^6fKs84Osx`^=kiE z_qj;|ivV@1L3Qv30affNDg1;lhvDO(&!Th25i2WZtu-6l_7;Ujv-qoQ_wKp*Du2j& zfry%-?qiuZ<=HZiGJS*T5=ERqO*dz0^f|5swI!)m=h%(Wgmf7iYMrTp`1fmsXalkTkme zyWQGe#}l~)+#CY53jWn@txX*r{>EzM0D&9|6r?pj*UG|R=TEHGbL?}bSCsy+U#HmO z#0Ptx{>=`Geov7Oig996yq-A{3>k?41YVZJVrzVQ@vDid?RORM^X@8y58Sh6`6_Qs zIHo49Fq{~Uh=z&=SB-~J!ewMSKWXa2@3YXD_IS!C`Rm4NR8HrPT{f3#m*rN%YR1#7 z!^Y`p?>^C1o$j=oa}53BPRO}DFeOV@*>UDz;;AU9k?>+TPpfZ=HvG6SJo^lilF9xE zyK3PWQcSp6sW}<$E!{q+0E}GPYw;Mz{Ew)VkaKmMM5vGp9sH_3=NuL4o0k(@yWSo( zbpD#3Cvz}nq{*9v^Pih3nP5rj1u{tTQ40$p*xc}g2y^0X?B^d{CUImkBr2Y>Hoxk7 zNnViDf1~8w`6(o`KyGZAC~n49W43_M7I|37ISSpwi`&st(K5CcOqMd50!soIJ0bnI z)^yh<$hk`J0}DT+1`uC;5lW1Yu<(#AX*pfzZe~Sw5%$11Up-bT9v5SIwX7mxF7Nw;BT3vjZx|^>tTte;R;?-s_-Zj0%LW>#>z86mGt9PL- zW|bHlyWB*VQ`?tLE9ESe+{mbv@r`yZQ3p0}29I)V>6jpiHmc&KN1VsYeV_!Wm5_fAI z1{)tP|qtWI4YiacU6ljEA^`+bhHyN9>h!?MJ#P*soQ zD$414W9ArsfxVc)&f_pGFU2*(SThbw^+U{L?s^f*EP&V-hxkPCN`BV8Aq9h}uh=09 z7w=daN;4DZHryg$&G;78tKa;-yr+omm2bA939A3YnG8FzE!>b?qKGhVIHeK-J27^%{a~Q;q{7S=No;_BU88wed3aGb~sLJlPEb+|-&D?+ zpxu*PVd>?wR)EiXEcdM7fUlH{+W+%rM1m$4Oko!GB9f@V>rNf@RZIWCz6pkM9Jlkn zt*t#D3XhRAT16`4@-YO;iPWyZ!x z2FFYu&@2?CiP`c|dR*?Uo0^V`d0gYUlcYEG)&6xgKdwROoiPV#wAc_#+ju!i@V`Td zz7oYm;grG?J(`qcc&FT&(fbMMah{^Mzw@OOwj)BKI=?Kn)S?Clde`MXKu7Odk%w>5 zQ1#hDtEUl1)|1WV+3nPnj--fdhid}2kBuqUEAhfxWZw?+R>A6Fdtb82vl?$oq2C_R zAwT9EL6$IjP^ZOet7#P@$bbT0cEz?$b(~XmM90?M>H*sJI-k3hJ+W0;+ebay2g8Gp z!gg89k{%@~e0X`>Ik>a(aRsS~O!Up|j~5#8j5(>134(4tbPx)C6^N$1r+cpRtI9jt zaf#em!J7iTbyqrvDE!UFrH+ZczTxq_%p=~)DPhX4iJY_geI%$o_y*nmjQsmg)3dl&~2{&_2Hry1o4NaZE9)QWoX`20jKgU5uiUVz_{fqWKEZCjl%4W-KxR z@diDHjNZtvUvF7HBarsUM?TPK@Upe%t3n8NkFQ73qr0WyKcd~U?#u{(U#+Cd@9<_T zCtZ?)@q^)ac3RO!v8mj&ek{*Yv2m|6I0eVnnZv8o4M<~QHK~}IFjpwvbs`NHv@Wk= zQg7Avn<#E5CBe?kaBQ*lO^IZD$F^HxjKLb&1Vnv@$ahF8q|!cd#$m%3 z;Y(o89DbE+6I~7Xh!1b(Y)-~3BB@_|fuYWmTRM01+3-fc-O@hNSn@`u(46v>-bN%s zavUkDjc`HK7AGes+N}MjH->$AY!{}Z@hNhzDdZ)#?)r(($u$evvC9nHWGGH$om-(C z6>oBhBTzDIh0o)_b^Y{Gb7%8Q_L>vbE(h18=!gXYwx*I2h|k1GW=CKM;S$S%C4^lBRRG$6mjvmD?0;TS=z2!CfD<^HE7 zr*Pp5bvu`3C#+{`kalMUI6hmlf7tdg%2Z139;19_ZE$@|KZbzj}>@=zf?4<8odiGi_Yv^bsGSWyS2<@wNQ> z>s-zrBdO}wOIJJdXm^!|9Ry1XT-iuf2fY^P`i-U9~`Q zgEN&BVGN;t=3HG;T8D&vm%z2DU3#-gUVeMyslI>r*TBbIBkTU>C>QU2P^l@NWvL?v zVgGe7L5!vUN))pP3K^QjC7)WynU{#KG_>zFB-b7A*{yir_8o{$TxD7e;wDIB=4rl# zX*;$`^P$(=^zFQz@D^DIi%42UpDf$0*3L#TOZR2+mAQymH6)mC{9I5UW4xzt#Zp;tsVaIzmdizcO)o7&YsOcJ5#7iSQN7k$VnU=oWK5c!K(kO7yS%R;LAge`hiXeS z(cSlzXi43N_@WO3(m>Zcsz83~{oHfGEhh1=O$}GsZ(16@Na!+UFb#czqMdA3VeYqBATxXM@Pv@z+1IJa^5zJa-p;#Q37!bCgLrh{o`-(f7}LO)^v9lR;8LJD@< zn7y+!+4c6Yg=)>oI#d*;_~ap^@-%Rfm?oE+2`Q)H_n#=M^p?;hGYxQS4E_ z%{oT0U+NC9ymz0$uV$MnNJ1z7f^l*@b3v8SfQCl)!Klbc-DKxnkLJp!L-NX%TXDVv zA!|dkcZ3+!?(IlL9yfTro7`mq?vEhCgNN{Pm$0%rLxnkyffBoIiG5+F{T{txj_HU!8%gnJsQNw1qcM80s_#>;X z5|?QYInkHtI?AHOKHe2=U0q>CL2Tk-ee&(SVGQlu`&Z<4WS*Iy=&ti@W2B=6NUGms zZn&HHw#TRl?~0td3sRZxS}wCYM}|+fg=@b*UMhT(qNd?0eo_wEY_-1;!f@qzi`+=f z&)RaYY!}LJERTAByk4I5%|4mmK&7)qSmfz8DTap7x_PNh@O^5^@{!2Y%K`UjhE<>R zyt-Fe^>D*Gv1EN*fA@{x-Z{Msl_O~d%_WZm75ARpAG#y>x|4tlMuOKpn&FcL;sF9P z9ama*jhjW{V_{==QE3(n=PbH?1xBCR$^v_FU2k^w63vGrhKh?bG8Q(%^fF@!&R7I> z8?RQ^I8|50QM&F`+^>IfOsW0G`+UE@w{S;#`iwIPDz5~x(%}|SV2jbaq3xXauY4jJ zYS**8CDj+A{iYeoZ9lBMGc3$UwxkPEmUym+{fWk}XtJK0?}$)8-YC~4E?Qs3*|^)j z@EOBH)UaKZ`#ns^fzOkiEnX06iPZ@!Y^&LQKBf=ks4D$1!o($dOzfsHX*Nf%71Uz9 zpPAuQ82iYgew4}?#Vv3b>nPPc+P`(>y&#i5$@Qh}!uO*(aanBQc%@Cz{P}~)O^Gkk z%1|}F7W*|RRx=)wWbH?nXM3DO=3(a=Fw5yCUwpxvJHJs+dgn#Q(aJ~9y6z;bGNOr& zye|w2ETow9vR?Vl?}iSE4fS?RlNT#ZEx$QBo4b4(egSupK`+J^?eao~QztK#<~8yC zq7;KqTYi+LQ4dEVt)hG;<|mpGjARWX`;PeaE|A6-*c&abtj!6#+pUs|hfDH~@FCgZ zXa`owMPb=74r>x=^loO2qQ_Q$k;IjQuMHraAmbLfwtmm8-{VA3hSW6_;673GM5gZBx%qRuihDl3 zeju;@o2=c2Qn=DU8+=a@;6I->xtfCiTIl$n^L9AsnAH#koK(Rq{XV3D<9!%(+T=O5 z(&&+@KkUxmG&1Isb8}oH8ts!LJartlWcZX1&!p(6b41pf>k57+ze5E1p=FqF#C&@r zb`Yx(sUnwt0JaheHhkXgPf_<$bo)f@*BYC|R(q`IS}1Fti!oX)dF}8#aa|R3?YpsN z@Ojd9ep~FRb(NlJ9@~@jckahJjjL$zX2x&>I#e>?ls3R9;(|ejHX<@2IFu$O|q79HqpM;3?hr4#!hVNJpL4EA&C*E-1x6im=#;O!;6B8FR% z14v74aA2Je@eB{8*_?Jti9Pohp{W-ZPwaz?h# z;k9A#xuV2Ihhxq%Y}hMhG-i(OmQ+6A{oDIk#>8FCI99nk{9FS@5B-Pu z9tW5jpdqY;J$3lp9V3HG>{=YhULbuBnSz)dM%mH=w{IFzl2m3r#(?l5RWoFnl=`_$ zK_nK2QRfzUr>J|4_`1&L03?%%>v_(%>8X+LB$E`+gqjbWo9cnvpO;3=UOW&i!EPZ= zVWxd`7f~)w&4?Wyn>P1RK+DS(7!`ILX?oAMew=trl#ao9XEN3Bdd2~4@Fxi<9b$`b zJ-;H%2X36dK+2p(*Hx%Q<%DJ(N>?cUT-*xAPOVFF9vMd5MUyIH6OL-oHu{nw+WZz< z+o3a5L{ipGBkbu2d3owrJ+quNo|1l>w>`T^$7 zBbBVN*RQ`!m3>=zvRpBK@H);VQ?;%8N;rax_!Mz<3yS#bd~-7yWHWK};3$+4_^Jyk zVRL)lI&liss@)*?pd zuwGJjVZpcqk`&Wk4B^s5h(=KH!fq;VTlZAMnYFytqohJc6fWH@C`Y|&G^kUyeH66l zw^BfvHa4ZlaYenaVPT%~@TtlzZ(09did+SOb@=Jy(ay^^kNx%E4iAUWoqv`HjGU+>ii$M^ zPCQKqoe7(m9RWAmxP>OVcG}>Ow>O;7TIHyP@FfioJX32P6Q+In;j8}Uq2r0<3Y$kd zl_45d3kZBQ2w!Bm;R)enT~pfUE3n|;x#5WCI?kJxD8XdB1ud~I5F74KTk#q7#M)G` z69+tJutuY!deo!A#>d?M_>t-dbmV~P0nc1#S)WNHm1ilUV&D31@0A_JANepmVpv!) z*hx{W|48ZGeNpVQ6v@S0zl6X5Y+_iUwC$h{qIfrA0803P(SFnm1d)Sh9n;t#{YgFrHijwmxl>14tCakG} z@2a>k+xc1@c+2q^7|hCQ1-fdYLS7Mw-njai)VIIDM(AekVP7~Nwn{W}Ks?ENERyIj zHfID<#DIC2cvWuv60YntbegV};BICe3nQhgs+d!WJ8yl{Jhe#^N2<==tPeMiMaXAWTDZ z6*u0{xWW8$k_Gp$ZrWu}&ZBa3@r!hDHO*uT(Zf>x#JQ1`(OU=&MJHQCbQ;MD>UA?` zTJy4Ix})Ku(gw%;qLHKHA5FD$Z7kn6-1_nin}W9O&jbz zO6R!`I;04xmj>W6i#aAzYn@eQ&%@Q@>?m%1CcTDDQke2|0i{lY#k%L9-6zLakvz{C zXM$%rc1+v%h6raQX0|}L;!ORD#I?5Ae6C~i=B+7*M)J=i`S|-$$}FmcF&#QeSqj(dD96b2o|T3fUlG!y@E)Kbaa~a(YS%Nsf6ZY17)q z2Y1Oiiqw!M47j>hYb`{-NBnL*av@mOe#R#yvbF{>%j%2(kfV@0;Y`Iz6V*^8q(*eeN0?G-J77H8H~kE4 z?e9u?XLBt?^PG!z8oJ3Qe7ZuAZ~^6tu%5i;KslGvGO`{V1H6iG#Dlhoh$Y$cykm zLT+{uv%!cMJ5LAsZIN$G%O|=8HYA#o;H{&21Ejp z=1@dm2wB@(ldQhu6I^Wi(CRw9`*pWJ`}!*k0oRx;@q8Cx2si=5^7j%-d(QP(wU)Xgh*!zqwRP;m#SE2TVJ=cur;0Bs ziF-}_0MXi3v610+rW!8J;6{SLO}}Yz_~h$ku0vgnnW`lkP5U|1RLbbR`!B90!_T-b zXIE;lD8joX)1jioqoZ|Ln{*VaE%;861W6JWH6#j}+Ofe^M({im``8=u!i_qTY4tEQ&K ztY8=Di>bIiK73r1jFDQd1}BAmJ3K&UAH_Po$>DK^HJYz(Y!a>6Oz5NdD+|3xhLm4h z8Z0TIF`O~vTd$?RzkL*y7Gj#*i&80I+t%?l)^G03Q*Y$Pg#})oZBDmMLH$Z|lJYK$ z-1RS7@^$b7qqD|wFv+`dh;mklG(6@lf^X&D3@wP*+Nm-n`y8}_r)aQ5wQ!6c$y_ci z6yB09w^DeOc%ucn=m-1(u;3dyVQj7lma|7*YfX0Yd?BQ__Q*#B9u$0_rS#4j*(oz@ zxY-tJY#QxCp2!mUrb^3MBvv(GSxyp$^Yt&2R4?t|awD z8x}z@iFM}sel@JI(OQQ>Dz+#+4-vK2Hp@VWhC5{97#-*Jcnttjp|)Tw8w+SAceH-s zeOF(8;n86N-~Zu_k3I3^;J^@rEH<@Hoi=m%(MO$q#!-F{0Etv?bHMkdulRmT`qp=^dvWv5dWKO7#Zn6zQ_pl#sWiwgO~rhr zR<&8e+FIcW*OyXe%wSB$ETj~kXYK35V-Z9;iCoWRo1{s!eAx+?UV408!&mQK*z7fRPBSD}+F@LJ+3~PiCn$N!r%dHZn2-2-aA1gVBTzSm8+%)q`T8t}UPy z#K1bP*AZ-~kk>k`ltToO3p^Aq>txO2tDjx-NL&vIEo50vQ5u>!PCdv1vY9Yo65sQX z*zuh>%^XLvPSSd;@;PSC(m2zZpUbgjt+Sl(g;CTQT z(>PRckyQgDWydeF zwP{951>noUN>r^3|M2>s^bS=_3I+}MIVmug3$D8Oy@$@8-qG4TI5@cOg%{U8_rjK) zJz<<_%LE3k6=){4wH|r+qN9#nGIPd3aXlOw8D6>ap{?7tb#?bGoIiKb5sQ2JhaY@= z4H6+T3vgXkkE%y6U)s^u{?wW$cJAD+1Rk|~>6|&Uwr$QH(^JkxV`WdA_I7sK5e$t`yW=kpK41)G4{Ug<(p^@L-^;^%+ zlcZFEBntpKP9{&8eCC;FR?EW=KKOvqS_#Zvk!klo8UXu;fw78`#nIvsFajeYbG=#% z3Wc0Bfx}<jw^@Ze%mZy1~F0Z*Q!HBfVnpnBNi1 zE8mIJNXMb?id^7@DYUgTH5E%rsd~NccqI#}7N&p>I7$hzyK{HY)DfX(lLfvy@tC7N zbIo5*X$M^g6G1T#Z@=o)^&89IyY9N1ZoR{C@?jYHo;vQh-~Ucj zt6y~fSyxO#zq4!@RZ|X5)XC${WTvw_1J}ufN$RL z&^NyS<7$*j&&jedFR@y!%$_!5>EcE2e#e!I=Fhz2wmVKaYDvIxjxt>xI^&e1@4olG zOHW&V`PnD@{HB{9dU*Bv7dLBEp2{~GK>|6#bxgg+V3em!5)&YxvPccO7_qezSZn)4 z?c6B$CW-a()`FJ{K-Zsp=9$u;o#!H4bj~@QJG)F$l}M2`=n!iI04Zn1=H^PdqCCfg z?Bt~jul?d*y8+yO=aav^^S;_}wY{l$`U%V4_SVxs@zM8h*|=`~mO-+7#DaOB`}>d1 zom1GjtLL^mR`zxenm9dl!NTKDK5_oMz{|B-1D*iV6%y8@2?~Ky>D2fLMZwJi925Hp zY>j7iy9*bbwDkP5PivbRtb2aorL9>S>m*6?$~ce+p@dU<{K*aV@TY(E;kTt3|K#Qe zy9O(UGDg_AaocA<@wbN^1ecz1>^E-sRXMeYh*An;r?j`c{nB#-fZJ}nqj#X3%QvNI z`uf%=|62e6`S?%2``uyOsJuP6av#&z$m= zzkA08XPtiU>a`no^i}IINGXjzddU$pr%m43nXO&B7LcMO!8cz=kBNQYUVAcB8XV<0 z^7!H-utDGjmjB{I9|D5@a`G?#_MbbtMx^5qW+n|Ch426K_bokq;i2?Q`snvYs~xCQw3cW!uM%_eY*AoJzO*o@b|*tKoft#KSPCj^j1 zF#rLJv6cqZSfs`PAf&bck{ma%0C(Q~z(0QNyDx0(@{1)RCk>-4Omd~eSwJm}>T!}8 zJ2+e>A#+79%d*U9Px@J!3c>f?ci)D~&Yitr?qP>6eCqj4Uar+@opbT*Q%{`K3g7$j zBO5ku9%FWkHz#RG?w{R20tQ13ve%yAsa762=ls)-UU5V{fg68$$4lG0weeB1fDCMO ziX$he_Vg8Gr{L zeWItY_qIFcoqN`43+B!8T{)?}dG^%ySshKM9Jh31ufFy_zJK%0cN(1?f7~(k1j1^0 z=8S1m=QNL0tj%z0TZ^epX>V(03-jmB419Odp$F#z>gh`!TJ@wCv`45w2qq|%@&xYi zV6Uq%jYF~^kcbI@koPR|Y-pje08$th)i};9^bb|H?db7>rl=Z&hXPfU)EQ))f%M&6 zsb~-~qoXvDikMI-R|ttDbAh*ech7I{TlL}hUv$aE7yazUU*bVs`qe z$N%kLeej|C?>qT~;|L(EXFFcnblkBk1cKISHu z)LD3iRuj9=?&#mtJ#^EZ4^8W6D+SI$lUt8jcI1(VFIu$Z$XOloZ$9$D-p;;fpIJMt zy`|*BaYxMk#Sgw^6(E2BkN^%t8i5au6jh;sH4UJXZ2*MFz6cvgso}Z63D7R23wT;A(YiW++*pbR`Y)}{m zkfIV*QAjP0qFI+I^n4=E|fLnia#|s;`C*b*o z<}|H4!d!mwc^lWSvpQlO^>kHTLEXD|m51jhQ8h^tAw;E8>FV4yGEzV(qBu?C77#Dx2Md#S9FFlu}6& zDWw1)j_brg)(RvB4FCwbv4VmKNMLHTbR5Tlfx+Rv-a)6SBTlrfCs`n+P?-k9fP%C& z^*Bm&l4T}IGB8#k7|Xuvp|DB9&ph|SLyvAd|D@ShU4F@P|M2B`b7q`>=IOw2>u+u| zab|*oR8}Xc<4Da1Fz}jSU;#BSATU`g7$le_hab{bgjmCa53Noz8#EQeOiQ%KAH8hO zLDPP8-4EXT?sx9qxx*nI9vaNzq`$x4k;+ORFjF7TLL@-u3jy2h6s|BWsD}cv>0UX=d#*XuaP$@>6RjVMWWAfB;xg1w&Kt!%< zYh{qG2m%vD;Cd?Oc#cvCyC!Kh6j~Wah8$vh*T0*G}MX6aUjbwCa6bYy`FO%j}2O_!DfV*C7G3s zLORNSc-87nmz;mh5gl(i?~LV34>t@CJp4#s-vEe!86b*PQ?XvHkaFIH7}zft&_b3d z*8w)5jUbDh`3l>b^V6raD}bk;ewq=ZdJ+UdG4D@lEiITgw>&U3wPUhQfB@J)6h+OY z7GQ9c1O{tCh{o*I*oOmxz-wu4?(XXL6%oM9=~JS5WyW-8(ZczHfNdrPnJh&~CXEF# zGJ~~J5fVcZ0TEa`wr9eg+av~I!I1$(7Q!UQ9O&eeAAHY;uexxuuM2t@hPSmAG6x1t zZKo6!SJoCDGJWdI>5+yfpWP5y@zir0BMW}PyZnl`F`<+M)__SpMV^#84CgLbpb55g z?(XUtCV>C_;XijN!erPrHAh!PHqsQNhcBF|weA_L2muGpoYmAEIFJ#izCtwFyt%WM zEI!N_NRmh?QV!K>6(aCF87HCVD4Qk(+|<$}2(-2hG9fq2o#lEh^c}aoxv0>BP6@#C zg18yV5H8s+<8AUgV9I|++4j{4T9j!rv1#k|LX^kZJGcG z6i7%Wi!x4I4w^D;>Qn>p;-;5?q;%Bq;D9yt)82haOOd+M#CMeE0x=}of`xp3?`KUC zakQlg0ay#x+FGq`a9ox#kqg=m+zT2@9-c0 zG3C>w(R8NL#;pe4`15V)Az&cfBNaa|M01&9P!0}yyni^SN87imz=h> zHJ^Rq`KO+H=2_>xbImjBH+F^drsY2O+0Xpw`k&P6bwB4_a`|PaowU3?2a>?|eQi05 zA^;Ew!chP=&SK%XX|0lmi4vwzC^`y&iAXrEtJ!Yfw(I2M54qyX%PRG>ufJSuYRM4D z?HV2)_8j-uxBlki|NE*b?Rf!k%N=*`?k`)52!@#fk(4sV9PowypZd>237w@Vu+hLw zvt?^1Po7lBE5p#)(_c?gKsBkOwN~NDZLO|^G>Th_g~l0@Br(Pi!MIuyf)GjwNdU}% z2vR_yP%y?25d-9MIUz(4z?7*So~tz5B(6IGTUwiXdwUtJR4Sj()uOs#kW%O{M9Pu)5!1FW_f{mg`dic_o7mt{K(DX_8p0}NM<;CX=3=RzpjgaF{ojxrnK$yXA9@_k! zpZ|8#?oj5ZRI}>$e{vI$dFR_Mxa{m@%MUv|tJMR9z~Nc5TQY!~9(c^^G(&O6Jr5o{ zch04koc*pV&N}_%v&sV_MPGGH%Lxan3@lV<_rP!OdFcIDpL_c0ho5xfmy-+_p%}or z=X-WWLo1doB;f)nC0*tE2}7k;B`FGpd>mzNF^{NBT!|7>4I#}egRItLo5a7k@mGr$ zee!~HmdrYMVG`R?i}%!XJOBFQf2Ra#t-~<9`R4mRbj9iAdh+YLR+dxD`JT~MTMcYb z$V8`a&bG(ni{?eFg`7IMA4 zBVcU3ULP76?&%wnBp3lf5YfoUP`O-@QZjR#B);dwVZC0hw6(S}K&75mDwXcOD2l>4 zb7pPbvAd9k<tj3aeBhx69$&k2*8osaCjctg zvZeE1{{35zKe^_d^DbPr_{e;r$%K_Sitf7mk^5FZ{OboEu2zl8wG0lAeC^-Awf5O3 z&O7()83!%Md44UaCcEPMA6@m(W6xA;^;F~aKe@4U*N(SdabDw~W-{7dCCp43Tg)Z{7L$Q``FnMl6YH-v9-9t21LlG-+?&;M33S*u1?nwHOqd zDN7!B_|dO@{RgLCaDJ}Tk}rD071+9SS8B8{tOUljN--ah1NZ%Q_4>^_zzIM~&@q?{ zj6v!Cz70+P+Y8P;?cLq|!>K`5o-vI@@Yv`_hT}`iVU!yuG0U_SPRT?mIZ|>Wb!FM& z!>+yd+RpBtUHwDVDDLm+oq5o-v@+bDcV|s4tbX``gXhfcnB30B*6X#ED_350(M55+ zZUGPx5%0O@o|8{LRXU0-3L?*QHa!1ankI`EFV<}9iGB2mHOo#orIwgYFYRnMK76sX)JGsYlj4URu{f0pcMk3oaLl7JZm!0-?_G6-B@v#?yA z(l)77%m;2zER?F%aA0`IXx`b~je#$7%@9n=!WhuFj!8y3gMzQEoZ2xZC;g)DrL}Tb z->w>P-JrD!7+o7@wGqb^#iqiP$um4hDM$y0`nrdPM`|hglbM0CnkQ^qYg1EG5lQau z>92%w7KbgqWabFmj1-fX)rOjVlO#!<3QnOdt%M*TmzR)49LCDc)uqbf7$hkIEDw8% zny0q6bW9=kdk2OFYxN|Hg)t6hlk?8Kcihxgg!g{lIg6#hOk3gSjcM$V z@}|j;q7@dF%%3Lr>pNO!fD*_BDJ>c%l_Yl4_U&h$cM%IGvMfEieryvyQlS9k|Zaee4=tCB7g;JL6Jb>Wy_At7)B~l zEio&OUDDYTe(oQ?yt}8DP`ZvYW5$eceB&FlW~p`STBAzY%@?c%lVx7MDbv!h9dBgI zXva5$f;0sLp#s~|iVXEi6+Fjpo!&J#Jd#Q_b;7|kjfo+j&%618F})i)6l_!*UqbJV!Zh zJ~e2if?@!1qS>@GcbFvX?CtL^mlfnw4VgCNI!KsBwJYCsS!)TNd$IT7HP3*W(96JyDz)Ki86+f0(%s$7 z1jXipW=#TwgdiWdzKaMb011$QnGG9l^;m2$+N0ESgGNP8TP7)lfS0!I=IYt_kViJaptXL*KieV*28kqC*eKyJ16EjQlU{2Sg6fzVqFYZ*4H0ws zM8Z&1B?ly?t}tL@S0V%sn8Z`$5Cdz^b$uo4wW=dUp{)&=Axt1)5N?vCs1Rd>OVxhacJF3>ADAK9%e4m+(epME{U_forvXIKAhU>A;G$% zvB_k>eUJ#xi@ zr=IV=>CXGuD`lyHBmriVnJ6(96_5huj`2zwM34p<(K2Z!JKjZDutfkyWE_8u$cPMr zK{P(Zu~x+6ZB<8)$FUFpH1;}Z@Qe44H)<>)5K{s+17QI`+3mgwk>9aV+xzjW!^MR8x{+9wB4U2pXZ9q|@>xVh9{4 z4|SLFDvaQXHBV*eGANT7&!g$HXZbm()L`3=&Y)Ndqqw=HW3XHiZh#Vabcc~WEHvQ8 zJ0Wlyl@5!@>;RYq5WpeO5deS?Rv_q@V2&MdsCCvdV5#b#?9Mz_6$|S#Gpk~jsDSq zY{4d=!0~|yP(v7juLyEdVO$;rWQUwI)o#9+B$Z1tF|ktXT=U64XKa_1 z-UkODwIB&X1CKtl^PxxA+TF-nG-^2N`N4#$K>Z&XKa}QwDpQsuC9a>h@9`l z^;im-ltb`*EH!f$6Q??jENkEQqG|qlIE(bzBxO(-?zv=@Es@Rf+ zA=u371dI{B&q~=Og){+QN{c3oAak9(j}|jsvnGbX10w;5z)G+Zt*=DL%+<1!%cZpt zNTL#4uLGj=BrpoFY-K%(JwF#E30MH-AaLM&SsJBrCL9NVg;L}=L_%Bh3I*By_tpP6 ze4$qXM`QVgwLm0ad-FdFMoAgbE)XKf;HTA$DOlh&vG0G5#u;{ zVg2(X!~MBj&dudB%a--v?p+Vwf2XfhYR$9jUZmpG>u$bd^GjV6w5npkn0U_YX(ul~ zk_~Lw@cizcZX%LG##u_rGj>9^%?bUV8-L#$yV)562nj&iWI0DHJN(dVKJ|&&^QXEF zys$0WxN+momo^sj!IC9M9J*-c@kh;AcGQfpmTunInfHsefdN$#Sy};b6^bN{Q2}Qe zIg(hYQoGK|)pCVM_=SRTh_&T3gCtFD+}ze)tyURGH8p3NfjQGUOKM)e5XZ5UGOSgT z!TzANEzyQd0%!_3SD>wip|G*zIGGEHsX$nlO%4gFXITTX7yHWpBT ze5HP@f5M!(SFJfWpwPer31O{8mYrRF{X^juSG?=Fb!*Q(dj$g2M(XRHed^THPE3+C zaGlgx&y`0Wc~pB_bCNL;zWBnXxgC=ZTQHx5c5dtwYBB)%ddFrJKs8E`gBREHdF)Pq6aaWB(8I!n+y3ct}w?0uF+l; zY2{MR3xIVv)F+FrngNn}uC)}G(|Tpd6(Xz-%RGQ)$THzNj;A~&T(?l}?#^{gN*rly z20BaXRjFika3Gft98N)l(P5^uoR@Q2g5lm?Rcdkk0vNEVwrOgTicon%Wuw>tL>u~g7;sN<+9?^>&?VNB9BzOSu?B-2^u2EMeZP3o>h4M;!+tP+9)Pe{ii z#ZiLd|Igao>xKcu(Y?m3waiRJh^ktJZ-4)%OO_t%lc0F0G^-OA?T&|>Klf{P~+}qnbQcq+) zr{maWnV-uEf#5)?=te>dvglBAbIA|9YPnLamdpJ^L1~J%t_9NdT0TI}<>qF;V_Jt5 z?$E$+I#Sm4(56}irA!rd7WqC@209_C=8DBhE$u-N43?_{BUM+q)qy_BmweCRB#f%V ztwpa?DovU;bD&(?y}Kt2Lu(nrNahRUtO0!a)<*x0FwmF*M*-021w>>4{ajP;VEDg2 z_K9o1^2PfedbH&&XEYZeUufR4W!s`f3mV>&bUe$LYIa>YJQNFZogg2lcJ;d9xcvO{&-Wz|z(5u5z4!Ke?_KqqTh{u1t0a-j2jBUZFSoaq{^6@%Yo2t_ z`#OK6+>)Y=>XoC8 zT=J>E`QLrLyMOZ2pRHK2;*^t5I`Z%i1PEie{nvMV`};S%)E%c$>;(CasU08r;JeN{ z=eYJZKp2hxhPutF2Oj**uWx;P-DaKDC>Lb4?qe1&xccgMpMCanPmNmM{wl0~bjz)` z-SO~)57vhV51u{ast;ZL_A4(elpsYwf-r{l&kwI&{n!ux>qlWdRj#Xz{R6Z1e~5^d z*^6uS*f4^S%%l5Kj`c5@08GUFfGCdc{u9>|H(%`R>>4T$FIlp9^X6@yTX0=>)21!1 z=QGH1t^UHs&3?WVr#8)K$M)V`UA@z0&A#iQRp1wYdB@71-+Y(w3!Ya@MtYl?J>vRT zzxe4H9mO3x2fq5R-|Q|&87LtnN@cA@AsK*(MyZse8xJy$Z+f&Ro%e=>13*?`dhyw( zTzJOP9XkepeB&>le(@#no2-!l0)!NlrpK<20 znN#u>pq4b2C;(LqPdYnjwGY&A~LhJ9JIEUyLRU$O}c;8V=GtQf95I2ty=Za`RAOryMMTU8E}5KfeFc?p-S%d9s#pQ~R`XH4?Vwx+Jpl=Rft)g$oWc05{xx z+xjh?ZlSF{IHF1=K(J9Jd}+02(P-^7zSHFRRx5Ap)Pi6YSx&-ZmM*mb8OpmKc(~X$ zeJ}!$4v+%YrXCrqrEnNA(yT4#a_)?&?VtVZC+5#+y8q$luKC;-`}&87XwIyeU;Kwp zFIzI>^Pl_FUw-uC^}Z-hBPnIhhl3BEbN7R5es~H>h`O;~Zz2*GdZ~u+e;3+8?0vAf9()WIN>u+xP zWoKvCq^Z;2{q`&0bJaN)oqODaYhV2FO}9n$a_6q}mS5leg|$z>+b!-nH`4cfIYcBg2C;XU?2GGbktO=;M#fVtDkuCvFEpL+`hdEzEvv9tV8H6h+KIk^^_vI&;|D*}lusj#`Jy%q z0O)##8O8vxFG}Bd+e&P8ROx8)THBfpz>eL0?Bs^3F~}Sk14Iah!GhHq6$l3;AnPct ztvK$CBNjDn-WL7a*SBo;= zI!_TBDU&o3%!9qPFMj!J_dWbr9LJe9aqsYdeDA;J&zf?^iHk3N%OyAb>{rOfYX0F5 zzT*%eQmq<##bznx{rBCoWZ|3-eBd32Eu1d}3Z|ovUY2C=$U_fxcJ6efhis+5^6Z&D+Yqi?#x8MHYL;o^5J|QBc$oI)}cPx$ug~!@aK94H`VL*jiv*q#W#=XCIY|GXs z?)?5wPCsqq;NajTm%Q%r#~(j1nLPOLL(@}@9Xp@icW|tlH9+fd;RrCMqmu*WpbY-J zGtd0XzxZHiVB7BT_x|CZ=z&F9M&9Q$n)`n4(w&xY4O_ray%n2Nvm~x_o z6et6ZA#Wf;Xb6LH=9wLUb0TRxpkH^{g&N?Y`yY9H%g(7RFApt5famrfnjU@Rf%~>z zarvpgamlN`ar>PN;sqzG^6Y`Ju|su-hC*#KnW!eu9vG`T7@w?;PgYZlpaW7y0~{RP z&kjlf7)6YzltQsdy}E7tj_GQ$U}#}%%+y4^Q60PUdq2GRqBE8(TDX4g`X`>)nkF^d zm|iqA5QgFEHJfxiI5<#Vx(?(|wsiM1`>nHa90%o6 zwOaMgW|{_D^08=V>-cTgGvqPAJF|K8us$a{?78^>{dYV^S9!4)U2 z5J1!#(L`aGEB2Y?JoAL0G=qX5#-J>zv$nQw?Me&q*kfCjE|Y|*s6c571{BcNt=lfU z{M3_HF12|gBAUQETbr)hG^J9Yi~>t}p4RJi5y!ZzVKx+`; zG*1OkX%oglSekCs0;QwDxY1}#)*8;)Cw_o?(-+kv* zBNZ5(@E`eapZwMxKUC$#P%god#6>F-jv+TQv>#owJ9!};#s~I~!{!yQSiiv#d68sv z6iOvR(19ip?;J3LOT;Nq7#Ov5XdnXEyLYdMpw`Z^vw0N9k>I|4`$B*vCk)4N>}{?9 zN?M0TDWgQZ%Y8@?5GjI+0Yf4-4>XacG_!&tB88sJ2{;x;PzVaiIUkl6WYwumG63Tk zrw&bqP`Cxw2Fk%Hr>y$KM{n4$VOj2A%hm&jrjzRQq1xEfr>0*IUMT>(_xrEje9J$6>-KtPfAq7vKl3-YzWv%aFJD=H)ACEM zz4j6Y*f$10yZ4d5{rnep?S5u--?KwYm)7bTymZe|qyZEV@08X^~c?$!7)wMPxw~f(arAP~>4_QY?flhR``C)F232LpUgt2NsM(N+7GlU`6tL z^1bi-=%!aJJ8%d-^5MUFV%Kxe>>GEkmW=QGga7o7-?->ptsP-qKpz;hpZv_{Z@J|k z&OUwPtIj#&w2kXlEMK^Msk;7;e`odD4Ili_pL_2=|HUufd+$A)Pu;NTv{N^2JazTj z;S(0Yo31=_#qy7R;LmP2aByOBbX1oHdzBV=>@G4KO+J8(%;Ky75h@*rNSYa(a|}{H zGzn1Iz?8Z-iZqL4{Lp5YF z;i3UXXQ#(8h@aOZsv~zYq8vrI3XtehV$&c0^saYadwDs4w_W|l8$SL&!+~M&$^qq! z1VX@IGY1ZshlYozMyq>wJ-2T4iKlPc_|5PB!1@#bAk@~U=NScXQU2FRLJ5Co&+ll5wC z@1AFFx`QQjD*yl(4M{{nROu$4rRSb|&SjTfcHO(Ly5mk)&6uyxjZLCG0g zDbbmX4u*&G=?SgF>cQuhuU;Mov|wPxS*LG0=k(Lh+HmSAt4>^40TLLS82#Q)fA+aA z-@I+t7)47V9ATS*2cK2LNLzLS8oN%wGg_c#in*CQ!ADo!CWv4npYqmiJ9cj0eg4@e zz45Y(zx7YweR%s*9!iWzCNMhkN!?}X;DQB9mMmGjcI^XqPj7wnmmAldxOwyXRVOX^ z<*oxTv>24~wds@BE?c*56$nA7ZGDZ z6GlV?-U2ukXg@hcfS^=$dg8Nx_c#A=%T53MottjI^-G`l$REA+>Pt3lIx&jj>D`n6 z`)l9&-QWM?>u>nTQ_mcT2S?ZeXamalG>xKAj&M^ivJM{`#_AjpR+Hq$|M96qH5gu8 z`pl<4^_!PoJXlg%a?Bf$*0tC*t4_S`?Qi+w-+tztv(9WJ`Tzaq9aA+p^URHJyY|gd z#l+e|dT7a_fp@+0ch;|8bEpd6`{7S&^+c4;MR^5C3Q2=!u+3g_|n(c8t}Dmd^3oLrl!-~&o+iC zxMBS%;_8)13^Xc{zv#mA&%f|BrLsa@@?KEfU;ovAzwGrFmdna$4kMN14G(tp$tw{c z)Ua#E)*CVa^PH=r%9ft%a)(0wXQjsoSd}Ik)-y*zxSqh{rhXy zp1kIPhaMD>3(vpcHLux}B=CQ}{_SnM_OlK=k`KZh!P&g5xSmvlDAwY0MCaKMC=CR; z@{Us4!ZIjv3pGJ9nS)xncJ*I=z5m@;yzf2#VcE#y?c2A<<$+C`HeGPRtIK6b0P0SHl9I;wrLR5d z?9+aK`&%x1@WBTke)wT__BF4)=(0;+2LQL;cIU*Q1FKdnzVT!K<=^et@zcBRetgST zaDM5MWmmuT+LKr6AN=g;M;?7Nch;DI1q4~Twk^PBN|mFyO~0V{LN9;}07P^VuDyuU zh(ZJiNQ0FDwzaI$xcTNEj31bsn5=Doa_7GN2cLazUp>i!xMIRVMxQ1bh9NX>S8(ex z0L?_zJp!rhScsO$XcUXXAf8H+uibjvV^8e7_UbqN+e=^l>Q}D4^n$hRhKK6#!2R3q zd-&1seDAK*vdiq}zx=h_`8Qtv`YT^|_GK5J4FE>Lu6_2aH{J4$TW@>rxzTWFan3?U zXBLKrhN3V`lZHzZG)n8hgz-cQNtPL7jA9d&0i&euGRvhhSO5Z5pPGmQN*Qem3kKr1 zUUSu8333J|a2{^D^{$WK_{q`fJc>)x4SV}{f3RfnqAP#%ym!6h3V|z}z;qREyZyWM zjQ`_xR|W%vqZ8w$IQ*yEesazkr(S&F=1VTz%y69n5P*qk_{vRp+0&RX}%v(^DX5zjFZxZ{V9eep|QedN(Cq$3>$F0(zRn`3#cc^+{k`s(1HUkCvb zDNe2q&;l|FkOV%>D&-)lkA3KdKf3MKTc6uITCF82j2s{{dj>%QQc4G?O>TXM-B7x| z9Z!!SfVax1NR!V}aoLF{jI3U@Y}Jb8YfoM?GBPqTF|lXQo_+fd?A^O}&vT=x#A%ir zjbgJkE0-=?GJMV%r!QZ&R79THyYHcY+4AV)PfRszSRMc!=4tJ;bt{%E9=Y%SM`{hP zOqrBcgaUTeiY4pUo&3~OJGX7y0V)Cvz#B9=*8aS6&m?dUKJarx{=9R}`qU?HoSK@v z@e?0gII{TUwWll`S^Ui21NZ#=zHK|6Y^2Uh5X4bZpZ00}l(nl~^~$r?uRVD|rM&Cu zCm(tAu^l^iMU@4s)|@gnF}>yS?NJa61hiq@nhhH^EM2;EU|@imckkZ4W5;tl`B`ST)BGn>P@F@+_!JZ?$=={D3z-93`uvJI9oox za&&E)C~(&L<;Q{sfMY=b%mF+ggHS**TcljrapuHDGtdPA+ z*=L5xXcCb|n&=>k;!3sFV5aimLJ*PMrAeKH!cu6+q&8*CWGK`jYRnp$6NijpDMZFB zZ;T9As?{kGq#(46UdRD*?jQ_X+Kc9`k7L0HS~PHUWg(P89AXseB=kJXLK9dkQB=}F z$;1^jP6s7xUCv&-C1rvj)Jl8rofnZJQkL}dgE)R3^tC!D17WO9SqXca6Ji(#4t2dz zWiL@2>mah$dS*d|U;wC|S+UGfSXx*%3X&wrJO-8FPz5ZQI`)D|L<~ zXway2C|-Ha0v#kt3ND9u5D?SpDo7rb2Nd{fQjdbNqaYVhQ6(3pN<$@6$sAP2s!*zg zrNL~v4n~0psQ@$(8N#wKSMwwc!^+5TwbrnyHH+qxQ)A4on823WGRzoaPqLs3=l#Rr_ z)bH=0^xLh4i&WXxOCw1cD9fGYT#OD($Vkq)q>+FZAOfY}WfB=&FC1}>AxmAJI$=QD3osxAr3zaK z!Vn~5K&6ceOG<|cGv^-If>JszD`S|s5FuU`G~mX@p)#Pt&}SYTqf$WRY^I|!i`bk2 zfWnxxc8>FE9guVsA!3^5;60iM6ghSfgotQJiHJ=S*Qi1mmdh1(nU)~UEPw)FFb0Uo zkhmNGytQGef~3=00^%f!GV6dajG{F0^(+@uJ0o&MgCx7ho3e zn2{(@#U&W$oXhj#PEYsku;cfk!3taFZ4Qbsih$WW2c(AnXZdf)p$kR-|I_&AUj0T3~zvdt{mTvsZtJ{81~_ui)|m{3Kr zcg&3xv`(k$5NKe?8jUE9b5hRdE>F-HGRk`gEI=AOh3 zl@d@k%K!)h?eYXQI-3X*7!ANa&jAQb2mqiFm_Z=`WqE=E1R@#)tmoF9y$+nRE`dl1 zSWw_OE9y}hFAM|_C=t$W1_)pj0PUS;RFliP#}j%Jse($ACQ20%=^g34Hz9-)Ak+j< z=}mes(yR0i(tAg`AOeE)Ud7Ps4eoQ+K6>`q>#qChemIjgSxMGAzdX;BtY>E4%)iFT zZCBHoB3MHxE}q`{IROs5i7&rul|@aKK}Pi+IZg4|k6SVC6tLt;fCMp%sIaMR-A!Re z5KB=8(M~VHJ&wBdviq1#L5o4&uSTM^9ptV=BZ%?znKXv2KL4_o;8g0}xhjo;~AvcPu zArFh33k#(8iq{pJ1<(XxWj)2L%Q~k0u=M0>dUzF!dSl%2te#ub!|i$Ht?V!szNb@&N3ZoUrRD}%A@a3EGT^J{6Xr-0q|zy#mQNd|5^wGQp= zTFDh3rHMWKvX{?iWfO1mJ1U1noAv zD~8aI1YPK(#aNuFRo#2u5#f<%JJ5Gq22l|AdFgj8o_^U)xxxIU7cxo{ax8Hd1&Q`yq#HY^lsIiAK&J8 z_}5NF0A`5L93Qv2w6L7oX}laJSicw(d*Avb(QdXMupr&l!shsM5ipt9;OdzW%nsXi z!Jtw3mMA995QI5tlXkm!L#rL+v14)CnAO6BvT?DRm7jq8pR!+wUz*-i!TUAz1YTsT zZC*1ZL8&zthcJCmC{EG z*2Z5&5R)86@MZkaZ|WQSjU zJ~UP2yd?ejF0AO{88MF{6(1i1r3V5NFrvE7jO$~VbX$51f##WBmedH)fvl>_OQ~O- z@v_lp(!DG_jq91Zm^L?BY)=fZZhA;seIH1~A~aI5nr<{ExE#>`#c`SLk-0kB$<_~s z$7_{0E_9s@*=qWIli8vT`C-1F8&y&+SQH2pjf|VN&dtcyk;OH( z>of(bVen>FY)s(eQK1O{xW0LsPmtYFkObfm=$eA4EM9k#rAu=^Yq%S^>DrLMos!7C$srZEch5BEk^;8wg$TBmQSUx5DCOOQ1t0jo z7M>r75L^2|=wiudC&S0um2!eHz-qa@8`b|P=>%vvH3e~{_|Gmi&h*Y#wL^HluZCq%Th2b_ziRT9qK+FSSbIgC0Hk$Z*4cuN zXc8aew;5awKXu0+aKp@|!du6E(K*}2Z~WOd+{HKCeA?q~>?XQF8mriw^+t3G*V)6J zH>F{U{B6N0OGmkP=f7NJ`>&rZ_>`H1a`kf-x5kAAp%_R8C*wrmlLYnT*s4c2NJlr; zns-mmki33bE2JejG&au;YYo<=dMAiF=qFgY=3_whwemFZU}ub9*oF8p_h>UQWYuxk zM{l$yt@%>W;R%gztZcseXh!=7p<9o!6xN#@6GCMf?5nM1UL=3o#V^2m_ia#IPio7(B6~0D zfj!3DS*gRC0DnC8c!62~^MNvh5a<<$IhGu*NRnlf%H!Bp9VQ}O@v+jf+8p1}LjiWf z7csAY_@83e8gPw762aI|Ms%Gut6Lz&{Cd^>Q>WZ6kgQxc7a_r=q4Dr9IeQl_&C-PE zlJ8+Nv=Wkry4J$>yvYx#?NW$sl&0&h4i%6KrGe?=O4nycXVuKXqb_qY29))p;k+&|d|quEK3%d6 zecF)L(P1v+f^*RI$-CQZNwa|^O0_0!aaggF_3ATUtGf~bn%lL(BaI6g3E4;4>icRc zb5pet>bE(2$TOMep57G=R8?6e^bHw*>C?w1&baz9O!?lU@ZXR+R2gk7D*>Wqw$Ql7(2Vza;%9AN7bFY z(8QqM2$Hxot1ZDE7j*}7Fw2CIV)zRvH-?pX0p_J!`r{~w# z!o$34Uf1DA;#Kj%K;S&;%iula0pp(Nc*@01&O3nodl6yc!rShndSq@2Y=YRv9rHE* z)Plzx$^}3x>|WH-+0@h|~v~?3b~~B%|a8y6D)< z{tzs(*JhsV_0mu;M9frQKH4r54E(p&iy{ ziy}RZWnE0ONIvr+&38_+uO-B7nwoyMbS*U8V}Lcy#Z$c~cyOa>dxO6hGp(^#L(rKs z$|E#pLdNh6SAYD{F~nDUOGKYi6z55*jaaWAv1diKY?W#b#ZZOm(%?zwRNN^MPPp2s z@FzkjoiKth8bU_&9mI9 zF~#z{f4;X8W@U@YHPz|Vo#|XxeoaL}MH%Q`;Ph4@pPA4%G{5-Oi9|`e0_xm*Z6Sr3 zt#l~P%!rF;#UqEc-Q4?)IV8O!TS!$7vZ8M!%G^~x#R+aaH6nB2RpL6 z1#*yHdM7|ch$Cy`SqgM;<|~tzs)<@|l3Ds(g*UH%fa_}PnForrRTHoeffXU`;Q zBiC)5f*>0iRj8`39=|1(8y`@sLZI=XXWGRxaMbCCao~MiL)eUa-VywutLE~!yROdT z$5q|h$Kl&5RQ$X;nD4@82E^i3EmUE2NjV;U&U!F==ES{ zTpemHbd=E5IX_`e-HWHXU9BHS@9>V4hhLLi2N6k;4}MQtIIrFMs$~}lYdkB>jUUKO zn#gmCsv05+|MtyU4M&PsjVDNzO0}{KfZy|J=5`qos4L=tf2!eBXow_CMaI4NY!)Fu z(5zPbUWbv*n8(AnwLjvZGN%2L=>~;(U{7i)DwDvK{m~kE{`Zv~;YIOlQ=&&6`vR?LLA5SMIU!d-V2nLrEE|TOjdJL~5 zT=JBU7O}0zRut(35a$#UV{r(-86JQde(^p}((77Pv+SaM)C6YeoTE5o+XT;!jI>TnnQA%fc`x!qt zID?`4oVaE2Y}S^m339SCX|a}ZD-g&9#M1xf_S`;Yb!UGqVBo_0nzq*TUj(6tAh|v)P&veLe z-;cS7Drm_L{aD}H;Y?PDLW_)+C7H_`e0$eL9f6h7OVy^hc5M$vOO6kf^07*p8p$6| zqnRip@ZUuGxvUgq#oj%T_1pIbl&m+RuHoHFJMO*>GdLD43WhLEF#D>OxaVY>ph$EX zmkV%m67j7iq8u$-27&Eq`Gb2YME7kaR#@fV)@jsYs^IiJxR&Q4DjG}%v<0dK1+TFqd{G!I#Av(-9!7UH zl=nPMJv`qPbc-JjTbf+D+cU}Dl$8}}Rjf8oKptqN8?!Bym4pAD1z7rOU+TZ+3gK2 zgJ@7+c`1|X(BO48U-yR#jgAzxZ0NC95L_*7Dhu%%c~mWBOiaMqLH&OiX~-gkrzUcB@d=2)lz2v@+E`m}*laIYXmN_f zifA-t7feY{7n!Inn*H-CN%*hk>fBNdjdVIfxg<1=LzJ{95F2u7tu@@WV4}MO;1n9F zl>85>YynmmnWJBDzTg;5)&F=9C&6w?Kh`0#ilyc38X9-<=B3~v>;*#5)$ALwgm^G7 zZ>@iSQgbWA;e>tqmIZh9H-$#CN9+`*7~RiFE@>(Ei;HY8X$LLmL`SbN}o4=Sf zI*dxHvp96l$E|_wRGdTf;0#rYg7@Fe`gKbJ70Roi23L*(dh>l@$nzpvl4|Nx!S?W5 zSzYci-aA^tQqoe$+xvY)m6eS~i&%{c92*fx(AZ+`p>dA_=MLM%Hq>YaODWl1TpdZJPwvzi) z-LWDYiZu%ob}r#6SMD$FyuH?kA{(2o->F&Naxsd?e{IG3+QUR~Nkq%itBz)PdGg%} zVfIemIVMcMd%|jrq@&>T7gACiySq8LxjnZ?iVN+?bi=xTkL;#CBMd+e@AKurPKd3S-XNlD5=koty(jjb&@s&Lek=Dp#PJM|}V z{utRjf)(LvAHTt~=V-QW*&VH0K}d7xn*B6_ZOt?~ShMGImW9N{#UaH#0wTcysj-0W z_HJZ?68=4q zG~AmBE!4bXTd>l{gw0Eg7{`z44b^2rRtU*ZpX9h$cl_PTj0Z|q@TYsXnxwThg?&@_ z!rZ<;r=ax16%mP)ZVu7B_ejRKT{L)A$-l;a?aaIm`b{_0eZ&1NrqriX#%H&yA^<_5 zgVT^u+tpLLXv1Y1YW)?*-#W3s8G7m&50{*_`D6I z8Vdl&>tl!Dc-y+p?p!m6Nqm>b_X{qxWb>3&$RAuzq6jNlsn!Um(>`LPqO*#EPM1Yj zf3I545$AHA3`Cyi$VaS|h)NP9pAk+h-ta`#L>%FyYkZ%h+7m0f*Z7IPsxw_p>FJ|~ z(d^}0CmqZ37zzR6Zo>|PqnO`|C3%-Z`ip|=WPf;yMUzj7^UaA%OEI0@4cQ-R&@6k! z*k8|(1{Ozrqu9P=z2-X-L=z>ZnmbqAOUrk>XAx4A-7l;rO>XpzN6v1{7m#E3t zS>D!y5IrK#OC)Lr+o}616dQsD7x^ch&+Lgl3NGz35DS$MFQj;-KrI`{9Ge%jElCPK z+|%%^a+lGPwL=LFdc~s{Q>eQ~x6S=s^ZIGy*fkkf!G|8j;)zU!XlD94>v4SdHbH6| zD)KQSmd|fVu_-h;7FD#y+9<8uy;a%RQ(WN`TMQ#RaI{3En?{}N)4ohrz`5hXSH!se zo3=EXWAZsXB64uL=fx+$hyG58aOW0{zM%r{GFj8I2xk0B{{4c&^U1_KRZIDK1<`)PtRzAiYez7PO}V+J%-hIczo62Ush_P(nVd% zZ5I=)-27(`9t`EY1nXQLe(21hPK_Mo&^T#Q(c2Nj)i3XWP1WT+GgiqrdyZVCP6Iv=u-(vKK1gB znkuxF#@cg@thIzOOp16riznaN60@|70qZU$rKQ^+9&Tn-#kD=`flX7WF0`H zJkM7}L4EcxNv|cyNo;LaRU?Xz`n0gX4=+O4Zobvd+}ynH*v$Y1U1h92rD%Dlglvf4 z_``-|5i}bHAuGTkCney@B;`(v1kv19TiSr{9CmwF1DL%qXov<1R>7}snIjXOO~XP;>y`!Oev~6Ahr+>*mFctT`0)+SU=y4g!O19c|zyrf`r26y{`M>df}a z8mcV!D~@7PR*M~pn?$a5Qvbn1KHuQ(BR~0f91H}8TR2(3U;h;>I<6k28CmQz<{xrx zfADT#{;0pekeY24Hh)KY4h^0um6rE++Aa5 z{f`#;wRvR;eqq5KKsGQlQ-{BUO*;|u?jVghKpJihd*gwtezD>Gvh + + */ + public static final int securitycompasstitle=0x7f050024; + public static final int setservercredentialsactivity_configureprompt=0x7f050013; + public static final int setservercredentialsactivity_donebutton=0x7f050016; + public static final int setservercredentialsactivity_password=0x7f050015; + public static final int setservercredentialsactivity_username=0x7f050014; + public static final int setupunlockactivity_configureprompt=0x7f05000f; + public static final int setupunlockactivity_donebutton=0x7f050012; + public static final int setupunlockactivity_password=0x7f050010; + public static final int setupunlockactivity_repeat_password=0x7f050011; + public static final int statementscreen_clear_button=0x7f050007; + public static final int summaryscreen_accounts_button=0x7f050004; + public static final int summaryscreen_statement_button=0x7f050006; + public static final int summaryscreen_transfer_button=0x7f050005; + /** Error messages + */ + public static final int toast_loginfailed=0x7f050017; + public static final int transferscreen_amount_text=0x7f05000a; + public static final int transferscreen_enteramount_hint=0x7f05000c; + public static final int transferscreen_fromtext=0x7f050008; + public static final int transferscreen_success=0x7f05000d; + public static final int transferscreen_totext=0x7f050009; + public static final int transferscreen_transfer_button=0x7f05000b; + } + public static final class xml { + public static final int userpreferences=0x7f040000; + } +} diff --git a/res/layout/loginactivity.xml b/res/layout/loginactivity.xml index ae1a8c3..6025f2a 100644 --- a/res/layout/loginactivity.xml +++ b/res/layout/loginactivity.xml @@ -4,5 +4,7 @@