From 05a5da4c8d24f4eac45de221f5aa067b3f6f29ab Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Wed, 6 Dec 2017 22:28:25 +0100 Subject: [PATCH] Add fingerprint dialog and update icons --- app/build.gradle | 1 + .../com/keepassdroid/PasswordActivity.java | 94 +++++++----- .../FingerPrintAnimatedVector.java | 54 +++++++ .../keepassdroid/view/FingerPrintDialog.java | 84 +++++++++++ app/src/main/res/animator-v23/scan.xml | 39 +++++ app/src/main/res/drawable-v23/fingerprint.xml | 65 +++++++++ .../res/drawable-v23/fingerprint_scan.xml | 109 ++++++++++++++ app/src/main/res/drawable-v23/lock_open.xml | 12 ++ .../res/drawable-v23/scan_fingerprint.xml | 26 ++++ app/src/main/res/drawable/circle.xml | 6 + .../res/drawable/ic_lock_open_white_24dp.xml | 9 ++ app/src/main/res/drawable/type_assword.png | Bin 0 -> 2676 bytes .../main/res/layout/fingerprint_dialog.xml | 136 ++++++++++++++++++ app/src/main/res/layout/password.xml | 58 ++++---- app/src/main/res/values-fr/strings.xml | 7 + app/src/main/res/values-v23/fingerprint.xml | 51 +++++++ app/src/main/res/values/donottranslate.xml | 6 + app/src/main/res/values/strings.xml | 7 + art/TypePassword.png | Bin 0 -> 2676 bytes 19 files changed, 705 insertions(+), 59 deletions(-) create mode 100644 app/src/main/java/com/keepassdroid/fingerprint/FingerPrintAnimatedVector.java create mode 100644 app/src/main/java/com/keepassdroid/view/FingerPrintDialog.java create mode 100644 app/src/main/res/animator-v23/scan.xml create mode 100644 app/src/main/res/drawable-v23/fingerprint.xml create mode 100644 app/src/main/res/drawable-v23/fingerprint_scan.xml create mode 100644 app/src/main/res/drawable-v23/lock_open.xml create mode 100644 app/src/main/res/drawable-v23/scan_fingerprint.xml create mode 100644 app/src/main/res/drawable/circle.xml create mode 100644 app/src/main/res/drawable/ic_lock_open_white_24dp.xml create mode 100644 app/src/main/res/drawable/type_assword.png create mode 100644 app/src/main/res/layout/fingerprint_dialog.xml create mode 100644 app/src/main/res/values-v23/fingerprint.xml create mode 100644 art/TypePassword.png diff --git a/app/build.gradle b/app/build.gradle index 18fedc719..b0f2970f1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,4 +66,5 @@ dependencies { compile "com.madgag.spongycastle:core:$spongycastleVersion" compile "com.madgag.spongycastle:prov:$spongycastleVersion" compile "joda-time:joda-time:2.9.9" + compile "org.sufficientlysecure:html-textview:3.5" } diff --git a/app/src/main/java/com/keepassdroid/PasswordActivity.java b/app/src/main/java/com/keepassdroid/PasswordActivity.java index 4ec59630a..473a2c8b1 100644 --- a/app/src/main/java/com/keepassdroid/PasswordActivity.java +++ b/app/src/main/java/com/keepassdroid/PasswordActivity.java @@ -44,11 +44,10 @@ import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; +import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; -import com.kunzisoft.keepass.KeePass; -import com.kunzisoft.keepass.R; import com.keepassdroid.app.App; import com.keepassdroid.compat.BackupManagerCompat; import com.keepassdroid.compat.ClipDataCompat; @@ -58,6 +57,7 @@ import com.keepassdroid.database.edit.LoadDB; import com.keepassdroid.database.edit.OnFinish; import com.keepassdroid.dialog.PasswordEncodingDialogHelper; import com.keepassdroid.fileselect.BrowserDialog; +import com.keepassdroid.fingerprint.FingerPrintAnimatedVector; import com.keepassdroid.fingerprint.FingerPrintHelper; import com.keepassdroid.intents.Intents; import com.keepassdroid.utils.EmptyUtils; @@ -65,6 +65,9 @@ import com.keepassdroid.utils.Interaction; import com.keepassdroid.utils.MenuUtil; import com.keepassdroid.utils.UriUtil; import com.keepassdroid.utils.Util; +import com.keepassdroid.view.FingerPrintDialog; +import com.kunzisoft.keepass.KeePass; +import com.kunzisoft.keepass.R; import java.io.File; import java.io.FileNotFoundException; @@ -96,8 +99,10 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp private int mode; private static final String PREF_KEY_VALUE_PREFIX = "valueFor_"; // key is a combination of db file name and this prefix private static final String PREF_KEY_IV_PREFIX = "ivFor_"; // key is a combination of db file name and this prefix - private View fingerprintView; - private TextView confirmationView; + private View fingerprintContainerView; + private View fingerprintImageView; + private FingerPrintAnimatedVector fingerPrintAnimatedVector; + private TextView fingerprintTextView; private EditText passwordView; private Button confirmButton; @@ -205,10 +210,16 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp getSupportActionBar().setDisplayShowHomeEnabled(true); confirmButton = (Button) findViewById(R.id.pass_ok); - fingerprintView = findViewById(R.id.fingerprint); - confirmationView = (TextView) findViewById(R.id.fingerprint_label); + fingerprintContainerView = findViewById(R.id.fingerprint_container); + fingerprintImageView = findViewById(R.id.fingerprint_image); + fingerprintTextView = (TextView) findViewById(R.id.fingerprint_label); passwordView = (EditText) findViewById(R.id.password); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + fingerPrintAnimatedVector = new FingerPrintAnimatedVector(this, + (ImageView) fingerprintImageView); + } + new InitTask().execute(i); } @@ -216,6 +227,11 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp protected void onResume() { super.onResume(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && fingerPrintAnimatedVector != null) { + fingerPrintAnimatedVector.startScan(); + } + // If the application was shutdown make sure to clear the password field, if it // was saved in the instance state if (App.isShutdown()) { @@ -287,7 +303,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp if ( !fingerprintMustBeConfigured ) { final boolean validInput = s.length() > 0; // encrypt or decrypt mode based on how much input or not - confirmationView.setText(validInput ? R.string.store_with_fingerprint : R.string.scanning_fingerprint); + fingerprintTextView.setText(validInput ? R.string.store_with_fingerprint : R.string.scanning_fingerprint); mode = validInput ? toggleMode(Cipher.ENCRYPT_MODE) : toggleMode(Cipher.DECRYPT_MODE); } } @@ -304,7 +320,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp // errorCode = 5 // errString = "Fingerprint operation canceled." //onFingerprintException(); - //confirmationView.setText(errString); + //fingerprintTextView.setText(errString); // true false fingerprint readings are handled otherwise with the toast messages, see below in code } @@ -314,7 +330,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp final CharSequence helpString) { onFingerprintException(new Exception("onAuthenticationHelp")); - confirmationView.setText(helpString); + fingerprintTextView.setText(helpString); } @Override @@ -370,6 +386,12 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp @Override protected void onPause() { super.onPause(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && fingerPrintAnimatedVector != null) { + fingerPrintAnimatedVector.stopScan(); + } + // stop listening when we go in background if (fingerPrintHelper != null) { fingerPrintHelper.stopListening(); @@ -377,42 +399,48 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp } private void setFingerPrintVisibility(int vis) { - fingerprintView.setVisibility(vis); - confirmationView.setVisibility(vis); + fingerprintContainerView.setVisibility(vis); } @RequiresApi(api = Build.VERSION_CODES.M) private void checkAvailability() { + // fingerprint not supported (by API level or hardware) so keep option hidden if (!fingerPrintHelper.isFingerprintSupported(FingerprintManagerCompat.from(this))) { setFingerPrintVisibility(View.GONE); } // fingerprint is available but not configured show icon but in disabled state with some information - else if (!fingerPrintHelper.hasEnrolledFingerprints()) { - - setFingerPrintVisibility(View.VISIBLE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - fingerprintView.setAlpha(0.3f); - } - // This happens when no fingerprints are registered. Listening won't start - confirmationView.setText(R.string.configure_fingerprint); - } - // finally fingerprint available and configured so we can use it else { - fingerprintMustBeConfigured = false; + // show explanations + fingerprintContainerView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + FingerPrintDialog fingerPrintDialog = new FingerPrintDialog(); + fingerPrintDialog.show(getSupportFragmentManager(), "fingerprintDialog"); + } + }); setFingerPrintVisibility(View.VISIBLE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - fingerprintView.setAlpha(1f); + + if (!fingerPrintHelper.hasEnrolledFingerprints()) { + fingerprintImageView.setAlpha(0.3f); + // This happens when no fingerprints are registered. Listening won't start + fingerprintTextView.setText(R.string.configure_fingerprint); } - // fingerprint available but no stored password found yet for this DB so show info don't listen - if (prefsNoBackup.getString(getPreferenceKeyValue(), null) == null) { - confirmationView.setText(R.string.no_password_stored); - } - // all is set here so we can confirm to user and start listening for fingerprints + // finally fingerprint available and configured so we can use it else { - confirmationView.setText(R.string.scanning_fingerprint); - // listen for decryption by default - toggleMode(Cipher.DECRYPT_MODE); + fingerprintMustBeConfigured = false; + fingerprintImageView.setAlpha(1f); + + // fingerprint available but no stored password found yet for this DB so show info don't listen + if (prefsNoBackup.getString(getPreferenceKeyValue(), null) == null) { + fingerprintTextView.setText(R.string.no_password_stored); + } + // all is set here so we can confirm to user and start listening for fingerprints + else { + fingerprintTextView.setText(R.string.scanning_fingerprint); + // listen for decryption by default + toggleMode(Cipher.DECRYPT_MODE); + } } } } @@ -428,7 +456,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp .apply(); // and remove visual input to reset UI confirmButton.performClick(); - confirmationView.setText(R.string.encrypted_value_stored); + fingerprintTextView.setText(R.string.encrypted_value_stored); } @Override diff --git a/app/src/main/java/com/keepassdroid/fingerprint/FingerPrintAnimatedVector.java b/app/src/main/java/com/keepassdroid/fingerprint/FingerPrintAnimatedVector.java new file mode 100644 index 000000000..1c15aa55d --- /dev/null +++ b/app/src/main/java/com/keepassdroid/fingerprint/FingerPrintAnimatedVector.java @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Brian Jeremy Jamet / Kunzisoft. + * + * This file is part of KeePass DX. + * + * KeePass DX is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * KeePass DX is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeePass DX. If not, see . + * + */ +package com.keepassdroid.fingerprint; + +import android.content.Context; +import android.graphics.drawable.Animatable2; +import android.graphics.drawable.AnimatedVectorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.widget.ImageView; + +import com.kunzisoft.keepass.R; + +@RequiresApi(api = Build.VERSION_CODES.M) +public class FingerPrintAnimatedVector { + + private AnimatedVectorDrawable scanFingerprint; + + public FingerPrintAnimatedVector(Context context, ImageView imageView) { + scanFingerprint = (AnimatedVectorDrawable) context.getDrawable(R.drawable.scan_fingerprint); + imageView.setImageDrawable(scanFingerprint); + } + + public void startScan() { + scanFingerprint.registerAnimationCallback(new Animatable2.AnimationCallback() { + public void onAnimationEnd(Drawable drawable) { + scanFingerprint.start(); + } + }); + scanFingerprint.start(); + } + + public void stopScan() { + scanFingerprint.stop(); + } +} diff --git a/app/src/main/java/com/keepassdroid/view/FingerPrintDialog.java b/app/src/main/java/com/keepassdroid/view/FingerPrintDialog.java new file mode 100644 index 000000000..f05c150be --- /dev/null +++ b/app/src/main/java/com/keepassdroid/view/FingerPrintDialog.java @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft. + * + * This file is part of KeePass DX. + * + * KeePass DX is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * KeePass DX is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeePass DX. If not, see . + * + */ +package com.keepassdroid.view; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.RequiresApi; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; + +import com.keepassdroid.fingerprint.FingerPrintAnimatedVector; +import com.kunzisoft.keepass.R; + +@RequiresApi(api = Build.VERSION_CODES.M) +public class FingerPrintDialog extends DialogFragment { + + private FingerPrintAnimatedVector fingerPrintAnimatedVector; + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + LayoutInflater inflater = getActivity().getLayoutInflater(); + + View rootView = inflater.inflate(R.layout.fingerprint_dialog, null); + + View fingerprintSettingWayTextView = rootView.findViewById(R.id.fingerprint_setting_way_text); + fingerprintSettingWayTextView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + startActivity(new Intent(android.provider.Settings.ACTION_SECURITY_SETTINGS)); + } + }); + + fingerPrintAnimatedVector = + new FingerPrintAnimatedVector(getContext(), + (ImageView) rootView.findViewById(R.id.fingerprint_image)); + + builder.setView(rootView) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + + } + }); + return builder.create(); + } + + @Override + public void onResume() { + super.onResume(); + fingerPrintAnimatedVector.startScan(); + } + + @Override + public void onPause() { + super.onPause(); + fingerPrintAnimatedVector.stopScan(); + } +} diff --git a/app/src/main/res/animator-v23/scan.xml b/app/src/main/res/animator-v23/scan.xml new file mode 100644 index 000000000..d4965f389 --- /dev/null +++ b/app/src/main/res/animator-v23/scan.xml @@ -0,0 +1,39 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable-v23/fingerprint.xml b/app/src/main/res/drawable-v23/fingerprint.xml new file mode 100644 index 000000000..6794fb4af --- /dev/null +++ b/app/src/main/res/drawable-v23/fingerprint.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-v23/fingerprint_scan.xml b/app/src/main/res/drawable-v23/fingerprint_scan.xml new file mode 100644 index 000000000..a313e708b --- /dev/null +++ b/app/src/main/res/drawable-v23/fingerprint_scan.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-v23/lock_open.xml b/app/src/main/res/drawable-v23/lock_open.xml new file mode 100644 index 000000000..d65cefb28 --- /dev/null +++ b/app/src/main/res/drawable-v23/lock_open.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v23/scan_fingerprint.xml b/app/src/main/res/drawable-v23/scan_fingerprint.xml new file mode 100644 index 000000000..248691440 --- /dev/null +++ b/app/src/main/res/drawable-v23/scan_fingerprint.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/circle.xml b/app/src/main/res/drawable/circle.xml new file mode 100644 index 000000000..bea663f9d --- /dev/null +++ b/app/src/main/res/drawable/circle.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_lock_open_white_24dp.xml b/app/src/main/res/drawable/ic_lock_open_white_24dp.xml new file mode 100644 index 000000000..f54491132 --- /dev/null +++ b/app/src/main/res/drawable/ic_lock_open_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/type_assword.png b/app/src/main/res/drawable/type_assword.png new file mode 100644 index 0000000000000000000000000000000000000000..7a6c072a8ad6d3fa6eee83af5664baa73c3f5f28 GIT binary patch literal 2676 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/fingerprint_dialog.xml b/app/src/main/res/layout/fingerprint_dialog.xml new file mode 100644 index 000000000..418db9b0d --- /dev/null +++ b/app/src/main/res/layout/fingerprint_dialog.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/password.xml b/app/src/main/res/layout/password.xml index 71bf5a64f..0812797c9 100644 --- a/app/src/main/res/layout/password.xml +++ b/app/src/main/res/layout/password.xml @@ -79,40 +79,46 @@ android:layout_height="wrap_content" android:text="@string/entry_and_or" /> - - + + android:layout_below="@id/password_label"> + + + + + - diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9b4da6533..e124e46a9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -208,6 +208,13 @@ Définir les caractères par défaut du générateur de mot de passe Notifications du presse-papiers Activer les notifications du presse-papiers pour copier le nom d\'utilisateur et le mot de passe + Comment configurer l\'empreinte digitale pour un déverrouillage rapide? + Définissez votre empreinte digitale personnelle pour votre appareil dans + Paramètres -> Sécurité -> Empreinte digitale + Tapez votre mot de passe dans Keepass DX + Scannez votre empreinte digitale pour stocker votre mot de passe maître en toute sécurité + Il suffit de scanner votre empreinte digitale dans Keepass DX lorsque le champ mot de passe est vide pour ouvrir la base de données + Usage 30 secondes diff --git a/app/src/main/res/values-v23/fingerprint.xml b/app/src/main/res/values-v23/fingerprint.xml new file mode 100644 index 000000000..bfef565a6 --- /dev/null +++ b/app/src/main/res/values-v23/fingerprint.xml @@ -0,0 +1,51 @@ + + + + + + 160 + 160 + 80 + 5 + 7 + 80dp + 80dp + + + M56.2199243,45.3815903 C56.2199243,45.3815903 65.1913567,38.8543184 80.3604294,38.8543184 C95.5295022,38.8543184 103.720044,45.2851323 103.720044,45.2851323 + M45.5181172,67.9181841 C49.9761548,62.7019025 59.122049,49.7790452 80.2279027,49.7790452 C101.333756,49.7790452 110.740506,62.0384399 114.937688,67.9181841 + M51.7375623,107.718438 C51.7375623,107.718438 48.7129745,99.6302234 48.7129745,91.6334356 C48.7129745,81.3266864 55.9028711,60.2476586 80.4057228,60.2478671 C100.798248,60.2480407 112.457463,79.7942647 112.457463,88.386575 C112.457462,99.2963939 105.619846,103.039218 100.781849,102.18762 C95.9438519,101.336021 90.4490979,97.2187731 91.0639139,92.3178681 C91.67873,87.4169631 85.2177374,81.3265129 80.7504553,81.3266871 C73.0900115,81.3269859 69.8146331,85.3921834 69.8146329,92.2700585 C69.8146324,107.718437 83.7557525,121.02713 91.6787289,121.027128 + M70.7357889,121.024995 C70.7357889,121.024995 57.4650216,106.018711 58.8888756,91.5596242 C60.5513085,74.6777941 73.9858126,70.313752 80.3788823,70.3807995 C86.771952,70.4478469 101.550994,76.8218704 101.550997,92.2895418 + M80.1599645,91.1813411 C80.1599645,91.1813411 81.1144795,102.68333 86.7971146,107.529716 C93.2390527,113.023667 105.911091,112.342743 105.911091,112.342743 + + M52.2735573,79.0771904 C52.2735573,79.0771904 69.2403688,96.0440006 69.2403683,96.0440014 C69.2403679,96.0440021 109.820188,55.4641819 109.820188,55.4641819 + + M62,62 C62,62 80.5647617,80.5647617 80.564762,80.564762 C80.5647622,80.5647622 94.2921789,94.223714 98.5644262,98.5644262 + M98.5644262,62 C98.5644251,62 81.1979242,79.366503 81.1979229,79.3665033 C81.1979216,79.3665035 62,98.5644262 62,98.5644262 + + + M0 0 L160 0 L160 40 L0 40 Z + M0 120 L160 120 L160 160 L0 160 Z + + #deffffff + #ffffffff + + #ff607d8b + + diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 26180f6a0..da67c61f6 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -126,4 +126,10 @@ @string/special @string/brackets + + I + II + III + IV + V diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f28c8b79b..d9d7ed91c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -208,6 +208,13 @@ Set the default password generator characters Clipboard Notifications Enable clipboard notifications to copy username and password + How to configure fingerprint for quick unlocking ? + Set your personnal fingerprint for your device in + Settings -> Security -> Fingerprint + Type your password in Keepass DX + Scan your fingerprint to store your master password securely + Just scan your fingerprint in Keepass DX when the password field is empty to open the database + Usage 30 seconds diff --git a/art/TypePassword.png b/art/TypePassword.png new file mode 100644 index 0000000000000000000000000000000000000000..7a6c072a8ad6d3fa6eee83af5664baa73c3f5f28 GIT binary patch literal 2676 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 literal 0 HcmV?d00001