aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--Graphics/android-icon-copier/.gitignore81
-rw-r--r--Graphics/android-icon-copier/LICENSE21
-rw-r--r--Graphics/android-icon-copier/README.md109
-rw-r--r--Graphics/android-icon-copier/classic.py146
-rwxr-xr-xGraphics/android-icon-copier/copy162
-rw-r--r--Graphics/android-icon-copier/options.templ.json8
-rw-r--r--Graphics/drawables/All_Icons.svg (renamed from Resources/graphics/All_Icons.svg)0
-rw-r--r--Graphics/drawables/comment-text.svg1
-rw-r--r--Graphics/drawables/create_key_robot.svg99
-rw-r--r--Graphics/drawables/drawer_header.svg5885
-rw-r--r--Graphics/drawables/drawer_header2.svg1636
-rw-r--r--Graphics/drawables/first_time_1.svg354
-rw-r--r--Graphics/drawables/function.png (renamed from Resources/graphics/function.png)bin97519 -> 97519 bytes
-rw-r--r--Graphics/drawables/function.svg (renamed from Resources/graphics/function.svg)0
-rw-r--r--Graphics/drawables/ic_action_encrypt_file.svg60
-rw-r--r--Graphics/drawables/ic_action_encrypt_text.svg60
-rw-r--r--Graphics/drawables/ic_action_safeslinger.svg (renamed from Resources/graphics/ic_action_safeslinger.svg)0
-rw-r--r--Graphics/drawables/ic_action_search_cloud.svg (renamed from Resources/graphics/ic_action_search_cloud.svg)0
-rw-r--r--Graphics/drawables/ic_action_verified_cutout.svg74
-rw-r--r--Graphics/drawables/ic_cloud_search_24px.svg54
-rw-r--r--Graphics/drawables/ic_launcher_old.svg (renamed from Resources/graphics/ic_launcher.svg)0
-rw-r--r--Graphics/drawables/icon_sizes.txt (renamed from Resources/graphics/icon_sizes.txt)0
-rw-r--r--Graphics/drawables/key_flag_authenticate.svg (renamed from Resources/graphics/key_flag_authenticate.svg)0
-rw-r--r--Graphics/drawables/key_flag_certify.svg (renamed from Resources/graphics/key_flag_certify.svg)0
-rw-r--r--Graphics/drawables/key_flag_encrypt.svg (renamed from Resources/graphics/key_flag_encrypt.svg)0
-rw-r--r--Graphics/drawables/key_flag_sign.svg (renamed from Resources/graphics/key_flag_sign.svg)0
-rw-r--r--Graphics/drawables/material-launcher/Feature Graphic.psdbin0 -> 1134998 bytes
-rw-r--r--Graphics/drawables/material-launcher/Feature-Graphic.pngbin0 -> 58185 bytes
-rw-r--r--Graphics/drawables/material-launcher/preview.psdbin0 -> 1853453 bytes
-rw-r--r--Graphics/drawables/material-launcher/preview1.pngbin0 -> 56983 bytes
-rw-r--r--Graphics/drawables/material-launcher/preview2.pngbin0 -> 68451 bytes
-rw-r--r--Graphics/drawables/material-launcher/preview3.pngbin0 -> 56336 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src-blue.pngbin0 -> 13422 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src-purple.pngbin0 -> 13229 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src.pngbin0 -> 13548 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src-blue.pngbin0 -> 16655 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src-purple.pngbin0 -> 16340 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src.pngbin0 -> 16742 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src-blue.pngbin0 -> 4609 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src-purple.pngbin0 -> 4515 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src.pngbin0 -> 4641 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src-blue.pngbin0 -> 25761 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src-purple.pngbin0 -> 25761 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src.pngbin0 -> 26237 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src-blue.pngbin0 -> 6863 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src-purple.pngbin0 -> 6717 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src.pngbin0 -> 6885 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src-blue.pngbin0 -> 8887 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src-purple.pngbin0 -> 8709 bytes
-rw-r--r--Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src.pngbin0 -> 8916 bytes
-rw-r--r--Graphics/drawables/material-launcher/vector-src blue.ai671
-rw-r--r--Graphics/drawables/material-launcher/vector-src purple.ai683
-rw-r--r--Graphics/drawables/material-launcher/vector-src purple.psdbin0 -> 300066 bytes
-rw-r--r--Graphics/drawables/material-launcher/vector-src.ai635
-rw-r--r--Graphics/drawables/material-launcher/vector-src.psdbin0 -> 301448 bytes
-rw-r--r--Graphics/drawables/material-launcher/vector-src.svg213
-rw-r--r--Graphics/drawables/material-launcher/vector.psdbin0 -> 1134732 bytes
-rw-r--r--Graphics/drawables/originals/gnupg-infographic/README (renamed from Resources/graphics/originals/gnupg-infographic/README)0
-rw-r--r--Graphics/drawables/originals/gnupg-infographic/gnupg-infographic.png (renamed from Resources/graphics/originals/gnupg-infographic/gnupg-infographic.png)bin486199 -> 486199 bytes
-rw-r--r--Graphics/drawables/originals/gnupg-infographic/gnupg-infographic.svg (renamed from Resources/graphics/originals/gnupg-infographic/gnupg-infographic.svg)0
-rw-r--r--Graphics/drawables/originals/ic_action_qr_code/ic_menu_qr_code.svg (renamed from Resources/graphics/originals/ic_action_qr_code/ic_menu_qr_code.svg)0
-rw-r--r--Graphics/drawables/originals/ic_cloud_24px.svg1
-rw-r--r--Graphics/drawables/originals/ic_launcher-old/AUTHORS (renamed from Resources/graphics/originals/ic_launcher/AUTHORS)0
-rw-r--r--Graphics/drawables/originals/ic_launcher-old/COPYING (renamed from Resources/graphics/originals/ic_launcher/COPYING)0
-rw-r--r--Graphics/drawables/originals/ic_launcher-old/kgpg_key2_kopete.svgz (renamed from Resources/graphics/originals/ic_launcher/kgpg_key2_kopete.svgz)bin36830 -> 36830 bytes
-rw-r--r--Graphics/drawables/originals/ic_search_24px.svg1
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/README.md (renamed from Resources/graphics/originals/modernpgp-icons/README.md)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-closed.png)bin4406 -> 4406 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed.svg (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-closed.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@200.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@200.png)bin6746 -> 6746 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@300.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@300.png)bin9753 -> 9753 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@512x.png)bin17387 -> 17387 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-error.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-error.png)bin4627 -> 4627 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-error.svg (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-error.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@200.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-error@200.png)bin7152 -> 7152 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@300.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-error@300.png)bin10220 -> 10220 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-error@512x.png)bin18697 -> 18697 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-open.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-open.png)bin4426 -> 4426 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-open.svg (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-open.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@200.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-open@200.png)bin6812 -> 6812 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@300.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-open@300.png)bin9704 -> 9704 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/encryption/lock-open@512x.png)bin17498 -> 17498 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint.png (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint.png)bin7848 -> 7848 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint.svg (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@200.png (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@200.png)bin14346 -> 14346 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@300.png (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@300.png)bin21322 -> 21322 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@512x.png)bin38093 -> 38093 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-key.png (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-key.png)bin4176 -> 4176 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-key.svg (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-key.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-key@200.png (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-key@200.png)bin5987 -> 5987 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-key@300.png (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-key@300.png)bin8197 -> 8197 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/keys/icon-key@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/keys/icon-key@512x.png)bin14384 -> 14384 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout.png)bin5003 -> 5003 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@200.png)bin7965 -> 7965 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@300.png)bin11515 -> 11515 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@512x.png)bin21420 -> 21420 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired.png)bin5037 -> 5037 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@200.png)bin7936 -> 7936 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@300.png)bin11420 -> 11420 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@512x.png)bin20650 -> 20650 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout.png)bin3643 -> 3643 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@200.png)bin5165 -> 5165 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@300.png)bin7712 -> 7712 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@512x.png)bin14332 -> 14332 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid.png)bin4024 -> 4024 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@200.png)bin5969 -> 5969 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@300.png)bin8833 -> 8833 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@512x.png)bin15993 -> 15993 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout.png)bin5061 -> 5061 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@200.png)bin7818 -> 7818 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@300.png)bin11578 -> 11578 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@512x.png)bin22423 -> 22423 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked.png)bin5083 -> 5083 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@200.png)bin7928 -> 7928 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@300.png)bin11727 -> 11727 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@512x.png)bin22153 -> 22153 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout.png)bin4845 -> 4845 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@200.png)bin7571 -> 7571 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@300.png)bin10941 -> 10941 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@512x.png)bin20160 -> 20160 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown.png)bin4723 -> 4723 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@200.png)bin7337 -> 7337 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@300.png)bin10570 -> 10570 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@512x.png)bin19036 -> 19036 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout.png)bin5004 -> 5004 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@200.png)bin7911 -> 7911 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@300.png)bin11425 -> 11425 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@512x.png)bin20909 -> 20909 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified.png)bin4236 -> 4236 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@200.png)bin6283 -> 6283 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@300.png)bin8964 -> 8964 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@512x.png)bin15762 -> 15762 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout.png)bin4976 -> 4976 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@200.png)bin8034 -> 8034 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@300.png)bin12079 -> 12079 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@512x.png)bin23287 -> 23287 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified.png)bin4374 -> 4374 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified.svg (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified.svg)0
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@200.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@200.png)bin6840 -> 6840 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@300.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@300.png)bin9773 -> 9773 bytes
-rw-r--r--Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@512x.png (renamed from Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@512x.png)bin17688 -> 17688 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_18dp.pngbin0 -> 544 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_24dp.pngbin0 -> 696 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_36dp.pngbin0 -> 999 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_48dp.pngbin0 -> 1380 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_18dp.pngbin0 -> 857 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_24dp.pngbin0 -> 1059 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_36dp.pngbin0 -> 1522 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_48dp.pngbin0 -> 2040 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_18dp.pngbin0 -> 572 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_24dp.pngbin0 -> 740 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_36dp.pngbin0 -> 1052 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_48dp.pngbin0 -> 1476 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_18dp.pngbin0 -> 370 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_24dp.pngbin0 -> 463 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_36dp.pngbin0 -> 696 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_48dp.pngbin0 -> 891 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_18dp.pngbin0 -> 539 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_24dp.pngbin0 -> 701 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_36dp.pngbin0 -> 1059 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_48dp.pngbin0 -> 1359 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_18dp.pngbin0 -> 387 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_24dp.pngbin0 -> 485 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_36dp.pngbin0 -> 740 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_48dp.pngbin0 -> 943 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_18dp.pngbin0 -> 696 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_24dp.pngbin0 -> 891 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_36dp.pngbin0 -> 1380 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_48dp.pngbin0 -> 1818 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_18dp.pngbin0 -> 1059 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_24dp.pngbin0 -> 1359 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_36dp.pngbin0 -> 2040 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_48dp.pngbin0 -> 2756 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_18dp.pngbin0 -> 740 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_24dp.pngbin0 -> 943 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_36dp.pngbin0 -> 1476 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_48dp.pngbin0 -> 1938 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_18dp.pngbin0 -> 999 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_24dp.pngbin0 -> 1380 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_36dp.pngbin0 -> 2035 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_48dp.pngbin0 -> 2832 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_18dp.pngbin0 -> 1522 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_24dp.pngbin0 -> 2040 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_36dp.pngbin0 -> 3072 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_48dp.pngbin0 -> 4203 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_18dp.pngbin0 -> 1052 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_24dp.pngbin0 -> 1476 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_36dp.pngbin0 -> 2257 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_48dp.pngbin0 -> 3107 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_18dp.pngbin0 -> 1380 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_24dp.pngbin0 -> 1818 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_36dp.pngbin0 -> 2832 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_48dp.pngbin0 -> 3815 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_18dp.pngbin0 -> 2040 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_24dp.pngbin0 -> 2756 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_36dp.pngbin0 -> 4203 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_48dp.pngbin0 -> 5697 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_18dp.pngbin0 -> 1476 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_24dp.pngbin0 -> 1938 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_36dp.pngbin0 -> 3107 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_48dp.pngbin0 -> 4241 bytes
-rw-r--r--Graphics/drawables/originals/nfc/drawable/nfc.xml8
-rw-r--r--Graphics/drawables/originals/nfc/readme.txt5
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_18dp.pngbin0 -> 518 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_24dp.pngbin0 -> 402 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_36dp.pngbin0 -> 496 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_48dp.pngbin0 -> 343 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_18dp.pngbin0 -> 723 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_24dp.pngbin0 -> 445 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_36dp.pngbin0 -> 562 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_48dp.pngbin0 -> 356 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_18dp.pngbin0 -> 550 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_24dp.pngbin0 -> 427 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_36dp.pngbin0 -> 512 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_48dp.pngbin0 -> 352 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_18dp.pngbin0 -> 316 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_24dp.pngbin0 -> 222 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_36dp.pngbin0 -> 402 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_48dp.pngbin0 -> 279 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_18dp.pngbin0 -> 423 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_24dp.pngbin0 -> 235 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_36dp.pngbin0 -> 445 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_48dp.pngbin0 -> 287 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_18dp.pngbin0 -> 329 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_24dp.pngbin0 -> 231 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_36dp.pngbin0 -> 427 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_48dp.pngbin0 -> 284 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_18dp.pngbin0 -> 402 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_24dp.pngbin0 -> 279 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_36dp.pngbin0 -> 343 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_48dp.pngbin0 -> 407 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_18dp.pngbin0 -> 445 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_24dp.pngbin0 -> 287 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_36dp.pngbin0 -> 356 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_48dp.pngbin0 -> 416 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_18dp.pngbin0 -> 427 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_24dp.pngbin0 -> 284 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_36dp.pngbin0 -> 352 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_48dp.pngbin0 -> 414 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_18dp.pngbin0 -> 496 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_24dp.pngbin0 -> 343 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_36dp.pngbin0 -> 642 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_48dp.pngbin0 -> 574 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_18dp.pngbin0 -> 562 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_24dp.pngbin0 -> 356 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_36dp.pngbin0 -> 687 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_48dp.pngbin0 -> 581 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_18dp.pngbin0 -> 512 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_24dp.pngbin0 -> 352 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_36dp.pngbin0 -> 674 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_48dp.pngbin0 -> 580 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_18dp.pngbin0 -> 343 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_24dp.pngbin0 -> 407 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_36dp.pngbin0 -> 574 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_48dp.pngbin0 -> 725 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_18dp.pngbin0 -> 356 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_24dp.pngbin0 -> 416 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_36dp.pngbin0 -> 581 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_48dp.pngbin0 -> 734 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_18dp.pngbin0 -> 352 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_24dp.pngbin0 -> 414 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_36dp.pngbin0 -> 580 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_48dp.pngbin0 -> 731 bytes
-rw-r--r--Graphics/drawables/originals/qrcode/drawable/qrcode.xml8
-rw-r--r--Graphics/drawables/originals/qrcode/readme.txt5
-rw-r--r--Graphics/drawables/originals/tango or oxygen/1270234450.svg (renamed from Resources/graphics/originals/tango or oxygen/1270234450.svg)0
-rw-r--r--Graphics/drawables/originals/tango or oxygen/application-pgp-signature.svg (renamed from Resources/graphics/originals/tango or oxygen/application-pgp-signature.svg)0
-rw-r--r--Graphics/drawables/originals/tango or oxygen/application-pkcs7-signature.svg (renamed from Resources/graphics/originals/tango or oxygen/application-pkcs7-signature.svg)0
-rw-r--r--Graphics/drawables/originals/tango or oxygen/osa_id_card.svg (renamed from Resources/graphics/originals/tango or oxygen/osa_id_card.svg)0
-rw-r--r--Graphics/drawables/originals/tango or oxygen/osa_padlock.svg (renamed from Resources/graphics/originals/tango or oxygen/osa_padlock.svg)0
-rw-r--r--Graphics/drawables/originals/tango or oxygen/tango-style-pen.svg (renamed from Resources/graphics/originals/tango or oxygen/tango-style-pen.svg)0
-rw-r--r--Graphics/drawables/status_lock_closed.svg (renamed from Resources/graphics/status_lock_closed.svg)0
-rw-r--r--Graphics/drawables/status_lock_error.svg (renamed from Resources/graphics/status_lock_error.svg)0
-rw-r--r--Graphics/drawables/status_lock_open.svg (renamed from Resources/graphics/status_lock_open.svg)0
-rw-r--r--Graphics/drawables/status_signature_expired.svg (renamed from Resources/graphics/status_signature_expired.svg)0
-rw-r--r--Graphics/drawables/status_signature_expired_cutout.svg (renamed from Resources/graphics/status_signature_expired_cutout.svg)0
-rw-r--r--Graphics/drawables/status_signature_invalid.svg (renamed from Resources/graphics/status_signature_invalid.svg)0
-rw-r--r--Graphics/drawables/status_signature_invalid_cutout.svg (renamed from Resources/graphics/status_signature_invalid_cutout.svg)0
-rw-r--r--Graphics/drawables/status_signature_revoked.svg (renamed from Resources/graphics/status_signature_revoked.svg)0
-rw-r--r--Graphics/drawables/status_signature_revoked_cutout.svg (renamed from Resources/graphics/status_signature_revoked_cutout.svg)0
-rw-r--r--Graphics/drawables/status_signature_unknown.svg (renamed from Resources/graphics/status_signature_unknown.svg)0
-rw-r--r--Graphics/drawables/status_signature_unknown_cutout.svg (renamed from Resources/graphics/status_signature_unknown_cutout.svg)0
-rw-r--r--Graphics/drawables/status_signature_unverified.svg (renamed from Resources/graphics/status_signature_unverified.svg)0
-rw-r--r--Graphics/drawables/status_signature_unverified_cutout.svg (renamed from Resources/graphics/status_signature_unverified_cutout.svg)0
-rw-r--r--Graphics/drawables/status_signature_verified.svg (renamed from Resources/graphics/status_signature_verified.svg)0
-rw-r--r--Graphics/drawables/status_signature_verified_cutout.svg (renamed from Resources/graphics/status_signature_verified_cutout.svg)0
-rwxr-xr-xGraphics/get-material-icons.sh28
-rw-r--r--Graphics/screenshots/device-2015-02-20-110958-device.pngbin0 -> 905897 bytes
-rw-r--r--Graphics/screenshots/device-2015-02-20-110958.pngbin0 -> 93621 bytes
-rwxr-xr-xGraphics/update-drawables.sh88
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java238
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java223
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java126
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java364
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java259
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java61
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java51
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java39
-rw-r--r--OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java7
-rw-r--r--OpenKeychain-Test/src/test/resources/test-keys/broken_cert_version.asc17
-rw-r--r--OpenKeychain/build.gradle27
-rw-r--r--OpenKeychain/src/main/AndroidManifest.xml80
-rw-r--r--OpenKeychain/src/main/java/android/support/v4/widget/FixedDrawerLayout.java49
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java21
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java23
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java131
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java85
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java103
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java136
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java66
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java66
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java72
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java200
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java63
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java139
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java53
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java90
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SingletonResult.java34
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java82
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java13
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java33
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java26
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java353
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java470
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java640
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java176
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java578
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java135
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java347
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java132
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java37
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java123
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java33
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java59
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java156
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java265
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java609
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java35
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java140
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java292
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java108
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsHeaderFragment.java108
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java36
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java350
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java404
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java678
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java146
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BaseActivity.java131
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java92
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java184
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java24
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java125
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java14
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java19
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java306
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java49
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java38
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptDecryptOverviewFragment.java150
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java69
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java73
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java18
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java29
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java184
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java13
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java222
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java371
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java50
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NavDrawerActivity.java50
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcActivity.java71
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcIntentActivity.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java115
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseWizardActivity.java575
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java482
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java166
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeScanActivity.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java66
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java70
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java145
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java508
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsKeyServerActivity.java165
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java14
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java17
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java528
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java257
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvCertsFragment.java342
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvMainFragment.java351
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java387
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java125
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvancedActivity.java93
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvancedFragment.java378
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java232
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java350
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java390
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java14
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java26
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java16
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java50
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java26
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AdvancedAppSettingsDialogFragment.java72
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java34
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ActionBarHelper.java99
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/FormattingUtils.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java101
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java113
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/AspectRatioImageView.java138
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java17
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java39
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ListAwareSwipeRefreshLayout.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SlidingTabLayout.java318
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SlidingTabStrip.java211
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java49
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Iso7816TLV.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java15
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java11
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/apptheme_fastscroll_thumb_default_holo.pngbin260 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/apptheme_fastscroll_thumb_pressed_holo.pngbin467 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/create_key_robot.pngbin2259 -> 2299 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_action_collapse.pngbin467 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_action_encrypt_file.pngbin0 -> 623 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_action_encrypt_text.pngbin0 -> 787 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_action_expand.pngbin415 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_action_nfc.pngbin1660 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_action_qr_code.pngbin2134 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_action_safeslinger.pngbin2616 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_action_verified_cutout.pngbin0 -> 1080 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_apps_black_24dp.pngbin0 -> 182 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.pngbin0 -> 287 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_check_white_24dp.pngbin0 -> 309 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_close_white_24dp.pngbin0 -> 324 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_cloud_search_24px.pngbin0 -> 1025 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_expand_less_black_24dp.pngbin0 -> 234 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_expand_more_black_24dp.pngbin0 -> 244 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_folder_white_24dp.pngbin0 -> 224 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_help_black_24dp.pngbin0 -> 559 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_launcher.pngbin5093 -> 6885 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_lock_black_24dp.pngbin0 -> 397 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_lock_white_24dp.pngbin0 -> 399 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.pngbin0 -> 351 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_nfc_white_24dp.pngbin0 -> 740 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.pngbin0 -> 282 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_qrcode_white_24dp.pngbin0 -> 427 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_refresh_white_24dp.pngbin0 -> 531 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_repeat_grey_24dp.pngbin0 -> 297 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_repeat_white_24dp.pngbin0 -> 296 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_search_white_24dp.pngbin0 -> 504 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_settings_black_24dp.pngbin0 -> 561 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/ic_vpn_key_black_24dp.pngbin0 -> 381 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/key_flag_authenticate_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/key_flag_authenticate.png)bin1302 -> 1302 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/key_flag_certify_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/key_flag_certify.png)bin2289 -> 2289 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/key_flag_encrypt_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/key_flag_encrypt.png)bin1530 -> 1530 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/key_flag_sign_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/key_flag_sign.png)bin1751 -> 1751 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.pngbin402 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_disabled_holo_light.pngbin361 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_focused_holo_light.pngbin413 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_holo_light.pngbin242 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_pressed_holo_light.pngbin423 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.pngbin800 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_disabled_holo_light.pngbin624 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_focused_holo_light.pngbin1699 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_holo_light.pngbin1519 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_pressed_holo_light.pngbin803 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.pngbin330 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_disabled_holo_light.9.pngbin422 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_focused_holo_light.9.pngbin400 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_normal_holo_light.9.pngbin406 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_pressed_holo_light.9.pngbin390 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.pngbin1398 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_disabled_holo_light.pngbin717 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_focused_holo_light.pngbin1467 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_holo_light.pngbin736 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_pressed_holo_light.pngbin1574 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.pngbin2383 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_disabled_holo_light.pngbin1169 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_focused_holo_light.pngbin2199 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_holo_light.pngbin1402 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_pressed_holo_light.pngbin1908 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_activated_holo.9.pngbin115 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_focused_holo.9.pngbin139 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_longpressed_holo.9.pngbin115 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_pressed_holo_light.9.pngbin115 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_selector_disabled_holo_light.9.pngbin189 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_bg_holo_light.9.pngbin175 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_primary_holo_light.9.pngbin381 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_secondary_holo_light.9.pngbin149 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo1.pngbin729 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo2.pngbin810 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo3.pngbin913 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo4.pngbin954 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo5.pngbin840 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo6.pngbin960 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo7.pngbin761 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo8.pngbin832 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_default_holo_light.9.pngbin304 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_disabled_holo_light.9.pngbin378 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_focused_holo_light.9.pngbin499 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_pressed_holo_light.9.pngbin359 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_activated_holo_light.9.pngbin199 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_default_holo_light.9.pngbin187 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_disabled_focused_holo_light.9.pngbin1208 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_disabled_holo_light.9.pngbin1116 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_focused_holo_light.9.pngbin298 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_lock_closed_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_lock_closed.png)bin675 -> 675 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_lock_error_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_lock_error.png)bin748 -> 748 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_lock_open_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_lock_open.png)bin675 -> 675 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired.pngbin723 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout.png)bin789 -> 789 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout_96px.pngbin0 -> 3241 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid.pngbin528 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout.png)bin444 -> 444 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout_96px.pngbin0 -> 1656 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked.pngbin714 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout.png)bin861 -> 861 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout_96px.pngbin0 -> 3638 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown.pngbin640 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout.png)bin740 -> 740 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout_96px.pngbin0 -> 2878 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified.pngbin536 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout.png)bin813 -> 813 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout_96px.pngbin0 -> 3257 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified.pngbin541 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout.png)bin695 -> 695 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout_96px.pngbin0 -> 3277 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-ldpi/ic_launcher.pngbin1967 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-ldpi/uid_mail_bad.pngbin531 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-ldpi/uid_mail_ok.pngbin646 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/apptheme_fastscroll_thumb_default_holo.pngbin169 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/apptheme_fastscroll_thumb_pressed_holo.pngbin306 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/create_key_robot.pngbin1766 -> 1767 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_action_collapse.pngbin404 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_action_encrypt_file.pngbin0 -> 480 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_action_encrypt_text.pngbin0 -> 572 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_action_expand.pngbin345 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_action_nfc.pngbin1147 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_action_qr_code.pngbin1314 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_action_safeslinger.pngbin1457 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_action_verified_cutout.pngbin0 -> 751 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_apps_black_24dp.pngbin0 -> 173 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.pngbin0 -> 240 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_check_white_24dp.pngbin0 -> 243 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_close_white_24dp.pngbin0 -> 279 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_cloud_search_24px.pngbin0 -> 712 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_expand_less_black_24dp.pngbin0 -> 206 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_expand_more_black_24dp.pngbin0 -> 206 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_folder_white_24dp.pngbin0 -> 206 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_help_black_24dp.pngbin0 -> 390 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_launcher.pngbin2896 -> 4641 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_lock_black_24dp.pngbin0 -> 291 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_lock_white_24dp.pngbin0 -> 296 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.pngbin0 -> 272 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_nfc_white_24dp.pngbin0 -> 485 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.pngbin0 -> 257 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_qrcode_white_24dp.pngbin0 -> 231 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_refresh_white_24dp.pngbin0 -> 346 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_repeat_grey_24dp.pngbin0 -> 238 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_repeat_white_24dp.pngbin0 -> 236 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_search_white_24dp.pngbin0 -> 346 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_settings_black_24dp.pngbin0 -> 416 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/ic_vpn_key_black_24dp.pngbin0 -> 293 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/key_flag_authenticate_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/key_flag_authenticate.png)bin897 -> 897 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/key_flag_certify_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/key_flag_certify.png)bin1746 -> 1746 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/key_flag_encrypt_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/key_flag_encrypt.png)bin1153 -> 1153 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/key_flag_sign_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/key_flag_sign.png)bin1353 -> 1353 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.pngbin300 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_disabled_holo_light.pngbin329 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_focused_holo_light.pngbin319 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_holo_light.pngbin183 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_pressed_holo_light.pngbin289 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.pngbin592 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_disabled_holo_light.pngbin508 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_focused_holo_light.pngbin1100 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_holo_light.pngbin1004 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_pressed_holo_light.pngbin554 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.pngbin232 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_disabled_holo_light.9.pngbin313 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_focused_holo_light.9.pngbin286 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_normal_holo_light.9.pngbin276 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_pressed_holo_light.9.pngbin265 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.pngbin778 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_disabled_holo_light.pngbin479 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_focused_holo_light.pngbin802 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_holo_light.pngbin451 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_pressed_holo_light.pngbin962 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.pngbin1278 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_disabled_holo_light.pngbin736 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_focused_holo_light.pngbin1184 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_holo_light.pngbin847 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_pressed_holo_light.pngbin1118 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_activated_holo.9.pngbin110 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_focused_holo.9.pngbin117 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_longpressed_holo.9.pngbin110 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_pressed_holo_light.9.pngbin110 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_selector_disabled_holo_light.9.pngbin171 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_bg_holo_light.9.pngbin161 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_primary_holo_light.9.pngbin270 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_secondary_holo_light.9.pngbin135 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo1.pngbin413 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo2.pngbin485 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo3.pngbin539 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo4.pngbin521 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo5.pngbin506 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo6.pngbin538 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo7.pngbin489 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo8.pngbin507 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_default_holo_light.9.pngbin237 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_disabled_holo_light.9.pngbin274 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_focused_holo_light.9.pngbin390 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_pressed_holo_light.9.pngbin279 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_activated_holo_light.9.pngbin165 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_default_holo_light.9.pngbin151 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_disabled_focused_holo_light.9.pngbin1133 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_disabled_holo_light.9.pngbin1094 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_focused_holo_light.9.pngbin264 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_lock_closed_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_lock_closed.png)bin528 -> 528 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_lock_error_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_lock_error.png)bin622 -> 622 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_lock_open_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_lock_open.png)bin522 -> 522 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired.pngbin601 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout.png)bin643 -> 643 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout_96px.pngbin0 -> 2411 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid.pngbin463 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout.png)bin410 -> 410 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout_96px.pngbin0 -> 958 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked.pngbin613 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout.png)bin685 -> 685 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout_96px.pngbin0 -> 2475 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown.pngbin517 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout.png)bin589 -> 589 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout_96px.pngbin0 -> 2105 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified.pngbin469 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout.png)bin667 -> 667 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout_96px.pngbin0 -> 2314 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified.pngbin476 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout.png)bin557 -> 557 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout_96px.pngbin0 -> 2148 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/apptheme_fastscroll_thumb_default_holo.pngbin324 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/apptheme_fastscroll_thumb_pressed_holo.pngbin613 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/create_key_robot.pngbin3176 -> 3153 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_action_collapse.pngbin631 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_action_encrypt_file.pngbin0 -> 836 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_action_encrypt_text.pngbin0 -> 976 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_action_expand.pngbin582 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_action_nfc.pngbin2297 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_action_qr_code.pngbin2959 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_action_safeslinger.pngbin4012 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_action_verified_cutout.pngbin0 -> 1455 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_apps_black_24dp.pngbin0 -> 193 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.pngbin0 -> 336 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_check_white_24dp.pngbin0 -> 363 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_close_white_24dp.pngbin0 -> 402 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_cloud_search_24px.pngbin0 -> 1428 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_expand_less_black_24dp.pngbin0 -> 259 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_expand_more_black_24dp.pngbin0 -> 272 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_folder_white_24dp.pngbin0 -> 273 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_help_black_24dp.pngbin0 -> 700 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_launcher.pngbin7870 -> 8916 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_lock_black_24dp.pngbin0 -> 498 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_lock_white_24dp.pngbin0 -> 465 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.pngbin0 -> 378 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_nfc_white_24dp.pngbin0 -> 943 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.pngbin0 -> 318 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_qrcode_white_24dp.pngbin0 -> 284 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_refresh_white_24dp.pngbin0 -> 637 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_repeat_grey_24dp.pngbin0 -> 317 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_repeat_white_24dp.pngbin0 -> 314 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_search_white_24dp.pngbin0 -> 591 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_settings_black_24dp.pngbin0 -> 691 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/ic_vpn_key_black_24dp.pngbin0 -> 446 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/key_flag_authenticate_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/key_flag_authenticate.png)bin2161 -> 2161 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/key_flag_certify_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/key_flag_certify.png)bin3713 -> 3713 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/key_flag_encrypt_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/key_flag_encrypt.png)bin2310 -> 2310 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/key_flag_sign_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/key_flag_sign.png)bin2705 -> 2705 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.pngbin462 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_disabled_holo_light.pngbin375 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_focused_holo_light.pngbin479 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_holo_light.pngbin293 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_pressed_holo_light.pngbin549 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.pngbin1059 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_disabled_holo_light.pngbin762 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_focused_holo_light.pngbin2921 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_holo_light.pngbin2651 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_pressed_holo_light.pngbin1134 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.pngbin390 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_disabled_holo_light.9.pngbin541 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_focused_holo_light.9.pngbin443 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_normal_holo_light.9.pngbin520 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_pressed_holo_light.9.pngbin507 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.pngbin2082 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_disabled_holo_light.pngbin919 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_focused_holo_light.pngbin2161 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_holo_light.pngbin950 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_pressed_holo_light.pngbin2235 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.pngbin3484 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_disabled_holo_light.pngbin1643 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_focused_holo_light.pngbin3568 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_holo_light.pngbin2467 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_pressed_holo_light.pngbin2683 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_activated_holo.9.pngbin121 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_focused_holo.9.pngbin154 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_longpressed_holo.9.pngbin121 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_pressed_holo_light.9.pngbin121 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_selector_disabled_holo_light.9.pngbin188 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_bg_holo_light.9.pngbin178 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_primary_holo_light.9.pngbin477 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_secondary_holo_light.9.pngbin150 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo1.pngbin821 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo2.pngbin989 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo3.pngbin1187 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo4.pngbin1135 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo5.pngbin1083 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo6.pngbin1190 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo7.pngbin1069 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo8.pngbin1055 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_default_holo_light.9.pngbin392 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_disabled_holo_light.9.pngbin420 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_focused_holo_light.9.pngbin659 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_pressed_holo_light.9.pngbin507 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_activated_holo_light.9.pngbin237 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_default_holo_light.9.pngbin220 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_disabled_focused_holo_light.9.pngbin1176 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_disabled_holo_light.9.pngbin1116 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_focused_holo_light.9.pngbin434 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_lock_closed_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_lock_closed.png)bin911 -> 911 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_lock_error_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_lock_error.png)bin1008 -> 1008 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_lock_open_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_lock_open.png)bin911 -> 911 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired.pngbin1049 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout.png)bin1179 -> 1179 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout_96px.pngbin0 -> 4973 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid.pngbin736 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout.png)bin676 -> 676 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout_96px.pngbin0 -> 2306 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked.pngbin1033 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout.png)bin1218 -> 1218 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout_96px.pngbin0 -> 5757 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown.pngbin906 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout.png)bin1043 -> 1043 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout_96px.pngbin0 -> 4395 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified.pngbin706 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout.png)bin1166 -> 1166 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout_96px.pngbin0 -> 4908 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified.pngbin784 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout.png)bin1017 -> 1017 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout_96px.pngbin0 -> 5309 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/apptheme_fastscroll_thumb_default_holo.pngbin600 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/apptheme_fastscroll_thumb_pressed_holo.pngbin911 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/create_key_robot.pngbin4039 -> 4030 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_collapse.pngbin901 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_encrypt_file.pngbin0 -> 1095 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_encrypt_text.pngbin0 -> 1331 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_expand.pngbin974 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_nfc.pngbin2378 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_qr_code.pngbin4129 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_safeslinger.pngbin6626 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_verified_cutout.pngbin0 -> 2168 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_apps_black_24dp.pngbin0 -> 213 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.pngbin0 -> 410 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_check_white_24dp.pngbin0 -> 460 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_close_white_24dp.pngbin0 -> 492 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_cloud_search_24px.pngbin0 -> 2128 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_expand_less_black_24dp.pngbin0 -> 304 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_expand_more_black_24dp.pngbin0 -> 316 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_folder_white_24dp.pngbin0 -> 342 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_help_black_24dp.pngbin0 -> 986 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_launcher.pngbin14153 -> 13548 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_lock_black_24dp.pngbin0 -> 636 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_lock_white_24dp.pngbin0 -> 760 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.pngbin0 -> 490 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_nfc_white_24dp.pngbin0 -> 1476 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.pngbin0 -> 399 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_qrcode_white_24dp.pngbin0 -> 352 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.pngbin0 -> 875 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_repeat_grey_24dp.pngbin0 -> 400 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_repeat_white_24dp.pngbin0 -> 397 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_search_white_24dp.pngbin0 -> 871 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.pngbin0 -> 969 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/ic_vpn_key_black_24dp.pngbin0 -> 622 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_authenticate_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_authenticate.png)bin3073 -> 3073 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_certify_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_certify.png)bin5303 -> 5303 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_encrypt_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_encrypt.png)bin3158 -> 3158 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_sign_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_sign.png)bin3765 -> 3765 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.pngbin455 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_disabled_holo_light.pngbin1177 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_focused_holo_light.pngbin538 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_holo_light.pngbin329 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_pressed_holo_light.pngbin598 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.pngbin1117 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_disabled_holo_light.pngbin1574 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_focused_holo_light.pngbin3942 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_holo_light.pngbin3606 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_pressed_holo_light.pngbin1155 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.pngbin544 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_disabled_holo_light.9.pngbin1643 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_focused_holo_light.9.pngbin834 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_normal_holo_light.9.pngbin890 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_pressed_holo_light.9.pngbin823 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.pngbin2511 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_disabled_holo_light.pngbin2208 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_focused_holo_light.pngbin2720 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_holo_light.pngbin1490 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_pressed_holo_light.pngbin3039 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.pngbin4515 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_disabled_holo_light.pngbin3894 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_focused_holo_light.pngbin4895 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_holo_light.pngbin3657 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_pressed_holo_light.pngbin3544 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_activated_holo.9.pngbin133 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_focused_holo.9.pngbin158 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_longpressed_holo.9.pngbin133 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_pressed_holo_light.9.pngbin133 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_selector_disabled_holo_light.9.pngbin280 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_bg_holo_light.9.pngbin1084 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_primary_holo_light.9.pngbin847 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_secondary_holo_light.9.pngbin147 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo1.pngbin1328 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo2.pngbin1631 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo3.pngbin1909 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo4.pngbin1906 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo5.pngbin1801 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo6.pngbin1947 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo7.pngbin1745 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo8.pngbin1748 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_default_holo_light.9.pngbin443 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_disabled_holo_light.9.pngbin1326 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_focused_holo_light.9.pngbin696 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_pressed_holo_light.9.pngbin630 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_activated_holo_light.9.pngbin338 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_default_holo_light.9.pngbin325 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_disabled_focused_holo_light.9.pngbin464 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_disabled_holo_light.9.pngbin315 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_focused_holo_light.9.pngbin513 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_closed_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_closed.png)bin1160 -> 1160 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_error_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_error.png)bin1316 -> 1316 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_open_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_open.png)bin1165 -> 1165 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired.pngbin1429 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout.png)bin1590 -> 1590 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout_96px.pngbin0 -> 6986 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid.pngbin840 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout.png)bin694 -> 694 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout_96px.pngbin0 -> 3701 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked.pngbin1353 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout.png)bin1660 -> 1660 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout_96px.pngbin0 -> 7922 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown.pngbin1231 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout.png)bin1377 -> 1377 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout_96px.pngbin0 -> 5952 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified.pngbin946 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout.png)bin1555 -> 1555 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout_96px.pngbin0 -> 6544 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified.pngbin1012 -> 0 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout_24px.png (renamed from OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout.png)bin1319 -> 1319 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout_96px.pngbin0 -> 7353 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_apps_black_24dp.pngbin0 -> 236 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.pngbin0 -> 530 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.pngbin0 -> 587 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.pngbin0 -> 662 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_expand_less_black_24dp.pngbin0 -> 360 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_expand_more_black_24dp.pngbin0 -> 379 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_folder_white_24dp.pngbin0 -> 504 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_help_black_24dp.pngbin0 -> 1323 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_launcher.pngbin20825 -> 16742 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_lock_black_24dp.pngbin0 -> 830 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_lock_white_24dp.pngbin0 -> 971 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.pngbin0 -> 632 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_nfc_white_24dp.pngbin0 -> 1938 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.pngbin0 -> 477 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_qrcode_white_24dp.pngbin0 -> 414 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.pngbin0 -> 1148 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_repeat_grey_24dp.pngbin0 -> 481 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_repeat_white_24dp.pngbin0 -> 478 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.pngbin0 -> 1090 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.pngbin0 -> 1257 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable-xxxhdpi/ic_vpn_key_black_24dp.pngbin0 -> 789 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable/apptheme_fastscroll_thumb_holo.xml20
-rw-r--r--OpenKeychain/src/main/res/drawable/cardview_header.xml11
-rw-r--r--OpenKeychain/src/main/res/drawable/drawer_header.pngbin0 -> 49186 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable/fab_label_background.xml11
-rw-r--r--OpenKeychain/src/main/res/drawable/first_time_1.pngbin43898 -> 40232 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_activated_background_holo_light.xml20
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_btn_check_holo_light.xml65
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_btn_default_holo_light.xml32
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_btn_radio_holo_light.xml59
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_edit_text_holo_light.xml25
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_item_background_holo_light.xml26
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_list_selector_background_transition_holo_light.xml20
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_list_selector_holo_light.xml28
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_progress_horizontal_holo_light.xml32
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_progress_indeterminate_horizontal_holo_light.xml30
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_searchview_holo_light.xml7
-rw-r--r--OpenKeychain/src/main/res/drawable/keychaintheme_spinner_background_holo_light.xml25
-rw-r--r--OpenKeychain/src/main/res/drawable/nfc.pngbin0 -> 14331 bytes
-rw-r--r--OpenKeychain/src/main/res/drawable/section_header.xml2
-rw-r--r--OpenKeychain/src/main/res/layout-large/api_apps_list_activity.xml18
-rw-r--r--OpenKeychain/src/main/res/layout-large/decrypt_activity.xml18
-rw-r--r--OpenKeychain/src/main/res/layout-large/encrypt_files_activity.xml17
-rw-r--r--OpenKeychain/src/main/res/layout-large/encrypt_text_activity.xml17
-rw-r--r--OpenKeychain/src/main/res/layout-large/key_list_activity.xml18
-rw-r--r--OpenKeychain/src/main/res/layout-v11/safe_slinger_activity.xml75
-rw-r--r--OpenKeychain/src/main/res/layout/actionbar_custom_view_done.xml26
-rw-r--r--OpenKeychain/src/main/res/layout/actionbar_custom_view_done_cancel.xml28
-rw-r--r--OpenKeychain/src/main/res/layout/actionbar_include_cancel_button.xml41
-rw-r--r--OpenKeychain/src/main/res/layout/actionbar_include_done_button.xml41
-rw-r--r--OpenKeychain/src/main/res/layout/api_account_settings_activity.xml39
-rw-r--r--OpenKeychain/src/main/res/layout/api_app_settings_activity.xml132
-rw-r--r--OpenKeychain/src/main/res/layout/api_app_settings_fragment.xml12
-rw-r--r--OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml20
-rw-r--r--OpenKeychain/src/main/res/layout/api_apps_list_activity.xml11
-rw-r--r--OpenKeychain/src/main/res/layout/api_apps_list_content.xml14
-rw-r--r--OpenKeychain/src/main/res/layout/api_remote_create_account.xml60
-rw-r--r--OpenKeychain/src/main/res/layout/api_remote_error_message.xml36
-rw-r--r--OpenKeychain/src/main/res/layout/api_remote_register_app.xml50
-rw-r--r--OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml44
-rw-r--r--OpenKeychain/src/main/res/layout/certify_fingerprint_activity.xml32
-rw-r--r--OpenKeychain/src/main/res/layout/certify_fingerprint_fragment.xml154
-rw-r--r--OpenKeychain/src/main/res/layout/certify_key_activity.xml36
-rw-r--r--OpenKeychain/src/main/res/layout/certify_key_fragment.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/create_key_activity.xml20
-rw-r--r--OpenKeychain/src/main/res/layout/create_key_final_fragment.xml8
-rw-r--r--OpenKeychain/src/main/res/layout/create_key_input_fragment.xml4
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_activity.xml11
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_content.xml109
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_files_activity.xml26
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_result_include.xml4
-rw-r--r--OpenKeychain/src/main/res/layout/decrypt_text_activity.xml26
-rw-r--r--OpenKeychain/src/main/res/layout/drawer_custom_header.xml16
-rw-r--r--OpenKeychain/src/main/res/layout/drawer_list.xml18
-rw-r--r--OpenKeychain/src/main/res/layout/drawer_list_item.xml31
-rw-r--r--OpenKeychain/src/main/res/layout/edit_key_activity.xml26
-rw-r--r--OpenKeychain/src/main/res/layout/encrypt_content_adv_settings.xml31
-rw-r--r--OpenKeychain/src/main/res/layout/encrypt_decrypt_overview_fragment.xml135
-rw-r--r--OpenKeychain/src/main/res/layout/encrypt_files_activity.xml34
-rw-r--r--OpenKeychain/src/main/res/layout/encrypt_files_content.xml23
-rw-r--r--OpenKeychain/src/main/res/layout/encrypt_text_activity.xml34
-rw-r--r--OpenKeychain/src/main/res/layout/encrypt_text_content.xml24
-rw-r--r--OpenKeychain/src/main/res/layout/first_time_activity.xml9
-rw-r--r--OpenKeychain/src/main/res/layout/foldable_linearlayout.xml52
-rw-r--r--OpenKeychain/src/main/res/layout/full_screen_dialog.xml10
-rw-r--r--OpenKeychain/src/main/res/layout/full_screen_dialog_2.xml12
-rw-r--r--OpenKeychain/src/main/res/layout/full_screen_dialog_2_cancel_button.xml27
-rw-r--r--OpenKeychain/src/main/res/layout/full_screen_dialog_2_done_button.xml27
-rw-r--r--OpenKeychain/src/main/res/layout/full_screen_dialog_done_button.xml25
-rw-r--r--OpenKeychain/src/main/res/layout/full_screen_dialog_old.xml10
-rw-r--r--OpenKeychain/src/main/res/layout/help_activity.xml38
-rw-r--r--OpenKeychain/src/main/res/layout/import_keys_activity.xml112
-rw-r--r--OpenKeychain/src/main/res/layout/import_keys_list_item.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml4
-rw-r--r--OpenKeychain/src/main/res/layout/key_list_activity.xml11
-rw-r--r--OpenKeychain/src/main/res/layout/key_list_content.xml68
-rw-r--r--OpenKeychain/src/main/res/layout/key_list_fragment.xml125
-rw-r--r--OpenKeychain/src/main/res/layout/key_list_item.xml4
-rw-r--r--OpenKeychain/src/main/res/layout/key_server_preference.xml142
-rw-r--r--OpenKeychain/src/main/res/layout/keyspinner_item.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/log_display_activity.xml32
-rw-r--r--OpenKeychain/src/main/res/layout/nfc_activity.xml49
-rw-r--r--OpenKeychain/src/main/res/layout/passphrase_wizard.xml11
-rw-r--r--OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_nfc.xml29
-rw-r--r--OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_passphrase.xml117
-rw-r--r--OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_select_methods.xml89
-rw-r--r--OpenKeychain/src/main/res/layout/preference_toolbar_activity.xml10
-rw-r--r--OpenKeychain/src/main/res/layout/qr_code_activity.xml39
-rw-r--r--OpenKeychain/src/main/res/layout/safe_slinger_activity.xml122
-rw-r--r--OpenKeychain/src/main/res/layout/select_key_item.xml2
-rw-r--r--OpenKeychain/src/main/res/layout/select_public_key_activity.xml20
-rw-r--r--OpenKeychain/src/main/res/layout/toolbar_standalone.xml31
-rw-r--r--OpenKeychain/src/main/res/layout/upload_key_activity.xml112
-rw-r--r--OpenKeychain/src/main/res/layout/view_cert_activity.xml423
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_activity.xml210
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_activity.xml41
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_certs_fragment.xml57
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_certs_header.xml (renamed from OpenKeychain/src/main/res/layout/view_key_certs_header.xml)0
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_certs_item.xml (renamed from OpenKeychain/src/main/res/layout/view_key_certs_item.xml)0
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml164
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_share_fragment.xml212
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_subkey_item.xml130
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml34
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_adv_user_id_item.xml (renamed from OpenKeychain/src/main/res/layout/view_key_user_id_item.xml)0
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_advanced_activity.xml22
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_advanced_fragment.xml87
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_fragment.xml47
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_main_fragment.xml164
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_share_fragment.xml212
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_subkey_item.xml130
-rw-r--r--OpenKeychain/src/main/res/menu/api_account_settings.xml4
-rw-r--r--OpenKeychain/src/main/res/menu/api_app_settings.xml10
-rw-r--r--OpenKeychain/src/main/res/menu/key_list.xml43
-rw-r--r--OpenKeychain/src/main/res/menu/key_list_multi.xml5
-rw-r--r--OpenKeychain/src/main/res/menu/key_view.xml20
-rw-r--r--OpenKeychain/src/main/res/menu/key_view2.xml11
-rw-r--r--OpenKeychain/src/main/res/raw-bg/help_about.html57
-rw-r--r--OpenKeychain/src/main/res/raw-bg/help_changelog.html232
-rw-r--r--OpenKeychain/src/main/res/raw-bg/help_nfc_beam.html12
-rw-r--r--OpenKeychain/src/main/res/raw-bg/help_start.html19
-rw-r--r--OpenKeychain/src/main/res/raw-bg/help_wot.html17
-rw-r--r--OpenKeychain/src/main/res/raw-bg/nfc_beam_share.html11
-rw-r--r--OpenKeychain/src/main/res/raw-cs/help_changelog.html8
-rw-r--r--OpenKeychain/src/main/res/raw-cs/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-cs/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-de/help_changelog.html6
-rw-r--r--OpenKeychain/src/main/res/raw-de/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-es/help_changelog.html4
-rw-r--r--OpenKeychain/src/main/res/raw-es/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-es/help_wot.html6
-rw-r--r--OpenKeychain/src/main/res/raw-et/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-et/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-et/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-fi/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-fi/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-fi/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-fr/help_changelog.html12
-rw-r--r--OpenKeychain/src/main/res/raw-fr/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-fr/help_wot.html8
-rw-r--r--OpenKeychain/src/main/res/raw-is/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-is/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-is/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-it/help_changelog.html24
-rw-r--r--OpenKeychain/src/main/res/raw-it/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-it/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-ja/help_changelog.html6
-rw-r--r--OpenKeychain/src/main/res/raw-ja/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-ja/help_wot.html4
-rw-r--r--OpenKeychain/src/main/res/raw-nl/help_about.html14
-rw-r--r--OpenKeychain/src/main/res/raw-nl/help_changelog.html270
-rw-r--r--OpenKeychain/src/main/res/raw-nl/help_nfc_beam.html8
-rw-r--r--OpenKeychain/src/main/res/raw-nl/help_start.html6
-rw-r--r--OpenKeychain/src/main/res/raw-nl/help_wot.html14
-rw-r--r--OpenKeychain/src/main/res/raw-pl/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-pl/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-pl/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-pt/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-pt/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-pt/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-ro/help_about.html57
-rw-r--r--OpenKeychain/src/main/res/raw-ro/help_changelog.html232
-rw-r--r--OpenKeychain/src/main/res/raw-ro/help_nfc_beam.html12
-rw-r--r--OpenKeychain/src/main/res/raw-ro/help_start.html19
-rw-r--r--OpenKeychain/src/main/res/raw-ro/help_wot.html17
-rw-r--r--OpenKeychain/src/main/res/raw-ro/nfc_beam_share.html11
-rw-r--r--OpenKeychain/src/main/res/raw-ru/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-ru/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-ru/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-sl/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-sl/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-sl/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-sr/help_changelog.html4
-rw-r--r--OpenKeychain/src/main/res/raw-sr/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-sr/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-sv/help_changelog.html58
-rw-r--r--OpenKeychain/src/main/res/raw-sv/help_nfc_beam.html8
-rw-r--r--OpenKeychain/src/main/res/raw-sv/help_start.html8
-rw-r--r--OpenKeychain/src/main/res/raw-sv/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-sv/nfc_beam_share.html8
-rw-r--r--OpenKeychain/src/main/res/raw-tr/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-tr/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-tr/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-uk/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-uk/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-uk/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-zh-rTW/help_about.html24
-rw-r--r--OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.html18
-rw-r--r--OpenKeychain/src/main/res/raw-zh-rTW/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-zh-rTW/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw-zh/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw-zh/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw-zh/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/raw/help_changelog.html2
-rw-r--r--OpenKeychain/src/main/res/raw/help_start.html2
-rw-r--r--OpenKeychain/src/main/res/raw/help_wot.html2
-rw-r--r--OpenKeychain/src/main/res/values-bg/strings.xml66
-rw-r--r--OpenKeychain/src/main/res/values-cs/strings.xml84
-rw-r--r--OpenKeychain/src/main/res/values-de/strings.xml328
-rw-r--r--OpenKeychain/src/main/res/values-es/strings.xml218
-rw-r--r--OpenKeychain/src/main/res/values-et/strings.xml12
-rw-r--r--OpenKeychain/src/main/res/values-fi/strings.xml187
-rw-r--r--OpenKeychain/src/main/res/values-fr/strings.xml281
-rw-r--r--OpenKeychain/src/main/res/values-is/strings.xml9
-rw-r--r--OpenKeychain/src/main/res/values-it/strings.xml59
-rw-r--r--OpenKeychain/src/main/res/values-ja/strings.xml310
-rw-r--r--OpenKeychain/src/main/res/values-large/dimens.xml1
-rw-r--r--OpenKeychain/src/main/res/values-nl/strings.xml834
-rw-r--r--OpenKeychain/src/main/res/values-pl/strings.xml57
-rw-r--r--OpenKeychain/src/main/res/values-pt/strings.xml9
-rw-r--r--OpenKeychain/src/main/res/values-ro/strings.xml66
-rw-r--r--OpenKeychain/src/main/res/values-ru/strings.xml297
-rw-r--r--OpenKeychain/src/main/res/values-sl/strings.xml32
-rw-r--r--OpenKeychain/src/main/res/values-sr/strings.xml217
-rw-r--r--OpenKeychain/src/main/res/values-sv/strings.xml263
-rw-r--r--OpenKeychain/src/main/res/values-tr/strings.xml253
-rw-r--r--OpenKeychain/src/main/res/values-uk/strings.xml129
-rw-r--r--OpenKeychain/src/main/res/values-v11/styles_keychaintheme.xml35
-rw-r--r--OpenKeychain/src/main/res/values-v11/themes_keychaintheme.xml32
-rw-r--r--OpenKeychain/src/main/res/values-v21/dimens.xml11
-rw-r--r--OpenKeychain/src/main/res/values-v21/themes.xml15
-rw-r--r--OpenKeychain/src/main/res/values-zh-rTW/strings.xml250
-rw-r--r--OpenKeychain/src/main/res/values-zh/strings.xml13
-rw-r--r--OpenKeychain/src/main/res/values/attr.xml9
-rw-r--r--OpenKeychain/src/main/res/values/colors.xml63
-rw-r--r--OpenKeychain/src/main/res/values/dimens.xml6
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml237
-rw-r--r--OpenKeychain/src/main/res/values/styles.xml32
-rw-r--r--OpenKeychain/src/main/res/values/themes.xml52
-rw-r--r--OpenKeychain/src/main/res/xml/preference_headers.xml4
-rw-r--r--OpenKeychain/src/main/res/xml/preference_headers_legacy.xml12
-rw-r--r--README.md11
-rw-r--r--Resources/graphics/create_key_robot.svg102
-rw-r--r--Resources/graphics/first_time_1.pngbin43898 -> 0 bytes
-rw-r--r--Resources/graphics/first_time_1.svg351
-rw-r--r--Resources/graphics/ic_action_nfc.svg61
-rw-r--r--Resources/graphics/ic_action_qr_code.svg826
-rw-r--r--Resources/graphics/ic_launcher.pngbin77995 -> 0 bytes
-rw-r--r--Resources/graphics/originals/ic_action_nfc/NFC.pngbin88038 -> 0 bytes
-rwxr-xr-xResources/graphics/update-drawables.sh74
-rw-r--r--build.gradle7
m---------extern/minidns0
m---------extern/openkeychain-api-lib0
m---------extern/openpgp-api-lib0
m---------extern/safeslinger-exchange0
m---------extern/spongycastle0
-rwxr-xr-xprepare-tests.sh30
-rw-r--r--settings.gradle4
1184 files changed, 30606 insertions, 12248 deletions
diff --git a/.travis.yml b/.travis.yml
index 81ef10638..af67b2333 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,8 +11,7 @@ before_install:
# Install required Android components.
#- echo "y" | android update sdk -a --filter build-tools-19.1.0,android-19,platform-tools,extra-android-support,extra-android-m2repository --no-ui --force
- - ( sleep 5 && while [ 1 ]; do sleep 1; echo y; done ) | android update sdk --no-ui --all --force --filter build-tools-21.1.1,build-tools-19.1.0,android-21,android-19,platform-tools,extra-android-support,extra-android-m2repository
- - ./prepare-tests.sh
+ - ( sleep 5 && while [ 1 ]; do sleep 1; echo y; done ) | android update sdk --no-ui --all --force --filter build-tools-21.1.2,build-tools-21.1.1,build-tools-19.1.0,android-21,android-19,platform-tools,extra-android-support,extra-android-m2repository
install: echo "Installation done"
script:
- ./gradlew assemble -S -q
diff --git a/Graphics/android-icon-copier/.gitignore b/Graphics/android-icon-copier/.gitignore
new file mode 100644
index 000000000..3336b9152
--- /dev/null
+++ b/Graphics/android-icon-copier/.gitignore
@@ -0,0 +1,81 @@
+# Python
+
+*.py[cod]
+
+# Options
+/options.json
+
+# Packages
+*.egg
+*.egg-info
+/dist
+/build
+/eggs
+/parts
+/bin
+/var
+/sdist
+/develop-eggs
+/lib
+/lib64
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+nosetests.xml
+
+# Translations
+*.mo
+
+# Mr Developer
+.mr.developer.cfg
+.project
+.pydevproject
+
+### Generic
+
+*.log
+*.sqlite?
+
+### Compiled binaries
+
+*.class
+*.jar
+
+*.o
+*.bin
+*.a
+*.lib
+*.so
+*.out
+
+*.obj
+*.exe
+*.dll
+*.com
+
+### *nix OS / apps
+
+*.swp
+*~
+
+### Mac OS generated
+
+__MACOSX
+Icon?
+*.DS_Store
+*.DS_Store?
+._*
+.Spotlight*
+.Trashes
+
+### Windows generated
+
+ehthumbs.db
+thumbs.db
+Thumbs.db
+
diff --git a/Graphics/android-icon-copier/LICENSE b/Graphics/android-icon-copier/LICENSE
new file mode 100644
index 000000000..4dc1175a5
--- /dev/null
+++ b/Graphics/android-icon-copier/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Lucas Tan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Graphics/android-icon-copier/README.md b/Graphics/android-icon-copier/README.md
new file mode 100644
index 000000000..3e12ae472
--- /dev/null
+++ b/Graphics/android-icon-copier/README.md
@@ -0,0 +1,109 @@
+[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-android--icon--copier-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/1325)
+
+What is this
+============
+A commandline tool to copy Android Material Design and FontAwesome icons to your
+ project folders: `drawable-ldpi`, `drawable-mdpi`, and etc.
+
+How it works
+============
+It downloads from these repos:
+- Material design: https://github.com/google/material-design-icons
+- FontAwesome and "Classic" Android: https://github.com/svenkapudija/Android-Action-Bar-Icons
+
+Resolution supported
+====================
+ | l | m | h | xh | xxh | xxxh |
+--------|---|---|---|----|-----|------|
+FA | Y | Y | Y | Y | Y | - |
+Classic | - | Y | Y | Y | Y | - |
+Material| - | Y | Y | Y | Y | Y |
+
+Sizes supported
+===============
+Material: 18, 24, 36, 48 dp.
+FA and Classic: 32 dp only.
+
+
+Usage
+=====
+<pre>
+Usage:
+Material : ./copy {proj path} {category} {color} {icon name} [size]
+Classic and FA: ./copy {proj path} {fa/classic} {color} {icon name}
+</pre>
+
+`[]` denotes optional args.
+**Args are case sensitive!**
+
+- `proj path`: Path to project folder relative to `base path`.
+ - `base path` can be defined in options file (see below).
+ - Auto-detects new or old project structure: `MyProject/src/main/res` or
+ `MyProject/res`.
+- `category`: Either "classic", "fa", or Material category.
+- `color`: Color of icon: Either "white", "grey" or "black".
+ - For Classic and FA, "white" refers to the Holo Dark theme (dark background).
+ "Grey" refers to the Holo Light theme.
+ - For Material, "grey" refers to grey600.
+- `icon name`: Name of icon (must replace spaces and dashes with underscores).
+ - Without any prefix. Examples: FontAwesome "thumbs_up", Classic "search".
+- `size` (integer): for Material only, Size in dp, defaults to 24 which is the
+ action bar icon size for material design.
+
+Examples
+--------
+- `./copy MyProject maps white place`
+ - Downloads to `BasePath/MyProject/{src/main}/res/drawable-{m,h,xh,xxh,xxh}dpi
+- `./copy MyProject maps white place 48`
+- `./copy Path/to/MyProject fa grey thumbs_up`
+
+Windows users need to use `python copy` instead (I think).
+
+Filename mapping
+================
+The tool also supports filename mapping of destination png files. (see options)
+Mapping vars:
+
+- `cat`: category
+- `name`: name as specified in commandline.
+- `color`: color as specified: white, black, grey.
+- `size`: integer only.
+- `bg`: derived from color. black => bright, white => dark, grey => light.
+- `bgSuffix`: "_dark" if bg is dark else empty string.
+
+Options file
+============
+Named `options.json` in same dir. Sample:
+```json
+{
+ "basePath": "~/Documents",
+ "filenameMap": {
+ "classic": "ic_action_{name}{bgSuffix}.png",
+ "fa": "ic_action_fa_{name}{bgSuffix}.png",
+ "material": "ic_{name}_{color}_{size}dp.png"
+ }
+}
+```
+
+~ is expanded to the user home dir.
+
+`./copy Path/to/MyProject fa white thumbs_up` results in the
+target filename of `ic_action_fa_thumbs_up_dark.png`.
+
+Installation
+============
+- Python >= 2.7 (older or newer ver might work, you may try.)
+- Python Requests package: `pip install requests`
+- Git clone this repo or download the script.
+
+Icon cheatsheet
+===============
+- Material: http://google.github.io/material-design-icons/
+- FA: http://fortawesome.github.io/Font-Awesome/icons/ (icons in 4.2 not supported)
+- Classic: coming soon.
+
+License
+=======
+This project is under the MIT License. (see LICENSE)
+
+Please refer to the respective icon library for its licensing info.
diff --git a/Graphics/android-icon-copier/classic.py b/Graphics/android-icon-copier/classic.py
new file mode 100644
index 000000000..17ae1aac4
--- /dev/null
+++ b/Graphics/android-icon-copier/classic.py
@@ -0,0 +1,146 @@
+# Maps icon name to the dir name.
+CLASSIC_MAP = {
+ 'about': '13_extra_actions_about',
+ 'accept': '01_core_accept',
+ 'accounts': '10_device_access_accounts',
+ 'add_alarm': '10_device_access_add_alarm',
+ 'add_group': '06_social_add_group',
+ 'add_person': '06_social_add_person',
+ 'add_to_queue': '09_media_add_to_queue',
+ 'airplane_mode_off': '10_device_access_airplane_mode_off',
+ 'airplane_mode_on': '10_device_access_airplane_mode_on',
+ 'alarms': '10_device_access_alarms',
+ 'attachment': '05_content_attachment',
+ 'back': '02_navigation_back',
+ 'backspace': '05_content_backspace',
+ 'bad': '03_rating_bad',
+ 'battery': '10_device_access_battery',
+ 'bightness_low': '10_device_access_bightness_low',
+ 'bluetooth': '10_device_access_bluetooth',
+ 'bluetooth_connected': '10_device_access_bluetooth_connected',
+ 'bluetooth_searching': '10_device_access_bluetooth_searching',
+ 'brightness_auto': '10_device_access_brightness_auto',
+ 'brightness_high': '10_device_access_brightness_high',
+ 'brightness_medium': '10_device_access_brightness_medium',
+ 'call': '01_core_call',
+ 'camera': '08_camera_camera',
+ 'cancel': '01_core_cancel',
+ 'cast': '09_media_cast',
+ 'cc_bcc': '06_social_cc_bcc',
+ 'chat': '06_social_chat',
+ 'cloud': '04_collections_cloud',
+ 'collapse': '02_navigation_collapse',
+ 'collection': '04_collections_collection',
+ 'computer': '11_hardware_computer',
+ 'copy': '01_core_copy',
+ 'crop': '08_camera_crop',
+ 'cut': '01_core_cut',
+ 'data_usage': '10_device_access_data_usage',
+ 'dial_pad': '10_device_access_dial_pad',
+ 'directions': '07_location_directions',
+ 'discard': '01_core_discard',
+ 'dock': '11_hardware_dock',
+ 'download': '09_media_download',
+ 'edit': '01_core_edit',
+ 'email': '05_content_email',
+ 'end_call': '10_device_access_end_call',
+ 'error': '12_alerts_and_states_error',
+ 'event': '05_content_event',
+ 'expand': '02_navigation_expand',
+ 'fast_forward': '09_media_fast_forward',
+ 'favorite': '03_rating_favorite',
+ 'flash_automatic': '08_camera_flash_automatic',
+ 'flash_off': '08_camera_flash_off',
+ 'flash_on': '08_camera_flash_on',
+ 'forward': '06_social_forward',
+ 'full_screen': '09_media_full_screen',
+ 'gamepad': '11_hardware_gamepad',
+ 'go_to_today': '04_collections_go_to_today',
+ 'good': '03_rating_good',
+ 'group': '06_social_group',
+ 'half_important': '03_rating_half_important',
+ 'headphones': '11_hardware_headphones',
+ 'headset': '11_hardware_headset',
+ 'help': '13_extra_actions_help',
+ 'import_export': '05_content_import_export',
+ 'important': '03_rating_important',
+ 'keyboard': '11_hardware_keyboard',
+ 'labels': '04_collections_labels',
+ 'location_found': '07_location_location_found',
+ 'location_off': '07_location_location_off',
+ 'location_searching': '07_location_location_searching',
+ 'make_available_offline': '09_media_make_available_offline',
+ 'map': '07_location_map',
+ 'merge': '05_content_merge',
+ 'mic': '08_camera_mic',
+ 'mic_muted': '08_camera_mic_muted',
+ 'mouse': '11_hardware_mouse',
+ 'network_cell': '10_device_access_network_cell',
+ 'network_wifi': '10_device_access_network_wifi',
+ 'new': '01_core_new',
+ 'new_account': '10_device_access_new_account',
+ 'new_attachment': '05_content_new_attachment',
+ 'new_email': '05_content_new_email',
+ 'new_event': '05_content_new_event',
+ 'new_label': '04_collections_new_label',
+ 'new_picture': '05_content_new_picture',
+ 'next': '09_media_next',
+ 'next_item': '02_navigation_next_item',
+ 'not_important': '03_rating_not_important',
+ 'not_secure': '10_device_access_not_secure',
+ 'overflow': '01_core_overflow',
+ 'paste': '01_core_paste',
+ 'pause': '09_media_pause',
+ 'pause_over_video': '09_media_pause_over_video',
+ 'person': '06_social_person',
+ 'phone': '11_hardware_phone',
+ 'picture': '05_content_picture',
+ 'place': '07_location_place',
+ 'play': '09_media_play',
+ 'play_over_video': '09_media_play_over_video',
+ 'previous': '09_media_previous',
+ 'previous_item': '02_navigation_previous_item',
+ 'read': '05_content_read',
+ 'refresh': '01_core_refresh',
+ 'remove': '01_core_remove',
+ 'repeat': '09_media_repeat',
+ 'replay': '09_media_replay',
+ 'reply': '06_social_reply',
+ 'reply_all': '06_social_reply_all',
+ 'return_from_full_screen': '09_media_return_from_full_screen',
+ 'rewind': '09_media_rewind',
+ 'ring_volume': '10_device_access_ring_volume',
+ 'rotate_left': '08_camera_rotate_left',
+ 'rotate_right': '08_camera_rotate_right',
+ 'save': '05_content_save',
+ 'screen_locked_to_landscape': '10_device_access_screen_locked_to_landscape',
+ 'screen_locked_to_portrait': '10_device_access_screen_locked_to_portrait',
+ 'screen_rotation': '10_device_access_screen_rotation',
+ 'sd_storage': '10_device_access_sd_storage',
+ 'search': '01_core_search',
+ 'secure': '10_device_access_secure',
+ 'select_all': '01_core_select_all',
+ 'send_now': '06_social_send_now',
+ 'settings': '13_extra_actions_settings',
+ 'share': '01_core_share',
+ 'shuffle': '09_media_shuffle',
+ 'slideshow': '09_media_slideshow',
+ 'sort_by_size': '04_collections_sort_by_size',
+ 'split': '05_content_split',
+ 'stop': '09_media_stop',
+ 'storage': '10_device_access_storage',
+ 'switch_camera': '08_camera_switch_camera',
+ 'switch_video': '08_camera_switch_video',
+ 'time': '10_device_access_time',
+ 'undo': '01_core_undo',
+ 'unread': '05_content_unread',
+ 'upload': '09_media_upload',
+ 'usb': '10_device_access_usb',
+ 'video': '08_camera_video',
+ 'view_as_grid': '04_collections_view_as_grid',
+ 'view_as_list': '04_collections_view_as_list',
+ 'volume_muted': '09_media_volume_muted',
+ 'volume_on': '09_media_volume_on',
+ 'warning': '12_alerts_and_states_warning',
+ 'web_site': '07_location_web_site',
+}
diff --git a/Graphics/android-icon-copier/copy b/Graphics/android-icon-copier/copy
new file mode 100755
index 000000000..995a8789e
--- /dev/null
+++ b/Graphics/android-icon-copier/copy
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import shutil
+import requests
+from os.path import expanduser
+import classic
+
+resolutions = {
+ 'material': ("m", "h", "xh", "xxh", "xxxh"),
+ 'fa': ("l", "m", "h", "xh", "xxh"),
+ 'classic': ("m", "h", "xh", "xxh"),
+}
+
+
+class AppError(Exception):
+ pass
+
+
+def make_filename(filename_format, cat, name, color, size):
+ args = {
+ 'cat': cat or '',
+ 'name': name,
+ 'color': color,
+ 'size': size,
+ }
+ bg = {'white': 'dark', 'grey': 'light', 'black': 'bright'}.get(color) or ''
+ bg_suffix = '_dark' if bg == 'dark' else ''
+ args['bgSuffix'] = bg_suffix
+ args['bg'] = bg
+ return filename_format.format(**args)
+
+
+def download_url(url, target_path):
+ print("Downloading {} to {} ...".format(url, target_path))
+ print("")
+ #r = requests.get(url, stream=True)
+ r = requests.get(url)
+ if r.status_code != 200:
+ raise AppError("url not found, perhaps invalid name, size or color")
+ with open(target_path, 'wb') as fd:
+ for chunk in r.iter_content(4096):
+ fd.write(chunk)
+
+
+def make_material_icon_url(cat, res, name, color, size):
+ if color == 'grey':
+ color = 'grey600'
+ elif color not in ('white', 'black'):
+ raise AppError('invalid color')
+ return ('https://raw.githubusercontent.com/google/material-design-icons/master/' +
+ '{}/drawable-{}dpi/ic_{}_{}_{}dp.png').format(cat, res, name, color, size)
+
+
+def make_fa_icon_url(res, name, color):
+ if color == 'white':
+ holo = 'dark'
+ elif color == 'grey':
+ holo = 'light'
+ else:
+ raise AppError('invalid color')
+ return ('https://raw.githubusercontent.com/svenkapudija/Android-Action-Bar-Icons/' +
+ 'master/Font Awesome/holo_{2}/ic_fa_{1}/drawable-{0}dpi/ic_fa_{1}.png').format(res, name, holo)
+
+
+def make_classic_icon_url(res, name, color):
+ dirname = classic.CLASSIC_MAP.get(name)
+ if not dirname:
+ raise AppError('invalid name')
+ if color == 'white':
+ holo = 'dark'
+ elif color == 'grey':
+ holo = 'light'
+ else:
+ raise AppError('invalid color')
+ return ('https://raw.githubusercontent.com/svenkapudija/Android-Action-Bar-Icons/' +
+ 'master/Android Stock/holo_{2}/{3}/drawable-{0}dpi/ic_action_{1}.png').format(res, name, holo, dirname)
+
+
+def make_target_path(base_path, proj, res, filename):
+ res_path1 = os.path.join(base_path, proj, 'src', 'main', 'res')
+ res_path2 = os.path.join(base_path, proj, 'res')
+ if os.path.isdir(res_path1):
+ res_path = res_path1
+ elif os.path.isdir(res_path2):
+ res_path = res_path2
+ else:
+ raise AppError('missing res dir')
+ res_specific_path = os.path.join(res_path, 'drawable-' + res + 'dpi')
+ try:
+ os.mkdir(res_specific_path)
+ except OSError:
+ pass
+ return os.path.join(res_specific_path, filename)
+
+
+def do_material(options, proj_path, cat, name, color, size):
+ base_path = expanduser(options['basePath'])
+ filename_map = options['filenameMap']
+
+ for res in resolutions['material']:
+ filename = make_filename(filename_map['material'], cat, name, color, size)
+ target_path = make_target_path(base_path, proj_path, res, filename)
+ url = make_material_icon_url(cat, res, name, color, size)
+ download_url(url, target_path)
+
+
+def do_classic_or_fa(options, proj_path, cat, name, color):
+ base_path = expanduser(options['basePath'])
+ filename_map = options['filenameMap']
+
+ for res in resolutions[cat]:
+ filename = make_filename(filename_map[cat], cat, name, color, size=32)
+ target_path = make_target_path(base_path, proj_path, res, filename)
+ url = globals()['make_' + cat + '_icon_url'](res, name, color)
+ download_url(url, target_path)
+
+
+def print_usage():
+ print("Usage:")
+ print("Material : ./copy <proj path> <category> <color> <icon name> [size]")
+ print("Classic & FA: ./copy <proj path> <fa/classic> <color> <icon name>")
+ print("")
+
+
+def main():
+ import json
+
+ if len(sys.argv) < 5:
+ print_usage()
+ return
+
+ option_filename = 'options.json'
+ if not os.path.exists(option_filename):
+ option_filename = 'options.templ.json'
+ print("WARNING: using the template options file")
+ print("You should create your own options.json")
+
+ with open(option_filename, 'r') as fd:
+ options = json.load(fd)
+
+ proj_path = sys.argv[1]
+ cat = sys.argv[2]
+ color = sys.argv[3]
+ name = sys.argv[4]
+
+ if cat == 'classic' or cat == 'fa':
+ do_classic_or_fa(options, proj_path, cat, name, color)
+ else:
+ size = sys.argv[5] if len(sys.argv) >= 6 else 0
+ size = int(size) or 24
+ do_material(options, proj_path, cat, name, color, size)
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except AppError as e:
+ print(e.message)
+
+
diff --git a/Graphics/android-icon-copier/options.templ.json b/Graphics/android-icon-copier/options.templ.json
new file mode 100644
index 000000000..319d90f42
--- /dev/null
+++ b/Graphics/android-icon-copier/options.templ.json
@@ -0,0 +1,8 @@
+{
+ "basePath": "~/Documents",
+ "filenameMap": {
+ "classic": "ic_action_{name}{bgSuffix}.png",
+ "fa": "ic_action_fa_{name}{bgSuffix}.png",
+ "material": "ic_{name}_{color}_{size}dp.png"
+ }
+}
diff --git a/Resources/graphics/All_Icons.svg b/Graphics/drawables/All_Icons.svg
index e88ead4ef..e88ead4ef 100644
--- a/Resources/graphics/All_Icons.svg
+++ b/Graphics/drawables/All_Icons.svg
diff --git a/Graphics/drawables/comment-text.svg b/Graphics/drawables/comment-text.svg
new file mode 100644
index 000000000..b881741b1
--- /dev/null
+++ b/Graphics/drawables/comment-text.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22V22H9M5,5V7H19V5H5M5,9V11H13V9H5M5,13V15H15V13H5Z" /></svg> \ No newline at end of file
diff --git a/Graphics/drawables/create_key_robot.svg b/Graphics/drawables/create_key_robot.svg
new file mode 100644
index 000000000..ac951c8e5
--- /dev/null
+++ b/Graphics/drawables/create_key_robot.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="45"
+ height="45"
+ id="svg4316"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="create_key_robot.svg">
+ <defs
+ id="defs4318" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="15.839192"
+ inkscape:cx="16.585032"
+ inkscape:cy="15.200896"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="2558"
+ inkscape:window-height="1419"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata4321">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1007.3622)">
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#8bc34a;stroke-width:1.74663651;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 22.166071,1009.3123 c -5.613738,0 -10.131173,4.5175 -10.131173,10.1312 l 0,18.6956 c 0,5.6138 4.517435,10.1365 10.131173,10.1365 l 0.6677,0 c 5.613732,0 10.131173,-4.5227 10.131173,-10.1365 l 0,-18.6956 c 0,-5.6137 -4.517441,-10.1312 -10.131173,-10.1312 l -0.6677,0 z m 0.336476,3.3649 c 4.044517,0 7.223786,3.1791 7.223786,7.1291 l 0,14.9628 c 0,3.95 -3.179269,7.1292 -7.223786,7.1292 -4.044516,0 -7.229038,-3.1792 -7.229038,-7.1292 l 0,-14.9628 c 0,-3.95 3.184522,-7.1291 7.229038,-7.1291 z"
+ id="path5399" />
+ <rect
+ ry="0.79848224"
+ rx="0.79848224"
+ y="1025.4666"
+ x="5.5190063"
+ height="24.945528"
+ width="33.961983"
+ id="rect5401"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#8bc34a;stroke-width:1.74663651;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0"
+ id="path5403"
+ d="m 11.109664,1043.5389 c 2.495006,2.065 6.666898,3.4226 11.392966,3.4226 4.725665,0 8.89263,-1.3579 11.387713,-3.4226 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#8bc34a;stroke-width:1.74663651;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="3.1415927"
+ sodipodi:start="0"
+ transform="matrix(0.1819265,0,0,0.1819265,-43.957774,964.33702)"
+ d="m 316.87315,407.66223 a 9.388834,9.388834 0 1 1 -18.77767,0"
+ sodipodi:ry="9.388834"
+ sodipodi:rx="9.388834"
+ sodipodi:cy="407.66223"
+ sodipodi:cx="307.48431"
+ id="path5405"
+ style="color:#000000;fill:none;stroke:#8bc34a;stroke-width:9.60078144;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.1819265,0,0,0.1819265,-21.704758,965.01923)"
+ sodipodi:type="arc"
+ style="color:#000000;fill:#8bc34a;fill-opacity:1;fill-rule:nonzero;stroke:#8bc34a;stroke-width:9.60078144000000044;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path5407"
+ sodipodi:cx="307.48431"
+ sodipodi:cy="407.66223"
+ sodipodi:rx="9.388834"
+ sodipodi:ry="9.388834"
+ d="m 316.87315,407.66223 a 9.388834,9.388834 0 1 1 -18.77767,0 9.388834,9.388834 0 1 1 18.77767,0 z" />
+ </g>
+</svg>
diff --git a/Graphics/drawables/drawer_header.svg b/Graphics/drawables/drawer_header.svg
new file mode 100644
index 000000000..b8896d6ad
--- /dev/null
+++ b/Graphics/drawables/drawer_header.svg
@@ -0,0 +1,5885 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="512"
+ height="288"
+ id="svg4270"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="drawer_header.svg"
+ inkscape:export-filename="/home/schuerm/Projekte/OpenKeychain/Graphics/drawables/drawer_header.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4272">
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6747-5"
+ is_visible="true" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6749-3"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4566-7-3"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6679-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4678-8"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4668-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4452-8"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4450-4"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4448-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4446-9"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4436-5"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4434-1"
+ is_visible="true" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4428-2"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4416-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4294-5"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4304-7"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4308-0"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4312-7"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4316-5"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4320-7"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4324-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4328-6"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4332-4"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4342-4"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4349"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4351"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4353"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4355"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4357"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4359"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4361"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4380-4"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6355-7"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4658-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4566-97"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4543-2"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6052"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6050"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6048"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6040"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6038"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6036"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6028"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6024"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6020"
+ is_visible="true" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6204">
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:0.28078841;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect6206"
+ width="74.565163"
+ height="170.26346"
+ x="425.43484"
+ y="1201.8348" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6278">
+ <rect
+ style="color:#000000;fill:#b22222;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect6280"
+ width="57.606529"
+ height="95.568382"
+ x="0.98397124"
+ y="1276.5299" />
+ </clipPath>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.9899495"
+ inkscape:cx="554.63796"
+ inkscape:cy="-13.509829"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1918"
+ inkscape:window-height="1179"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata4275">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-764.36218)">
+ <use
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ x="0"
+ y="0"
+ xlink:href="#path3638"
+ id="use15188"
+ transform="translate(27.508011,546.95333)"
+ width="500"
+ height="2100"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <use
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ x="0"
+ y="0"
+ xlink:href="#path3640"
+ id="use15190"
+ transform="translate(27.508011,546.95333)"
+ width="500"
+ height="2100"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <image
+ y="350.52448"
+ x="-81.698944"
+ id="image3307"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDgAAAeACAYAAAArYecKAAAABHNCSVQICAgIfAhkiAAAIABJREFU
+eJzsvWt7FEeW7xux4paZVUjqwjPu4WLPtAdE90B7b2OMwPs5r87+AOe8PefD7A93AAE2+2k3HluW
++3naGGNPYyQEqqyMy1pxXpQEQta1bplVFb+XICpDVGZkxD/W+v/51f/rf9xjIJgQ/IKQ4jwH4GwE
+VK979007u7n3z2y3+sIU5joHfuQ1vHMbAoQQSi6OYiyRKEaKLPjwJSEFAH4BlDonlYBRfP4845zb
+AAa/Si0v1z2Wg3Bl9VQafR7EaO7rxOEQRgrBbpGPa0KKllDy6kn+311ZPZV6sO+IiCKjyALiYwrh
+FQd4DyRcAhAMRHq+68BV9lsJ8l+EhJHM35MieCRN7JnU6kLdY5l3AiJF77cwsDVQIIWEfweAxVGt
+T06L7VVftbLsGpzi+q60q0Wu/yikGPg5iDHGSMTQ4+OA4RVw8aHU8pxIc1utOGc3pBSllNMzV1Td
+6iudm1Pdw4OCiGQ9fq0zc23c15p10CNhcOsQ+Utl1LIQsHjcHmoUxBjJVv6xyeRZqfX5cV/vJESM
+VFF8aM60bh7/06O8LtLGa/tQFcXQ1yXEaLu9uwD8lqxhHq96vTWR5ZeHnQcCIlXIvpZZ3thnXOo8
+uznKh4ViJLddPdwvbhAiCQnsJNdSWndc164xztkwi4NdOADnwJiW4tP+giEyQlqvur1fgfM2KLgK
+oBgInhYNp0Rr3XHOsVD5dZmpS3WP5wA2GGeNmJxnleCR0PvHDKCUUl5RSpxqTuGMvWBssO8IADjr
+P9vXmNGMiGJE2kIfvnc950DwsyDVJQBIz/eE0Jm54ir7LQuSTZPIEX1YB2MaKdTOA8Ej+RCeMcIn
+QskzUqur0sBI1yeTRBdmpezatTxXTA54WMM551wIBkJck1H1xQ6kdVtVvwqQHySxox60Np2qZ59z
+BlujWKNOAiIq+YQepap0982Z4tZELjaDICIF658xwic6Mx/q3Ay9IT0NrnKbjLHv8nb22SSvexyB
+AhMmm/h6ngsBC7m69MradWXMUPscEILnC+3PXWW/cz0bdaaXRzXOk5Dl+XK53btjzrQ+H+ZzAIBR
+5V+zbFQjGz1yEuIGY4wF558po6+f9LN0yyzbbrUKxWgFmP6CgTMQcFlqeZmIYiTa8t5/G3vIQPJl
+odRiWjScnCaLHJEx1pjZeYZARELrn1GMT6SWH+hMXxv0dDWO8CvqCx6wJJT8lDHGCPvPd/Due7LR
+AmMfglLnkuAxXqZR5ODINpq0mJt1KEaiQAx9WI+RXggj3zNGXeKgz/NJ7cTGjG6ZZevcRqS4rsxw
+78Y9YsdlpdVlQozviB1SnhOpKnViZLlZrsrqYVaYT5s+b8QYiTOIk3iuyu3eqm7lK+O+zqwRYyQf
+AmPePwABMs/VdSGyiVYIISJZ6x8URXZFKDnRKomTEJDWlRC1HEIoozptsqz0YWsU3QU6M5dJyWi7
+vTvA+K1JdhRoo295Z9eVHlysAc6BM4IY40TmlUGQo/qgo8QNxhiLGH8AAad6WE0rW7Gvy7vZQuv2
+aEb5W95siCRbiRRjjJEh0jr2yucM4D1Q6hJIYP0akMRhaK07zjdP5IgxlkniGA3vtKBo1ZFGXzrt
+M30oY/qKQABnoi94vK3ewp+Cw6eRkHHeb1dLz/jo6Ysc/lsWWONFjuCRlJYf1D2OWYcwElFgwftH
+nHMUUp1XuZro6eSkkVp3nMelUPbu50U+sk0DCMHfih0UEXHddqtfgcuzSslLSewYP1mR3ei97t1t
+LRZjW6OOAiJiUkF73NepetWayLMr01p1VQd7W1CMUcuiyGupWrOVfQpCbLbPtBpbNUeRvwAhahub
+yU0nvCrXPMDCKNre66rmkEoA9jyRoDjM7yEZK1iMjDXzdmH8+v/7P+OwH0IxkuvZhyY3B768g0fi
+jH6WWp26tIgwUnDuoSkOFk7GCRFFQvwJPf4UWRQg+EdSqsXU2384zrsNjvyFaojIUW2Xd7J2MVQp
+1rzTb0FxjxiI0G8/ATZKxdaV1VfS6In0Bu9lj+DxDAM+jTFGEHyZC7WYBI/R4Sr/rQRotCeHL+1a
+rs3l5NUzegiRsEF+GoNge9VX7SwbuEqNsZ21TNVbbbWLW+Oc6wgpEuIz58IPwCGJHWMmYiTn7cNR
+ilejBn2gyOGVlGJpXNfwLmwi512p5NT4ktTF/hYUKeFcXSJv8J5CwNWsld8SNYoHx4GI5Lj42hT1
+ez68fNld5Xlxc5Tr4DfeHBOs5hi2VSVYT05lHGQz75uhBY7jxA3G+hsYnQ9ewu692wCCF3VWBvSr
+O/pmX+jxNQj+QTr5PZgQ3AYh+0kbXftElASOwQgeibxfpxhfKKP+NM4NiS2rr7QZfH4YFbsVXIS0
+HkL4lVHUoPhHIomaQ9MXOfi/NLVfPby294p2nnrGR8Rv/DSkuMr5yTy4msgoBI5dfFk9zHNzeRLP
+wm/FDnEJpGA8rVlGCiISo/i3YduQxkVVuU2t5NK4Tr/7pqLhkc6yT8fx+bPA/hYUrdX1OgWFiJGs
+c49NphpjInoU3npirRYXDdhMxxhpY6s3EtPR/Thnv8PuZKo5gkcKjP42aKtK8EgW5M9Cnb54YRIM
+1aJyEnGDMBLnrDfMwkAp3fHWMgz1GTpx4JyzvtmXyvYsHHr+B86iFkp8kpIb+kipO8hxyVV2VWem
+tl5MipEY1D8ZTguESMH7LfLxG2nUe9LouTrR7j/jb/15ItFOy1pc973er5wxDUp8AjI956dFZ+qK
+s9WP0dN/SaUaZeS5055ytu5xTDPz4KcxKlSR3Sgr+21GclsNUNV6GkAABwHnpVbn+xWp9FOvrJ4k
+sWO0CCHAoT3LA3vayGQVpB+Z5mOr3ihLey8f0rRwVkGPFFx4LHjs1dmCshdXuU3G+Vrezm9OS3tg
+oPhIAT+xj+M44ZzDUsvceFn1/qrMaCtKtDaXSchoX3fvAoiVcVZzDNuqAgAs+vALmzWB4yTiBmOM
+EbotadRng15nF2VMx3XtGi/4QhMeyL0LhzcxtC58SehSDC3rv/A5Y5/ZXnXf5JNvL2KMMUbEANiZ
+Wq49JfQ3Jp4Fiw9AgJRaX4cMJtpP3C8hq/2R/g0c+qsQEOyy2it4BHzsK/uKczjTT2BKgsdJ0Ca7
+6K3bCN5/1ySRI4bwTKjhnNHnkb1+GoyBk0p+MNt+GqP7tXRmrjjnNphlQ5uPnhQA4ABwQSp5YVfs
+qHrVT5yBEAo+kVImsWMImpysQkTb49IZy271hWnljfYgmTRvWlAY/qC1+deipSbegnvYuKz1D4pW
+dkVIOTVGsDFGIsldE/4PdxFKQDvA+a4PT0fdlgVC8Hxp4bZz9js35moOk2cDp6qA4EA9bxnLxzG0
+oRlI4DipuMEYY+jwG6n1SEp/d5NVzIiTVYYlxdAeDAgBSsONukSOyBhLh4cHs9uCEhl7KbVcNoVq
+1DPVRN4KHuKa2omkZRRZ2BU8AN4DCZeS4HE4yuiOt441SeTgiE8gG5FZ7oyz10+DS86kEldMnl2v
+u71sGpFadxziku/27udF9tkkK11+I3YQbVW9au2N2AGS8Tlbr4yCfrJK+UVW5NebshmLMRLnXIzj
+/qp61ZrIzL835Xetk4iRbPBb3Ic1raGV5+rqpFNQjsJW9qlQcrO90Bqpd8QkoEBM6uzDusexH5Ob
+Ttgun7vAxyJqvqnmGHPSyjCpKiCijkSxiWuAUwscpxE3gkeSRr03yofJtLIV27X3snbWyH7pFEP7
+LiA4KG1u2G5137QmK3JEYoxzMJO8ZpOhnVMFwvhEGvmhzHQjTlsjRV/3GAahn8DEmJbiGtsRPCLS
+Fvrwves5B4KfBakupUjad3kjcji/LnW9PeuISEqZ9+ocQ9MJHokwPEOiH4QQRmp1XRpIgugIkEIA
+AdzY3u7db7WyWsrFd8SOJSnlzV2xw/nq22hBJrHj9GRF8WnZLe+0G9KyQURMSlmM+nO9C5tMSC4E
+jK31ZRpA73daUHgvN2pZmGYdFu2YiN7LW8XtkaXeTRiP4ZmUeSPbIFrtYtm/7K5GyG+OY5P/Jmll
+jNUcw7SqaMbfDzE2sAb7lCajpxE3GGPMlXZN5+ryqL90QiQM+EhnZqoMjfbG0Ebn3sbQzsEGiGIk
+X1YPTWtyTuPBI3HOGmFKVBfvRLtK0RJKXm2ar0bV7d0xeXZ72k4VjmK3kisSbQXE7yNSeBNJOwfP
++0nw1m1AZC/qFDl8ZZ/m0pxv2jNRJwf5aQgQlzjwkaYnTRO2W37VLlrXxrlx8aX9S57rf21Ke8Ou
+2IHefxuJSSb4R0aaxSR2HE+TklW89wRcjHQdFDFSz9tHOsunag0+Kva2oBhtPhQSzjfhsGgvb0xE
+c92RqoG+MKdgu/Kr+eKZRleevHi5fUcV7bGKmuNOWhmkVSV4T04YDlI27rs5scBxWnGDYiRf2YfZ
+mOJdvXMbEOtNVhmW3eqO4MLabgytkLNd3VF1q7tZK5tIv2awjkAKXmdudl30o139YwZQSglXAMRi
+k04V9jKLAsd+9kTS/oQYn0ZC9kbwmOMkprpFjrBd3i1a7bnvHz/ITwMauGivC+xWd7JWPvY5ylX2
+20xK0bQ0jkgxUiQWnPuSMAYuYVnN+FplWLz3G8D4i7q/S1tWT5UZrYi7/bq8m51pzdW8+W4LimhJ
+pRp3WLTLromoKczUmIgeBiJSxcX/zou8EQajh4GItPU6PJLF+A/enbPfhW4vmiwbaTVHQCRP9Dd9
+ilaVgEgVsq9lVn98735O1KJyWnGDMcbIhy2l5NiMUZTWHVdWXV5jssqw9EvcYUlIeXNvDK0v3WsQ
+/CwodWnWNj9ZK7tdbZerppWPXY2lSFvA5NyUTyIiofXPKMYnUssPdFZ/9OqJiHHmT4b3tK5dkIxd
+eBtJi89Czz+NFAVI/hEXanHWnvmjqLNdZd7bU5KfRvPom4/6DarcX01Wf8z6Lhw4F0wwkeefvhU7
+wpeuqgKXIokdB6CU6jhnGfd8SypZ2xqVIv3COBtZeX/Zrb7SrfmJ1EbvCR0+AsFCodVNyFRjKwmm
+1UT0KCgQU63so7rHcRxCCDiThz+8tm5dGj3WtYzW5rIUKtpuOVJvDikEoDtdqwoAMKr8a5aNYgSj
+5ViBYxBxgzHGyIU12R6v54IusouurP7Cwfx52lXKY2NoxezEU2btYmUSIgcn9oQxNtMCxzstKFp1
+pNGXprXPcp7YE0m7k8S0K3jQuu9Wv3LGNFf9iq5ZeOaP4o3IYf26nOBpJ9qwZQbMf59WAiKRT34a
+TUZq1SHEpXK7ezcviltN+27eih3i00j6XbFDiGU1Rx5jx7GTrLLGOWd1HcQRMTuq9XFV9p6KzHww
+7evt49htQeGRnmijP9At3RjT2MOYZhPRoyCix4JDY8Teo1DGdIy3/3AhbAk5XlETBLzx5qi6vSrL
+sj+P4nNPm6oCnANEYjHG2LT77kiBY2BxA5GEkZ1J/LK6yD623WrVtLKZeqgPjaElb4GzD6c9hjZr
+FytVt7dq8vEl4hBjvHldYaOh34LiHjEQQSl1k2uYqft/3tgjeFyWeyNpMa77Xu9XDrwNAq7Oisi5
+H2V0x7sJixwU1zjw2nvkx8lBfhpSq0sK+Pk0X5yCCVeZgRDA8vz2dre3Wpf56El4R+yIOkYihgHX
+nbXPgYsPpZbn5l3syHKzXHV7q3krn7iQGDGSkGIkZ6vehU0mVSmEmMkDlL0tKMaojs6n47AouLAZ
+MPznNJuIHoUH8Vo1tBXoIFptcyW+Kv+CAH+eRDXkbjWH2y7vckZ/lFr/bujPzPUtb+1flTEnEpYE
+Z20WI2MNW1KIc3/+6H8d9BeEkVx1enGDMcZ85X6SWv3rpCZzUOKc77mHUo82i7gpcM45B+BCyXNC
+iYsgxEKk+L2r7BoG3GSM/okxiE076TkOqdUFW1b3hRRjWWwHH/5LSvn+rCzkg0cK1n3nnf9OSFiQ
+Sv2bVPIiB+DT/DsG53+UWn1Q9ziaxJtnXsBZqdVFIeCfOXBOAb/2VfW3GGgzMvonxlgj47kGQQiR
+Y0QePT0FKc6O81qESJLx/5JSNtKZfRgIIyGG6Kz9EgP9AAJAavlvKtMfCCHO8v50MRP3zKSILvyo
+jJ74HCWUvFB17XdCcAUADSwCfsubOUuKs1LJiyD4AhF9b6tqjTByDrzdVKFm3EitLpSvu/d0pi9O
+8rqEFDnnXSGGm093Nv9fqcx8PKqxNQX0nkLlv2QRf8y0/HeT6QtCiveavp6OGMla91eVKZkV+dWm
+j3cQEJGY0lZIOdb1wKjRRv2+fN29B3oyzzsHzmWmL0bgG7bX+7uU8v1hPg8AODnvIgd2kvcOj/Gf
+ECRv2lr0QJNRwkjODiZuMMaYLXv3sgn36BEiEdLXyjSnb3USvDEq9f2khmmMoe1XcpiRRyxV3d4d
+U0y3eSUhUvB+i3z8Rhj1nhBwqanGVoNAMZIrq3tZkTciUm9aIKLIKLKA+Bg99j17JFwCmP4KD+/c
+Bkc2VnM+Z+1mIfTSrBgQH+SnAQCLTVtwTCu43buT1xj7ic7+qEBWdRtWDgohRkRa9879KkB+IKU8
+J6a4AnUQ6khW8dYTSMHFkPPc9uvyrmkXt6Z5LbWX/S0oTUxBOQpXuU0m+N9MZhrfOjMMtnKb0G4v
+TWMSYkSkjdf2oSqKiVaJElJ02+W9UVRzlNvVXXOmONZMOHhPFvTPQqlGHRj9poJjWHEjeEdSygUQ
+kz1t4AAcEVUMceynf02if2gCmVTynJDyPIDICOP3oeytEVIZGe8wxhtd3SG1uuAquwoCLozyBRoq
+91Rlkz91GxaKkTD46Hrufozxv6TWf+ifvsLZJn+PgxAZi+jDU6lSBcdp2HNa+r7S6iIIOMsje4UB
+v/aV/zshTsWzfxC7lRzk6akY01yOVfiLVnqk882kCYgUnP/JOf9XxthzqeUfpFYXpJYXASCb5t+t
+aZALT5WZ7On7XkDIRU/Iow//KZU8V9c4BqVfjSbOKq0vAsAZivS9rdwaBio5451ZEu0PgwPnMcYi
+4vjmtf1477+TQg61bqh61ZrMs/827RvpiJGs9y+xsn9RAnrGqH81/XXVwrTMlYhItnJ3s8L8szbm
+D9My7kGpAv1FZ2Yq39McgCvOip4LTydZgfKmmkPwF7bs/R2E+KdB//+44OeDD4/F8RUh0SM9AamG
+qhwZNe94cBBG8tY9MLkZ2H2XLD6QLVVLX7PSuuMq9w8ecGqTVYZhbx8/0/LybnWHt7bxMbQmz265
+slqTRv0exPDfHcVITMCJIpCbQvBI5P16ZOyl1HLZFGr2zf+o7gHMBm8SmZT8dDeStl/Z5b6PFYU3
+kbQADETzE1qU1p3gHfPWr4/61JoQSUshp+3Z2vXTIB/WMeILaVTy05gQnLHa3yVS9s1Ht1+Xd1qt
+/Pa03b+77PiLXVZaXd41Uy+77gfgcFYpeWmWKzuUUp3KWsYD35JjNiFkjLGItDnM1FBZt8m1fn+a
+xY3dFBQuIiu0vt7kFJSjsJVdE0q61kJrqquST0rESEKIxrU9nAZlVKdNlpU+bIkJJykppS+IBXne
+bZf3aMBqDikEkPNLeMyeGoSAaN2r4UY8et4IHLvihs714OIGIoGqd+GoM33Flb2HANmn0/xgjIKD
+Ymijx8dVQ2NodZEtu7JaE5oN7zhOjIGAhRENbWzQTqkkYXwijfxQZvryNC8mBgGg+d/TNLEbScvE
+u4IHIf4UrP9px+26L3g06Pnfj1S6E9joRY4QwlYh9fVRfd44IYxEFFjw4TGLbFto9aHM1GUtzFzN
+EYk+IARAIT7f7larRa7/OO0HOXvN1IkoUtgrdohLIAXjDZ2fBiUzO8kqbPzJKhQZDroeR4/EODwX
+Qlwe9bjGDXokDG6dUXxhMvMn3RJT28qxz0R0Kn+HQQgUmDBZo1oeBsHkphNelWseYGHS3x8I4Nli
++7b37mm1Xf6ojbl62vWezrOL5XZ1F9r5kS1qnKOJRI3yhJOMjUbcYIyx4PwzZepfOOoiv1Ftl3fz
+M61je4fmhd0YWibENbEbQ0v4k+v5J02Kod0VORgbVuSgxjn67vJOtKsULWn01Vl0v040g13BAwRc
+kFpdeBtJi898z//AKGqQ/CMu1GLTBI9dkcNZ91c9Kn8lH9e4hMamp7zx0yD6GwcRpBJXTG6uNWnh
+kKgXXZiVsmvX8lwxOeGTwXEBABz0HrED6aeqVz3hbPbEjkkkqyAiaSUHOjyIMVLP+YdZa3J+IcOC
+iOQ9bvHgvzFGv6czc3maBYGIkaxzj02uO0Zlc+dRFpDW1RSKawfRWiiWX77srsa8qKV6aNhqDp2r
+leDc46NSVUQUZ2KMrEkPnByVuMEYYxHpSVM2ajrPV2y3um9a2dRM0JNk5+TkglTqwm4kZVNiaHWR
+LbvKfsvY4CIHEWvUg8bYbrSrf8wASinlFaXE7LegHEtzhahZZU8r204M9a7gQeu+W/3KGdNc9dvZ
+6hY8GeuLHAS45HrVqs6zod5ThJEkB9605y4gEvnwDEN8KhRIqdV1yeF608Y5j1CM1MQ5SrfMsnVu
+I1IceRtX3QAAB4ALUskLRBSJaKvqVWucgRAKPpFSTr3YkbXylW63vNMel3ktRcaFGMhksNyuHph2
+88WNGCP5EBhz4REXrN+CkqupN0PdNRHN2/nUVp4MC0X+YlZMwBljbHGx+Gxjq/dg0qaju7xbzdH9
+UZvsxNUcJ2lVUYpfcrH2Ts534Ff/7//j3ijEjeCROKNnUqtGCByM7SSrhPg3lc3Wy3+c7ClnfxZ8
++IFz3hYKrgKoiffuu8p+K6T8l0FEjuCROGe8bvdlRCS0/hnF+ERq+YEQ4nw6iX1LPyUGvx7Z6Xxi
+aHYFT8S4jt495xzOgICrdVd4ESJh5R4MI3IE78gw+UpIuTTKsQ02FqS9fhoCxCUOnE374nzWoBgp
+lvZe3i4aeYoagt8ApPVJpnPUxa7Y4a1/K3aAZHwKfIUOAvspaWNJVqkqt6mUXDptgkrVq9ZAN7v6
+YX8LihCwOAtiMCKSs/5e3sr+ownvqLpARHJcfG2KfKbWheiRXlbua2Xq/b0GTVopt6u7+pBWlYBI
+FbKvZdac74x/8v/8nyORXFy3+kIX+nrTNm/euQ0QUErZHOFlmog7C4o3MbTALwijzk3KqNRV/lsh
++L+c1qAneEfABYcaBI53WlC06sxatOsoQUQij3MX7zxNvKnwCviYQngFHM5wBVfriKQdVuRwXfdF
+K6vnPXWQn4YQcC7NDc2m6QIHYzvvnKq32moXt+blxHdX7EDvv43EpFByKsUO7/0GMD7yWOyqW32l
+c3PtNPeDdW4zguRSisZtrve3oAglLs3Svb5rIqqNvjrvIre3nlirVfsB5TiwPbvRJVFKJWvfk3rv
+nrrt7sZJqzkIkRzS1we1qlCMtF2Fh7rVaozQLo//keMhjMSBYdPEDcZ2klW69jnPYC6TVYaFA3DR
+Nyp9Y1aISOvYK58zgPdAqUvjTGbQmbribLURHftOannifrxIjDE52dux34LiHjEQQSl1k2uYSrfu
+RGIvHPpHY1qIa8xoRkSRUWTBhy9dzzkQ/CxIuDQJwQOEAJbpz2xZ3TfF6doPCSNJFif6njrIT+O0
+m45EzUxB0hMIDrpV3C671cM8N5fnYa2z08ayJKVc2RU7nK++pSoyLmFZNTQxbj9KqY61tjvqZBWK
+tH2a5QciEhJ7qrVozGHDmxYU7x+AAFkYdV0Ueqa89ebVRPQoAsVHCnjtfo7jwOSmE7bL5y7w2vek
+SukLclGet69P5s0BQgAc0qoCnAMg4o6Jfe33cfCeRlLBESq7KbRcanK/lO1Wq6YwN5sowkwruzG0
+IdC3MSADxZfHFUPrnNsA4i/kCduN+pGzeuxllrvRrhTjC2XUnwBgMd1jJyd4pIipgmOaIaIYkbYC
+4vdE0QJn74Ecr/BJGCn0qoenETkm1Z7yGz8NJa5zDmwWSqjnEcJIEPzXOsumYo5yXbuWFaqlZP0n
+hHUQKUaKxIJzXxLGMC1iR9Wza1k+mhS1GCPZrl3N2vmJxIAYI5Xb1X1zprg17LVHwW4LCkT+Uhm1
+PCstKHvZayIqVaow3yXGSGUIq/mZhZkSsvbz8mV3lWd5Y/akp6nmOKxVpexWX/FWuzZDdOpXhG9x
+ct+YIvtwJAKH3S7vZmeKxt+Mttu7kzW4zHSa2RtD6z2OJYb2NCKHK6uvZKbHclLa943wW+TjN8Ko
+91ILyuAkgWO22K3yeiN8ErJxRdKeVuQYZ3tK8tOYXaZN4GCMseDchgYx8raHaeOt2BG+JAyBC7Gs
+VHPFjlElq/RbP+lrlZ3svVpu91ZVMb5El5OAiBSsf8YIn+jMfCglnJvVSrddE1GTmbk1ET0M9EhB
+65+V0VMfEXscL15u31FFuzF70kgU7evjvTkOa1VxVbURTOt3ky52CN4TD+GxElDqTN/ctSYYWuDY
+MRf9WWrV+JuRMFJw7lSnfonB2I2hRY8/MRbFqGJoTypyVGX1lcn0yJREipEoeBYsPgDRTzlIosbw
+JIFjttlrWowBn+6UL45M8DipyEExEivdw2xEZn7JT2N+mEaBg7F+JRH34WFeZJ8loa0/FxG9FTsA
+5AWp5cT8xE5K1a3uFWfyoSopvPfEuXh1Ei+NqletcW3eFwIm7ruxvwVFa3X9tKao00QyET2eqrJP
+RfvM+Vn039gPItLW6/BIFubTuseyl+D9U7u9fWQ1h7PVj0yahb2tKsF7sqB/Fmr8ekC/WsNtccJv
+TJF9qKQ8t3+/N7TA4Uq7pnN1uSllNsfhvdsAghO3OiSG590Y2jh0DK3zboMjf3FUOk7Vre6awgwd
+F7bbghIZeym1XAYQM1cqWSfBI/EYXwmVXvbzwNtIWnwWAv7AKGqQ/CMu1OKg88FJRI7gkTSxoVK+
+3vHT4ByFUssgYDGdwM02hEgQ4tf6hKfhTYJipNCzD1qt7Ga6T9/SF16/gvlgAAAgAElEQVSJIdJ6
+8P45cPFhU8QORKSI+Ehng296bFk9VUafP+4k1Tq3GbnoTtrwcB5aUPaTTERPxnblV/PFM3PjX+et
+3Xjt+AtpdKP2pCep5tjfqkKIVI45SaVfreEeaaWYMur6UXPcUCajFCNFHl9Oi7jBGGNK6Y63lmFI
+pqOT4o1JYS4+3XuiW3XdQDG0WulO4I75yq8fKnJEGtjohnZKJQnjE2nkhzIbTV9s4hA4T8/hnMCB
+c844AwHnpVbndwUPRFq3271fOWOaK/6RkGrxpNVeIDjIVnbDdg83Ho0+rIMxJzYp3iX0Y563iNia
+UP3KLcnh+qwvxhOzAXAOushWyq79S57rf01rnj6cc86FYCDEZankpV2xw1bVrwLkB3WKHUII8Eh/
+8NavD9piFCPbYJwfeYraNxWNT3UmJyLc7W9B0bmZi3VVMhE9OREjca3UvIgbjDGmjOkYb//hQtgS
+IzQZHhYOwLPF9u3g/dNqe/tHrbKr+/doWa5WnHOPd1tVQAiI1r0a9Vj61Rr+GUR6UhT6A5G3TtRq
+PJzA4d2WMmp5mM+oA2VMx3XtGssYSy/8ydJfWOzd4Ozk2jt3qhhaKXUHOS65yq7qzAwUGbmXd6Jd
+pWhJo6+CgGT8NHaQcSbqHkSiJvYIHpeVlpd3q70w4GNf2VecwxkQcPW49jbgR4scHNnGSRfTwSP5
+EJ4xwifSqPdUpi9x4HNzopSYPVRhPi4r+22G8h/z7suxn71ih9LqMiFFRHwrdkh5TgxYXTYoSg+X
+rIJEr4+b78rS3svPtMba/x9jJO/9FgthTUlo5bm6KkQ2F+uqvSaiRmWN8VloMiEEplrFR3WPY9K0
+2uZKfFX+BQH+3LSCAanUBbG4eN71qkfk/B/2VnOAECBCOL83VQVYFJEojuL3CN4T8+6R0YqplrkO
+Qpxq7hiqRcVt91Z1O5vahV8/WSWr1Vgp8Za9MbTRuZ0YWrh0VHUHIZJ3/qHJ325qCCN5b/+3ybJj
+Y6b60a7+MQMopYQrqQVlsgTvCJjgMAf9lonT86a9LeBjCuEVcDjDFVw9LJKWYqSw3XtoWm+9NoJH
+UsR+Vof4RPX9dYihD+sx0ovkp5HYS0AkOaUtKvsJzm9Izn8yM/C7TIJdscO78CtwOKuUvDRJsWOQ
+ZJWIkaytHmZFcWjLXtntfSHzbGwGl+g9BUePBY+9eWlB2Yt19inn8EsyET0dtme/EgsL1+b13bux
+uX1XttqNDexAH1667e73UulP9u7Jym75hS5a1zlw3ivdWszzy4Maje54azwTjP1gcvWhEPL8oGLJ
+wAIHIVIk+l5qdeqy3yZhu/Ze1s4aEY2VeJffxNBKviwOcEAnjOSdfSNyECKFgF/rQ4wrsV92/oxi
+fCK1/EAIMfADlBiOYB0BJIEjcTJ2I2kR8XsM5EDwsyDfFUH3ixy+tGu5ebccmhAJkRgG/yj5aSSO
+YpYEDsZ21m7OreatYmiPqnmCkCIhPnMu/NAXO8QloeTYxY5et1wt2sWJDxLRI1GM36tD1ubjMhWd
+pxSUw0gmosOxbcOdYvHM3Fa7RETaeG0fqiPEybqJRNH1qi9ZCB/tVnMQIrlAj1RmPg3ekxOGg5Sn
+evaD88SDe6CNbiktr44iiWVggcOVdk1l6vK0K22ESBiGM3RKjJ/dGFrEuI7W/7o/hpYwkq/sQ9PK
+biIiUXg3meOdFhStOinatRkE6wiE4JOOlUrMBruCR0D8fsfA+D2Q6hIAsFD2RY7w2t4r2vmt/X4a
+QorrAJwlcTNxFLMmcDCWzEeHhYgihXfFDpCC8RHGYO/lNMkq3nsCLvhBKRTehU1k7PmoDiYjRrLB
+b3Ef1rSGllDq6iynoByFreya0pJLrS8l4fD0ICJ5ob7X2em9smYJb/3GK0cvlDGNbiXsV3Nsfy+V
++QQEB2/tRpRaxMjOVBz+JvXx49+t1pCcnugs+5MQYnGU67GBBA6KkXyvup+1houyagreuQ2IKVll
+mtgbQxtZFCD4RwLEmeDCl0LrGyz2o4v7LSjuEQMRlBI3OQBLL5/mkASOxKjYY2D8E2J8GgmZ61aQ
+KaGFUKU06j0B4hIHnuaAxImZRYFjF9e1a3mhfj+Iz0OiDxFFQvrJO/+EMd7WSl4dtdhxmmSVqlet
+aW1+c/iIiGS9f6SzfOjDvH4LSngsBC+VVlcEzFcLyl6CC5tI+E1W5LfSodng2MptQru9NA/xsMdh
+e3ajJCGEava8vL+ao+yWXyhT/Pcu4heqaB1YhUIxEvnAeHAPdKZbSo2mWuMgBhI4gncEHGYq2tFZ
++6OUaiGZjk4fe2No0aH11iqVZUtcsF+VUX8CgJGqgonR4a0jISRPC4PEqCEirLa2v2QB3eLvlj5P
+c0BiEIJHkjEe2vI47aCzPyqQVTIfHR7aNU23fo0zEELBJxIk4ydMiDsK7/wGcP7iuO+p1y2/yPLi
+N0lPr1+Xd4YxFX3TgsLwB6PNh0LC+Xmu/okYyXn3SGf691INHj+e6LNd+dV8oX0zvaf7dF+Va15l
+U9ElsVvNIbj6b57wLxWDSrXb78w1b6s14hOTmT/BiKs1DmKgFBWy+EC2VGN7hAZBG3PRde0aL/jC
+PE/a08g7MbRZjFBBoIBfZ61WY816EonE+CCM5K37Ils6cyN07cNeZVeN0X8SIgnYicRehDYXXfAb
+1Ku+NPnxxtyJwwEADgBLUsqbu2JHZauRiB1Kq46tjk9WIWJ2v7hRdquvTCs/9XpobwuKMaqjc30p
+pcsxZiv7lAv4JWvlyUR0BESMJITgSdx4S2uhWH75srsa85P779SFUHIpW1y47nrVl9S1/8yZ/Eck
+ipHzSN5v8eDXssx0RCu7dNoklGE49URLiMS1bM1iOZpumWVX2vsxxoGTZRL1wjnnQirBATrB+Z/q
+Hk/iaCLSet1jSMwWO8lKD0yR3QTOIcYYZWZWvHW/YAhbdY8vkWgaUqoOCfHfy+3u3Uhp/TMKAIBL
+KZfyVn5T5+o6B/7K+epBVfa+8NZTxEin/UyTmYu+8n8nogO/I0QkIUW298+qsvdUZPqD02zE0Xty
+3eoL9PZBocRS60x+U5np99wbFvRIvbK6a3LTzov80yRujIZAgQlzcMrZPLO4WHwWer0HdY/jJHAA
+blrFp8XvfrfAXLXte7114e3DlhG8vdi+qTI9cLLKoIh/+fMf/tdp/oGv3E9Kq3+fRYGDMcZAiXO+
+5x5KLedepZ5W+sIh+5EF7HIp3m+6+jnPkA8/gRDvz+p8kpgszrvNiPFvOtNvTqIJMQKIBWHUe975
+55zYP0DA2TrHmZgeiGIExp4LKd6veyzjhANwUOpir7T3pYAzAJAd/68SJ4FzzgEgk0pdEFL+S+Tx
+VfDua2/9E4zY4pybk26WpZK/73V795VW5/evbSLGyDkwIWCBsb6paASxJZU8dvOIiOQr9xM591hJ
+CTqTy1qriwDA530NFWMkZ913QsFmVuQfgxB53WOaJZyn72Rm/i1VcLwL55wbAedKax8Lqabi/QMC
+MpVnFzlnP2et4joIkdU1f5y6giNS/GGWVVzgHKSRN5x1f617LInB4MBYZIypVv6x2+7dq3s8icOJ
+jM3sXJKYLM65TR7hudrnlQBKnSfCZ4wxJjNz0UY8621IlUOJEyOEuFr3GCaFLsxKWbpfgk/VTuOA
+A+dSyiWT559mRX5TKbUUfHjU65arla02EfHYyo6syD8ru9VvTnaJiIHg5xjrl/17DGtHJaZEjFRZ
+t2m3y1VB9H2R6/OtM8VtpeWFVJ3Qxzm36axbzYr8sjLm8ryLPeOAYnyRjOYPRigBbQnngw9P6x7L
+SZFKCYZYxkMqzSbFqQSO4JGkkR+OazBNAYQAxuL5UPm0CJ5COAPGdqpsVStb8UmsajbptZYYEufc
+JjB4rrT8zWIeJDD0+GZxoI3uoGQfVWV1f7KjTCSmA90yy73g0du0BhonHDgXQnCTm31iR3e1qg4X
+OzjnoI264Sv7ztoGAz7e3X93y96qyrIDvfJSC8rxICL1etUXSqtucaZ1O/3fjAdEJDD6TN3jaDIm
+Nx0TXRcDTo3obDL9GYXwrM4xnErgIOcfCSnmok9Kad3BSDhNN1RiB2CMiL1mjDEhBESkpfQ9JhKz
+ibN+DTg8lweIG4z1q/J2ImTfnCYIIYAbfaPcLpPnQCJxAFqbjmN0tlf2khA4Ad4RO1rFTa13xI6y
+vGN79ul+sUMIAcT4+b0iFBGVnHNWdquvdCu/tbfaABHJltVT1y3vCs6f5S19PS+yFSHF3Leg7MdW
+9ilFelS0i+spIWW8UCAmtZ6bCrlBabWLZe6qb+quijgpUikItvqhzjGcWOAgjMQlnyuXW53pK8G6
+v0/LDZXoA5wDI3zznekiu+itW08bmeYRWSrgSAyOs9WakPC+VAeLG7twyS/v944GwUG189tlr3f/
+MNO+RIKxU3tBzgxSqg6T+sb26/JOekYmB+ecw9vKjtvKyPNE9H3Z7d7dK3YorTp+5yAuxkicQbTO
+v9w1FX3bgtK9k1pQjmfXRDTLTTvLk4noJAgUH/H033wilpZaK6Eq79Y9jpOipL6CNbY6nlzg8G5L
+KvXJOAfTRHSRfVx1e/dSssp0o7PsE2ftVLgRJxKJ43G9ak1I9b4QYum4nwWplijg9wf9nW7lK1VV
+fZWqvBKJ3wKCgyqyz8tu9UV6RibPrtihtLqct4pb+8UOxcVlV7m/hxBi5LFNjP0XI1pw3eqL4KtH
+/RaU4nZqQTmcGCPZyq5xwb9vL7Zvg5THvlMSwxNjJJLcJyHp5CydyW+F0n5R9zhOgszUUqiq/6zr
++icWODDgN/M6OepWvuLKtDmeKjjwvaIUCA5cwKUUHdss+l/QXE4riSFwZfWV0CcTNxjr+3AEpOeH
+/b0q8o89+p9D8FNj5JVITBJVZDfK0v3iw/SY3c0ae8WOot26rYw6T4y+x4jdl883/79yu7fJAm5I
+gFd5S18vivzT1IJyNG9MRFv5ZWX0kZWAidHSb0/JPqh7HNOEEALO5OwPwbrG+yMB5yAku0CItRQI
+nEjg6JuLqpk3Fz2M3WQVn0xHpwfO2mxf0Y3WukMBt1OpbSIxvVSve6sy09dOKm4wtuPDwUgf1aYm
+jLlikYqUsJJIHIxumWXnQ5HMR5sBCHgjdrQW2r/v/PPv/kfrTHFbKrGUTsWP5jcmoun/a+J4xGcg
+xLm6xzFtKGM6hkfE0PykK63N+WD9ozqufSKBg7x/LOR834QgBEROZ9MJ33QAbLc64F10kS27spqa
+HraZh2KZCjgSJ6V63Vs1LXNzkMUoCP6H4zoNtdEdB3jW2ekoAU2Mn0iMpfPvt0itO46zj8pu735q
+3W0GMUbiIF4KKU4VHDCv7JqIttqtZCJaI4Hxp5Bu2YFotc0VFZrvEdlPJUVJOPlxHntnEUbinPXm
+yVz0MJTWHaxwqqJ65hXOWDxQ4WCMqdzcStGxDYEzrHsIiemg96q8b9rZzUHfRUf5cOxFK92JUnxS
+lWkDl0gchNxJIdp+3b2XKiLrJ4TAtNHLdY+j6ew3EeWQpMu6iBiJa6VS+9TgtBeKj7FX3qt7HMeh
+tb4WvD927TVqTiBwuC1hVJo4d9Atsxys/a7pqtncI+DaoX+VomObQ9o/Jo6BYqRqu3c3XyhuDrMY
+AgksBPz1RD8rBPDc3Oh2y/tprk8kfgtwDrpV3C67Nhn01gyF8EAIWKx7HE0lxkhVz32VTESbQwiB
+Ka0+qnsc087vFvIVX5aNjvKWUkD07sWk11LHCxyO1gDSxLkXXeQ3bGpzaDT9XdDhz1KKjm0OScFP
+HAZhJN+zD7N2fnvYzwLOIfKoTvqSBc7BtIuVXmVXEdMGbl5JL4ijUYX5uLTu5+TLUQ+ISFKqVqpG
+OJhdE9G8nV1LJqLNIURaB572lsPChYCllrrhrW30/Gsy/RmF8GyS1zxS4CBEEkZ20gbkt6gsu2XL
+qtGq2VxzmAnHHnSWfeJ6KR0nkWgihEje+QemyG6O6jNBHu/DsR9VZLe8db9Mg6FXYlykJdBR6Mxc
+cURnbZVaPydNsOGZVOpq3eNoGrsmolprnkxEmwdy8eu8JnOOGqEUtCU7i765axSpFHhr/z7Jax4p
+cAQb1kGIS5MazDQBggOX/FJIySoNRTAiOlItBMGBqxQdm0g0jRDcZvDhkcn1yig/Vyi1hIFO3Qsq
+imzZhfAquJSwkkgchNSqQ8D/I5mPTpbI2I9po/gutrJPieLXrXbrulCpHaVpICJJo/+p7nHMEiY3
+HY3ulzrMPE+KluqPkxRhDhU4KEaKPL5ME+fhKKU7xLDRqtm8woGxGOPGcT+XomMTiWbhnNuMBM91
+Zj4d9WcLIQBP6MOxH5mZizbi2RQjm0gcDOyaj2737qd36vhBH8hk5o91j6MpoEeqetWdLDftrMiu
+pbadZhI8bgkp0+H5iGktFMvMNldglplaCs59O6nrHS5wBM+Ukslc9BiUMZ1gwy/JZKtZcHby3ukU
+HVsPFCOl/MXEXpxzm8DgudJyfL3Sp/Dh2I82uoOSfVSl9sT5ASkJWqcAOAddZCvdbftdSG1dYyV4
+/yiZi75rItpaaH+eTESbDcb4t9QxNB4WF4vPsGxmsgpwDgLoHCFORIA5XOCw+ACEmPuJ8yTolln2
+lfsmGVY2CThVQkeKjk0k6sVV1VPg8FyOU9xgjPEBfDj2InZOqcvt8k6a82cf4KyqewzTiG6ZZef9
+q2Q+Oh4QkaRSbN6rFJKJ6HQRYyQuFQ4a9544Gs45LLazFW97jdzPaG3Oo/VfTuJaBwochEhcy+TK
+fApMK1uxZS9VATQFYIyQXp30x4UQEGOKjp0oxBjj6SWXYMzZak0o1ZZqvOIGY4P7cOwFBAfVzj8v
+e6kUP5E4DKHNRUd01vbcF3WPZdYINjwTSl6vexx1kUxEp5MQAhNGna97HLOMUALaEs4HH57WPZb9
+gBAQIw5cRXuqax30h8H6Z1KK5Mp8SlSmb7nKphd5AwDO4TQVHIwxprMUHTtpgLMzdY8hUS+uV60J
+qd4XQkykrFgIASH4f4zis3QrX6mq6qskjM4uyGLaOA2B1KpDgn9Sbnfvpnfr6KBIPwgh5vLeTCai
+00tAtg5CJIFjzJjcdEx03SauTbSW17zzQx0ynYQDBY7IYnJlHgAQAhiwP6RkleklRccmEpPD9ao1
+oScnbuzCAc6M6gRBFfnHHv3PIfjGnZYkRkRaDQ0FCAEiz29vd6v7TVxwTxvoA2VZ9mHd45g0yUR0
++qEYX8CcCnOTptUulsH21idRLXEapFIQvXsx7nH9RuAIHkkqeXGcF51llNIdZJill3gD4Fyc9sQo
+RcdOEmLJZHR+sd3qnjT68qTFDcYYExKujtJoXBhzxSIVKWElkTgcXZiVsnS/hJQ8NxTB4yOQMDen
+4MlEdDZARAJjdN3jmCcWf9f+NFRl4+wTTKY/oxCejfMavxE4yPlHQqbyoWHQxlwMlf8l9WbXC+e8
+OHmWylveRMc2OE86kZhmqte9VZ3rlbr6prkULAR8PMrP1EZ3HOBZZ1ObYiJxGLpllnvBYzIfHYyI
+kbjkOC+eE8lEdHagQExqNbe+MXWxdCa/FcpmrUukUuCt/fs4r/GOwEGIBBJYcrcdHt0yy660jc0j
+ngdOExW7H11ky66XomPHSWSp8nse6b0q75tWdrPO94wQAjCEE5sQnxStdCdK8UlV9lKM7AyR5qnR
+orXpOEZne+k5OTU2+C2t9Gd1j2PcJBPR2SNQfJR85SePEALO5OwPwbpGicpaqj9SGF9k7DsCR3B+
+rl2ZR40qzGe2a1frHse8whmLAyscLEXHJhKjhGKkart3NzuTf9aE3ulR+nDsBYQAnpsb5fb23ab1
+viYSTUFK1WFS39h+Xd5J1a4nJwb8RsjZ9jBIJqKzR4yRSHKfhKp6UMZ0MoEZhua0B8pMLXk7Ps/D
+dwSOiPQkmYuODuAcVCZvurRJrgcB14b65yk6dqxEqnsEiUlBGMn37MOsnd/mvH5xg7EdH44x7auA
+c1Dt1u2yV91HTPNHInEQIDioIvu83K6+TO/Z40GPZGbYXDSZiM4uFIgJbc7WPY55pijyiyq4vzfl
+4AU4BwF0jnA8VRxvBI7gkaRRMztx1gUIAYzF8ylZZfL034zDPTcpOjaRGA5CJO/8A1NkN+sey15A
+CuZxtD4c+9GtfMVb90uTTk0SiaahWtmnZel+8SGkJKIjCCGsCwnn6h7HqEkmorOPR3wmhLxU9zjm
+nfZC8TH2ynt1j2MXrc354PxY1mFvBA7y/rGQYuYmziagtO5gJEwnFBMGGBuFLKGLFB2bSAxCCG4z
+eLxvcr1S91j2A0IAjcGHYz+iyJY90s/BpYSV6SUdJI8b3TLLzocimY8eTIyRGOMvZ63EP5mIzgeB
+8acgfpNrkaiB3y3kK74sG+F/BEIAI6SxtAsz1i8f5pz1krno+NCZvhKs+3vqNZ0kgkWioWOIgKfo
+2HEBQlytewyJ8eC824wEz3Wmb9U9lsMAgDOTmJOFUVdsxLMpRjaROBypdcdx9lHZ7SWD9n1Y57d0
+ppfrHseo2DERXU0morNPxEhcK9WU9tR5hwsBSy11w1e2EesRreU1HENk7I7A4bakUTPvylw3usg+
+Tskqk4MDYzHGjVF8VoqOTSROjnNuEyI8V1o2+kQONFxlE3qktdEdlOyjqqwacXKSSDQRKQRwo29s
+v+7eSwdCewi4JgQs1j2MUbDHRPRmMhGdfUIITGn1Ud3jSLxFKAVtxc4GX3/7rFQK0NofR703BsYY
+Qx+/4ZBKhyaBKsxnrkztDpNgmJjYg0jRsaMGU+H3DOJstQkMnsuGixuMMQYwfh+OvYidzVtvu3c3
+Cd3TAUS2nSaqyQKcg24Vt8uu/Sq19varHbQxnWk/Ad81ETVFdj6ZiM4PIdI68NkQ52YJk5uOQffL
+uEw+TzUWrT8bdcswBI8ktXhv2ifOaQE4B2nkDZ9MRycAsBjJjfITVW5upVScROJgnK3WBEg+DeIG
+Y5Pz4Xj3mhxkO7tdlr376YS6+cBQYeOJYVCF+bi07ud59+UILqwLKabWoHHXRBQk/7m10P5ciNmO
+uU28C0b+IiV0NpPWQrHMbHW/7mQVaRT4qvp6lJ8J5Kd74pxGQAiInM6G4JNj+DgBxiLGapQfKYQA
+lqJjRwOx5N03Q7hetSaken/aSo4FwHt1CA26la/0qiqdUCcSR6Azc8URnbXVfB4sxBgpRja1G0Tn
+3Ka3/mHezq5Jrc/XPZ7EZEFEknn2Xt3jSBzO4mLxGfa6q3WPQ0t1hcLoqkkg8vgymYtOHqV1Bz1t
+p8Xt+ADOgSGN/N5O0bGJxLu4XrUmtHpfCDFV4gZjjHENlyLRRKs4dtFF/rFH/3OKkW0waZqvHalV
+JwD/j3k0Hw0hMJOZP9U9jtOy10Q0P1PcTCai80nwuCVkiodtMpxzWGwXN33Vq1VElpla8nZ0Fg6g
+lJwZV+Zpo5+sYr+ruzRophEQx7EgStGxiUQf263uSTOd4gZjfR+OgFhbCbww5kqFiClhpbmkFt76
+eWM+uj1frV0UwoNpMxdNJqKJXTDGvyVtq/kIJaCt4LyvMS0SOAcBdG5UniAAQkzVxDlr6CK/UXV7
+9+oex8zCmRlHB3WKjh2e/teSXnzTTPW6t6pzvQIwneIGYzstg360Xj2nRRvdcYBnnbVf1DmORKLJ
+AOegi2yl7NqvwhxUPSEiSSlb02LGGbynqlfdTSaiCcb67VVcKkxdAtOByU0nY367zopSrc354PxI
+jN8hTUD1o/N8xabowLHAGdejzVJ5S4qOTcwz1eveqmllN2dh8QKCn637VFgr3YlSfFKVvfQuSCSO
+QBXmY+f9q1k3Hw02PJNKX617HMcRMVLVs18JKX5uLbRvJxPRBGP99iphVPJdmSJa7WIZbLVeV2cB
+CAGMkEZx/ZQN2wBAcOCSX0rJKqNn1FGx+0nRsYMTkdL9PoVQjOS65R3Tzm7OikBepw/HXkAI4Lm5
+UW5v300eP4nE4QhtLjqis7bnZrbqKTL2Y9PNRV3lNr33D/N2nkxEE+8QkK2DEOmemDIWf9f+1JVl
+bZ0FWstrGMKzYT8nCRwNQSndiZzOop/9sssJM5YWlb2k6NjB4IyNNOEmMX4II/mufahbxeez5EtQ
+tw/HXoBzUO3W7bLXu4+YTKgTicOQWnVI8E/K7e7MCYLoAxmjL9Y9jsNARCrLalVnyUQ0cTAU4wtI
+1TxTSWcxX/Gl/bKOa0ulAK39cVj/xCRwNAildSfY8EtKVhkdXMDY3ZuFEMAYnU/f2+mIjPFkwTE9
+ECJ55x+Ydnaz7rGMml0fjiYlNOhWvlJZ90tKWEkkDgeEAJHnt7e71f1ZahcNHh+BhEaeftvKPo2M
+fd0+k0xEEweDiATG6LrHkRgMIQQs5OzfvLW1HPxopS5TCENV1SaBo2Holln2lftm1k4j6oIzNpGY
+P22yTj86dnYWWInELiG4zeDxvsn1St1jGRcg+NnYsMdXF9myR/o5uJSwUgcUI9U9hsTJ0IVZ6Xbt
+d7NgPoqIJJVgTauK2DERvZMV+XmTmWQimjgUCsSkltfrHkdicJQxnVxQVkdngcp0x1fVUGajSeBo
+IKaVrdiyl3wdRgGIcXeovEEX2Se28ikR54Q0ayuZOAzn3WYkeK4zfavusYwTrlUjfDj2I4y6YiOe
+TTGyNZH2cFODbpnlnvc47eajwYZnQjVnc/jGRFTJZ62F9udN9wVJ1E+g+IhD2mJOO0WRX1To/l5H
+dZyS8MEwkbHp7msoKstupWSV0RADfT+J6wDnAJJfCcks9sSkVVKzcc5tQoTnSsvLdY9l3AAACxQm
+MlecFm10ByX7qErvhETiSLQ2HcfobG+K04go0pOmJJG4ym36EB7k7fyaVOpC3eNJTAckuW9aBVJi
+MNoLxcdUlfcm3cKrtD7vK/tg0H+fBI6GspuskjbLw8GBscjjxEaRTlIAACAASURBVMwstdYdIqRZ
+6gVOzCfOuU1g8FzOgbjBWH/OjYHZJvlw7EUIAdzoG73t3t2mjjGRaAJSqg6T+sb26/JO3fHPpwU9
+ksmyD2sfx66JaK553s5X0mY1cVLQIwltztY9jsTo+N1CvhJ6vYHFhkEAIQAYLQ1axZEEjgajlO4g
+wyyZVw7OuGNiD0IX2bIrbWpVOYb+95LWTE3E2WpNcODzIm7sAsAa58OxFxAcZDu7XZa9+8nvZwIQ
+Y1yArHsYidMDgoMqss+7XXt/mtZQ3vvHQsK5OsfwxkR0oXVTyGQimjgdHvGZEHLsBv+JycGFgKWW
+uuGryZqOmsxcCs4P5MWRBI6Go425GCr/y7SdQjQHYDGSm/RVdaFXUnRsYhpxvWpNSPX+PLrjN9WH
+Yz+6la+UVfXVNG3cphXgrKh7DInB0YVZKUv3iw/had1jOY6IkUBCr65qieDC5jsmojMUBZ6YHIHx
+pyDS9nLWEEpBW7GzYYKmoyAEcAx2kAOddAdOAbplll1p76dklQEAxmKgibWovLlsio49HoplKuBo
+Fq5XrQmt3hdCzJ24wdiOD4cP39Y9jpOgi/xj71KMbCJxHLpllp0PRdPNR23wW1rpzyZ93Tcmolp0
+k4loYhgiRuJaqSSOzSYmNx2D7pdhzD9PizLqEwzh2Wn/XRI4poR+sopdrXsc0wZwXts9nqJjj4Ez
+rHsIibfYsveFNPMrbjC248OxQ91jOQmiyJYrREwJK4nE0UitO46zj8puc81HY8BvJn3y7Sq36Sk8
+SiaiiVEQQmBKyY/qHkdifLQWimVmq4m1yUqlAK398bTrsiRwTBEqkzddZb+oexxTB+esrg1Lio49
+gunYQ84F1eveqs7MdYD5FTd24YKfb7IPx3600R0HeNbZ9G4YPcTSMml2kEIAV/rG61fbd5vW9ose
+yRjz3qROvhGRemV1R+ea50X+aTIRTYyCEGkdQCzWPY7EeFla+v/Zu7fuNq5rX/BzzXWrAkCKAXPa
+OaYUn50diUoixedYpkkpjz1Gv/V7f7n+OJYpWVGPxPK2acljxI4s+1iOGZEEqta9H0DQFEVSvACo
+C+Zv+MG8CFgSwULVv+aas7sRisHMbrorKW9E78+1fZjeuRsEOUdg8DuarHJOjC3MvNPoPhodezoq
+Y6xeuVts6m62zugEFwAAUMqVGMO5yyGrpKTqJ8E/KBs8GpOQWUDOUHU794aD8lGdtpB6759yyWfS
+mNGUZisBfN5d7N6jJqJkkgLjP9EWp/lwZbGz7spiJr0GZab6rizP1WyUAo6GkUr1Q4qhTm/MdTc6
+0lZ3s4ZGx5K6KveK+7qXrTOkoGkMESG4UPuGhEch58hyvTbc27tP/ZoIOZ3sZGtDY7+vQ1+OlFIE
+YP+edhXFoSaiN6iJKJm0EEIUWv23qtdBZoNzjosaV5x1383i+aTA356n9wcFHA2kMnXTG/uPupVY
+1lUVo2KPotGxpE5iSNHslQ+yXn6PTnJf17Q+HIchYyh73XvDongQAoXglxWrXgCZKpXpmzbGZVNW
+O/HMOvdKabU6rcenJqJkFrwLr7ig8bDzRGrdzyDuzqLZuVRqxZXm4Vm/nwKOhlKd7H07NA+aeBJe
+gV9VnnAAjY4l9RBDiM6YT3UvW696LXXVtD4cR6luvlEamrBCyNsIJfse2Z+Gg6Ky86nkwhYXOJW+
+BdRElMxKSOlr2uk6f7o9fZO78qtpNx1FzhEhLp21Gp4CjgaTHf2RHZ49zZpXyHGl+hoOGh17WEwp
+AhUOzFwIIXoXHugOhRunaWIfjqNUJ1t1wX/vLU1YIeQ0gnNkWq3t7RUPZl0ZG0KISuv+pCvpqIko
+maWUUmRCBurlNZ8Wr/TWfDm8P+3nkVpf986eqRcHBRwNhoyh0GLNUVXA6RDqkG8AwGh0rDdu6kkn
+IUdZZ7djSM9Upu5WvZa6Q9HMPhxHca1vmhSWaYwsIadDxlB1so3hwPzdz7DyyRv/govJNhelJqJk
+1rz3wLVcqXodpDr9hfyuG5q/TvM5hOCYnBuc5RqKAo6GQ84xQVrxM2ry0ky8LvkGAADIjr4z96Nj
+IwADJqpexryw1m5jwpdSiRtVr6UJkO334WhBs06lVd9jWC6HJU1YOa8I4y7VZE7Ijn6/LN3OrJqP
+JoB/TqonBjURJVUJIb5AzingmGOMc1zM8T+cMVM9dupMfRS8f2uFLQUcLSCV6ocQd2nrw8liCOca
+LzRNNDp2hCHrVL2GeWCt3UbAl4LCjXNhnK20pcWRkKrPtFor9or71LeJkNPJXF+zMS6bwj6a5vM4
+56LO9B8u+zjURJRULST2LUO6pJx3Ust+zlMW3PSq4ISUGEz5zdvOZejV2BKjySqGtj4cg9XwVU6j
+Y8ksWOO2ENmAwo3za0MfjsOQMxS97N5wWDyg9wlCTieU7EfOPhjuDaY2djl6/5DzyzUXpSaipGoh
+hIhaK6oYIgAAnU52TSb7j2le3yipbkbvd077nhpe+pGLUp18rRwU87314Rh1GBN7nPHo2Pm8oxqB
+moxOlzXlFhf4jhB00nsRbenDcZTq5hvF0D6iMbJnwxj2q14DqQZyjjzP7+0NygeTPlkPIUQhpGB4
+sTdCaiJK6iL6CEKJO1Wvg9RHr9d5H8z0JlPJTPV9af7rtO+hgKNlVJ5vGNprfQRC8nFY9SqOozpq
+w1lXm+0zpB1sUW5xId/hnFODuQtqUx+Oo2RPrzkaI3smiOzdqtdAqqU6emMwMF9NsvmoN/4Flxe7
+KKQmoqROfAhPaHsKOerKlc5HviimNulTCHY1hnDi+Rm9IlsGOUOhxJqb8/4OhyFnmFL0Va/jOPM6
+OjYB9e6bFjMsHnFF4cYkMMFutLXAiney1TK4QBNWCHk71dWrhXNhUs1HY4rfcM7P9TZITURJHUXJ
+B1RBRI5ijOFSV6+5cjpNR6VSK640JwYoFHC0EHKOicXlaTZ5IZNDo2PJpJS7xabK9B0KNyYDhVyK
+Pjyreh3TonTWtxiWTWFo1Dghb6GU7luIy8WwuFSVbHA+Zln23lm/n5qIkroKLkSu9HLV6yD1xCXH
+noRlP4XrUeQcGUvZSdsHKeBoKalU3xv/w7xVBpyIMahzr4t5Gx2bYtUraJ9yt9jU3Wyd0Z2UiUGB
+4EN8WfU6pklJ1QfF/1Re8qKtnehARV4nhOyDUGu7OxdvPupdeIwCzzRS01jznJqIkrpyIbzgXFyv
+eh2kvnSu+zrZqVyPKqVue2eP3eZPAUeLqa5edaX9oo17yM+NsYVadhrdh4whShodSy6m2Bk+0L1s
+/aIN68jxkDFMEFXbj6HIObJcrw339qY2MYKQtkDOUHVHzUfPe9KeQoookL2tpH/cRFRr3aMmoqSu
+PLDnyOlSkpyu2+usMlt+MelKdSE4JucGxz0uvSpbTnezDbM3nJvKgJOMzgzqfd6u5HyNjmUMddVr
+aLqYUjR75YN8sbNO+7GnAzn7XY2LvyYGGUPZ694bFsWDSNvlCHkr1dEbw6H94Tzl18a5V1LJD079
+ntJsMQbPqIkoqbMUUuScMzr3IGextNTdCMVgc9KPqzP1UfT+xdHPU8AxB2SHJqswAGjCNco8jY5l
+yKis8RJiSNEV5lPdy9arXkubtb0Px1Gqm28UpfmKtjfSVjrydqqrV433Z24+mkL44qTmot76bVOa
++1knvyG1vkEXjqTOvPfAM7Va9TpIc1xZ7Ky7sphozy8hJXpTfnP08xRwzAHkDJlg1+d8+8Ovql7A
+WdHoWPI2IYTorHuoOxRuTBsKBO/DT1WvY5ZUJ1t1wX3vLU1YoUtM8jZCqb5l8J/Dwel9bIILUR/T
+XDSFFE1pHnHFB52F7j1qIkqawKf4FJFfqXodpDk457ioccUbO9FzCynUzaODNSjgmBNSqn6EsDyv
+d+WQ40rdt6iMzcfo2EBjYi/IOrsdffhc52qj6rXMA2QME0ty3qYcca1vmhSWaYwsIW8nOEcm1dru
+zt79k7Z4OeeecIHvHv7cuIlo1s3vUBNR0iSB8Z8ojCPnJbXua5ZC8JObrCIyueTL8r8Of44Cjjki
+te770v0wLz0eXoPQlHwDAGh0LDmetXYbE76UWt2uei3zBMV89OE4SmnV9xiWyznf4kjIWYyaj3bu
+DQflo6M3KPabixbjZqHURJQ0WQghCikWq14HaaZuT9/krpzYNQ4yhlzA1RjCweNRwDFnVFev2sI8
+mL9O+RxSSjtVr+I8Wj06NgJQCcf5WGu3EfClUOJG1WuZN1zKpeDj3PThOExI1WdarRV7xf156A10
+2OgvSwcqcj6yk60Njf3eWffd+HPGu1dKqo9SSpGaiJKm8y684krdqnodpLkWr/TWfDm8P6nHU0qv
+eOMejz+mgGMO6W62YYZm4p1s6y7G+G3VazgPGh1LxqxxW8go3KgK5xzDnPXhOAw5Q9HL7g2HxQOq
+KiPk7VSmb9oQclPaUUM9H7Z88NvW2E1qIkqaLqT0NRUdkcvqL+R33XA4kQrR0fb+IMa7FCjgmFMy
+E+u2NI+qXsessIa+0ts6OrZVf5kps6bc4gLfEZLCjUrNYR+Oo1Q33yiG9lEIbe4PRMhkCKX6Htmf
+Xv28/dAUxiithtRElDRdSikyIQOjhINcEuMcF3N53RkzkRu5Sqnb3rlnABRwzC3kHIHB7+alOoAB
+QlOrq1UnW7WlbeHoWHpvfBtblFtcyHc451TGXDE2p304jpI9veaM/WGSDcLqKsX4ouo1kGbyLsRy
+aJ6XRbn5yvlSXumoiOyfxrqt4AINICaN5b0HVNQQl0yG1LKf85QdnYJyEUJwTM7+K8WYKOCYY1Kp
+foCQtXtaxz4EiBF2q17GRalM0ujYOWOH5d+5onCjLua5D8dRvJOtlsGFtk9Y4QD/qnoNpDl8GIUa
+e3uD+5bFZ5DLFczkH670f3Wrs7T4a845dn/Vu8G7+nsb/CcUdpAmCiG+4IK/+/bvJORsOp3smkz2
+H5OoVteZ+ih6/4ICjjmntL7mjf3HSWPN2gIZQ4ihsX/Hg9GxE0g4ayHEz6peQp2Vu8WmyNRtCjfq
+g3OO3rsfq15HXSid9S2EZVMY+l0mc8uHEMtiP9RIo1BDLXbvCSVvALKUAL6QmViKMZXYydbMwD5U
+mVrp/WrxLoUdpIlCYt8ypMtHMlm9Xud9MMWDy1arCynRGfMPeoUSUJ3sfTs0l35RkelSOut76/4x
+730A2q7cLTZ1V6/T2MD6YYgL9Pv3C6VVHxT/UzksaIwsmRsHoUYx/Nim+AyyX0KNw/01rHFP8m5+
+FxDBOrfLGEPsqLViZ/T7gpwzCjtIk4QQImqtqEEumYYrVzof+aJ4eNnHUUL+gQIOAgAAsqM/skNz
+6RdVrTFkTQ9xZCe73YbRsQmAUQuONxU7wwe6l61T86564gJvNfwQMnHIObJcrw339u63bfx4gETH
+KQIAADGEaMpyezAsNssQP4dMrshO/kaoMeat385y3WeIDBnDtF96zRhDzMRasft6KEhhB2mC6CMI
+Je5UvQ7STowxXOrqNVderumoyOQSBRwEAEZbOIQWa9bY9pYbM+g1fXwHMoZCio15aQ47L2JK0eyV
+D/LFzjrdGakvJjh4H6gXzhHIGMpe996wKB60fbsjmR8xhGjtKNQYev84abUkutm6yuRt5MhOO1an
+FL+USvzSiDFFPr7BwjhH1G+GHGMUdpC68iE8oe0pZJq45NiTsOwvsSUfGUMxyUWRZkPOMYSw4kv3
+VGTyetXrmTQGAAlS40sHhORonYvB4ysu+JWq13MRdAX0ixhSdMZ8qnvZetVrIafjnKPzZge0qnop
+tTQaI1tuZUr9pqnHJjLfYgjRB/fKedhKnAmh5B2h8VzBsy3NVr7Q2Tj8uRChk1KC8cMwzhE0rBV7
+xWbeyzeOfSDYDzs4X1GZWokhJO/CC1uU36aQ+oLhdS45XW2SmYmSD2j7LJk2neu+3xtuWc/goucS
+dGAkr5FK9UOKoY2TVXCUb7SC6mSrzrjPm7zlht4hRyfTzrqHukPhRlNQH47TqU626oL73jv/VdVr
+IeQsYkj7lRrl5tC7x1HKJdHR6yrXHyLnp1ZqHOVdiCrX7OhFYGKg4cjbNeccQYmPir1i8yyPTZUd
+pErBhciVXq56HWQ+dHudVWbLLy56vkUBB3mDytRNb8xXbTuJTwjXql7DJKlMbjhj/1r1OsjFWGe3
+gw+f61ydePeO1A8XeCu169A4cVzrmyaGX7dhjCwFse0UQ4reuTgcFI+G3hwKNbJRqIEX2yqYov9E
+Knnjjc8DXD/udgTnHEGIj8w595xT2EFmzYXwgnPRuupuUl9LS92NUAzOFAAfRQEHOZbq5GvloGh8
+M8vDkOFSmzZHIOcIyH7XxNGxo5/C/F46WGu3WcKXUqvbVa+FnA8THFygPhxvo7TqWwzL5bCkCSuk
+Fg6HGkWwDx1nO7yb3blsqDFmS7OVdTv3jvsaIsBJBZdccgzAls8bchw8NoUdZAY8sOe0O4XM2pXF
+zrori3P3h6SAg5xIdfMNM2jRySlCm/INAABQStHo2Iax1m4j4EupxBt3+Uj9cc4xer9T9TqaQEnV
+Z1qtFXvF/SZvpyPNFdOhSg1nPh2FGvqOzPQGF2LpsqHGmA8hSi3tcRNVRhCC9ycGo0KKfkhs2V5y
+egCFHWQaUkiRc85owhuZNc45Lmpc8caer8ptWgsizTeerOJaM7GDQ0qpdRcmspPdNkN7oRKuygTY
+m8cCDluWz5HhS0HhRqMh4gJNCzkb5AxFL7s3HBYPmhnEzuGBquFGoUYYhRrml1BDdbL1Uagx+Yu0
+aO2m1OrWSV8fVXCc/hhCib6fQMhx8JwUdpAJ8dEDz9Rq1esg80lq3dcsheDPXrFOAQc5FXKOicVl
+793zqtcyCTHGb6tew6SNgii53qjRsTh/d3OtKbe4lD0hKdxoOlR4C5p4rV6h0YQV+yiE9jWwJtUb
+hxrFsNwaGvOp5WnqocaYK8zzvNf746nNSBHBOrf7tscahRxp2Z7zbuXbUNhBLsOH+BSRJmOR6nR7
++iZ35Zn7Q1LAQd5KKtUPZRg0fbIKYut2qBwQkmOMITbmZzRn+YYtyi0u5Duc86Wq10IuD5H6cFyE
+7Ok1Z+wP57kLQ8hpDkKNsti0CC9YR91QnWxdTDnUGIshRKHFNgo89diOjGEKZzsxF0r1fYwTDzkO
+1kJhBzmnwPhPJ2+/ImQ2Fq/01nw5vH+W76WAg5yJ6upVZ8zTZpYYj52hRrTBmjY69jyj95rMFuUW
+VxRutAlSH44L451s1Xq/4239J6xgjK7qNZA3jUONvWJ4/yDU6HbuCcmvHh3POv21uMdS6xO3prwm
+RX7WcyihVN+6uOyMm+q4ZQo7yNuEEKKQYrHqdRACANBfyO+64fCt/SEp4CBnpjv5h2ZYnik5qyUE
+iCG2+qKERsfWixmUnwitblC40T4c8dfUh+NiRKavmRSWTWHO3Rl9lhCwpBYc9XA41DAsfV9lqHGw
+JmO2827n92dtVBoidM5zwFC56hsXfj3tkGOMwg5yHO/CK65O7i9DyCwxznExl9edOb1XEQUc5Fxk
+lt01DR37h4xhmys4AJo9OrZtyt1iU+Vqo6qTbzJdTOH1FNsdmE6T0qqfFP9TOSwa+X5Cps+7EMuh
+eb43HH5iWPqe5aNQQyqxUvVxNY6mSnyN4uzhdWKgz3sOonLVL63LZ72ti8IOMhZS+prRaQypEall
+P+cpO+1ahwIOci7IGTLBrjeqoeWcodGx1St2hg90N1unkWrthcjBh0DHwUvgnCPL9dpwb/hxii1P
+n8mZ+LAfauwN7lsWn0EuV1Svc1cqsVKnHgDe2ccy13fO82cSwPWLvMp1J7s2LN33VfWuobBjfqWU
+IhMyVB0oEnJUp5Ndk8n+I57Q24gCDnJuUqp+hLDcmIaWhzHGm9Kj4jJ0N3+/rqNjY0oRWtp+I6YU
+y73ifr7YWT9r2TJpJuQck4u26nU0HTKGspf/ZVgUD2q35SeluekVVKXXQo20H2osdu8JJW/UKdQY
+89ZuZ3n2m/MG2KNRsRd7ietc36wy5BijsGO+eO8Blbxa9ToIOU6v13kfTPHguOs6CjjIhUit+750
+PzQt5GCMddq+TWWscaNjGy6GFF1hPs16+b2q10JmAzlbrt1FeUOpbr5RlOarpr2nkIvxIcSyaE6o
+MRZTigngC67E+S/6ECE4f+HpSwchR6jHFlQKO9ovhPiCC/5u1esg5CRXrnQ+8kXx8OjnKeAgF6a6
+etWV9osmlRYzaO+o2KNqOzo2AjDGRNXLmKQYQnTWPdSdbL3qtZDZoT4ck6U62aoL7nvv3fOq10Im
+L45DjWL4sU3xGWTNCDUOs8Y9ybr53Yv8WYTLn3/oXN8cFuUPdQk5xijsaKeQ2LcM6VKR1BdjDJe6
+es2VrzcdpVctuRTdzTbM0NRyK8RxGECam4QD6js6ljHWqXoNk+K93fbOP9a52qh6LWS2qA/H5HGt
+b5oQO87Uf4wsebsYQjRluT0YFptD7x9DJldkJ29UqDHmXYhZrpcv3I8AEaxzu5ddh847q8Oi/CGG
+mt282EdhRzuEECJqrWibHqk7Ljn2JCz7Q01HKeAglyYzsW5L86jqdZwJx9tVL2HW6jc6tj3nN9bZ
+7RTxpcr0h1WvhczeuA9H3QLEplNa9S2G5bKhE7vmXQwhWvtLqJG0XBLdbF3l+kPkyJp6wZSi/0Qq
+sXLRP4+MYTqhId556byzOhgUtQ05xijsaK7oIwglztVIl5Cq6Fz3dbIHrRMo4CCXhpwjMPhdE/o9
+jM6q5utapJajY5t5fvsaa+02JnwplbhR9VpIdZCz5URtOCZOSdVnWqyVg+MbiJF6iSHthxrl5tD7
+x1EeDjV4Y0ONMVuarazbuXR/pRiTntSEM91tRsgxRmFHs/gQntD2FNIk3V5nldnyixRjwhjooEIu
+TyrVDxCy2vV7OGoSm2AbiEbHTpYty+cI+FJQuDH3mJLUh2NKkHPk3Wx9OCwe0LGrfl4PNcwo1Ojo
+1oQaY96FqHLNJrGlJgGoScZ1uttZHeyVJ45KrCsKO+ovSj6g8bCkaZaWuhuhGGzy5d9f/b9Naf+R
+fBgCY31AltrypkRmiwtxxRX2GxS4XNfXUIyQUorfI+eLVa9l1oSSvzEDsymUuFblOmJKCWJ6yQV/
+p8p1XJQ15RaXsi/kxUuVSZuw5L37LyEEdZqfEq7kVTOwj5CzHiJms3jOmFIE559LrX47i+drihhS
+DMGnsrR/dSz+E4T4b1zJ/xRKrjBs7vaT0wTv7med/H9N5LGCt3muF887YvY0QsnflLvFplDiahP/
+/Rki44Ivqlxfk1ouA8fvrbWfex+GLEK/ab1a2iC4EJNUJRdiueq1EHJeSokVITL9oQCAGGIKPnxn
+jf0OE3Au8T+5FFeQc6pPImemunrVDMpN3c3W6/hGyxAg+vQzAMzlxel4dKzI5PWq19JEtii3uJLv
+cM6Xql4LqQfkDJMHk1SimwNTJHt6zQ3LLVASuBBXZvKk9OMEgFHYE70Ha/3jJNGj4Dd5N7vDsP3/
+QK4wz7Ne50+TerwEbGUaG67UQn53b2ew2Vvsrjf5rjtyzhTnKypTKzGE5F14YYvy2xRSXzC8ziVd
+k8yCC+EFz3M6TySNxDnHg1GNyJEBx6tcyqspppRSBFuGJyHYHcHZr7mS1xERkDM6uJBTyY7+yA7N
+Q92t38jMeRoTexwhOdrgQ/DhFRd8NhcJR6SGFp9SuEFOggjLKSZgvLHXFY3AO9mqLc0/ZYQfhRJ0
+8j1Fh0ONyFngSqzyrr4zycqDuvMhRKHFNgq8OqnHRAQYbWmb/PtvttDd2NsZbC4sdtfb8HOisKM6
+HthziWwubwSSdhDHfZIhYww4IOe3BUhIMabo4ysX7ZcpAgjOrqKU7wo6uJBjIGMotFizxn6mtKrZ
+1BIESL7qRVRKZfpmOSjvI8e7dMf5bMyg/ETm8g+IFG6QNx304eBYSWg4T0Smrxljfw5F+Ezneqrv
+L4nBXB0fR6FGBGvt48hZwP1QQ7TgYvkiorWb2ZWFuxN9UEQIPnwrlJzKazdb6G7stijkGKOwY3ZS
+SJFzztr0+iHz59iA4yiGyBjiEoLYGFV3JPAuPDWF+Ulw7HGFtxA50HYWMoacYwhhpXbbIRAgBmoI
+qDK5YY15rLOskhFgjLF+Fc97EeVusam7eoPe7MlJEBG8MV9yKWpXtdZGSqt+CGGpHBYPsk4+nX/z
+CCA4LkzlsWvGuxCdc08Dxn+hUn+c51BjzBuznfe6f5z0TYBZ9Dk/CDmu9Gq5VfiyKOyYLh898Cxf
+rXodhFzGmQKOw0bVHQyQ4w2h5I0UY4ohvvLGPUvJGs7ZeyjluygQkNF2lnkmlerb0v7IKtwOcRQy
+hkATBwE5RxbCfwTnX3E5o/3shzDERjRkHIUb2fo87DUnF4ecYdrXxguKOuKcY9S4Ntwbfpx38nv0
+O3o+B6EGi/9CpX+LHXVDzXmoMRZDiJzzr1HwDyf+4IhgjNnJOtPtlZstdDd2X+21NuQYo7Bj8nyI
+TyVymhBHGu3cAcdRB9UdQnyYUkopJgg+vLCl+wYhKWpWOt9Upm7aYfk3RP3nOt0BpwuR0ehYMyj+
+hhxr9bOpg5hSdIPhpu51aBsPORPG2Qr14Zgt5Ayxl/9lOCg28zxrdHPFWTgcajCp3uMUahzLO/e4
+s9CbSnUjMoazuseSLXQ3dv+9u7n4q8WN2TxjtSjsmIyY2L9ocg1puksHHIcxxhjjDIDjCpewkmJM
+KaX9ZqVmV3Bcpmal80d1svfLveH9rC4Xi4xxSADztbv6eLqbv1/ulZ9kvWyy+4xPFYABn93TnVMM
+KTpjPtW97r2q10KaA6VciTG8QI7UmG3GVDffKIblVqbUbyZXLdjQbshHUKhxPt7a7azT+f00K4Ji
+TDrFmGZxYyFb7G3svtq9v3BlYa7ezyjsuJgQQuRazcXWT+m0AwAAIABJREFUPNJuEw04jmI4eocY
+Nysdj6J10T6HCCAErnJF1R3zQHXzjbpMVmGMdYASjgM0OvYXMYTobHioO9lc3PEikzPqw+GeCykp
+4KiA6mSrzpgvE8RdIeSEpl4089TEuxC98y98Ct8yrd7jubqh6I7sW8WQIgP8iks+1fOUBKBSmt0Z
+iO517xU7gwf5Yrfy868qUNhxdt6FV7yX36p6HYRc1lQDjqMORtHCeBRtAmvC0+DtS8HZwqhZqaTq
+jhYaT1ZxpXsqK76QHo+KpbO9kZmPjo0AdSzg8N5uRw9f6lzNsJqFtAX14age1/qmMfbnFPxTqedr
+jKwPIXrjX/jov8VM/RpzeV1xPbHxpvPAOvekt5B/NO3nSRB/lWbcC4x38/V5DjnGKOw4XUjpa46s
+kubzhEzSTAOOw05uVmqexZT8eBQtNSttj9FkFbvsvXs+uTtsF6Kn3sa8YeZ9dKx1dpslfKkyQeEG
+uTDqw1E9pVXfOguhCJtZrltdieVDiN76Fz5QqHFZ3vrtLNf9WWwbScAqqfLCTrZW7BQP8sUpTR5q
+GAo7XpdSikmgpV5GpA3Y+//P/1m7S71xs9IYwtPg/U+cMSUU/wAFjaJtAzswWyKTE9wrfT7O2MiF
+YNRE6XUxpOic+f+mPTrWGRs55wx5Pa4CrbXbCPhSKEFdw8mleBcii/F72qZSvRhCTKX7VHeyjy4S
+2voQovDpc5Wp29NY30W9EWpwfp3eyy4nphSDdQ86i92ZBNzeubjY6+0KJWd+DpRSinFoP6WQ42Tz
+GnYEF6JX6nupFb1/kcarrILjNONmpa9Vd8QEvnB/DdHYg2alVN3RSKqrV+2w+BQx+7CK6R2jJ6xd
+rlc55AxZwBmNjq3H+bg15TYyQeEGmQgUCH5AfTjqADnH2MG14bB40Mmz9SZPioohROfcKx/TFlOi
+j5m8LlGtzGO13TRY4550F/LZVfsgQvDhW6HkzMMzxhhiJtaK3eJBvkAhx3HmtbLDBf9CiJzeu0gr
+8KX3fvN/cSmu1vmNkjHGGCJDId4VUl4DhssxhBfOuC+D8T+kFHPGmG7yCcy84VKulIPiE6nVtVk/
+d0yjFhxUhvcmznnuSrOFgr8zrWNC8O7fiDybZpf6s7Cm3OIoekIJekMnE8EYY96451wIuvisAcYY
+40peNQP7CDnrIWJ21j8bU0oY4SUX/J1prvHE5w8hOm//XRr3Nwfpf6NWv+NaXuWC/5ohY/T6mgzv
+QlSZ3BFC/HpmT5pYEpy/FFJU8tpiiIwhe9cN7UOpK90uXHsMkXHBF1Wur0ktl4Hj99baz70PQxah
+36bqKePiE5ln1+jYQtqA/+b96/+vKYoHokEnZAwZQ84XuRBXGef/PQHLvI2fm9I+Sz4UwFgfgKWq
+L6DI6ZCLFVeah0KKmb7BxpgShPg1Cr48y+dtCqHkb8yguC+U/O00Hj9a/xVy/k6Vv5+2KLe4lO9w
+IZaqWgNppxhCQuSL9P5TH1yJFV+abxhj8qwhRwwpYZptwHE01GBK/o5reVVIsUKhxnQE6z7Juvn/
+nOVzJgYpWP91lmdTeY89C4bIErJ3fWEfSEUhx1m0OewIIcQo1I9CUfUhaQcBAKCyfKPYK7eyTvYb
+FFhJX4SLGjUr5QejaFOMKfr4ykX7ZYoA42aloqUlZU2GnCET7PqsR5QyBIgxlbN6viYSWt9t6+hY
+W5RbXMl3OOcUbpCJQylXYgwvkCOdKNYI72SrtjT/lBF+FOqME1ZmcLkSQ4o+mFfOw1biTAgl7wiF
+6xSQTZ8tzVa+0Jl5Y2lkDOuwSZZzjkHBR8VesZn3ZrhFpwXato0l+gi8K35f9ToImZSDHhyqk62W
+xnypovhRqOZe1IxK73AJQWyMR9F6F56awvwkOPZGo2ipWWldSKn6zlqYTd+HkfGYWHIyITla57Lg
+ceKjYxMAq6oFhxmUn8hc/gGRwg0yHdSHo75Epq8ZY38ORfhM57qy5qExpBijB+PCw8SBQo0K+BCi
+1NJWddc9xqRTjKnqrdWcc/Qi3TCleaoz3dhz/yq1IezwITyRDGvVUJmQy3ityajS+qY37mdI7qnQ
+zQ05xk4eReuepWQN5+w9GkVbPalU3w7MFjAGs5msgpCSs9N/nmZTnexaOSg2kWfrbSiNLneLTd3V
+G1WfUJJ2Q8ZwfxIYbZOsIaVVP4SwVA6LB1lndk0Wx6GGtf5xkuhR8JtCago1KhKt3cyuLFQ2FjwB
+qJTq0W5bSNH3zgOFHJfX1LAjSj5o8hYbQo56Y4qK0LIfnQM7NA9UR7eqw/JBdYcQH45H0QYfXtjS
+fYOQFJf4n1yKK1TdMXuqq1fNoNzETjb9Ez4ESIG2qJyFyrKPrDGPJzk6torqmVG4MYPXFiEAwAS7
+kVKqrlSJnIpzjlHj2nBv+HHeye+ddFzgnN+6zPPElGL0r4cavKvvUMhaLVeY53mv98cqg/sE8Vcp
+1aeWVEjR99aDLc1TRSHHRDQl7AghRC419aQjrXLsmFiUsh9TXCv3ivu6m91tw93bo8ajaIHjCpew
+kmJMKSWwZXgSgtk9GEWLCMipumMWdDfbMIPi46zX+cs0nwcZQwixda/paRiPjvXePRdico3IZvWP
+H1OKflh8onv5vTYex0g9oZBL0YdnyJEuFGoKOUPs5X8ZDorNPM/WJzVVaxRqRLDWPo6cBa7EKoUa
+9RFDiEKLbRRYaWPNBGylbptlhRqFHEAhx8TVOezwLrziOqefN2mVYwMOAABkiJjpe8XucDPv5Y2e
+IX8WDEe3cMbNSmOIKfjwnYv2OUQAIXCVK6rumDaZqbumLP86yYqBY/FRFTld9L6dUqrvBsU/I/KV
+Jo3WjSFFV5hP9ZQDM0KOQoHgjH8pAOikseZUN98oh8XftNL/46JbJI+GGrgfaogGHS/nRXD+Yb7Q
+rbw6GREgxviCA9SqV88o5LAAxj5VWtHxawrqFnY4YFs5ssp/JwiZpBMDjjHVyTfKPfOp7ugbTZuw
+chnIkQHHqxzk1XGzUmvC0+DtS8HZwqhZqaTqjglDzpHF8B9Tn+DBQEOCemyAbQDZzd8v94YTqa4Z
+3bOa7j98DCE6Gx7qXkad4cnMjaYkREV9OJpBdvL3nTFfJoi7v1SqRQA4/e3duxCdc08Dxn+h1L9F
+CjVqzRuznXXzm7X4nUSE6OPPoOoVcAAACKUo5JiRqsOOFFLknLO238Qm8+etAQcAgOzotdKUWxlo
+wJk0gayXk5uVmmcxJT8eRUvNSidDStW3xgzYFCZ4jDFgCijhOBeh9V1Xuqey5qNjQwgxuPBA56qy
+BnKEIGe/oz4czcG1vmmM/TkF/1Tqk8fIHoQaLP4Llf4tdtQNRRcHtRdHF3Jfo+AfVr0WAAAEhBhj
+bZudC6X6trDAwH0ltbxR9XrmQRVhh48eeJavTvpxCanamQIOAACls1Vr3M8ixFZMWLmM45qVehee
+hsL8xBlTQvEPUNAo2stQWl+zA7PFOmxxGtsixqNi6az07CY2Ojal3Wn9w1tnt1nClyqjcINUi/pw
+NI/Sqm+dhWTCI0T8YPz5w6EGk+o9TqFG43hnH3cWOtPd+noOyBla68q86oWcQuWqbwoLAEAhx4zN
+KuzwIT6VyOlnS1rnzAEHwKEJK4V5pHJdixS8auNmpa9Vd8QEvnB/DdHYg2alVN1xbuPJKro7lTGl
+umb9vRqhzqNjrbXbCPhSKEFv1qRyKBBc6X6a9xsCTaOk6scQlgb/HjyCTC1Fzn5iUr3Hc3VD0RjF
+RvLWbmd59ps6luHXvReYylW/LMyPyNkrLsTcVXDXwTTDjpjYv2g8LGmjcwUcAPsTVkJYauMY2UkY
+VXcAoOAfCoCDZqXW2O8wAadRtOczmqxiPsl62UTvyDOO1+vWwbwpLj06NiWY9AkdhRukbpAxTCzJ
+FGOq44UVeVNMKXrnXkWXtiAX/Sjl/6EyRceUBospxQTwBVfiXtVrOSqEsAApAdQ33wAAAJ3rm8PC
+fNnJACjkqNYkw44QQkStFqa5XkJmLaUUAS4QcACMGkFGZGvl7vC+7uZ3a9GwqaYOmpXKcbPSuD+K
+1u4Izn5No2jfTmZi3Rr7mdLq9qQekyFQvnFB0xode1HWuC3krCsEhRukXlCM+3CQOgshxGD9i8TS
+d0LKVan5eooxpZA+B4ClqtdHLs4a96S7kNdzyyLDUb5R9TrO4CDkyAE4p5CjDi4bdngXXolefmtW
+6yX1NQ4FAAAgHvrfw9908geQ0vH//9r3HflfzuGz0QfptUNgOuHajKXohJTlG2uHxBiwgz81frAL
+BRwA+2Nk8+xeMRxuZnn+B+TzM2HlokbNSvnBKNoUY4o+vnLRfpkiwLhZqahwHnYdIecYQliZ7GQV
+TvnGJVxqdOyRg9ll2KLc4kq+wzmnixBSO1zKpWDjM+SctqnUkHc2epseCoVdkalbyPEgsGWcM1cW
+O6BVlUskl+Ct385y3a/rePME8Wo66Wy+hijkqK+LhB0xwdccWW360jTN7EOB+Ipz/Hb0wdlCAUQY
+cuThjbWfEAoAAHDJOees++ZXDn/IgbFfLqM4579ljL1xTHiz/IEd/t8///K/7Nhvef2x2NGPTz2u
+XzjgGFNZvlEOyq2sk8E8jZGdhINmpSA2xqNovQtPTWF+Ehx7o1G01KwUAEAq1bel/ZH5MLHJKsnH
+ZyDowuOiLjw6FtlEzugo3CB1xzlH491Pkvpw1EYMIXrrX8SYvpWZ/KPu8vWTqlATIKdRv82VUvgv
+qfJLjzafFsbYUtNKSUchx3Crm+eAfP6mKjbBWcKOlFKMgtlZh3+XCQWOXsSfJRSAlF4wwf41+vz0
+QgGhuUbG9JtfgRNDASHEsVXpr7/bvPbBErBfKgqnEQq0yaUDDgAA1clWS2O/VJH/KBSdyF3EyaNo
+3bOUrOGcvTfvo2hVpm7aYfk3hvrPlz0oMwSIMb1R6kTOR+bVjI41w+KRzNTvESncIDVHfThqwbsQ
+vfUP8ZhqjZMwljo06reZbGm28l6ndn03XsMAYogvuICVqpdyHjrvrA4o5GiEk8IOZ1w/ovqtM2YU
+B1wyFOCc7eIxlyanhQIqE4u/fHTSxfovoQADzLg4firZKaHACrBffr8oFJgfEwk4AACUVje9cT9D
+cnM/RnYSjhtFG3x4YUv3DUJS89qsVHWy9ycxWWU8JpZcDuccgzn76NiYUrxsQ7Vyt9jUXb1OF4yk
+CRj14ahMDCF651+kFL8RSv1pdNw4+wGIcX6L3imax7sQVa5Z7adDIEIM8WeAZgUcAPshx2C41e1S
+yNEUh8MOV5oghPxBZnL/d4RCAdIuEws4APbHyAZPE1YmbDyKFjiucAkrKcaUUtpvVmp2D0bRzkmz
+UtnRH9mheai72SVeYwgpuuHkVjW/DkbHYnaui4eLGIUb038eQiaF+nDMnnchBmsfg+QgtbpzlmqN
+YyFCcPSza5oU/SdSZbXdmjKGgBBjtFWv46J0l0KOppKZ5ra032Yib1y4RshZTPxiGLlAkHyt3Cvu
+pyZ1T2oQhsiQcya0vK07+T0m5I3gwwtTlg+L3WLTFWY7hhDf/kjNhIyh0GLNle7phR+DM0wh+kmu
+a56pLPvIWvP4rd8YARiy7CLPUe4V93WPwg3SLJxzDD78VPU62i6GFG1pnpui+BhYeqG62R2d6Q8v
+cxcfESFC2JnkOsl0ucI8z7p5vbem7EPO0FrX6K2yuttZHe4Nv4ox0vl+0wTfDyHQz4200kQrOMaQ
+IWKm7xW7w828l1Mp+ZQdjKKF8SjaBNaEp8Hbl4KzhVGzUtmq6o7RZBW7XJdRpfPuPKNjGbBzjSWI
+KUU3MJ9mvWactBLyBoQu9eGYDu9C9N49YRztpao1joGcoStDoy9A54kPIYpMbiPnzTknYAAppdTk
+kn7V664Nd4pPOov5Rl0n1pA3cSWvRxdfcM6pioO0zlQveFUn3yiH5u/Rx1fTfB7yC4aMIUcmlLyh
+O9lfUMrbMbAdW5jHw91i0w7L596FGA93Mm4oqVQ/uLgXfLjY64sxoCqjyVFK9ZPx/zr9Ts75XnYx
+hOgK86nuXWY7EiHV4gJv0aFmcmJI0dpyu9wr7gNL3+tc375stcaJz8XYQqK7040Qrd2UWt2qeh3n
+EXxYaMOxQS3kd/d2Bg/od6U5uJRYluW3Va+DkGmY+h19men3S2O+jxe9CCWXwhAZCrEkMv2hzPQ6
+cLniXXhW7Bab5W7xyBsbm7ydRWXqpjfmqwu9qTK2QP3jJkt28/ftsLx/6jed8UZVCCE6Gx7qDoUb
+pNmY4OB9eFL1OprOuxBNUf7defdQSLWULXbuCSVXplkZw4H9qgXXn63nSvM873X/2LhKCIat6WOb
+LXQ3dinkaJQQfD8G+nmR9pnJlgWl9U1rfPDm4j0TyOUxdri6I7/HtboTEzJbuMeDneF9Myi3mljd
+oTr5WjkoPjnvnxudBdFxfdLGo2Mv8xjW2e0Y0jOdq41JrYuQqoz6cHjq5XABMY2qNUxRfgwsfS9z
+fVvnegM5n82FrBQrMUb62dVYDCEKKX5A0byx4Qni1TZUcIwdhBxt+ku1mFLyenDhRdXrIGTSZtaT
+QWjZjzEu28I8mtVzktONqjs4E5n+8HCz0nJQflruFo9c2ZxmpSrPN8ywfHCeP0OjYqeDc44phuy4
+rUMJTpwydsBau40JX0olbkxnhYTMHkOkrQ7nEEKIdlhuOWM+5VIy1cnuCSVXZr3HnyFAiJHKuGvM
+O/dYZvpO1eu4CMbYUtvORLKF7sbuqz0KORqAtqmQtppp00mUsg+IH9ihOdeFKJkN5Mi4lFdVlq1z
+re8kxpdsGT4f7BQfH1R3hHpWdyBniOLck1V+1bLzitpQneyaM/aLFM93gmOt3UbAl4LCDdIyXOCt
+RPnGqUbVGna7HJjNmNIz0dE3dCdf51wsVbX1gCFCDH63iucmb+et3c46nd83droWQ4ghtu4OerbQ
+3dj99y6d6zcAbVMhbTTzqRrIOYLka8OdwSbdzaqvUbPS8Sja7C8o5Y3o444py4eHm5VWvc7DhOSY
+WFwOzp+p3wtyXGnbnZM6OW507GnxmDVuCxmFG6SdmODgAvXhOE4IIbpxtQbnTPf0ulTyRh0mMiBj
+GCMg3Y2unxhS5Ihfc9m8rSkHECCE+HPVy5iGbLG3sbO9s1n1OsjphKBtKqR9pjIm9m2QIapOvlEM
+y0+yPPsjcrxSxTrI2TFExhCXEMTGeBStd+GpKcxPgmNvNIqWjwKsCkml+nZgtoAx4IKf/rpCoHxj
+ig5Gx1r3nVDy1DFk1pRbXMh3OG/wiSohp+Cco/NmB/S5piS3VkwpRu/A2/SQa97nub4hpzAFZRIY
+g05KCZrWv7LtrHNPegt5I7emjCEgpBht1euYlmyxt7H77937C0sLNOa9poQSUJbltzI7/TyNkCap
+9GJUZdndsix/oDGyzfL6KNr83i+jaN3jYrf4uOpRtKqrV115lu0RnPKNKVNK9ZPzPx0eHcsY6x/+
+HltQuEHmAyIunD5Guf1CCNEW5rkdmk2GfEd396s1ahpuAAAwzm8BFXDUird+O8t1f5oTdGYBOUNr
+XVn1OqZJL3TvFTsD2q5SU4wxpG0qpG0qDTgAAJTOVo1xO97ShJWmOjyKVmT6HnC5Enz4vtwzm1U1
+K9XdbMMMi9PHlQJApJLxqTs6OpYhvjv+fzMs/84VhRtkPqDCWzCn55De2VgOzGaI8XORqZVsIb/H
+pVhqRO8ERAgt7JPQVDGlmCB+IZW4WvVaJiElYG3fAoWdbI1CjvqibSqkbSoPOAAApJbXvIvLNEa2
++cajaLmUKyrX97hWh5qVHhpFO4NmpTLL7p42WYXV4tU/H44bHVvuFpsyU7cp3CDzAnG++nDE/WqN
+clDeH1drKK1u17la4ziICDGGH6peBxmxxj3JuvndqtcxKTHGXsvzDWCM4SjkKCjkqCGhBBhTflP1
+OgiZlEp6cBxHaNmPwS/ZoXmgOnq96vWQyWA4uj2HnN8WICGGmIIP37lon0MEEAJXuRJXptG7AzlD
+Jth1X7qnIpPX31gbALT9pKIuOOcYjMtiiq+kEEvlbrGpu9l6I+7eEjIhyDnGOejD4V2I3trHTHKQ
+mbqDHBt9px05Q1eGVm8jaArvQsxyldWhAe3EMAbzsAWKMYaYibVip3iQL+Z0nl8jjDH0IfRiiKlp
+ATQhx6lNwAEAgFxgxLhW7A7uZ93OXbr4aR/kyIDjVQ7y6rhZqTXhafD2peBsYdSsVALyydRXSKn6
+1pgB8/jqjaajiJBCGk7iecjxYkoRYoQEACjlynD71acGGHauLKzFFBMLmCb1syakCcZ9OFp1gQaj
+ag3v/IsY47dCyd/qbnan6f0RXsOYTjGmVv2dGihF/4lU2V+qXsckRYi35iDfAAAAxjliBmvFbvEg
+X6CQo04EF7dCiDs0+IG0Qa0CDoDRhBXM83vFcLiZd/J1OploL4aMMWCAHG8IJW+kGFMM8ZU35llM
+yQvOrqKU76JAQHbxi2Cl9TU7MFuswxYPX1QgY5hS9JP528yHUWABABAhjjcZxQAJAGKInwEAiylZ
+lpIBAEgMGee4wAAAGOtnvd6HjKVdYPB19MHE5A0rgwEAiIxpBKaAgUbE66MNdBwQAQBwYqEXIVVC
+hbdSjDuA7TiJ9C7EYO1jkBykbn61xkkYsHdSGlX+kWrY0mzlvU7rpnGM7uXNScIBo5ADNIUcdSOU
+ADssvpRqgX4mpPFqF3CMqSzfKIfmbzrT/wNFO04EyekORtEK8WFKKaU4GkUbCvMTZ0wJxT9AcbFR
+tKqrV82g3NQd2hZx1OEqi1FnlAAQAWKILxLAzwAAKcHu/heBca4ZYxoBEuP8NiAHxhgghz+P/mXZ
+6L9jZirGEGII4Z9SidtHv5ZiSgnS/nlegpQAUkxPg48mQhiw0gcAgMT2AxOAPnJ8F5ADAFAQQhoB
+kYO3/ikX4sOq13JRMaTorXkVQ/pCZPI91bZqjeNIXKEtjdXxIUSVa9bK8nmGEHx4xoV4YyttW3HO
+MWhYK/aKzbyXb1S9HrK/TSVF3sYKQzJ/ahtwAADITL9fGvOlBrHLhWzlXSFyPMYYY/xIdUdM4Av3
+1xCNFRyXuZLXz1PdobvZhhmYT7Je9ktzMoYspZSOuxhvqstWWSDyd4EDcC5WGIPRXHTGjg0szgs5
+Rzcsd4/rQTCu6Dnixi//qyAdZCCvByHgw2chAovRDVmMHhhCAjg5CMHLVQURclHIOSZnLeiqV3J+
+3oXovXvCEIcyU+vIeevupp+EIYIP4QkX/I1wlkxftHZTdhZb+XpDBIgxzV2PF845BgEflUX5WZZn
+9HtVAxz5B8HHHVR0Y5k0W60DDgAApfVNZ9zPKbinQr/ZKJLMh1F1BwAK/qEAOGhWao39DhNwLvE/
+uXx7s1KZiXVbmkcq06O7pwx6kKD2dcezrLKYNsZRXXQvO9vPQN4IQgT/Mz/04YWCEIRryPAKIAeG
++y8JCkLIFCBny025SxZDij6YV9HuV2vk+nYT1j1pDBGiNbsA7W4QW0euMM/zXu+PVa9jehC8D3PZ
+D4xLjt6lFVOapzrTdI5fMdqmQtqi9gEHwP6EFefAFuaRynVjy3rJ5Bw0K5XjZqURbBmehGB3BGe/
+5kpeR3xzuwJyjiGE340nq4zO0mefcNS5ymL6pr+X/XxBSBpnIDAKQtIr8PGfAQBCdLsYY4oMgVEQ
+QiaEKbxe9z4c3oUYvHsCDAqp1UdM491mHF+mAxnDkEbHjHn+d5i1GEIUWmyjaGdvF4DRlJ7g/Nz2
+AxNS9L31QCFH9WibCmmLRgQcAAAoZT+GsGT2ygeqqz+iEwwyNtrawA9G0aYYU/TxlYv2yxQBxs1K
+hRxVd0il+ra0PzIfXuH+pNhJvJjaVGUxTSjlSopxB2rQqXsUhLwRgyyBgCUOAHL/E28EISlBgjME
+IRyvAFAQQl5X1z4cMaXonXkVHdsSmvflnFZrnKKXUoKWHZJrzRn/sLvUbf3d5JSgddtlz0OoUchh
+S/NUUchRKY78g0jbVEiDDQfFVmMCDoDR3feIbK3YHT7IezRhhRzvoFkpiI3xKFrvwlNTmJ8Exx5X
+eEtIfsMb+xlj7MS7QvNdZTE9iAAhxG85QGP23E4kCEkJUkw7kCJEYJwx1kEGCRBvs/2JMaMgBAEQ
+KAhpsXEfjqTqcUETQojBuKcJ4d9Cy1Wp+Xod1lU3jPNbQI1GZ8Ybs91ZyG/Ow2sxxjj34dk45AAK
+OSolBIIpzZdCidYHi6R9TFE+17l6p1EBB8BojKzq5BvlnvlUd/UNmtdMTnPyKFr3LKVkzGD4RWcx
+rjOG/5uqLGbjtEajTfe2IGTsIAhJB5+AmOJ34NN2SJ6CkDmAnC2nmIDxag4do2oN9yq6tMU174uO
+vkHVGm+BCCHEF8j5StVLabsYUuScf42C16rKaWoYJgrPxiGHBTD2qdKKQo4KMM7R25K2qZDG8dZu
+o+BDIcTVxgUcY7Kj18qy3Mp0BjRGlpzVG6NoE4uusH/Xvfw/hBRUZTEjl2k02gbHBSEI/CpIuPpa
+EBJTOmiQCjAKQmJ8AT79fFwQwhhohnj9aBBCo3Prhyl5vYqtWiGEGKx/ERN8K7X4I1VrnB0iQAzp
+ZwCggGPKvDOPOwu9O1WvY1YihNuUb4wIpSjkqBhtUyFNE0KIIcLXWUd9CNCgHhzHUTpbNcb9U0b8
+USiasELOZ/+k/vNssfc/Q3Db0drHUukP6GR/FqbfaLQNGLI3WqUi8BUAWDk5CBlNjokxPQUfjUve
+sDIYAIDImGbAFGOgEfE6UBBSGUQE780zDmImF3He2ehteigUdkWmbiFvb9PGaUHO0ZXFThurz+rE
+W7uddTq/Hx3/5sPor0oJx5hQqm8LCwzcV1LLG2//E2SSaJsKaZpyaB70rnTvjj9udMABACC1vOaN
++xmi/UxkqjF7+kl9MAYgle7HkJbMoPirytR1lIIC2l0fAAAgAElEQVRS6ymqU6PRNjg+CIEbAABH
+g5DDo3PHQUj00cQjQQgCU3AkCEEcPTIFIZeHnGHyYKbZhyOGEL31L2JM38pM/lF3+fo8XTROBWM6
+xZTo33E6YkoxAXzBJb9X9VpmiiEEH55xIehm3T6Vq74pLACD51JJCmRniLapkCYZ7Aw2O4udjcOf
+a3zAAbA/Rjb4JTs0D1RHU9pIzowx2IX981TkDHU3/9BZ8zME/1ep9Ad0EjsdTWw02gbjnjSHjYOQ
+w44GISkBpJieBh9NhDBgpQ8AAIntN9UF6CPHdwFHcQoFIWeDCFPpw+FdiN7ax6iEpmqNycKUFlJK
+b46gJhNhjXvSXcjvvv072wURIMZUVr2OulG56peF+RGRveKCbjzNEm1TIU0wHBRbnYXO+tEgrhUB
+BwAAcoER41o5GH6s8/weXZiSMxl1LX/ttULVHNPX5kajbXBcEAKvBSFqv1EqwNEgBHz4LERgMboh
+i9EDQ0jj0bnHBSFzPDp3kn04YgjRO/8ipfgNl/I93c3v0Pvg5CUlridqljAV3vrtLNf9ubxjjAje
+h2HVy6gjneubw8J82ckAKOSYHSEQnLHPhJrNNkpCzms8MQX5m+8ZrQk4AEYTVlBnfymGw828Q2Nk
+yeliSBE5Xzzua1TNMX3z3mi06dh+BvJGECL4n9+cGHPOIAThGjK80vYgZBJ9OLwLMVj7GCQHqdUd
+qtaYLoYIPoQnXHCqPpuwlOKXUom5q94AGE3D8sYGgG7VS6mlg5AjB+CcQo5ZYJyjM6WjbSqkjg5P
+TDnu660KOMZUlm8Ue+VW1sl+QxNWyMnCW4uMqZpjmqjR6Dw4XxCSDtqDjIKQ9Ap8/GeIACG6XYwx
+RYbAjglCRo1SoVFByKgPR3Ln7cMRQ4re2YNqDdXN7lBQOBsMEZIxQ6o+myxbmq289/oe6rnDEFKa
+Xk+epqOQY/YSxxspxvG+U0JqIYQQg49fZ738xDHirQw4AABUJ1stjflSg9jlgpoTkTfFCCAlv/W2
+76NqjumgRqPksONG5wLAEghY4gAg9z/xRhCSEiTYD0JgFISwECAhT68FIRyv/DIxBmoThDDOVs7a
+h8O7EL13TxjiUGq1TtUas4eMoYsp0IXo5HgXoso1O67MeJ7EGHtptG226qXU1ijkGG518xyQczp3
+mDIl+JIt7ON8gbapkPoohsUnC1cW/nLa97Q24AAAUFrfdMb9nIJ7KjSNkSVHpAhwjusbquaYLGo0
+Si5iIkFISpBi2oEUIQLjjLEOAwDG8RY7MjoXEKYahKCUKzGGF8hx5bivx5CiD+ZVtOkLkcn3dK5v
+U7VGtSKyHqQEQBeiE5Gi/0Sq7NST1XmQGGig/i5vpfPO6oBCjpmgbSqkbgY7g83uYvetU7ZaHXAA
+7E9YcQ5owgp5Q0hPQbJzzVenao7JoUajZJreFoSMHQQh6eATEFP8DnzaDsm/EYQggwSItycVhCAi
+eOOeCylfCzi8CzF49wQQh1KpdczmbGxmjTGEq7S9bjJMYZ53FnJ6bQNAArhO+cbZ6LyzOhgMt7pd
+CjmmjbapkLoYTUzJbr4tbCt2i+etDzgAAFDKfkxxzeyVD1RXf0RlpQQAICYwF30lUDXHZFCjUVK1
+44IQBH4VJFx9LQiJKR00SAUYBSExvgCffj4uCGEMNEO8fjQIOTo6FznDNAaQvDOvomNbQvNrMte3
+6a5Z/SCXSzHGHaTtdZfiQ4gqk9vIOW21AgBkADSh5+x0l0KOWRCCLznj/sqFOLHfASHTZotyezQx
+RSyd9n0hhBhi/G4uAg6A0YQVyNR6sTvczHs0YYUAAMS9y5QYUzXHJFCjUdIMo9/tN4KQFQBYOTkI
+GU2OiTE9BR+NS96w/5+9e/tv47ryRL/22rcqAKRoKhmnRSrpno4u48vpOZFl0crbPJy3+Z/mn7NE
+yY7PZ9xsx7Tsz+kktOyJEiEiCVTt29rngYJMyRQvIIAqAOv7FkcCtyQSqPrVutTJAQCQEFaAMEKA
+Da7+p0y0i1q+UFbf0lbe4yC+vUbtdYrb6y6FvN8urqws5daUEwmEFOOO0oq/r87Jdju3hgfVw85q
+ucVh8HRIKdEP62hKy20qrBHR+75Q8plS6syq+2rgdmxZfrw0AceI6ZRb9aH7zHbtTX76stwEiIkM
+ieNqjvHxoFG2aE4OQuAmAMDxICS6mJKP35JIz4WSmLMAbe3Hyz5ocR6glBjqap/b68YXKrdX9rrv
+cZD3E0TgERxjMCvlJ8N9DjmmidtUWFNSShRD3C1Xumdu2UohESIKlNj8BPkm6I69W9f1jxTpRdNn
+Yc2glAklFpN6vVE1R0wx+br+w9FTXHYWRIBE9Oemz8HYLMSQyA/r3XpQPQCRf9Qdc1PZ4l7R62x2
+1rv3UnDfxBj2mj4nO1sGlPw+Px5KiZRVfVTy1FLjpYMIPoSDpo8xj8xK+cnh/uBRJuKfySkYtak0
+fQ62fKph9fA84QYAwHBQP9bWfAAAsJQBBwCAscUt71yKLjxp+iysCQkEiIk/ftPGrktp/m83qP5A
+IXKAdgaUEsnxBR1bXK+FGpl+UNbcLLrlfWX0BkoU0fuHyhwNGNWd8hYBdZxz/970udnpJNA7PC9h
+PDGEL7S1Z65oXzYoBObEN+jjKla6WwccckyFlBJ95WLmNz02Q4P9wXZ35eyNKQAAwQXSRm+OqriW
+NuAAAFDWrsdIV2Pt+WJyyRABoMLr03htrua4mNGg0abPwdik/CzUKF4PNUa/zru6b0rz/vHfa4xd
+10a9Xx0OH/DPRXtlpW7wtf7FRef6RafzW55X9RaZJP/cj+9VyME/nBOXpbhJKTV9DLYkzrsxZaQe
+1g+1Na8GVi91wAHwco2sEO/7oXvU9FnYDGUCgWKqcx+4muO8jgaNMjavKGc6NdQ44QOaciZI8I08
+YSI4Sonlaud+cP7zFPm9o5UQgSJ92/Qx5gmlTFLK76Tm1pS3SQQd/ji8nGKlu3Xw4pBDjgnTRnOb
+CpuJ825MGXFV3Tdl+drDoqUPOACOLiZBy7v1wfABP21fEik/mcXuDq7mONurQaOMzZHjoYYf1tsA
+9PSsUOO4VLknurAfn/ZrTLe4myjtRxe5lbJlEBESpedNn2Oe+BB2dGnvNH2ONssCLE8avbxipbt1
+8I8DfnA5Qdymwmbh2MaUc4UbOWcKPn2j9Ou/ngOOl1AgqrK4Xw2H3L+3BCiDm2WBLFdzvB0PGmXz
+4rVQo3Kvhxr6p97Ps6SUCKX059mYYgp7nVS+6oYVP5FsEZQCiVJs+hzzInrfL0q7LnjLxakywA3+
+KZ+MYrW3td/f3276HIvkqE2Fmj4GW1CjjSnGmjPXwY5Uh/VTUxY/e1jEAccbTFFuVYf1N7xhZdHR
+Icy4BZirOU7Gg0ZZm41CDTesPn8t1OgUFwo1jou1fyyNPveQRaP1uu4Wd/2wekQ8hLA1SIgVfiBy
+NsqZMsAftVGbZ//q5Xa0Kpa/pSalWO1tVfsDruSYEK30WgyBW/PYVFSHw+3zbkwBOApEAKAvpfzZ
+dRgHHCcwneJW7dwP0fOGlUUlQGQhmhlyxtUcP8eDRlmbHA81QuU+EyLv68LeuUyoMeK97yurNy86
+ZBGFQLvS2eJVsu0hEDb5XvRs3oWdolt+0vQ55gNCCnGn6VMsEtkt73HIMRlSS3SVe8bVhGzSBvuD
+7e6V3oU+J6qB29HFyRu5OOB4C2Pt7RjoKq+RXTyUMqHEoskzcDXHm3jQKGvWUajhXws1TGHv2E5x
+Tyq1dplQ47WvE9JXSuuxn2TzKtn2QKnXiOcHnSqGREVpr07q52fRIQLwR+HkYae4W+1XHHJMgBD5
+OrepsEm66MYUAIAQAimp3vrZwgHHKZTV60R0lTesLJoEAoRp+hQAXM0xwoNGWRMovRlq4GuhxqTn
+BfjK7ZnSvn/2rzwdr5JtB54fdLZM8aE2aqPpc8wNRPCBWzYnTQiB2DEcckyAVGYjxshtKmwifO37
+ttDn3pgyUh+6x8rqa2/7/zngOANqvQ5a3q0PqwdckrUYiACEFO80fY4RrubgGwU2O6+FGm76ocbx
+rwtC/CjlZFZk8irZ5qGUSCEeNn2OtvK12y26nftNn2OeoBCYec7OVAghEAt1tzrgkOMypJboBjW3
+qbBLi973hRTPlNYXui5yte+bwt4+bdQABxzngAJRFfZ+dcAbVhZCJkCJrXuitMzVHDxolE3Ta6FG
+CI9nFWocF5zb0VZPfEUmr5JtFgGIZQylzxJTIlNacZ5NQewNmSRfa06HkBLRcshxWQK5TYVdzjgb
+U0Z85b5S5vRQhAOOCzCdcqs+dJ9T4g0r8yyn9BSgnddcy1zNwYNG2SSNQo36zVCjMFuzCjVGYkik
+tCqmNYeAV8k2RwjoZJ6a8DPk/bY2+sIXrgwgEXT4p3h6hJQIVt2tDiteITsmblNhl1UNq4cX2Zjy
+6vcdVHu2c3ZlIAccF6Q79m5d1z9STBxyzKmc8Xkz+1PObzmrOXjQKLscSpmiez3UsEXRSKhxXPJh
+W2p1Y5pfg1fJNkNI+QHwG9drQuX2yl7vvabPMa+yAMujRqdLSolg1Mcccoxn1KbS9DnYfBrsD7a7
+K90Lty+mlCgRfS/Vz9fCvokDjjEYW9zyLibesDKv8rCtFRzHLVs1Bw8aZeOglMm7ul8fVtvB+y9Q
+SvF6qNFsnOm97+tCvzeLtdS8SrYBiJAC8ZPMlyglUlb1UeFEZs0sowxwY7E/7dtBSomg1Meudnwt
+PwaCfD2lxN+p7ELG2ZgyUg3cji3Lj8/zazngGNOrDSuV+7zps7CLImr6pucilqWagweNsvOilF4L
+NZTSa7ZT3LOl/QiVFG35+aacKcf8R6kuNh38sniV7OwgIhAkDmZfit5v68J+0PQ55hkiAHeazYbU
+EhOIqxxyXJwxZiMGblNh5zfuxhQAgBQSIeK55zpxwHEJqPU6IP6O18jOD0qZBErZ9DkuahmqOXjQ
+KDvN8VAj+vh6qCHbE2ocF2v/1BTmkya+Nq+SnQ2UAlNMddPnaIPoXL/sdWdSrbTQECGFuNP0MZaF
+0mo9ZXHVc8hxIdymwi4ihEACL74xZWQ4qB9ra84dnnPAcUkoJYKWd+uD4YNFvOlcPAmkwE7TpxjX
+oldz8KBRdtzbQg3T4lBjhFIigdhvcosEr5KdDRJiZdnftyhlklJ+h2oya5CXGQJP4Jg1ZdR65JDj
+wrhNhZ1HSomSD49NcfGNKQAAwQXSRm9epK2FA44JQIGoyuJ+NRw+4g0r7UYZQEix3vQ5LmOxqzl4
+0Oiym+dQ47jg4hfaqFaU6vMq2emSIN5Z9vetGNwXuiwmvgZ5KSGCc47bnmbsKOTIV73z/D55TsYo
+blNhZ6oGw+1xNqaM1MP6obZm8yK/hwOOCTJFuVUP6h8pcsjRWjkDIl5r+hiTsIjVHDxodDlRSuTr
+N0KN7vyFGiMxJFJG/qqprS0n4VWyU6Rxg5b4fSt63y86nd/O289pW6EQyCUczVDGrEciDjnOSWrN
+bSrsVIOD4efd1d7YrbquqvumLN+/6O/jgGPCTKe4VTv/Q/S8YaWNcopPYYGuwRatmoMHjS6P9Gao
+od8INea4jz96/1BpfaGnDbPAq2SnQyAu7fsW5UwC8BupuTVlkoiyXfa2p6YoY9Z94JDjvATQVW5T
+YScZDqrdTs/+dpyNKQAAOWcKPn2j9MWHknLAMQXGmtsx0FVeI9s+mfD5/N42vd2iVHPwoNHFllIi
+P6z36kH9afLxC6XNwoQaI97VfVOaCz9tmBVeJTt5AhEoxaV83/Iu7NiuPdfaPnZ+GcDM9+OK+WbK
+o5AjuPBN02dpO2n0DQr0tOlzsHbxte8bq7rjbEwZqQ7rp6Ysxvp84YBjSpTV6wT5X3nDStvkIcDc
+30OdaFGqOXjQ6GI5HmpQyt8qazZsx94/CjVwIUKNEUqZIME38hIf6LPCq2QnB4XAnAGWrfUn+tgv
+SrveplasRZGB3lmyb6fWMaVZdyH9ggc0n05qjXVdL2UFGztZCokEimfaXGxuxmuvkRIBQF9KOdbn
+CwccU4RSHW1YOaweLNuFT1sJgLTofcLzX83Bg0bn3atQ46B6cDzU0EbdXLRQ47jo3I4u5+dpNq+S
+najesn3M50xfa6Na14q1CDKIjabPwI5CjmEdfuCQ4wwprnObCgM4uv4L3o29MWWkGrgdXdixB7Vz
+wDFlKBBVYe9XB8NHfAHZLMqZ8oLeWL1pnqs5eNDofDox1OgVnyx6qDGSUiIppRi317QpvEp2MoSU
+H8D8vM1emq/dbtErx56Kz06HCMCfg+1gS3ubQ47TcZsKG7nsxhQAgBACKamuXuZ6igOOGTGdcqse
+ui95w0qDKIFCXGn6GLM0j9UcPGh0fpwUahQr5cJXapwk1v6xNLoVa2HHwatkLwkRUlqOC/wYEpnS
+zl2YN1cQIcXEn4Mt8SrkSPNxHTVr3KbCAC6/MWWkPnSPldWX2njJAccM6cL+W+3cDxQTv0E2gDKA
+QGGbPseszVs1Bw8abbcYTg81mj5fE7z3fVXozXlvf+NVsuNDRCBKPzZ9jlnIFB9qoy9VfsxOh8Cb
+YtvGlvb2sKp/5JDjZCnFdd7OtbyGg2q36I6/MWXE1b5vCnv7sg/IOOCYMWPtbe9i4g0rDcgZUOKN
+po/RlHmq5uBBo+1yPNTImUONN1FIXynVvrWw4+BVsuNBKTD55Jo+x7T52u0W3c79ps+x8BDAOcct
+Ki1jy86tYVX/SIkfVL5JKX0jhbQUVWzsdaONKUpdfsC6r9xXyuhLvw4HHA1QVq8T0VVfuc+bPstS
+CfkFzPcD1kubn2oOHjTatOOhBnCo8Va+cnu2LBbqho9XyY5JCtPe99TLiymRttrzz//0oRBcwtFS
+tuzcGgwqDjneoC23qSyjSWxMGakOqj3bmUyAzgFHQ1DrdUD8Ha+RnR2C/JclzzdeaXs1Bw8abcbL
+UGO3HlQPINMPo1BDcahxIkqJQIgfF/XvhlfJXowA8e4id/aQ99vamrmdMzNviLLlSsZ2sl0OOU7C
+bSrLJaVEwdWfXXZjyui1EtH3Uo23FvZNHHA0CKVE0PLucH+wzR9is5A9wELeh4ylzdUcPGh0dk4I
+NW4W3fK+MnpjUW/cJyW4sGOsvtP0OaaJV8legMaNRQ04QuX2yl7vvWUaHNy0DGAW9NtpIfwUcvD7
+4gi3qSyXajDcLld79ybzWm7HluXHk3gtAA44GocC0XTKreqo35mT4CkSAG7ehwBOQxurOXjQ6HRx
+qHF5MSRSWl0VS7BJglfJno9AhJjSTtPnmDRKiZRVfVR46b5odn4Z6J1FDcwWhe12bg0Pqm3i8BcA
+AJRRwG0qy2FSG1MAjtpcEFFM8vqTA46WMEW5Vdf1j7xGdjooZ8r85Omt2ljNwYNGJ+tnoUbBocZl
+JB+2pVaXWmM2b3iV7OkEIuQYh02fY9JiCF9oa7k1ZcYyiI2mz8DOZlbKT4b7HHIAAAghkNtUFp+r
+J7MxZWQ4qB9Puv2RA44WMba45VzYj543rEwcJVCIK00fo+3aVc3Bg0Yvg3KmU0ONJag8mBbv6r4u
+9FKW6/Mq2bdDIZAA0iL9vUTn+mW381uufpw9RACeRTUfzEr5yeH+4BE/lOE2lUXna9+XajIbUwAA
+ggukjd6c9DUpBxwto62+HgNd5TWyk0UZQKCwTZ9jHrSlmoMHjV7c8VDDD+ttAHrKocZkUc6Uk/ij
+nNCH+zziVbKn6i1KvkEpk5TyO1Ryab/XG4UIKSYu958TxUp364BDDlBGgXP1n5o+B5u8SW5MGamH
+9UNtJ/d6IxxwtJCyep0g/ytvWJmgnAEl3mj6GPOk6WoOHjR6Pq+FGpV7PdTQk0/Fl12q3BNTmIn0
+nc4zXiV7soywCQsScMTgv9ClXeghum2GwJti582rkGNRUs4xCCEwERkOvxdLznliG1NGXFX3TVm+
+P6nXO44DjpZCqRC0vFsPhp+2YR7C3Av5BXCF7YU1Wc3Bg0bfbhRquGH1+WuhRqfgUGOKKCUCKT3P
+LPkJr5J9HUq9Ronmvjw7et8vyuJXyzBEt61QCnS14yrGOVOsdLcOXhwudcghUf4uJa7AXSSDg8OJ
+bUwBeBmY+PSN0tOphuWAo8VQICpb/L4aDpe+5O2yCPJfON8YX1PVHDxo9CdHoYYnN6w+D5X7TIi8
+rwt7h0ON2fEufqGN5mGLb+BVsj9BBEg5P2/6HJdBOVMG+KM0auJlw4wtg2Klu3Xwj4OlrcJWRoEf
+Vl83fQ42GZPcmDJSHdZPTVlMbC3smzjgmAOmKLfqofuSN6xcFt//XUYz1RzLPWj056EG7pvC3rGd
+4p5Uao1DjdmJIZE28lc8bPFkvEr2CEqJKYS5fnLpXdgpuuXSt2G1QUppZdlDw3lVrPa2Dl4cPGj6
+HE0QQmDMJHmzzPyb9MYUAICUEgFAX0o5tespDjjmhC7sv9XO/ZC413ksAvIB35hMxiyrOZZx0Cil
+00MNLhlvRvT+odKan2ifgVfJAoAQdl5bS6OP/aK06xyetoTARRnpspRsr3u/2h8sZSWHRPm7FJfr
++m3R+Nr3pVRiUhtTRqqB29HFdFePc8AxR4y1t4OjDm9YuRjKmXj+xmTNqppjWQaNvhZqOA412sZX
+bs+UZiqDsBbRsq+SxZxX5vWPnXP6SnNrSmtkoM15/V5iR2S3vLeMIQe3qcy3FBKByHvaTm6oKABA
+CIGUVFenHaJzwDFnlNXrRHTVV+7zps8yNyiBRFxt+hiLaNrVHIs8aPS1UCOExxxqtBOlTCDgeymX
+dy3sOJZ5lWw26sY83pT62u0W3c79ps/BfiKEWAPepTL3sFPcrfarpQo5uE1lfo02ptiy+HDSr10f
+usfK6muTft03ccAxh1DrdUD8nTusl/Lp2EXxW+t0TbuaY5EGjY5CjfrNUKMwWxxqtFN0bkdbM7VB
+WItsWVfJCkSIKe00fY6LiCGRKa3gDUEtIwCI5n8rz7ITQiB2zNKFHBLl74jbVObOcH/wuFjpTvy6
+x9W+bwp7W4jpl9VzwDGnUEoUVt2tDnjDyplyBqklbz6YsulVc8z3oFFKmaJ7PdSwRcGhxhxIKRFq
+VfA8gstZtlWyAhByjMOmz3ERmeJDbfRES5HZBCACRZrrrTzsiBACsVB3q4PlCTmUQnC14zaVOVId
+DL/sXOnem0YI4Sv3lTJ6JtWwHHDMMRSIplNu1Yfuc0q8YeWtKPMClRmZRjXHPA4apZTJu7pfH1bb
+wfsvUErxeqjBQ2HmQaz9Y6XVjabPsQiWaZUsSoGUc2z6HOcVKrdXdDo8Y6aFEBCIyDd9DjYZQkpE
+uzwhh5ASY4rcpjInXF3tmq799TQe6lQH1Z7tzK4FkgOOBaA79m5d1z/yGtmTUco7nHDM1iSrOeZl
+0Cil9FqooZRes53ini3tR6ik4FBjvnjv+7owMymlXBbLtEqWhJiL9Z4xJVKF7qNCnjHTQigFeh/q
+ps/BJkdIiWDV3eqw2m76LLPAbSrzYVobUwCOqmET0fdSTW8t7Js44FgQxha3nAv70fOGlZPwLcrs
+Taqao82DRo+HGtHH10MNyaHGPKOQvpJT+KBny7FKViBszkNrHXm/ra3hFs42EwA8b22xSCkRjPp4
+GUIOblNpv2ltTBmpBm7HluVMZ5lxwLFAtNXXY6CrsfZL0ed8XkLAAScczZlENUebBo2+LdQwHGos
+DF+5PVsWvE1iihZ9lSxKvUYtb60Ltdsre933uEqp3VJMK7B4PyJLT0qJWcmbrnYLG/QCcJtK201z
+YwrAUXiCiDMfYM0Bx4JRVq+TgPf90C1Ff9+55Ax8Adesy1dzNDtolEON5UEpkUDs8zaJ6VvkVbJt
+b62jlEhp9SMqyVVKbSeQ840FpbRaTyCuLnrIwW0q7TWtjSmvXn9QP26iSpADjgWEUiFoebceDD+d
+9MrOeUMpE0q52vQ52JFxqzmaGDRKKZGv3wg1uhxqLLrgwo42ikv2Z2RRV8milJhCaO0FfQzhC13Y
+O02fg50tA20uYJETe0lptZ6yuOoXOORQCiE4/23T52Cvqw6GX3ZWp7MxBQAguEDa6M0mNtFxwLGg
+UCAqW/y+Gi77GtnE40VbZpxqjlk9DU1vhhr6jVCDK4EWWgyJlFZXeXXv7C3iKtkMKNv4kCF63y86
+nd9ySDsfhBBrAK37NmITpIxajwsccggpMYYQuE2lPV5tTJlitWo9rB9qazan9fqn4YBjwZmi3KoO
+62+WdcMKEQAqvN70OdjPXaSaY5qDRlNK5If1Xj2oP00+fqG04VBjSaXab0utrjV9jmW1aKtkJdA7
+bXvyTimTAPxGam5NmRsCgRI9bfoYbLqOQo581Tu/kCFHlngzEzV9DAbT3Zgy4qq6b8qysfXjHHAs
+AdMpbtXO/ZAWqPz33DKBQHGl6WOwk12kmmOSg0aPhxqU8rfKmg3bsfePQg3kUGMJeVf3ddfwwMWG
+LdIq2azUjbYFHD6EHdu1M51mzy4JASjR86aPwaZPGbMeiRYy5DBKrvnKf9H0OZZdSokg09Q2pgC8
+HFzq0zdKN7OJztW+zwHHkjDW3g6OOtEt2RrZlJ8AN6m03vmqOS43aPRVqHFQPTgeamijbnKosdwo
+Z4IE30jJa2HbYiFWySICRWpN33n0sV+Udp1bsOYLAgIR+abPwWZDGbPuA10NLnzT9FkmidtUmpdz
+plDVn9luOZWNKSPVYf3UlEUjQXpdu12rxYADjiWirF4noqvLtGGFMji+bZ0PZ1VzjDNo9MRQo1d8
+wqEGOy5V7oku+Kl228z7KllEhESpFU/eKWfKmb7WRjXSD83Gh1Kg96Fu+hxsdkxp1l1Iv1i0kIPb
+VJo17Y0pAC8rRAD6UsqZX1/XdbVbWvWuMmaTA44lg1qvg8S77rCeywvGi6ND4HvYufK2ao7zDho9
+KdQoVkqu1GAnSikRSul5LWw7zfMqWZQCiTlAHDEAACAASURBVFJs+hwAAN6FnaJXbjV9DjYmAbAc
+12xsxJRmvfahnPdWveOUkmvBhT80fY5lNO2NKa++zsDt6MLOfBPdUbhh3pUv54pwwLGEUEqUhblX
+HSz+hhUBIvMN7fw5qZrjtEGjMZweasz6/Gx+BBe/kEbzWtgWm+dVsiTEStOfszEkKkpTNLGqj01G
+irTC+cbysZ3i+rAOPyxKyCGlRF+5yG0qszWLjSkAACEEUlJdnfVnTTV4PdwA4IBjqZlOuVUfus8p
+LeaGFUqZUGLR9DnY+N6s5jg+aPR4qJEzhxrs4rz3fW3kr3hd5nyYx1WyEsQ7Td+X5hi3tdFTGyjH
+ZkAI3hS7pGxpbw/r8ENKixFygJbcpjJDs9iYMlIfusfK6pluoqsG1W6n+3q4AQAgOxu/+n9STH0h
+6JcAOfPwqeUitdpwrv6TRKkFioUKA3JOWRA8l1q+2/RZ2PgECqGMvhZjGNb79Q8UCVJMX6HEWmr1
+z7owv5YSr/JNKruoMPT/r+0Uja0xYxcnpSoRxS/rQf1QKbnZ9go9ArGCAAdNhe2+drvlSue/8/vj
+fEsp6qKwJVfhLCel1S/qyv+nkkIjzveDOyHA5kRfKDPbG+FllFKinNJ3pizem/bXcrXvS6V+KZUs
+p/21Rl6FGycMiEdZdO5naT90QYlhBd8evnAPhof158H5fkqRiGO2hWdsccs7lxZtwwoRACq83vQ5
+2OVQSuSqes9X6Wsfggq1+wtK0UMpfsuVGmxcvnJ7pmun/qHPJm+eVsmed3bQNMSUSFvN82UWgBBi
+jUs4lpst7e1hVf9IKbX6Pe8sozYVnikzXTlnqofu0bQ3poz4yn2ljJ7ZJrrqYPhlt2tPDDcAAOQ7
+t/7lfwkhhEAUKOVVVOo6CPlPRLIIIX8b6vRdcH7vZc7RAwSeabCAUKkyhiSA6FtUi1HxQClmqWTB
+VUnzh1Ii7/33buB3KItaSPXPKcUfbKf42HaLTYD8LJN4lnwMAmWPn06yi6CUiYieaKP/a9NnYeOT
+Rm3EEJ7lCH9FhVebPs9JshCZXPj/tNEzD9ujcw+LbucOX7PNPyLIWsrvpFKt/D5ns6G0/kVVVX/S
+Umoxx5UcMaWO1oorkqZouD941L3S3ZrF+391UO3ponh/Vv+e9WD4sNsr76B8e7WIOuk/jm4IpcSb
+oI8mNyfK4H36XgzjHkBKSuMvlJY3EAWglDzLYwEoq9cppTU/dI9Mx95r+jyXlvIT0IL7jucEpUTJ
+xRch0VdCyl+i1DdMFzcBANxw+Mh2ynvRexJSYkqwqZQYSmE2QgiPhMubqjTXUAh+L2Jnis7t6NLe
+afoc7PJMYa/7EJ67YfXIlMXHbbuZRyEwAoic80wfDoXK7ZW93ntt+/tg40EEIMq8KpaBLTu3BoPh
+brdbAkp5penzjEMbvRZc+INU6qOmz7KIhoNqdxYbUwCO2mAS0fdGyZmsIB8eDLZ7q52ts8KUEwOO
+NwkhBEgBCnATFGzmnDPlDHWgFzmmb0X2XmrR01p+gIgceMwxlBIJxd36YPjAdstP5vnJOGVw83v6
+5UApUYrxRfS0m1EoqfQdpcX942/Ko3Dj+O/Txqz7Qf3MlLhvC7tFiXKo3GMBYoODDnaaGBJJrXij
+xAIxWq+TUnf9YfVIF8W9trVkCAGdnDPMKmuglEhZ1UeFM7ngZLOAEGMaNn0K1g62O98hh5QS3WEV
+bafgroAJqw+rPdsx787qc7AauB1blh/P4mu9DDfunef6baybgFFLi5RqTVn7kSw697OwH7ogxeCQ
+/uPwRfWgOqy/jMETpcgzPOYMCkRVFver4byvkaVD4PfN1qGUKTjXrw6q7boOXxDINVnYe9raj1Ci
+OCvcGDHd4pavwpNMlFGisJ3ynrJmww/dtnd1f3Z/IjZPkvePpVY3mj4Hm6w2r5IVUn4AM2w3Dy4+
+1tby6uMFglJgijE2fQ7WHrbbuTU8HH4zrytXsxQ3KfEt4iT52veVVcNZbEwBAEghESKKWYQpw/3D
+c4cbABNcE/tyhodQhfmQB5cuBlOUW9Vh/Q3F+VwjK0BwMtwSlDLF4MkdVJ+7qn5MINekHYUaUpz0
+73RiuPHGx7jp2o/qw/rB6H+jRFF0y/tSaeEPq0+99xx0sFe8931dmNv8vrC4WrlKFhFSoG9n8aWi
+c/3OSnl7nqsv2clyPmp1avocrD1Mr3t3uF9tz2PIoZVeiyHM5H1xGaSUKAN8p62ZWWv+cFA/1tZM
+PUwf7h9ur6z1zh1uAEww4HjTKPCQWt+URXEfpL0Tkl6rKvh2uB8/G7yott3Q7cXAgUebmU5xq3bu
+h+jna8MKpUwCxblasNh0UH491EhJ7Atr76ii2EIpxWkX4KdVbgC8/ttUWXzihvWj4/9NSrVmep3f
+S5QcdLBXcqCv39yVzhaPMXZdG/V+dTh80IYqREQEgrQ/7a9DKZOU8jtUkr/HFxAR9TjfYG8yK+Un
+h/uDR/MWckgt0VXuGYd2k1EP3aOiY2c20yS4QNrozWm3+x6+OHy0sta78DyRmd0A8uDS+WWsvR1d
+eA45PFFWz0lpdwIU2Gn6FMuGciaKBKn2X5CAhErdEtbcURd4Azw93Pg5lAJTFjdiHZ+o4vXWA6nU
+muyp36cY/1Efum1l1cdK83vLMvKV2zOl3Wr6HGw2Rqtk/aD+TGp1UyrVWJ86SoGhTlMfEBmD+6Kz
+0uXhuYtKYJ5lqxObH8VKd+twf7C9stq9N0+bA4XI1ykRSCWbPspcG7w43O6u9WZ6fVMP64ed1ZXf
+T/NrVIeHn66tj/c15Du3/uV/Tfg853I0x0MIRLmKSm0Kqa5nkFdDgn3v0n+E2v9notQXkH8JAHme
+fmAXESpZUkoihfSl1Kr1g8tSoowoIkq52vRZlkEMiULtv/F1eAIoELW+JbXeFIjFeVNXypl8VT0+
+LdyglLLU6mfVHxJlGUIYogDAE1anIWIhtdzIRE99Fb4CIa61bRAhmx5KiXKGPyujFmIFNju/tqyS
+pZj+qpT8p2m1R0Xv+7Ysr6J6+9o8Nt9iiv+lKArBA5LZSZQ1m8ODwSNj9Mb8tGHiCgj4TvH647EN
+B9Vup9f5t1m+L7iq7ktt/wvK6awqzjmTGw4fr1xZ+WTc12jNk0weXNp+qPU6aHm3PqwetL6kLBOg
+xI2mj7HIYkjkBvXuYH/4IMT0g9D6pumU96XSmxcNJClnClX12UUqN95kCnvdV+HHt5VpCiGE0nrT
+du09yPmH+tBtx8ATrpZBcGFHG8VDF5eUKex1UvmqG1aPmvrsEiDendZXppwpA/xRam5NWWRHuX67
+L71Ys4qV7tbB/qCx97mLklqiG9TcpjImV9V7tpzdxhSAo/Ah+PSN0tNp9805UxgOP+ut9sa+HwAA
+EP/1f/6PufmmykQ55wyZ6Amk9DeU2WiN/4oKrwhEQIGtCWwWnR9W22WvbG0pXKiqPVMUG/yUfrJi
+SJRieBpD+jNq/RtEeelKCMqZqHKfqY49880sOk+mtKdObHbDarvslmf262XKOcX4JMVYK6s/kNwW
+t5BiSCQg/6CM5sBzyVHOFA6rx02sko0hkEElpJIT/7p17b/srpQf8pP9xRZDol6n+M4Udk5ahVlT
+6v3D7ZW1lQvPLWiCr6q/dFZWNqfx3rjIfO37KMWzWQ4VBQAYHlR7ypoNKSf/75VSolTXn3UuGW4A
+NNiiMo5RlQdKeRWVug5C/hORLELI34Y6fRec33s5r7QHCLxBY4qk1pt+4D6XSvYEiqmUKF1GCvSf
+2sh3+Xvg8igl8s5/74Z+J4OohVT/rKz5NUq5etlJ/RcJNwAAkg/fK6NP/bqo1DVfuc+00ae2Ugkh
+BEp5VUr5X3JI/xF8+D+I4pdtDe3YeHztHtiyeL/pc7DmCSGEsnozuvqbDFAjzq6FMQPknOg/lJIT
+bZOKPvZNYZRSsrEZI2xWcpYof1CaW+3Y6ZQ1m8MXh49saVvfUs5tKheXUiKi/JUt7Yez/roppD9r
+ayb+HpRSouTqx53VycwSmestEzy4tFm6Y+/Wdb1bWAvYuourPHxz2wY7P0qJQghPo6M/o1a/QKlv
+mC5O9IPyouEGAAAo8XcAOPVJPAqByui7wbl/1/bsN3+BKGRhPhREOfm4E13IyuoP+P1i/nlX901p
+ONxgr9Gd8pb37rlz7t/tOd4jJkEgAnl3AGAm+ro5p6+0Kac66I21BCLEmIZNH4PNh2K1t3Xwj4MH
+K2sr95s+y2lGbSqWK5POrR66R70r3bHnU4yrGrgdWxYT/8x8FW6sTG5Q6lwHHG8SQgiQAhTgJijY
+zDlnyhnqQC9yTN+K7L3Uoqe1/AAROfCYAGOLW9655yqplm1YIbpsdcGyoZQoxfgietrNKLtS6Q90
+R0xlWNVY4cYFoJQYUtoQMewpdXolx6vfgyiwMB8SUQ4u/EHk+CtlzTWUgt8n5hDlTJDgG1moqXyP
+sflmjF2nlNaqw+GDolN8Mu3KLRQCUz56EDOp91Rfu92y12n1zQubHBQCU4ix6XOw+WFXuver/cGj
+crXb6s9Bgnw9pZSn0fawaAYvDrc7V7oz3wgXQiAl1dVJt0KmkCil8Kiz0ptoYLNQAcebhBAChAAJ
+uAZSfQRwNMfDhQwU0o4AfyCl6GmLLwMPxTcyY1DWrlMI4Cv3uSlnt4P5bShlEih559Q5UMqUon8Z
+aggllbojCz3Vvs1phxsj2ph1P6ifiRJfyAtUGCGisKX9iBLlEMIj4fKmKs01FBx0zJNYuR1d2o+b
+PgdrrwZWyfZyzjCJt9cY0pnziNjiyRnEJEMytviwU9xte8hhjNmIIX4rpWzRg9L2GQ6q3c5q914T
+85bqQ/e4XJns91D0oS8EPOt0y4lXoyx0wHESgUeP9VHKDwHMq8DjaHCp48GlY0Kt1ymlNT90j8yU
+b1zPlkAK7DR7hvailIkoQKjT41ehhtX3ZlHxMqtwY8R0i1th6D7Djvjook9oUaKw0m5Rohwq91iA
+2DCdeehnZSklklLyOkV2LqZb3PW1+0t28Fdl1dQusIWUH8CElgVkig+1Kbg1ZckQ0cRCMrYchBB4
+FHJUj8rV8TfVTRO3qZytiY0pr7527fumsLcnGaxG7/tCiGe2mM6Q1KW/eX85tFRIrW/KorgP0t4J
+Sa9VFXw73I+fDV5U227o9mKIRC8nmLKToZQIWt6tD4YPMjW38okygJBivamv30aUM8XgyR1Un7uq
+fpyS2JfW3tPWfoRSikUMN0Z0x96tD+sH4/5+lChsp7ynrNnwh9Wn3tX9SZ6PTV6s/WNpNK+FZec2
+k1WyiJASPb3sy4TK7RXdkltTlpHAPKmQjC0PIQRioe5W+9Wjps/yNqM2labP0UbR+z4qOVRqOqtZ
+z+Ir95UyemJfO3rfFzi9cANgzraozMLRphYx2tSyCVJt5CxXfcpPY5X+6J3/ExFVALAOkDNvXHid
+EEKgVtddVT1SUq00sWGFUspKytVl/7ehnClFymHo/hBD3AMhV4RW/yK1vi4Qi1mWuBJlovry4QaF
+9Fel1bsXDWSEVJvRucdKq7ErMAQKIY3+NQjh4tD9IUFekVKW474emw7vfV9pVV6kLYkxAAApZYla
+XQuD6jFKuTH54DfnnNK3Sqlr475CTImUln9WRvMmjSVCKVPKlEPtfmmNAam5pZpdjEAUQoprYegf
+a3u+2WSzhAJWAARvU3lDSolSmv3GlJHqoNrTRfH+pCpiXe37UopndsrrbZeuReWieHDpeExRblWD
+erfoFIAKZ3qjkVN8CkqdumljkcWQKPnwhHL+B0p1S1hzRzUY9kwq3BgZ55YDpcCUxY1YxyequFwJ
+upRqTfbU71OM//CH1adg5HvGmHcu85psciikr2zPcuk+GwsKgXalsxWG1S5l1T3vkOJzvbaUGGpf
+X+Y1yPvt4srKzKfns+mjlImAABIB5fyCAP6Scx6CAJJGGRDCehErb8Q1Xw3/LAF7CuUHSiEIvvZk
+5yCkRLRwtzqoHpUr7WpXkVpzm8oJmtqYAvAyXCH63ig5kc9BV/u+VuKZmXK4AcABx4Xx4NLzM53i
+Vu3814bkX5WZ3YaVTPhciNNXiS6aUagRE/1dGvVr1Ppmk6HGCFEmcu6x6tiZT3x+k1Zm3dduICK8
+mMQwQal+CjrqQ7etrPpYab7IbJKv3J4tCy7dZ5c2tVWyQthMOY9THRJqt1f2uu/xgMn59bYQQ0hI
+qJQFIaws7AdKiDUQYk0IAaPvFTestntXrihb2A3RKTeJKKeUXjiXvgVXRy3wllLmiuTPIXYKISWC
+hbvVYbVd9srGr82OE0BXeZvKTwb7g+3Oaqexf6OjtbDlRIa1u9r3tcZnxuiphxsAHHBMBA8ufTtj
+ze3ownPIYYZrZLMHWPz3xuOhBmr1G6n1TWObDzVGXoUbZfPhxogp7HU/qHdtF1cnVW4nlVrDrryX
+Yvy+PnR7HHQ0g1ImEOJHlNi60ls2n6axShZzXsk5g7jgZxSlREqrH1HJxjeVsdOdK8Qoiw8UwM9C
+jLfxtXtYXOlt0cBvj74PEVEg4prS+qNMJmfK4GN6EqvhM5nhF1rpG0orELwBjL1BSonJwMdVVX9e
+lkVr3lOk0Tco0FMp5VI9pDzJcFDtdlY6jWxMATha34qIE9nUVddu12gpZhVuAACI//o//wcPdJmy
+TJQhAxClJ5CoLyBlpXFTankN1XIEHpQiQcqfzWLDShjWnxa9ciFL1CklCj48jZ7+jFr9AqW80cY1
+gdMKN0Ltviy6xYeXvdFww2q77JYTX4ebKecU49Po01846JgtN6y/tKW99PcGYyeZ1CrZGAIZVEKq
+iz2h9HX9eWeld2cWA6HZ2Y62kRFAPiXEMPoDAQAgBJwnxHibejDcLVZ77+YMqzrn/zBlcWZFESXK
+FOP30cXvMSWppfodKgmSW1nYMTHE5xLy39vUFuJr/3Blbbnb8FxV7ymre00NFQUAOPjHYLvolpcO
+WOra7ZZWvStn/GfhCo4ZGF1wS4k3QQPknHOiDN6n78Uw7gGkpDT+Qml5A1Es5BwPlAoJ6W59WD2w
+3eKTaZXYUs6UF6x8l1KiEMLT6Eahhr5huu19St3Gyo036bL4uB7Wj8vuZHtQBQqhjN6QSl0jH3Zc
+CFlZ/QFfVE5XDImUVgWHG2xaJrVKViBCTGlHKnnutpfofb/odH7L4cZs/SzEyPkvGeCnEEMKK82x
+SgwUMOlrm7p2u8Vq712p5FpwgaQ+33YolChQmk1lzSYRZaIMwYU/pCo4Tfk32qhrUmv+XFpySqv1
+GCK42j1pTciR4voyt6kc25jS2HV+cIG00ZuXDzeq3dKamYcbABxwNGJZB5eiQMTC3q8Ohttlr7w3
+lZsRSqAQVyb+ujNGKVFy8UVI9JWQ8pdtDzVGph5uTKjeDIVAZfTd4Ny/60n2178kUAhZmA+RKJOP
+O94dBR2L8rPcNsmHbdstlvqJD5s+U9jrPoTnblg9MmXx8Tg3swIRsnNDsOZcv55SJon4ndTcmjIN
+lBIRAUAmSERPM8BzQDgAAYBar6JRVki8Mc0Q421C7XaLTvGuVHINACCHuCPG+LxCRAEIIJX8KB89
+YQMf05NUDf/Gg0qZ0mo9+gi+dk9MC0KOZW5TSSlRDHG3XOk2+oCwHtYPO6srl6qErwbVbqfTTLgB
+wAFHKyzb4FLTKbfqofvftrD/POkNK5QBJAo7ydecFUqJUowvoqfdjEJJpe8oLe7Py0C5eajcOA6l
+xJDShvDhe2X0VD5IBaKQhflQEOXk4050IStrP0DJPdGT4r3v60Lz4EU2E0brdVLqrj+sHumiuHfR
+FkEUAgNAyjnn83zP+hB2eivlnfFPzM4OMaQVEm9ogA2BYuNlS0mj7yex9n1VGCH1TzcHIsOhuORz
+ISGEEEoCKnlTF+YmpZeDSn34GnwNWuhbSkoeVLpklDkKOaAFIYfUGuu6/rMupnNd1mbVsHq4cuVy
+wcJluarum7J8/zKv0XS4AcABR2st+uBSXdh/q537ugADqOTkQo6cAaVsPIE+L0qZUvTHQg11RxZ6
+4rMhpm3ewo0Rbcy6r93XAvGFnOT34RsQUWBhPiSiHHx4JFzeVNZc46DjcihnyjH/UVrFm1PYzFx2
+lSwB9HLOcNbbfPSxX5R2nVuvTkc5ExDBvIUYbxO972Ohn6ljqxRzSiSVspM+81ErC64po7fyy1YW
+F+JOHAwOlBRXNfKg0mVxFHJ4AOefGGsavY5OKa5TotzGGXPTMtgfbHdXu41ey+ScKfj0Tdkrxm7f
+rgbVbqdr3pWyuXADgIeMzq1FGVwaXXiuFP59UhtW4tD3danX2vymeNTXGyDV6QsSEFHre0Lg2API
+mkYpEvk4k3AjVO7Lonf5IaM/e92h+8x2zEezupGgRDmE8EhQ3lSluYZ88TgWX7k9bc1Gm3/e2WLz
+3j3PCb6/yCpZX9fPS1O8c9r3LeVMKYTtzkqzF7xtca4QQx6FGAIABApoc4jxNjGEPir5TBf2tW0D
+0QXSUv5grJnZU21KKaeYnqba/wkpGy3171AhDypdcNH75wrx702GHMEFstb+sCxVHMNBtVt2zLvY
+cCgwPKj2lDUb484/qQbVbrdr30UpG/1zAHAFx9xalMGlyup1CgF85T43pb10jzFB/osQ0PgP1pso
+Z6J4LNRQ6raw9o6a01BjZJbhxjTpjr1bH1aflqudmZQGokRhpd2iRDlU7rEAsWE6tvUzVtqEUiKB
+2Oe1sKxJ46ySRanXKKWnKPGtF+/ehZ3uSrlUc2WOhxhEBDmfUokhxIYQ0OpKjIuilAhQfKeLn18L
+EaWnyswu3AAAQCkFSrmhrdkgetnK4tK34OqohNzUSl/jVpbFo4xZ95UHAeEbbWe31vM4bZenTcVX
+dd+WzYcbKSUCgL6UcqxrqnowfNjtFv+tDeEGAAccC+M8g0uVxKvK4o22DS5FrdcppTU/dI8uv0Y2
+e4B2XOschRoEyYUdglyhUreENXfUgpQbvww3HqnSLsRFuCqLT9ywfmQ745fmXRRKFLZT3ksp/cMf
+Vp+CFu8ZW7wzq68/z7yLXxSl4dkErHEoJZarnfvnXSWLCJBSfq4ATrx4jyFRUdqrl51g30ZvhhgE
+9AQyOJBwkLMQ0qgVYXBdSnNNLGCI8TaUMiWix0Wvc/LDgph/BBSN3ewhokDENaX1RznbV4NKYzV8
+JjP8QituZVkkpjTrrvIAAva0uVgL3qQsQ5tK9L4vlHymlGokSDquGrgde44V1CcZHgy2e6udrTZ9
+ZnHAsaBOGlxKLR5cilIiobg73B9casOKAHBNt3rEkCj58CQm+rs06tdo9IeLEmqMNBtuTOevEqXA
+lMWNWMcnqhh/DeQ4pJRrstf5fUrxH+6geiCs/G/GGA463iKGRNrIX/FsAtYm510li1JiqKv9t21S
+yRQfalM0OmjuMn4KMV4GGW8JMZQ010CIm0LAXLaTTFKM/rNytXdaJaRry83DWweV1n4XUpIa1b8q
+La9wK8t8M6VZryv3V0Tx4qzQdhqU0jdSOL3SbZ61ZWMKAEAIgZRUY4XqL8ONe215fxrhgGOJvG1w
+KVHaEckdND24FAWi6ZRb1bDaLsryv6G82IYVyplyQxdIx0MN1Oo3Uuubxrbrh31SFq1y4zitzLqv
+3UBEaOQDXUq1JlfU/RTjUUWHke9x0PFz0fuHZW827USMXcS5V8kKYTPl/GYg72u3W/Y6rZ+7cb4Q
+Q68rKTnEOIMb1g8676y89d88hkTW6tVZnukijg0qvfdqUKkLf4iD2hvAX2ujrkmtOeyYQ7a0t4eV
++7pTAMz6mkgZBYvcptKGjSkj9aF7XK50L1y9PNw/3O5d6bYu3ADggGOpvRZ46KPBpSEBUEhPIIW/
+CSBsYnCpKcqtuq53C1vAhdbIUgKFuDLFo70mhkQphqcxpD+j1r9BtbihxsgihxsjprDX/aDetV1c
+bepNWyq1Jnvq9zGEvfrQ7SqrPlbc6wwAAL52e6Y0l1phxtg0nWeVLOa8knMGcawiLaZEprSiLSXZ
+J4YYiRxofGuIwVVVF+OG1Xa5tnLq52kmAqn1B7M602UIRCERQCr5ke7YnInAx/Q0VcM/ScCeQvmB
+UgiCqzvmxquQowSQcnYhhxACF7VNpQ0bU0Zc7fumsLcvGj4P9w+3V9Z6rd36yFtU2FvlnDNQhpTT
+9yLSnoAEUuM7sxpcGlz4i9ZYK3O+DSsxRpIZvlVTHIpEKVHw4Wn09GfU6hco5Y1Fe+N9mzaEG0db
+VMoPZ9GG5IbVdtktG3/zzjnnFOP30aW9ZQ86KGWKwX9my9nNSWHsMsKw2hXq56tkYwhkUAmpfppW
+76vqQXdtdaYXvZQz0dFAjLeHGEq9I1+tVuUQY1J87R7albP71t1htdvrdW/O+7UGEWVK6UV06VuI
+PmrAW0qZKzyodD64yn3dKfU/zTLkWMRtKm3ZmDJy0D/4tLN6sUqSwxeHj66803t7hWILcMDBzi3n
+nCFnoDwaXJqmPrj0ImtkYwikpRSoxltv9DaUEoUQnka3fKHGSBvCDYDZBhyUM6XKPSp67dhkkCnn
+FOPT6NNfdKk+Xsb+Zj+sv9Sl/bCN5ZCMvc1Jq2RjSKQIvtPF0WdbqNxe0ev0UOHEL3p/HmLknZzJ
+CykcCKlQYUdqeV0IvPKyjWRu15bPi3ow3C2vrJwrtAgH1YPuld4nbb6ZuKhMlDNlSDE9CcP6b0qI
+qzyotP1cNdztluWvUMqZhBw5Z4o+bPeuvL2Fa574qu5Lo4TSuhXhRnVQ7UljNuQF7puGB4cPVtfa
+/+/BLSrs3JoYXKqsXqcUz7dhhTKAmsznP6VEKcYX0dNuRqGk0nd0R2ws0gXGebUl3DiS/ay+EgqB
+YPU979y/m2M3Jk0RKIQyekMqdY182HEuZGX1B8sSdKSUSEopONxg8+akVbKICCmG5xo0UEqkrOqj
+Gn/lMaVMBGeEGIW5ro5CjA85xGhOZT3qzgAAIABJREFUXbvdYrX37nnCjZwSSSXlol17CEQhEI4N
+Kk05xfS9c/57TElqqX6HSsKyfL7NC1t2bg2OQg6YRcghhMBEZBahTeXVxhTdzOrdN6WUKBF9b9T5
+1sLmnMkNh5/NQ7gBwBUcbMIy0VFnC6UdkWhig0spE5H3D21Z3n/bRZkfui+Ljvlw3PJZSplS9MdC
+DXVHIC71ULTkQ58o7+lCN36DDwAQav9p0Svuz/LfJHj/XIH8+6w3q5wlE2XycSdRysrqD9q0+nka
+3KDatp3yHt+UsXl2fJVsGFSfdnrd3/uqetC5snLmE/pzhRhcidFqoXa7ulO8K/X5ytNjiKQF/mCs
+WZgS/bPQqLrDhT+kkJwG+I1WkgeVtogbDHe73dlUcgQXyJbFgTazH/w+KSklCrV73IaNKSOH+8Mv
+bVF8eK6g9WW40VvtzU17MFdwsIma1uBSFIhoi99Xh8Mz1she7FqOUiaiAKFOj0ehhrSab6LgKNzI
+OT9rS7jRFG3Muq/dX0UUL6SaTVnmeQhEIQvzoSDKyced6IJR1t5AuXjlvd77vi7Mbf65ZPPu+CpZ
+EmIlVO552eu+Nwo3Xg8xMhDA8RBDosIuV2LMp1j7viyL7nnDDQAACuGFKjvXpnmutkFEAS8Hleac
+c04EPqYnqRr+DTNc1VLf4EGlzbLdzq3BUcgx9UoOZRT4YfW1Nitzc3P9pjZtTAEASCERIp5roHVK
+iVJdz1W4AcABB5uyURAhJd4ErW8efVZl8D59L4bxwoNLTafcqofuf9vC/vObG1YE5IPzXOhRzkQx
+QKrTFyQgolK3pbUcahwzCjemObB1npjC3g5D9xl2xEdtG7CHiAIL8yElyiGER8LlTWXNtUUKOiik
+r6S1rbk4YGxclDMprTZc8M+rg8H/0b3Of/pkVI7hWxDCCymRQ4zFE73vY6GfaaMu9pma4DtAcWdK
+x2o9IYQQSh5rZaGcUnrhfPgafA1a6FtKSh5U2gDb7dwaHlQPO6vlmYNyL0MIgTGTJKI8jy2qbdqY
+MjIc1I+LbnlmYJFSouTqx53VXmsqT86LAw42U0IIAVKAAtwEBZs550w5Qx1Gg0v9mYNLdWH/rXbu
+awvqQL6cTE85E5xy/XcUahCk2n9BAhIqdUtYc0fN4ZvltHG4cTLdsXeHg+pBd6XTqg+qEZQorLRb
+lCgH5x4LEBuqNNdwzge2+crt2bJo5d85Y8dRypSBIBMAAAGl9EJk+AsBgAA4EIgAQigpZacoCgur
+UBa/eOe/ozoascAhxmKKPvRRq2famnE+U9083tRNC0oUKHFNGb2ViTJRBhfiThwMDpQUV63UN1Dx
+oNJZMSvlJ8P96YccEuXvUqR9NNiaKtrzGA6q3c5KcbtNP8PBBdJGb551plfhxsr8hRsAHHCwho07
+uNRYezu48Dyn8ERZfQMogURcffP1Y0iUfHiSEvxdavkehxqn43DjdKYottywfmQ77V1TihKF7ZT3
+KFEOlXssJNw0tnin6XONg1IiEOJHlOMPX2TssihnAgJ4FV4QQU70FER+ThkAJR4AAAgUFqW0Qot1
+ieoaCFgDEGtCALycifHqsyf42C869gUqea4yYTafKCUCKb7Thf3oor83pUTW6p9d17AjAlHIo1aW
+D01pgVLKPqanqa7/hJSNlvp3qJAHlU6ZWSk/OdwfbK+sdk9pH7+ceWxT8bXv20K3Zh3sSD2sH561
+FjaFRCmFR52VXguWC4yHAw7WOq/N8QADeRR4UNoRyR0fXLoWUyKq6HPU8nejT7BRqBET/V0a9WvU
++qa2fAF5lnkINzI0OxMZpcCUxY1YxydtGzr6plHQkVL8hz+sPgUt3pu3oCO4sGNLu7Tl2Wz6jsKL
+o6GdR/+BIOf8hDI5IcRQCJEAAKSSq0IIQIPXUagrIGADhNgQIAAEXHgYtYD8FUq1MvE/EGsNSpkS
+0eOi1xnrCShFAqn1B5M+16JCKQVKuaGt2SB62cri0rfg6qiE3NRKX+NWlukoVrpbB1MMOeatTSV6
+3xdStGZjyoir6r4py/dP+zXRh76gtNfplnMbbgDwFhU2hzJRhgxAlJ5ASn+DHJFigN6qXSfCv6FW
+v5FSXmvbrIQ2m4dwAwDA1+7Tzkqn8VkMwdfPtdJSqvmZ6p1S/Eeq/H+Ake8ZY1ofdMSQSED+QRm9
+NNsD2GRRygQwCi9eVl9k+nfKWQiAAwHi5TBDvSIQspDyQwEAIF6GFjCdthFXh73uamfDVe4PZbdz
+h1tTFg/lTNH7z8pLDOZzh9Vur9e5iVLy98cljAaVppiehNr9TWW4qpW+oTS3skxafTDYXrnSuzeN
+TXfBBSrK4kC1fJtKGzemABxtQhnsDz8re923vidF7/tCiGe2GKudrlW4goPNnTcHlwbnnidIfwRp
+f2uKCw7wYnMTbrSJNsW6H9S7tour8/A0AQBASrUme+r3KR5VdKA1n6gWP81KPmzbbjHXTxDYdPys
+ZeT4vIs3W0ZQWqmFRVQ3jpZsif/rpJaRmZ09JbKF7qOSmyjAcbixmELltjvvrFxqdhBm+Ps5F82x
+U5w4qDTG753z30NKUqP6V6XlFW5lubxipbt18OJwKiGHUgiudl8ro1rdptK2jSkj1WH91JTFx2/7
+/6P3fYHimR1vVlDrcMDB5hblTLF2X0irf6uwsJKfclwYhxvjM93iVj2ststOOVcbeKQ6CjpiCHv1
+odtTVn3ctqDDu7qvS/1eEzegrFmjlpEM8PN5FyA8onAAP7WMSI3vCFQbIGANhPj/2bv35yiuq2/0
+e++1b91zkSx8DjkWOOc8AUFi86aOuUjgOn++QWBM1eMojmXhqjiWZb8hfsbSaLp739Y+PwiBwBLo
+MjPdPbM/VanEMWgWCGa6v732WouHHRhN/bPjnH/W7eTp2NUMM0W5ni32LhTOxhCQAkBT/xy32cGg
+UnmFK3nl1aBS477yo8pKwj4Wkn8EQjTqM7FNdK+zNvxtuN7/oD/WDgYKwLytGn1MpYkbUwg56Coh
+hAwA4Nh5ZqayA85nJ9wgJAUcSUt5awcRyfci07cppRTQuTbdZDZBCjcuTuXZmimqR7rbvrOKXIgr
+wPly8P6nJgUdGCOSQL4D3eynNMnZvX1khCB5Pe+CkIIyFgiJFLjoUUoIKPj0ZWCxTChZntSRkWlx
+1g7yfucaZZRiiEgZ6LprSsbLlGY9G8PT64CRSAGNP0rYdkcGld4RuYoRkVgfdkJZ/ACEdTmDTzln
+hKbujjPR/e7a3mBv7CEHMPgMG7pNpYkbUw6VI7OhMn3ruH9nKjsQnL6QMxRuEJICjqRl3ujaONy6
+EjwKAd26a2uTFG6MDyixao35m1Tq2A+PJqOUUi7EFQC+HLzfqQrzs1D8szpbdUNptoRWJ7ZRJs10
+lhWpr46MEEIIpSsHt4LtDi/eB2NERuFb4Pw+IYQgIqGUyLrrSsanGhWb2UJvLEMW0bldluWNHmQ9
+ayillAKQV4NKA8aAYdcY9y2xFRGE3eBcLqRBpaej+9210W/7jzqL49vE0dRjKrayA6l4p2kbUwgh
+xDmHHPil44KXWQ03CEkBR9Iib3dtHP7/ESPhCtKk8VNqdbiB2LgbIAbAXAjLbdischLKKOVSLAOH
+j9D6DWNc5Ep8Ou2gI4SABMCmtZnNMYkVqfMoWLeV9btvPM2kDFRd9STjVVVmU/e7l8f23oXkR8po
+426W5snBURa2yIVYi4gxYiTWhy03Gv2HA70kWBpU+j6il98v90aPs/7Jgy3PoonHVJxzSBl9IWQz
+Q4Jq3zzJer///TdVtS0EL6Rs4b3AKaSAI2m847o23hDDFmUwk39Bx63V4QYhhDDWyK1PQsolW5l/
+U093gUPjWidPizJGQctbDDF66zfCy6CDTSnocMY/02kt7NTUtSJ13vgQUCj5ZnCHSBhAKwPR5E2u
+Mpu6oy8Dh/EFEpHsN+UGLjn4bKSMHBlUGmLw4Sdj7E8sBBDAP2McSBpU+nss13fLvfJx1s/GEnI0
+6ZhKCAGDdY3bmHLIVHYgtbr59md0VZnNTInLwPmxMzlmQQo4kkY7qWvjKIj4K0nX1+/V+nCj4aRW
+N11hvmQ5vdP2FcWUMSq0vIWIMVi/4Y2TXKnrDCb3pMpaOxAS/jDLxxSm6SwrUoG/sSJ1ZZIrUucR
+uvBEdPM3Lu6REAI11ZOMj6/sgOf6MvDxtaaHEFAp0RvX10vGjwFQBnCFK3kFESMGJM76r7CoPKdw
+RXBIg0pfopQylsuxhRycM+KMfc4lr/1hSDkq1nuL/cYNFT1kS/NN3n9zo0tVlZuZkmN9z2qiFHAk
+jfTero0jP06KNGn8fVK4MR0iV3eLUfmw08sb+4F3FowxyrS8hQGjc+4xNfEKz+RHbAItuejCN6qr
+GrdarWnavCJ1HjlrB1k//90TtBj8FuFprXmbeWsHTIsXXIz3+4geCRP86ji/ZjI5jDFKGCMg+J2Y
+qxgDEuvDViiL/7BILgkurnOY70GllFLGNL9bDsvHWe9iIQcFYM5Uru5jKqNh8bTTH998kXErh+W2
+yt+8Fp2XcIOQFHAkDXSaro1XMBCQbGZbrMYhhRvTJbVeM0X1WOW6UUOwLoIBowrUGgaMrjRPKKHL
+4ww6bGm2ZaY+GcfXarNZX5E6bzBGBIDvgP9+IF700ZA0gaO1vHUDJvgLMYHhfOj8FpvBoX/zgFJK
+KYcjR1kwhhB2jX05qJSKGxxgLgeVUgDGFBlLyBGBrUREQlg9v43FqNzMu+paU4+RhRAwIP4k+eu1
+sOWo3Mzz+Qg3CEkBR9Igp+3aeOPnBNxljH806draKoUb08eAshDp9TYPHT0JA0ZVnq1iwGhL+4hB
+/LNU+kKrDDFEJJT8BAAzEwgdZ95XpM4jb+xGvtA7diNQpMSmHKqdMASkwLaFnszmLBrjgNZ045aM
+16tBpfJgUCliJMb5DT8aDSVhHwvJP2J8fgaVUgBGFLlb7pfrWTc799wKyWHRlvZZ1pv+MZUmb0w5
+dLAWNrv3+p/LzbwjL0ODax63FHAkjXCmro0jWIw/Ukrm5i/sWcxauIEx4vt/VDMILpecrQj1ZBc4
+r30Q1rgxYFTn+kEI/je7X35BBP3LeYMOb8yGyNq9FjatSE3e5l1A2cn0SVs1GCUmfc/bB0PEgPhE
+d/OJDBWMMSIDTlMX1uyhjFFghACHWzJTBEOI1oedUFU/MIxSgPiM89k/ygIALEhy7yIhR13HVIIL
+jd6YQshBjYwxevjZM4/hBiEp4Ehqdp6ujaOAhSFlKl0IvMVVbkDp7IQbhyhpz7daSL1kR9Wmyll/
+VteeAvBF6PLPXwUdEv4ipTx10OFdQCa4bmqb5zuPjLxvRWo6MjLfENeFFI09n52cHcaI3vsvs/5k
+wg1CCAk+ECngQl1xSTu8HFS6LJRcRnx5lMWE58QcDioVH83qURYAYIGTe1VZ/U1n+lydUNM+phJC
+QGdNYzemHCpG1RPdOTgCVO6Pnna62TUGY9zw1BIp4Ehqc96ujUMYPCrB+5Oorc1mNdxoI9nRN2xR
+rqs8W53lp7Wvgg7vf6uG5UOu5Ro/xYVZsPaJ6oxnddxZpRWpyaQ4YwdZL//LSX82MESkDPS060ou
+xpfmUfZBb6KDkNGHXab1TB1tTN6PMUYZY4tciDsxvh5U6sriP/xwUKmYraMsIIB5F5dNZbaUVmf+
+M885LDrjvgJ+9oej59H0jSmEEOKMQyHFFcYYrUbFo04vX2vqA6RJSwFHMnUX7do4FDESLlmaNH6E
+q9yAsviCyxRuNIXIszVTVI90N5v5p7nA+SLrwv3g/U/Vvtnmit87Keiw1g6Elr/bLjEOaUVqUhcM
+EYHDd+yYwaKvfgwioZTIadaVXIwpyvVssTf5m5uAP1JG5+5pa/LasYNKvf/JGPsTCQEE43/iAhZg
+Bo6ycMGXvPXkPCEHADCzX3qZqYkfU2n6xpRDVVE9yvu9z4vhaL3bn99wg5AUcCRTdtGujTfEsEVY
+c8/BTVsKN5oLlFi1xvxNqskMpWsSSinlQlwBzpeD8zvVvvnxuKADXfgG1NnWwqYVqUnTeWM38g+O
+Hyx6FGWQdqi0hCnNerbQXZ3K+0Ykw3m+KUl+72BQqbzClbyCiDFiJMa4r0LpjMD4RyH5RyBEa8MO
+Lg9CDluZLXnWTg4BEz+mUozKTd1p7saUQ6asBjLLPin29te7C53Vptc7aSngSKZiXF0bRzFCBuk+
+5UAKN5qNATAXwvIsblY5CaWUcimWgfOPgvc7pqh+5Up8CgDMlmZbZfqNp6FpRWrSdt4FVL3s0ntn
+7iASBjAX7wNtV43Kr7OF7iqdws1CCAGVEunYbXIixtjL7kO4E2OMEZFYF7ZCWfwHCOtyBp+2cVDp
+QchhCTljyDHpYyqHG1N4w1erxhjR2fBdRB9TuHEgBRzJxI21a+MljBEli5jayOco3Dh4Qt/ajSRC
+yiVbmX9TT3eBQ2t/HWdF2WHQAR+h9RumtIhIGGN+5GxakZrMkIiPhJLv7UpCQghMoZzkYqrKbOp+
+5+NpDYmOHgnjPB27TU6FUkopAGFw5CgLhl1j3LfEVkQQdoNzudCWQaVcyoOQw9gtqeSpQo7DYyoq
+13HcDzfasDHlULlf7QTv6cLSwr30kOdACjiSiZlE18brLx4IE/zDsX7NFpqbcOMlykisu4aLkFrd
+dIX5kuX0zjSeCDYJZYyClreoowFJ/IfMdFqRmswMV7ntbCH75DQ/Nga/RTifi/fstnKV2dQdfRn4
+9LYPBOe3mGr+zVTSTAdHWdgiF2ItIkbEeDCodDT6Dwd6SbDmDyrlUi7Z0hJCTh9yRKArGAIBPr5b
+2hgjOlN9mfW7tQxBP4uqKv3gl//5/vLHl/8/b30kjERGGCFHvsuMsUZ/3ychBRzJREyia+MoRCTA
+57vFd97CjVkhcnW3GJUPO7280dO4J4UJAb6y+5SmYCOZDRgCcsV/YacM8qOPhqQJHI3lKjvgub4M
+U25LpySmY7fJWFDGKBwcZXnZ3RFi8OEnU1X/YhilAPEZ44w0cVCpzA5CDkrcd+IU2wCFFGM/pjIa
+7jd2Y0qMEb31xFq3hQF/JYxepZpDiEhiJD/HEH+N0VMSD54HRgxFjMQfPh2khBASCTBKcvIy86CU
+RMLoJWDwESGEvH7+RslBVtK+wCQFHMlYTbRr4wiGcYNSOvMDG0+Swo12k1qvmaJ6rHLd+KcDk8AA
+7qH3OyDFct21JMlFeeM3Oku926f98ZESm25km8lbOwAtXnAx3Q6bGCMywnHeOvuS6WAAlAG8GlSK
+AYmz/issKs8pXBEcGjWoVGZyyZSWMKC7wPk7j/SO+5hKEzemhBAQfSCVcc9ojAGUvCG0Wjk8Poce
+f7LGfqe06nIp/9e7vlaMB8nHy/8iJBISyev/TUgk+PIfEfGn6OL/HA1MaCQmYDBH26kpIYQR0iNH
+Mg9GqWIvH0TXEZikgCMZm0l3bRwFLAwpU3N5IZDCjfZjQBkiv+sqvyXmZOjoUVwAs0X1Q5YCjqTl
+nPUD1e8sneXGlFFiUvdS83jrBkzwF6KGYyLBByIVzP2x22TyDgaVMgKC34m5ijEgsf5gUCmL5JLg
+4jqH+geVykwuFaX5NteEvC/kODimggT4xaYbmao5G1NCCOit27XGb1JgnAt+TeX69nG1cQUrXIgP
+nA8DX/i/6Tw78QHw4f3ZKW/Trrz8z4mOC0wO/iv+LjCJMe6iw3+dGJggoYSR+L7AhJDD0ORIYELI
+q9CEMZYCjuTiptW1cfT1FICe9Os0UQo3ZgcXwJytLjFHdkG8+8N7FkVGbgbv3/t0JkmajJL4jZD8
+TOuOk+bxLiAFti10Pau8MSBh6owrMpPkgiillHIgjB8ZVBrCrrHuW2IMF4z/iQtYqOsoi8rUzdOE
+HIKLRe/c84scXbeVHQCvd2OKcw595XcC+h8o8D6X/FPVFe/diiKkXDQj8yTr56shhMXR7v7DrJff
+n0ZQc8bAZPHlf94pHnj5D4f/9TowifFgWPcbgcnBT3wVmKSAI7mQaXZtvH7RQCBjl6fyWg1yEG6Q
++Q03IhJKag/Vx0pIvWRH1aaklMzTZhVCCJFKL5nCPMr7vFGtoElyWq5y21n/bLN0MESkbD4D+qbC
+EDESfKLyfK22InzYoHp+j90mzfBqUKl8PajUOL/hR6OhJOxjIflHjE93UOmrkCMjBOD4kAMEMFNU
+L6RW185zL1LXxpSj8zS8978KpT4EJa5zUMtn+XUwABZZ1IgYAYBl/c6Dclh8qTK9wkX7ri3pgdP8
+0BMDkxRwJOcy7a6No0J0O5SquWptfx1upMn7s0Z29A1XlOssz1bnrW2dRnIFQ4gMYK5+3Un7YQgo
+tBgwDu9s3/3dz0MklBI5qbqSs8EY0Xv/ZdavMdwghJBIhtNaR5skp3FkUOktmSmCIUTrw04oyx9Y
+JFKA+Izz6RxlOU3IQWm8ep5jKtPemHJ0ngbBaLkUf+RarijILvT3Xyp5K9iwwzRbJoSQrJfftUXx
+bUD+bzWH3WGNGSiTtIe3dhCMeyYyfRtg+q1cnNBf5mlAWwo3Zp/IszVTVOt11zFtIOSyLe2TuutI
+krNyzj8TWn16np9LGaQdKg3hS/Mo6+e1DnsOIaAQPP2ZSBqNAVCh5LJe7D3gC53bIYO9EeKz/WK0
+bspyEFzASb7+QchR/YIh7B7374HLZe/987N+3dFwf133OvcuXuHJQghoymow3N1/Wu5XT0IkeyrX
+t7N+54HQchnG8JCHC8GMMf88+v/JPL+JGC8Ve6PHr898zIfUwZGcWp1dG0dxGt28POlO4cb8ACVW
+bWWeSq1q+7s1bQwoQ4caEWMThnolyWk4awdZt/OHc30OIRIG873ivClMUa5ni73aV0FGj4QLfq3u
+OpLktBhjlDG2yIW4E+PrQaW+LF5AJB8KLq5zMf6jLCrLb4zKYrOTZYTBm0cvQAAzo+qFVPLUx1TK
+YfF1p9+9P4kj9sEFtJXd8cFvU865kPy26ohjh4SOiwD2cfAhAn8dmCitllCEu8Xu8FHW696fl06x
+FHAkp1LLrI1jYPAoBHTrev1pSuHGfGEAzIXwX77yW3yONqtQwW956zZkTcP9kuSsGIVvuTzf7Bgk
+hFxszn8yDqY069lCd7XO65lD6P0OU3Kujt0ms+PYQaXe/2SM/YmEAOMeVKqy/MZoVGx2Or8POSg7
+/TEVU5WbsqM+Hmfg4JxDV/mdENy/QB7M09BnnKdxETxTy87Yr4BnbzwoYwAsW+g9KPaL/9Za/99t
+nMtxVingSN6pKV0bhyJGwhWcqy24TVK4cZxIyIwNGX2bkHLJVubf1NPdeRk6CgDMVnYkZIzz0pmV
+tJczdjPrd889ryEGv0V4el+vU1WVT7N+d/Usq30nKsZtSmkKOJKZcDCoVF7hSl5BxBgxEmPcV6F0
+RmD8o5D8IxDiQmGH6hyGHHn/aEfC4TGV921TsZUdAHB60Y0pR4eEYsBfuRR/BC2WJegzzWYaFwBg
+xiE5qSs27+Z/NWX5PyHAltKzPZcjBRzJiZrStXEUjbhBGcz0k94Ubsw3qdVNV5T/zXL9vxpzAT5h
+DOAeer8DUqSL/KSxfAgolLQXafGNPhqSpi3UpqrMpu50rjXlSFyMERnhOC/v9cl8YYxRcjCo9E6M
+8dVRllAW/wHCupzBp+cdVKo6+Y1iWD7K+9na4d/nw2Mq77p5Dy4goXFbqPN1jR4dEkpjDKDkDaHV
+SlOOfggtPwse95hkxz4kU1m2FFxYLHb3H+oprZKtQxoymvwOxoi2rJ5SDlRk6k5Twg1CCGEx7JPm
+lDN21thN4ISmcGO+iTz7azGqHtVdx7RwAcwW5od5G4KVtAu68OS8g0UPRUpsgz5S54qrzKbu6MvA
+YerD0U8SPBKp4MO660iSSaOUUsaBCi1X9GLvAfSyWweDSv2T/fJ8g0plL7tf7JXriPjq2gFJvBpC
+OPZa4nBjisr0mcKNV0NCf9tfLwvz7HBIqO51VoUUi00JNwghRCjBXFl9864fAwKY6uVrxbB4HPzx
+Q1vbLnVwJG9oYtfGIYwRpQBoWl3jYo3d5EAvswu2zCWzQWq9Vo7Kx1knq3XC/7REoDcxhD3gx6+A
+S5I6OWsHWT+/edFjVIwSk45iTZ+rzLbI9WVo2OcrhkDYHK5wTJKDoyxskQuxFhEjYiTG+Q0/Gg05
+0EuCnW5Qqexl9/f3Ruu9fmeVMkallMve+edwzDDnYm/0pLN4unWwzjn0ld8J6H+gwPtc8k9VV6y2
+oeOBArsSQojv2s5CKWV5v7NWDkebUqp9oWergzZ1cCSEkGZ3bbyCgYBgtZxrm7SDcIOlcCN5hQFl
+XIq7rvJbddcyDVKqJVOYdz51SJI6YIzIGPyjaTfHyel4awegZQGigd8/HzaaeLmVJNNEGaPAgcpM
+3cqX+g94N1/xkv08MtV6URRPnXEYwsndHbrXWRvujR5HxHh4TOXtH1MOi6/zhc6Jg4UPujscjobF
+5u5g76Fz+Jwpsay6nQcq17eAc9qGcIMQQqRSy8GFU63MzXqdGz6GrCzLp5Oua5pSB0fS6K6NozDg
+LmP8o7rrGLfX4UZz2maTZjjYrGIvMUd2Qcx+ZwON5AqGENkYdsInybh4Yzfyhd65tqYchSEiZaDH
+UVNyOt66ARP8hVCymcc+Ixk2qb09SZqAAVAGsCyUXEbEiAGJs/4rLCrPKVwRHH43qPRlyLHeW+iu
+Hh5TOexgOGljytF5GgSj5Up8zLVcUZC1+u8kCGDVqPxVKHGqlblKq6UQwuL+b8Mv8n7nQVuCnHdJ
+Accca9qGlPcBgt9TSm7XXcc4pXDj9DASMo+3vULKJTuqNiWlZNY3q4CQy7a0T3R3Po7lJM3nXUCZ
+az2Om1BEJJQSOY66kvfzLiAT8EJo1chwI4aAnPMUeCXJOxwMKmUEBL8Tc/VqUKkvixcQyYeCi+sc
+DgaV6l5nbbi7v57n6u7hMZVu6Ap7AAAgAElEQVS3N6aEENBbt2ut/54S6rkSN1Wub8/CTf1RXIuV
+4MIel6d7OAYALF/ofl4Oiy9Vplfavko2BRxzqi1dG0cximaWJo2ncCM5LdnRN1xRrrM8W53l8/sM
+KEOH+qQVZ0kydYjrQskLd28cogzSDpUpwBAxEnwidH7ulb6TFjwSIeBy3XUkSVtQSinlQBiHFaHl
+CgaMIYRdU7lNYgwIxv8kcn2vGJVPlEPkwP9EIm4zJj8ph+W2D36bcs6F5LdVR8xcqHGUVHKxGhZf
+csnP9MAo6+V3TVn9GJD9W7V4PlCawTFnWjFr4xgYPHLB+3XXMS4p3EjOSuTZmimq9brrmDQq+C1v
+3UbddSSJM3age9lfxvY5iUgYsNZeMLYFxoje+y91t7nhBiGEIIYdDjBTg/2SZJoYMMqlWNT9fFUt
+dG6Tjlw0NP69YtH/719+sb+9+J+H1rmhcf45U2JZ9zqrOtd32jRP47wopSxSsogBz7ydTmX6KiHx
+UrE3etzW7XYp4Jgj3tpBMO6ZyPRtgAYO23qHiJFwzq7WXcc4pHAjOS9QYtVWZqYGQb0NAJg3YRSx
+nR+qyWzAEBE4fDfOwc9ICJnpK+qG8MY+zvp584+5+fgLne17rCSZGowxYsAYfDBcSqY+vJR5BlL3
+uvellivAgbbloe64SC2vBxd2zvNzhVRLMld3R7v7j09au9tkKeCYA23t2nhDDFuEslafByMkhRvJ
+xTAAhoT8l5/xzSoM4J73/lwfykkyDt7ZDZln98b5NWPwW6SFH79tYvbLx7rfaXTnxiFGqJulY7dJ
+Mm3BOTRFuV3sFuvB+meMA1W9/LboZmvdbifv/p+L9/Z29x8jnr2LYRZwIZg11Q/n/fnsYC7HWjUq
+v/PW746ztklLAceMa3PXxlGMkEHbn3RYU6VwI7kwIeWSQx+CD636sDkLLoD5wvzQ1tbIpN28Cyg7
+2VgGix4VfTTj/HrJm0xp1rMPuvfa8BDHu4BC8W7ddSRJm8QQ0BmHZlh8XQ2Lhxjpc6H1crbYWZWd
+7A6Ig6MnobJbQvJPCSFE9Ttrw2Gxfp6jGrMABL8ZvL/Qrz3rdW644ENVVX8bV12TlgKOGTUTXRsv
+YYwoOG11a9lBuMFTuHERkRAGs3FM6aKkVjddZf4ZZ/ipRAR6E0PYq7uOZA5FfCQnsFY0UmJb/DHW
+aFVVPtX9fLUtHREYAgF+cAOWJMnJggtYjapBsVusm8o/owB7opvf0gvdB0LLFfbW0ZMYArLIfju6
+bl718vvDovhulh8MnUQquWgL++SiX0dptQSMfzLa3X/Yho6YFHDMoFnp2ngFA2HAPqi7jPNK4cb4
+UEpbf0xpXESe/bUYVY9mtctBSrVkiyoNG02mylVuW/eyTybxtRklZpa3INWlGhWbutO51qqhgT5s
+UJYuwZPkbTEEDMZhNSo3R8PiIcb4XGZqMVvIV3Uvu8MlX3xXd50rzY7O5O+OF6pOfmNUlr94N18h
+BwNgkRIYRygBAljW7zwo9oqvmv77mN5dZ8gsdW0chYgEeDsnz6dwI5kkmeu1qqgunMw3VqQfYwuH
+WyXthCEiV/wXNgsPBuaEq8ym7ncuQ9s+Y2Pcb/ux2yQZl+ACVqUZlHvFujH+SQTYk3m20jnapXGK
+ADPGiAzJT0e7N46SnfxGaaufvXXb4/9VNJeQ4rNgzzds9Dj5QueOt9XP1pjGzoNLAceMmLmujSMY
+xo02ZjUp3EgmjVHKuBR33YwOHQUhl2158dbKJDkNb+yGzNTtSXxtDBEpAz2Jrz2vXGW2Ra4vwxg3
+3UxDDAE5F2pWHkIlyVnFGF93aewWDwOGvwslF3U/X9XdbO19XRoncaNyR71nOLTIspuFD7kzdiav
+m44jlGDGmH+O82vKPL8ZMF4qR8VX4/y648LrLiC5GIwRfWWegRLXOPA7ddczCcDCkDLVqguBFG4k
+08IAmAv2EnNkFwSfqSM8DCgLDhcRMbaq/TxpHe88qn5naVIzHBCRUErkJL72PPKVHYCWBQh+pe5a
+zip4JELA5brrSJJpCiGgs343+vA9oTQIJZdlrldO6rY4q8PuDeDw3vcEqeVSVVkSjd2SSrayQ/ys
+ANjHwYcIfDy/34QczOXAEBZHv+09zHrd++MezH0RqYOjxWa5a+MQBo+cg6q7jrNI4UYybULKJVu5
+X2ZxgBYT/Lq3Ls3iSCYrxHUhJ3uzTFm7Psuayls3YIq/EBMYBDsNiGGHAyzXXUeSTFKMEYNzaEbl
+9mi3eBj8QZeG6uW3s35nlStxZVzhBiGE2Mruqiy7cdofL7RcshEvVaP2bAa5CJmpZTeBaykGwLKF
+3oOiKL9u0lyOFHC00KzO2jgWEsI5XKu7jNNK4cYkpVEM7yI7+oarzD8iztbQUQBgzngzyxtjknq5
+ym3rfn5/oi+CSBi0c5ZUk3gXkAl4IbRqZbhBCCHEx1/S/I1kFoWXa1zLYfHU7FfrGOnPItfLnQ+6
+D2SmbwEHOrFuTOe/AXG2a28u5VLg8Mlor3g8kZoaBABYcGE0qQ0oeTf/q3N2z1TNmMuRAo6WmYeu
+jaNCdDuEsVa03adwI6mbyLM1U1TrddcxbgD8M+/HNyArSQ5hCCi0GLAxtu0e+zqEkHRLezEYAkYa
+H7c63CCEMEJdW9bZJsn7vOrSGJZfBOufMQ5U9fLbeqHzQGi5PM4ujZOYyg5yfb7tVyCAsUzcHe2N
+Zj7kkFrcQ497k/r6KtNXGYM/FXujx3Wvkk0BR0vMVdfGEZzQX9rwS7VVCjeSZgAlVm1lntZdxzhx
+AcyN7I+zuhI3qY9z/pnQ6tNJv04Mfou04LOsqTBG9B6/1J1ssp02E+ZdQKF4t+46kuS84ssuDTMs
+vq6GxUOM9LnI9HLezx/ITnYHBJ9cl8ZJrPsG5Pkf+lIAxjr67v7e8OEsX2dwKYirzN8n+RoggKlu
+drfYGz2u89h0GjLaAt7aQUTyvcj07XkJNgg5uKARNDrKmv1rtlW1yXkKN5JmOBg6Gv7LV36Laz47
+LfGcrGAIe8Bna5BqUh9n/UB3O3+YxmdM9NGQNIHj3Lyxj7OFbqvDDUIIiYgEhJh4oJYk4xRcQO/s
+TnBxm3HgXIlroituNWGopDMOz9u9cRSllPFu58He7v56r99ZncXB5pRSFim5FEKIMMHOGkopyxe6
+a+VwtCml2hdaTH3mUOrgaLB57dp4BQNhAhr9pMNW1aYQKdxImkVIueSC18H7xgx8uigp1ZItqjRs
+NBkbSuI3kx4seihSYuftI3xczH45E+EGIYSg81uUpUvvpNliCK/XuO4XX2CMz4XWy9liZ1X3sjvn
+XeM6CcHYJ0zA2B58qH5nbTgsaj9iMSlK6+vBhefTeK2s17nhY8iqopz6INf0LttQ8zZr4ziISDiH
+xj7pOAw3KKRwI2kemamrrrL/nKkP6Ug/xhBm59eT1MYZu6l7nQfTej1GiWl6N2ITmdKsZx9079Vd
+x7iwSH5NA0aTJgouYDWqBuVesW6MfxIB9mSerXT63c+FliuMA23ag9ZgHOZKXxl3XaqXrw33y6fB
+48w8JDoEApir7K/TOoqjtFoCKT7Z/234xTSvR1PA0TBz37VxBItxo6kXAincqEGMaUrfGYk8+2tV
+VI9n5UwpCLlsS/uk7jqSdvMhoFDSNuUJZHI8W5lHup+vzspAzhgCAgeY5+u6pDlijK+7NHaLhxjj
+c5GpRd3PV3U3W2tSl8ZJnPVPQExm5bLqZnf3y+KXJq0+HReuYAVDmNrrAQDLF7qfl/vl02n9fqYZ
+HA0yr7M2TsJi2CdU1l3G76RwI2kTkel7VVE9yTrZat21XBQDyoLDRUSMs3g+NpmO6MIT0cmn9vcB
+Q0TKQE/r9WZBNSo2db/751n6ex4wEiGmcyQqSY4TQkBn/W704XtCaRBKLss8W2l6kHGc4BxmQl6d
+ZACqOvmNsiy/zYgmfIzHYOompFw0I/Mk6/OpXhdmvfyuGRU/BuT/VkpNdEZc6uBogNS18XsYIwoB
+qmm/FyncSNqGUcq4FHdd5Ruxm/yimODXvXVpFkdyLs7age7nN6d5XAQRCaWkeWl9Q7nKbOp+5zLM
+2GwrdG6XA3xUdx3J/Hi7SyP48Heh5KLu5bezfmeVK3GljeEGIYS4yj8BOfm/TyLLbpbW/uyc/27S
+rzUtDIBFFjWG6R9hVp38KiHxUrE3mmh3cQo4apZmbZzAB8IE+0PdZRyVwo2krRgACyRc8t5t113L
+RQEAc8abOEuzRZKpwBiRMfgH8Ol/1lIGaYfKKbjKbIpcX67jezRxgXxP2nkvmbRICAFdabAcFk/N
+frWOlP4sc73S+aD7QGb6FnCgbT/2FVxAzXlnWh1eIlM3S+c/tMbOxIMiQgiRSt4KLuzU8dpCqiWZ
+q7vF7v7DSYUsKeCoSeraeDeMuMtYc550pHAjaTsh5ZIr/ajOveTjAsA/876eD+akvax1W6qTTX8b
+ByJhwGZnZfOE+MoOuJYUxAyGGwfMLB25SZojOIdmVG6PhuUXwfpnTAqqevltvdB5ILRcZhNcCVqH
+UJkNrqa7bllquWQCXrLVbIQcXAhmTfVDXa/PAFi20P28HBXfeTv+jX8p4KhB6tp4PyD4fVMiH1um
+cCOZDbKjb7jK/CNiu4eOcgHMjeyPszI8NZk8HwLqTNE62rGRpPnI7+OtGzDFX3AlV+quZRK8C6iU
+6NddRzIbYgjojEMzLL6uhsVDjPRnkevlvJ8/kJ3sDghOZzVMCyGg4KKWX5/QcskSeqksyqfTfu1J
+4ABXg693M13W69xwwQdTmbEGRyngmKLUtXF6jKJpQgudLatNIVO40QiRkHSbcHEiz9aq/fJh3XVc
+GCcrGMJe3WUkLeFxXShZSxdFDH6LpI/7E3nnBkzAC6HVTIYbhBASEQlw3ti190nzBefQFOV2sVus
+m8o/owB7opff0gvdV10a83BfEQqzIeR0uzeO4hKWUPDPRnvF47pqGBeeqWVn7Vd116G0WmIM/jTa
+3X84rlWyKeCYktS1cXoYPHLBa3/SkcKNZFbxTN63lWn1Ewgp1ZItqjRsNHkvZ+xA97K/1HXxH300
+dbxuG2AIGCn9dpbDDUIIQee3mrr2Pmmmwy6NalRuvuzSeC60Xs4WO6u6l93hki/OapfGSUIICJS5
+ugejAgBjmbg72hu1OuQAAIYOybhChQvVIoBl/c6DYlg8Hscq2RRwTFjq2ji7iJFwDrU+6UjhRjLL
+GABDQv7Lt32zSqQfY6i3vTJpNgwRgcN3rMahlZESmz76fw9DRO/xS13HXJQpY5H8Slm65E7eLbiA
+1agalHvFujH+CQXYk3m28rJLY4Xx+ejSOEkozY7K1Gd110EIIRSAsY6+uzvYe9jm47JCy8+Cx8Z0
+w+b9zpq31c/WXOzISnq3naDUtXFOMdTazpvCjWQeCCmXHHod/PiHO00LCLlsS/uk7jqS5vLObsg8
+u1dnDYwSM821tG3hvf0y6+erddcxaTEEpHBwfqDuWpJmeWON637xBcb4XGZqUffzVd3N1rjki3V3
+KzRFDAEZgZ+aNDCVUsrUQvfB3u7+4yZ0QZyHUIK5svqm7jqOknl+M2C8VI6Kcx+fSQHHBKSujYth
+hAzqauVM4UYyT6RWV11l/9nWD2YGlMWAi22tP5ks7wLKTqbTDULzmP3ycdbvzny4QQghASMRkl+p
+u46kGYILWJVmUA6Lp9Wo+jK+7NLo9Lufv+rSmLOjJ6fhSrOjtKw1rD6J6nfWhsPi8aRWnk4aBXYl
+NKwbVmm1xJX8f/d/G35xnt/XFHCMWerauBiMEQWntbTgpXCj2WLAtBZ0AkSe/bUqqsdtbbFkgl/3
+xqVZHMnvIa7LmrdyYIhIGeg6a2gaU5Tr2QfdRt6oTAI6t8uhOWvvk+l6o0tjt3gYMPxdKLmoe/nt
+rN9ZTV0a7xdjRIbkJ+DN6d54m+rla6NR8XXwF58fMW1SqWVnm3cdBQAsX+h+XhTl12edy5ECjjFJ
+XRtjgoEwYB9M+2VTuNECnP5adwmzSmT6XlVUrTzqAQDMW29i6uJIjnCV29a97C9114GIhFIi666j
+KWxlHumF7upcPaEO5HsyR7/c5GAYpisNvurSYGxH5nql80H3gcz0LUhdGmfiRuWOqvmo4WmIbv7X
+UVn+Mo4hmdMEAlgwftTUbti8m//VObtnzjCXIwUcY5C6NsYHA+4CZ1Nd5ZfCjWTeMUoZl+Kua+nQ
+UQb8M+9D6vBJCCEHXRNc8V/qHCx6FGWg6q6hCapRsSk72Z/nbfMDIcTM4a95rsQYMTiHZlRuj4bl
+F8H6Z0xJqg67NJS40qTZEW0TMf7Q5O6No2Qnv1Ha6ue2hRxcixVs0LDRt6lMXyUkXir2RqfqOE4B
+xwWkro3xYzH+OM3fRldUj4QSKyncSOYdA2CBhEveu+26azkrLoC5kf2xrcdskvHyxm7ITN2uuw5C
+CCGIhMF0Q/smqiqzqfudy8Dn67M2hIBKidrX3ifjF16ucS2HxVOzX65jpD+LXC/n/fyB7GR3gANN
+wdbFmdIM8iz/pO46zkJk2c3CmuCMbc1DI6nkoqvMt3XX8S5CqiXVze6Odvcfv29mCJ9WUbPGWzuI
+SL4Xmb6dgo3xARaGlKmp/H66onrEtVhLbYJJckBIuWRH1QuasV3gsFB3PWfCyQqGsAect6vuZKy8
+86j6naWmvK8jIQTqLqJmrjKbOteXoSEdNdOEHgkT/GrddSTjEZxD7/xOcHGbceBciWuqJ26nIGOC
+nP8Gsuzzuss4K5nppaqyJBq7JZVsfMhNKWWRkkUMGJs8E4ZSyvKF7lo5HG0qrTpcimMHOKcOjjNK
+XRuTg8Ej59Np5U3hRpIcT3b0DVeZf0RsVzeElGrJFlXjhmQlUxbjoyZtrIjB17r2vG6+sgOuJQUx
+f+EGIYSg81uMsRS6tlR82aVhhsXX1bB4iJE+F1ovZ4udVd3L7nDJF1O4MTmmsoNcZ63q3jhKaLlk
+I16yVTs6OaSW1733z+uu4zSyXueGCyGvivJvx/37FHCcQZq1MWFICOdwbdIvk8KNlkKSvl9TIvJs
+rdovH9Zdx5lF+jE2bNVZMj0vB4s26mI4+mjqrqEu3toB0+IFr3mTTZ1ojAPK0qV2mwQXsBpVg3Kv
+WDfGP6EAe6Kb39IL3Qev1rimh5vTUbl/gGz3/RaXcslR+qfRXvG47lrehwvBXGVetOW4r9JqCaT4
+ZLS7//DtAanpXfcUUtfGdITodsiEn3SkcKPd0t+86eGZvG8q81XddZwFCLlsS9vKbTDJxWAIKLQY
+sIY9fIiU2Hm8ZPDODZjgL8QchxsxRmTA081ww8UQXq9xHRYPMcbnMlOLup+v6m62lta41iMYh1mm
+P667jnEAAYxk4u5ob9T8kEPymxhC3WWcGgCwrN95UO6XT48Odk0Bx3ukro3p4YRuT/I6IIUbSXJ6
+DIBFRv4f36LNKgwoiwEXMTRz1VkyOc75Z0LLT+uu422MEkPZfN3gYggYKf1WaDW34QYhhAQfiBQw
+9bX3yfsFF7AqzasujQiwJ/NspXO0SyNdK9bKGfsEJF+uu45xAQDGOrrxIYeQctEW7XtQlPXyu95W
+Px+ukk0BxwlS18Z0YYwoWMRJXQimcCNJzk5wueTQ6+B9a9adgeDXvXVpFscccdYPdLfzh/T+Xj8M
+EQPiE93J7tddS93Qh13GeeOHC86DGOPrLo3d4mHA8HehZOrSaKjgHGZSX521ey9KKYNutjr4bbj+
+9pGKpmAALFICTa3vXWSe3zxcJZu2qBwjbUipAQZCOfQm8aVTuJEk5ye1uuqK8r9pzv5XG4apMQBm
+K2OEEjH9nZ8PlMRvhOSNm7KPISJloOuuY5q8t19m/e5a3XU0QsAfKaOp87cmIQR01u9GH74nlAah
+5LLM9QoDSJ8LDecq/0R3stW665iUrN9ZG+6N1nv9zmoTr6uEFJ8FG3aYZq3roBFSLQGEu6mD44jU
+tVEfRCRcwNjbi11RradwI0kuRuTZX6uietyWwVMM+Gfeh52660gmz1RuW/c6D+qu4ziISCglsu46
+psUU1cOs353Zm5Izi2TYxJuXWRVjxOAcmlG5PdotHgbrnwklF1Uvv531O6tciSsp3Gi+4BxmQl6d
+9et21e+sDYfFevDYuA5ZoQSrTPVD3XWcFwNIo50PpVkb9WIxbow7T3oZbqzO+pvk3GjFrfXsEpm+
+VxVVK85lcgHMjeyPbQlkkvPxIaDSYtDk1nLKprP6vG6mKNezxe7cH0s5FEJApUS/7jpmXXi5xrUc
+Fk/NfrWOkf4scr2cL3buy052BzjQFDK1S6jcBkj4qO46pkH18vv7ZfFL8KFxIYcEuBp8e7fSzX3A
+kbo2moHFsD/OICKFG0kyXoxSxqW469oydJSTFQxhr+4yksmJLjwRWjVusOgriIQBm/kZDLYyj/RC
+dzVdP72GHgkDuFp3HbMoOIemKLeL3WI9WP+McaCql9/WC50HQstlBmmNa1sFF1ByMVehlOrkN0Zl
++cvRDSBNwDO17Kxt1Sa9o+Z6BkeatdEMGCMqMb6nXAfhhlydt8n1STJpDIC5YC9RH7c5F1fqrudd
+pFRLtqi+yPrdxs1mSC7OWTvQ/fxmk9/nkRACdRcxYdWo2MwWemvzdENyGuj8FpvjFbnjFENA75Gg
+dRuRkH1Q8kOh9XXZYcvp2n22hMpsqDy/VXcd0yY7+Y2yNN9mkQ+5bMa1FQCwyqFHxNjG9/e5DDgw
+RvSVeQZKXOPA79Rdz9zzgUDGLo/jS6VwI0kmS0i5ZEfVC5qxXeCwUHc97xTpxxhCTOeuZwvGiIzB
+P4DzRs7eOBSD3yKcz+xNblWZTd3vXm7yEaG60BgH6d77/IIL6J3dCS5uMw6cK3FNdMWt9GdtdoUQ
+UHBB5/V7LDJ1s6js/2QxbgklG9H5J7W4hx73mGTNvtY7xtwdUUmzNponRLdDKVx4Um8KN5JkOmRH
+37Cl24oNXyMGQi7bwrRibkhyesG6LdWCNaTRR1N3DZPiKrOpc30ZOKTrqLfEGJEBp+mI7OnFEF6v
+cd0vvsAYnwutl7OFfFX3sjtpjevsC4XZEFI098jhFEgtl6qAl6yxjTgKzKUgtqy+qbuO85ibgCPN
+2mguTugvF/12pHAjSaZLdtSdar96VHcd78KAsohxEUOzg5jk9HwIKJS0bbjZiZTYWbzU8JUdQKY7
+INJDouMEH4gU8EHddTRdcAGr0gzKvWLdGP8kAuzJPFvp9LufCy1XGIcUEs2JGAIyCmUb3tcnTWi5
+ZCNeqkbV3+quhVLKKKNLIbRv2OhcBBypa6PZGEVzkWAihRtJUg+e6TVTVI/rruNdQPDr3rqNuutI
+xsTjusgaPFj0CEbJhT7bmshbO2BavBCSN+KceBNhQMI4b0SLeZPEGF93aewWDzHG50LJRd3PV3U3
+W0tdGvPLlWZHZ/Je3XU0BZdyKUj4ZLRX1H59JbW+Hlx4XncdZzXTAUfq2mg+DB654OdepZbCjXmT
+vs1NwoCyyOl13+DNKgyAeetN04/TJO/njB3oXvaX9FleD2/dgAn+QqThme/mwwZN9+mEkIO5ClVp
+BuWweFqNqi8jYzsy1yudD7oPhJYrkLo05l6MERmSn9KsrDcBAGOZuDvaG9UacoAA5ir7a4yxVddQ
+MztkNG1IaYeIkXAF53oal8KNJKmf4HLJVmZEPdkFzhs5iIoB/8z7sCMku/Csn6QeGCMCh+8Y56t1
+13IaGCJSBrruOsYFQ0AC9HuhVRrM/j6RDNu4dWAcYoyI3hNv/Y738V9C855Q8lOW0dspyEiO40bl
+TpZnqXvjGBSAsY6+uzvYe9hf7N2v636WK1gJHve4aPhg+SNmroMjdW20TAxb5BzfohRuJElzSK2u
+2tL9gg3tkuACmBvZH9v2BCJ5zRu7IVt0EYyIhFIi665jHDBEDIhPVJ6lcOM9QggoBB/b2vs2CCGg
+Kw2Ww+Kp2a/WMdKfRa6XOx90H8hM30pdGslJDrs3gKfujZNQSpla6D7Y291/XNc1lpBy0ZXVt3W8
+9nnNVAdH6tpoH4j461lbOVO4kSTNIzv6RlWU61knW23i+y8T7B6GsNfULpPkZN4FlJ1Mt+18PmXQ
++htdjBG9t19m/e5a3bW0QfRIuODX6q5j0oJz6K3f8Uh+EJwpkOK2ytTtee1cSc7HVnY3z7IbddfR
+BqrfWRsOi/VeL1+d9t8zBsAiIxoDxrZ8Ds9EB0fq2mgnjBG5ADjL98sV1TrPUrgxn6Ktu4Lk3USm
+71VF1ci1rFwIZosqDRttI8R1IUW7hjYiEgasXTUfw5VmPet3W3EsqAnQ+x0GbOZC1BgCOuPQDIuv
+q2HxECN9LjK9nPfzB7KT3QHBaQo3kjNz/hsQadX0aalevjbcL58GH3an/dpSyVvBhZ1pv+55tb6D
+I3VttBgGwjg79Sq1V+FG+j7PJ8pMmjHabIxSxqW464z5m1DqVt31vC1G8mcMIaZhZu3hjB1kvbx1
+g0WREAJ1F3FBpijXs8Xe/brraJUYtymlMzHrJ7iA3tmd4OI248C5EtdET9xKQUYyDqY0g1xnn9Rd
+R9uobnZ3NCo2c52Rac7E4EKwUTH8QWjRive31nZwpK6N9sOAu8BP94QrhRtJ0g4MgIVIlr1323XX
+8jYu1KItTCM7TJLfwxCRS/E94+1b7x6DP9d8qaYwpVnXC930mXsGMUZkhGNb500cdmlUo3LzoEsj
+PhdaL2eLnVXdy+5wyRdTuJGMjfPfgGzfe3sTyE5+o7TVz95Nt5ODA1wNPrRillkrOzhS18ZsYDH+
+SCl975tbCjeSpF2ElEt2VL2gGdsF3pyp2wwoCy5+1KZzpPPMG7vRWerdrruO84g+GtLSCRzVqNjM
+FnpTP+fddsEjkQo+rLuOswguoLNuNwbcpBwIl+KmlGIlvT8mk2Qqm7o3Lkhk2c2iMD9mRPxvIfhU
+VnfzTC27yjwDnjf+czcLKKcAACAASURBVLlVHRypa2O2AAvD9z3pSOFGkrST7OgbrnLfxYZtVgHB
+l711aRZHw3kXUPWyS619Gk6JbePHVlWZTd3vXk43uGeHIRDGeaPnrsQYMbzs0hjtF19gjM9lphZ1
+P1/V3WyNS76YvvfJpEXrNlmLVo42lczV1dL5D62xW9N4PQBgiCQ2dWPeUa3p4EhdG7MFg0cleP9d
+PyaFG0nSbiJXd6v98ousn39edy2HGABzlcGoRGzrzfNciPhIKNmYPzdnxSgxbRuG7SqzqTv6MvA0
+9O9cfNigmjZu9lBwAZ33u9GH7wmlQSi5LPNshQFL2yuSqQvGYa70lXRtPx5SyyVrLSGV3ZJaTjxg
+FVJ8FmzYYZo1ehZH4zs4UtfGjEJCOLCrJ/1rMyoep3AjOSqSxgfGyTF4pu+bonpcdx1HUeC3vG/P
+NPB54yq3rXupfXmafGUHkOkOtHDeSWNEMmxC98MbXRq7xcOA4e9CyUXdy29n/c4qV+JKE+pM5pMz
+9gkIaPTNcdtwKZcsoZeKYbE+6dcSSjBnzL8m/ToX1egOjtS1MbtCdDuEqWPf4MyoeCxzfS99z5O3
+pT8T7cOAshDpdV/5La6b0b7NBTA7Mj9ywT9Kf6aaBUNArvgvDPidums5LwwRKQNddx2n5a0dMC1e
+CDmdc9yzKIaAnPPavuchBETriffhGSXUghJ/lLleSRujkiYJzmEm9dXUPTl+XMJSAHJvtDd63Ol3
+JrramwK7EkKI0OD3l0Z2cKSujdnHCd0+7tuawo0kmT2CyyWHXgfvp767/SRMsHsYwl7ddSRv8j48
+k5lq/ACzd0FEQimRdddxGt66ARP8hVAyhRsXEDwSIfmfpvqazqEZldujYflFsP4ZU5KqXn5bL3Qe
+CC2XU7iRNI2r/BMu4aO665hVAMBYJu+O9kYT7ZqVSi070+xZZo0LOLy1g2DcM5Hp2wCpVXIWYYwo
+WMS3zyebUfFYdbJ0LCVJZpDU6qot3S9NGU7FhWC2qBr9AT1vnPUD1cn/MAtP9yiDxu9QwRCQAtsW
+WqVw44LQ+x3G2ESHJoaXa1zLYfH0YI0r/Vnkejnv5w9kJ7sDHGjafJM0VXABNeedWXh/bzIKwKCb
+re4O9h7GGCdyvQUCWHBh1JTrueM0JuBIXRtzBANhgr+xSu0w3KirpCRJJk929I2qqB5P6kP3rGIk
+f8aW7HSfB5TEb4TkV+qu48IQCQPWiONYJ8EQMSA+kblu3FDMVopxm07gvi04h6Yot4vdYt1V/hkF
+2Dvo0ui+6tJI18tJG4TKbHAlPq27jnmhFroP9nb3H08qhOCKr6DHxnbBNiLgSF0b8wURCfDXF38p
+3EiS+SEyfa8qqid110EIIVypRVuaRtQy70zltnU3f1B3HeOAhJAm33FijOi9/1J387W6a5kFMUZk
+kY1lK1N82aVhhsXXL7s0ngutl7PFzqruZXe45IupSyNpm+ACCi5Sh9GUqX5nbTgsHmMYf8ghlVx0
+lfl23F93XGoNOFLXxnxiMW4cfqtTuJGcGmJ6f5gBjFLGpbjrjPlbE2qJGD+axId/cnoYAiotBozP
+xsyAGPwWafDljC/No6yfp8/dMQkeiVC8e+6f7wJWo2pQ7hXrxvgnFGBPdPNbL7s0VhhPXRpJu4XK
+bAiZujfqoHr52rAovgs+jHUGGqWURUoWm3r9VNsWlbQhZX6xGPYpUzSFG8mZMNbIN9Hk7BgAcyEs
+U+t+4lLUui4OBF/21m3ITKVW/Zo45591O3mrB4seFX00pKETOExRrmeLvZnolGkKDIGAUqe+eYsh
+IHokzvutEON/pJT/h8zUdcroappPkMyaEF52b6TVxLVRnfzGaFRs5jojXMDYZgVJLa97559LkI07
+kjn1Do7UtTHfMEYUAlQKN5Jkvgkpl5wPw3E/VTgrBsCC9RgbPCxrljlrB3m/c+3todNtFimxTby0
+MaVZzxa6aZD3uPmw8b7f0uACVqUZlMPiaVXaLyPAnsyzlU6/+/mrLo0UbiQzKJRmR0ieujdqJjv5
+jdJWP3s7vm12XAjmjHnRlLlqR0014EizNuYbxohYWTT7RZHCjSRJpFY3XeW+qztcoMBveR926qxh
+HmGMyCh8C3y2rgcYJaZpgU1VmK91L08dApMQ4/7bT6djjBiMw2pUbo52i4cBw9+Fkou6l9/O+p1V
+LvlieqKdzLoYAjICP6WVxc0gsuxm4X1wxm6N62tyyW9iCOP6cmMzlSMqGCP6yjwDJa5x4Hem8ZpJ
+/TBGJD4QF8JWQDZglBEf6f/FCYjhbvVQAO1yxT5lwAljtBEDb5MkmS6Rq7vVfvlF1s8/r6sGLoDZ
+kfmRC/5Rero9PcG6razfTYMuJ6yqzKbuZR+nG+rxiyEg50IRctCKj9YT78MzQmkQSi7LXK+km7tk
+XrnS7GQ6u1d3HclrUsulqrIkGrsl1cWPlggpF83IPMn6vFEPricecKRZG/MDg8eIkfiAWxjpfyIB
+BVJeo8BWOKWEUkppCBgi+TeV4s9ISb/yuEsq9y0jyIVgfwIBCwwghR1JMkd4pu+bonqscl3bByQT
+7B6GsAecj+18anIyHwIKJe2s3XRjiEgZ6LrrOOQqs6k7+jJwmKkumaawpcHoPGCID4UECUreVhm9
+nbZFJPMuxogMyU/Aof2rv2eM0HLJWktIZbekvljIwQBYZFEjYmzS+97EAo7UtTH7XgcacQMjGUbK
+FRf8GgW2ApSuHBtoMUY458xVYUvl/DYwvkiAr8UYo0UksXBfEeKNYPGPoPhHnPMUdiQH3UDJzGJA
+WYj0uq/8Fte8lmFVXAhm96u/Z4vdNIBxCtCFJ6I7e5s8EJFQSmTddRBCiKvsgOf68qwdAaqbdx7R
+uh2M8V+M0A9ZpgSJhALnn8GMbAJKkotyo3Iny1P3RlNxKZecC4tur3jcueBWLSHkrWDDDtOs1qHx
+R00k4EhdG7MJg0dEJMGRDaRkP1LZAwGfUqC3+ClTO0YpCxgqofV9Z81XUok7hJCD7g4AQgDuxBhj
+wEicCVtxVP1HCHqJC7jOOBBG01GWeUVJeiuZZYLLJVuZEfVkt64uisjITfQhzsq60qZy1g6yfn5z
+Vq8PKIPad6h4awegxQsu+ErdtcyCo6GGyvSHst+5zgCuuNIgl4JSRkmwfqfa2/+RS3lDaflB3TUn
+SZ0ixh9S90azgQAWGbk72hs97vQ75w45hBJsf3f/n0LXuxXvqLEGHKlrY3ZgjEgwkBBwN4T4PUFm
+UYgeB/iU6tMHGsd+bUKBMvb/s3dv7W1cx97g16pah+4GQFJUZrKHpOxJHImyLSbPWLJE23czV+/F
+7M/0fjlJlGRrnji0E4XOfrZtickbJ5Z5ANC9DrXmgqJEUTwTQDeA+l0lFAW0RbDRqK76lySJv42R
+thDhrQ8zUkopUApEuCG0vkFEqfTxhSj9C5CExsAngCh4lIWxyWIye811y2e2BTN1tDoqY+dcv3qc
+dSavs6ApKCVCxL+iata87sAQCUCsdWVecP4laPWTtoaLG5cQfCRy7p2ixsHvIYp/ElL/XgJIlZlF
+tHoh+ri1u9O9rwA/soWdlXxjhk2Zql+9LPLi47qPg51OIgK0sk93t3cetDrtzy5640EjvBdDTE3p
+YhtYgYO7NsbbWwWNkP4mJLiE5leIcB2UvC0BJA7qyQAKkZJQxs67XvdBlusTf6EkgESAJaH0UiJK
+VUwiVf4rED6gFktaqwVAHmVhbBKYVrZc9vpreSsf+TrLvQ6ztECR0qRlQzRFqNx6MduZ2LZlEkIM
+7L3yAoKPJBGe68yu1HgYY+ssRY2DEgkpDnQXSimlMmpOGfUFhZh6vd5jleSiyu0C8k0ZNi2q8GfM
+cx73HBNSSlDt1ue/bO2uzc607l3kBpPK7aKv3Feo8kY0OFy6wMFdG+Pp9YYTipsxwnMphZRaLwGq
+BdByqEUqkHJJvFoKqWy2Gl21rqw+08WYhFe79w6OsvTjhkzVT4jiVzzKwtj403l2t+qWa1k7/2zU
+z41aLQbn103OHxAHLfhIppVnk1w8SjFsCFXPWAjFREnQY1sUvJnmHM5b1HjHMa9mUCjzTusexZhC
+5dd9v0zamluoNV+fsIlVle5lUeQf1X0c7Pzymdbqzk5vrdMpzl3kQEQoPYWmhI1eqsDBXRvj46iV
+rVKrJamyRWXk4ih/flLCXBJJSLGXvuuCnJNHjKqc/jgHRlnEm1GW1PM/IJIxFj/hFbSMjR+QEoTV
+91xV/cnY0RYaABF8WVGyOskGvElPFKI1bfTIi1ajlEKqRA0JHJQShRCe5DNc3DiL4CNR8JsUaa+o
+0Wldh4vkBSThTjtJAKKEAleIKIUqbFQ73Z+tMXfRcqGDTSDnv8WZrLa17+xybKdY3dnpPWy3io9Q
+ne9zmcn0XQq0DeZ8f28YLlTg4K6N5jvLytbaDg5AxEjrgLgihBDG5tfOMqpymsOjLK9W0H4HgoJW
+sIwGZnmUZUwlIeCcBTA23gARfIyLdWxWkahWQoib2jQnEXzc+cq9zDvFR5N+MyRJ4er4Twz96mF+
+pcMfKk7wTlGjVVysqHFAEqISZ/x5A4CE3NxQVqXo44tyZ/cHVPrDLLccSMomQqw85TZ7v+7jYJdj
+O8Vnu93es1aWC6XxzNfe2hrobe1+q0y79hsZ5y5wcNdGM11oZWtdAIRw3gmhX3/pvKMqp9nLDIE5
+gepOSil5SqLqx41E5b8Mivd4Be34kbA/2MSmhTZm3pXVP2WQW6jO/iZ7WUojuG71o9JqoVHnzjFF
+MREq/CtMarDoASBFJWG0r5mq11/L5zo8736EYRQ1DkoinfuGkQSQysKSsnop+PhLd2f3gZLwnsnt
+guScDjbGfOUeZ532xJ/np4FtFcu9bu9ZIc5X5JAISzHGhFhv2OiZCxzctdEsg1jZWpf9VbFvfe3V
+qApE2hr0nfrDoyyRKLkqbopu+b1G2VYWbvEoC2PNZDJ70/eqJ1DIO6McGQENd2OM26qmlbWTJFRu
+vbgyucGidar61Vo+2x55IG+T7Rc1REzf69z+b6ZVXJcIIx3FPSulcU7Ntj+nEFPZd4+kSFe0sddR
+c6GDjZdYecpNdq2Jv2fsYkyrWO73q79kQv8vfcaV48baxejjd1jzNrEzFTi4a6New1zZWh8pU0rp
+4OvJ2PxaNYBRlVOfGUAqgEWh9SK9GWX5CwgSWsMyapzlFbSMNYcu7Ke9bv9Bq1OM7C610hp8r1xX
+M21u+7+E4CPZTn51koNF91FMJAGzUT1f2e1/nc+173FWTD1FjZQSwYAeHxRK28lXKVIKlVt3ZVmZ
+zHzCgaRsXHgXHmetnLs3JozO7c1+6X4WRBvamlOLFqgRym7/39rq39VZMzixwMFdG/UY6crWmpCE
+tkhJHJ5dVTZbjb5aV2YwoyqnOTDKsppSSo5IpJ7/SohQaUjv8ygLY81gsmy16pWPbJGN7AIqCfEh
+hZigIXvdx1Kih9qaqSgSEZGQUphRPFdZVs+ymdZ7TUirr0uMkaJzWyKKb3VWQ6cGkZAKOoN8SECQ
+UGQrRJSiC5vl9u6Pxtq7mgNJWYNF7ynX5hoXWyeTycx8WTqRSrdhstOLHMrijRho+zyjLYN2bIGD
+uzZGp86VrXUBKa4clagwzFGV00gppUR8s4I2JeGruJG65b+0lld5BS1j9QGUEJO8PsrQUWXsnOtX
+j7NOwXelLsCX/nk+m39c93GMkgQc+g4VX1bPslb2a1Q4N+znapr9okaK6ZmyWmWt1m2J8Hkd10kk
+hJDH7Yi9JACQkJlFtHoh+ri1u9P9Rin1kc3MrORrENYwsfRPbau4XfdxsOHRmZl3LorY63+ZF/mJ
+TQ8my+bKnd4TpVu1XTu9U+Dgro3ha9LK1rpIwMX9VbGH7Y2q7D7IC1tbaJqUUgopBQLcEPrVCtq9
+UZZnIAiNhU8AUfAoy4gkGtqFJBsfWpl570ohg9jCEWRj7OUFpQWKlKZhxGKQKEZSVv0Dpuk6gkjA
+kOeOfVk910X2a1RqaoobxxQ16s8d2atwDJWUUiqj5pRRXwQff+n1ek9UkosqtwvI1x+sAaKPZJS2
+09xNNi2UwfkYxVx3u/eoNXP8jR8pJSQQWZ3XTvK3/+///fo++n7XhsrMRHYN1OXtla3i30kog0b/
+TkqYFXWvbK0JxUhS0N+01kdeDFKMJGP1N2WO/vM6JaKUUhIp+K9AUEAtlrRWC7yCdnj2Xi/iG52Z
+kYwusWZz3fKZbdkbo7igohhJSPGNyS2/9s7B9aqvW/OdlWlqWXaVJ40ohzXSFJx7CUb/pK05U9jb
+OIsxUvRhK4X4TFmtlLW3AaFR10vRe0okvtPZaH8eFGPyffeVJDLaZrc4kJTVye30vi6KYoVvAkyP
+FCNR3z1pzRzfoRG8pxTF33WmF0d5bPuUENy1MWinrGxt1Bt0rUiUx/3R3qgKEBKlpl0gS3i1A3B/
+lIWS8P24Ian8FyoeZWFs2EwrWy57/bW8yO8NeyUnIIIvK0pWN+5c1FTehZd2pjU/bf9eKYYNoc6W
+NH9ewfmXoNVEFzcOFzVskd+GJnRqHIeEAISR34QBRGnb+R2KlIJz69VO2bXG3EXO6WAjFmMkrbTk
+4sZ0kYgArezT7a3d+52Z1pEjgkpr6PZ2vq+twMFZG5d3aGXrTpJmZlxWttYFECG6cltYfez3GJst
++97OfVNkjQ2oO7yClohS6eMLUfoXIAmNxU94BS1jg2eLfLXqlQ+zdv7ZsJ9LoloJIW5qA7W8UY8b
+KdK32qjGnreHJYVUiSEkcAQfCTT+pDM7ccWNsStqHEBCiDoD3wFBQp6tKEsp+vii3N59roxZtpm5
+UuNhsSkSe9W6LQrubpxCUkowneKL7a3dtc5M695RHbWo1c0YYsIagtqVVCi5a+PsJnNla13eXRX7
+znfY4rPgqw11zChL00gAiQBLQuml9Ca34zsQFLSCZTQwy6MsjA0GWn3PVdWfjB3u+IjSCK5b/ai0
+WhiHD1518qV/ns+Mbp1vkyQp3KBfHhQTJUGPdVasDvSBa/S6qJHiM6VeFTVAjt+6WyIhVP077SSA
+VBaW0KjFV4Gk97WU75vcLkjO6WBDkmIkkNjn7o3pZmdaqzs7vbVOu7h3+LVgrJlzZfUU1egDaBXi
+9ARVXcQ0rGyty3GrYg9q8qjKaQ6soL2TUkqekqj6cSPRga0syKMsjF0UIIKPcXEUm1VAw90Y47Ya
+QbjpuKIYSWf6JShcqvtY6gBSVIMcmaKUKITwJJ8Z/+LGxBQ1DqBIm0qIxnR1HQwkpRBTr18+5kBS
+Niy+X20WeX637uNg9bOdYnVnt/fHdpH/n6jerIYFRCASiYjSqENoj10TO62mcWVrXaQUZ2qjNDZb
+rno7D7IiG9u7gkeNsvSruClC9b1G2VYWbvEoy0mSGHpcPRtL2ph5V1b/lEFuHXxjHTSlNfheua5m
+2lM3enFW3oenbV4VODChco/y2fbQR7CGJcVIfr+ogZNR1HiLTP8WsjkFjoNAocw7rXsUYwqVX/f9
+MmlrbqHmnA52eSlGAhIvAKezmM3eZdvFH7rd3rMiy4XSb67FtNGfRBc3IRvtiO/UFzh4ZWt9JOBi
+Skevij0MbbE6TqMqp5EAUgEsCq0XD6yg/QsIElrDMmqc5RW0jJ2NyexN36ueQCHvDPPDUxLiQwox
+DWtLxjjzzr3M263/GHboa1NRTCQBs0E9XtXrr+VznbHr3Jj4osYBiYRseuEdECUUuEJEKbqwWW7v
+/phZy4Gk7FJ8v9rMC+7eYG8zrWK53+//JRfZ6yKHthp6W7s/jDpsdOoKHEevbDW/kwg3FG84GSkJ
+IBLRpkA89UUPiOA8EOL4jaqc5sAoy2pKKTkikXpxPaVyx6B4D61aUIpzOxg7iS7sp71u/0GrM7z8
+B2XsnOtXj7PO8fvfpxVI/Isyamy7DS6LiISUwgzisap+tZbPtsciaFOI6SpqvGNM/gsBQEJmFtGo
+hejji/5O93ul1Ec2M7OSx2TZOaSUCEi8wCkdRWQn03l+s9erfswJ/6mtuS6EEBJhKcaYEEd3c2ji
+Cxy8srXZiMTPeMYZVpM1f6vKZUkppUQUAnElJZ1iSsJXcSN1D+V28CgLY+8wWbZa9cpHtsiGUoAA
+KSFSWqBIiYPV3vCVe5bPtMeu22DQJOCld6iUZf/LfKbd+OJAipFCIBFDeKq1EjbP9rafNPy4B4pS
+b9z+Y/cDSZXVS8HHX3q7vTUl5XscSMrOypVuq+DuDXYCU9hr/dL9nCq3Yay5bnK76Cu/jgWObOPO
+xBU4eGXrGAEQ5P2OEMevij1s3LaqXIaUUgopBQLcEPrVCtq9UZZnIAi1hg94lIWxNwAlxCSvDzN0
+FLVaDM6vm3y4m1vGRYiRtDVu6gs+RAIQL/WaK7u9Z9lM+3ejDmM7q4NFDaVU0NbczFrZ7akqahxA
+UsSTQtKbTmmcU7OtzynEVPbdI5mo0Da7hZqvKdgJfPgW83xibzSywTCZmXfOCVG6DZOZ66Uvu6MM
+Gx3rAgevbB1vICXEFNNpq2Lf+juI4L3sTeKoymkOjLLcezPK4r8C4QNqsaS1WpjUFbSUhODUA3YW
+Wpl570ohg9jCIWw8AUTwZUXJ6qk7Bx2FfHysWzyyQ0KIy2xU82X1LJtp/RoVNmqzHRc1TkAkJ6EL
+GBRK28lXKVIKzq277bIyufmEA0nZYVW/ellk+cd1HwcbD8qYeeeiCDu9NZPpuxRoGwyMZBPdWBU4
+jlrZKpT5FfDK1rFFEjunrYo9TGf5H3xv96Ep7NTOex8YZbmTUkqRkvD9uCFT9ROi+JXSeB0Ur6Bl
+00mbbN51y2e2gJlhdBZIVCvBxe90BhPfSXYS79zLfKa4Oa3BogelGDaEUjcu8nd9WT3XRfZrVKoR
+xY2jihq2ld1uamdJHVJKJABS3ccxSIAgIc9WyL4JJDXW3tUcSMr2cfcGOydlcD6iuFt1y0cIAMqo
+kdwQaXSBg1e2Tj6Q4mIzy9ouh+BfKDXaVN4mOmoFbenjC1H6FyAJjcVPAEDwKAubJqaVLbtef80W
++b1BfwBXGsH1qn8ro343rR/uKSUCwD+jUmO7vnuQUkjVRd7NQuleYmZ6qFWtgX1c1DgnIiGlbPQ1
+9EW9DiS1eiH6uLW70/2GA0lZVTru3mAXgogQ29mnv2z+64EyKurMDr0foVEn52NXtmpe2TqxAK+f
+dVXsQaj1vC/DHxFogVtl3yYBJAIsCaWXElGqQhIp7I2yaAXLaGB2UkdZGDtIF/lq1SsfZu184N1e
+oNVdCmETzXQWWUPl1ovZztR20R2WpHDnvUQJzr8Eq37S1lyo8+OyUkoUXBAxhKcIGHVul7mocTYk
+hECFRd3HMUxSSqmMmlNGfRFDTL1e77FKclHldgH5hsnUSc4/g46d+nFEdnYxRiIXhPf+aUzJySL7
+7Xav91/Q6/6kdfZelukFNaRRuFoLHLyylUkBIiXaFOL0VbGHoc1WfL/30BSG7yAeQ8Kr28uvRlk8
+JVH140aiQ1tZ+K4Mm1Bo9T1XVX8ydrChoEojuLL873wKCxzBRzJFlk19sOgBIEV1nm6e4COBxp90
+Zkda3OCixoCQGJsVsYOACmXead2jGJOr3FeyT4YDSadHrDwVNlviz2XsJCklohCEr9ymj/S91NIq
+pW+jsbc1gPT9ijRKiVpdpxhTtyo3aGfnX1pn7+WZXRjk+WSkBQ5e2creAUJQFD+jOtuq2Lf+qpQQ
+tbnJoypnc9QoS7+KmyL47xHJGIufACpeQcsmCiCCj3FxGJtVkhAfxhi2EAcfZtpoRGvaGu7euCCK
+kZJMj3SWjeTfkIsaw0B1H0AtAFHaIr+zF0gaNqqd8mdrzF3knI6J5iv3OOu0uXuDveNwlwYa9T5m
+etECnDh5AYgSEG+IzNygGNNu1dugHT+wYsdQCxy8spWd6gKrYg9Cred9j0dVLkICSAWwKLReTG9W
+0P4FBAmtYRl1g0ZZkhCg4Frdh8HGkzZm3pXVP2WQW6hwYMUIZeyc77kn2BlNaFYT+Mq9zDvFR3xD
+4g2KiSRgdqbvTYlCoCf5TDHU4kZKiaILInBRYzhICEQ1te9Je4Gk5oayKkUfX5Q7uz8obT60mblS
+97GxwYreU26ya3zOZ0Kc3qVxkcc8WOyI4U2xI9PZe+aCxY6BFTh4ZSu7iP1VsZd5DMx5VOWyDqyg
+XX2zgjaup1TuGBTvoVULStVb7JBSTtddcjZQJrM3fa96AoW8M6hiKEgJkdICRUrTMK5BMREq/Cuo
+6SnonAURCSmFOcv3hso9ymfbQyluHFXUMFzUGAoSQqAUU/+eJAGksrCkrF4KLvyyu9O9r6V83+R2
+QXJOx0TwZXictXI+50+xi3ZpXAQqlKj2ih0hxOSq3gbtxp8yZd4/T7FD/vY//58Lfbg8dmUrwHUh
+peC76eysQr//pS2yS23Fic79jBB6qHStSfSTKBGlGPdGWfZyO+D6qEdZgg9kjJKgkM8r7FLKbv9B
+q1MMrBhKMVIC+dRm5s6gHrOpXFl9Xcx2VqahmHMewUcSlL7TVp+Yp1Ht9h8VV2cG+kHhqKIGKJjl
+osZw+X5FaLREfk96B4WYfN89kiJd0Zm9zoGk4yv6SBjTdyarJwiZ1eO4Lg2JIC7z3nIgg+Ncj5FS
+ShRJBB++EpFCprNlk+nZk84tZ+7g4JWtbFgkSC1SEuISLyE0Zt734o8AtMjFtcE6OMpCb4+yKK3h
+A9Q4yyto2bgwWbZa9cpHtsgG8kETEMGXlU5GpUk+9wQfybRyDhY9CpEAxBPzXap+tZZfGcwM+35R
+I4awAYj/1pn9yBTZbf7ZjBb/Yx8NFErbyVcpxhQqv+77ZdLW3MIhbUtgwxPLat22ioEGdLNmGmWX
+xnlJKSUqFKj2FiaESKLsdU8sdhzbwUExkCBxaGUrLklQi4IDQdkARe9JK5CAl7sTQimRKLtPdM5r
+rEYhpZQSkUjBcg9C7wAAIABJREFUfyVEqrRO76MazigLd3CwQQo+Eibxt0GFjgYfCRT8zWR6oCGm
+TRKcv1/Mdb6o+ziayFWeNOKx5ydXVg9tp1i9zJ2vw0UNZc17qHCRixr1qHZ7z0yR3bjsdcs0IKJE
+Lmz60v2YWcuBpGMi+kgY6BuTD3YDGWuGYXVpnOSiHRzHOdzZkZtsWdu9YsfrDo6jV7ZqXtnKhk4K
+EEKkbSEuN88KUkJEcz3GuIU4uCBBdjQppZSIr1fQRkrCl3FDpuonRPErpfE6KF5By5pHaQTvyqvS
+iy3Ul9+Asrcy1v1bG/W786wKHRe+9M/z2fzjuo+jqVIMG0KpI1u4y27vWTbT/vCiF4yh8hRD2JBS
+/lvn2Xt7H6q5qFG3lETFPRxnAwASMrOIVi9EF170d7rfK6U+spmZlXx90FixrNZtwd0bk6TJXRoX
+cbizw0cS/V73K0EpqKp0Xx9e2cqBoGykQIgY0w+A4tInUjRm3nd7X0Iub09yu3jTHLWCtvTxhSj9
+C5CExsAngCguPspyqRxaxt6hTTbvuuUzI6UYxGYVQLxLIWyimayV1RQTKav+AagmPmPkolJIlbDv
+ft2X1bNspvVrVDh3nsfjosaY4J/IuUgppbJ6L5DUx196vd4TleQiB5I2T4yRtNKSzzvjbRgbT5rq
+rWIHUVLSFLzhhNULQCTnehddFXsYFvkn3vWfGgu3B/KA7NwkgESAJaH0UiJKVUwiVf4rED6gFkta
+q4XGrKBlU8u0smXf669Bkd+7bOfFXhdH+d/5hBU4QuXWW/MdPpeeIEnhDt/88mX1TBfZr1GpMxU3
+uKgxZhLXNy5DaZxTunWPQkxl3z2SiQpts1sXWQfJBi/2q02b57fqPg52fpPWpXEREkAqvsvN6ra3
+apHCQB9Pqt/wqEozSHj1yfHgKEs/biQq/6W1vKoUj7Kw+ugiX6165cOsnV96dWcS4sMYwxbi5cde
+miD4QHamNc/XCScDKaqDBbJQupcqMxL1ycWN4ANF5/eKGpl9n4saY4TS7mWC0dmeN4GklIJz69VO
+2bXGcE5HjVKMBAJfACJvJRwD09SlcR5n3qLC2DAlATallAZVXXw9qlIAb/hpkKNGWfouboqe/x6R
+jLH4yahX0DKGVt9zZfWlyeylxjCUsXO+555gR01G0HFMa9qoga3UnQbB+Zdg1U/KHr1W8Z2ixozl
+osYYIhADu15hQgCChDxbUZZSdGGz3N79URmzbDNzpe5jmza+X20WeX637uNgx+MujdNxgYM1QgJp
+Lrsq9rA3oyqa26sb6uAK2vRmBe13IChoBctoYJZHWdiwASL4GH8byrBxmc0qe91oaYEipXH/0OpL
+/zyfKS7d1TLpKCaSgJkQQgTvX4LGn3Rm3ypucFGDsbORAFLtB5L6uLW7072vAD+yheVA0hFIKRGQ
+4O6NhuEujfPjAgdrBCnxVkppoDOtICUEib+JkbYQYSJaxieZBJAoYE6gupNSSo5IpH5cT1TuQIrv
+oYT/Q0iQgHyRwwZPGzPvyuqfMsity4SOolaL3oevLJqxDeWkGEln+iUovsg9DREJKYWhGClJ+Red
+2c+EOKqoYXil6IRIKZHkBI6hklJKZdScMuoLCjH1er3HKslFldsF5EDSofHd/mZecPdGE3CXxuVw
+gYM1AkgYyqIMZeyrURXJoypj5MAK2hUhjHD90pdVXMuMQt/3AqS4IhGvA4DgggcbFJPZm77X/yMU
+2e8vmjsBiODLSpNRaVi75IfN+/C03Sq48+2MUpI6BHqic3Ov6vafcVFjwhEJ0DBT92FMC1Ao807r
+HsWYQuXXfb9M2ppbqDmnY9AkiR+RC9u14C6NweICB2sGECISrYPAge/cxsx+4l31lbF6bO+oTjtl
+NEqN84iozGz2u0RJJEpb0bvvQt87KcVVieI6wGVW0TImhC7yP/S6/QetTnHh7AnQaiW4+J3J4MLj
+LnXxLrzM2q3/uOxWmWkRnaNQup+yuY5CxL9zUWPykRCCOzhGDxAlFLhCRClUYaPa6f7MgaSDU/Wr
+l0Wef1j3cUwT7tIYHi5wsGYAEMJ5N6hVsW89NCKEiL/lUZXxBiBD6aIsFGwD4qxAMYc6vyMKIRJR
+opi2Ygw/Bue3BaUOSHELFBc82PmZLFvtd/uP8lZ+obBQRARXun9ro343boUCKdK32qgv6j6OpgvO
+U4zpsUA1l3VM0ZrjVbpTY6/CwWoCABJyc0NZlaKPL8qd3R9Q6Q+z3HIg6WX48C3mOZ/7h4i7NEaH
+CxysEfbC+WI5rMdXxs67XvdBluvPuCo6rpLQNrtZ7nbX8k5x7+AHRwkgEcQcapwTmRWJKCVKIoa4
+7pzbFjFZwPQBoJoVALySlp0IUIIy+lNfhg19wdBRQLxLIWyi0YuDPr5h8ZV7ls+0eWvKMSgm8t5v
+yiR+sO38o0zhvRhTisH9KZTlhsqysevYYRdBdR8AE68CSS0sKauXgo+/dHd2HygJ75ncLki+sXEu
+VeleFln+cd3HMYm4S6MeXOBgDQI4yFWxhymbrUZXrSurBz4Gw4YMQERPOzoTQmbF3arbf5x1imPv
+rkvYK2GAwhWdmdcFDyLaCJX7l4hkQKYPBKpZUFzwYO/a26ziroIXW6jVuTu/lEZwZfnf+ZgUOEKM
+pK1xvN3jXcFHouDXQete0WndOxi+iikmIVUIQl4Vzm8po7lLcNKREEqpW3UfBntDaZxTs+3PKcRU
+9t0jKdIVbex11FzoOBPnv8WZjLs3BoC7NJqBCxysMQhkMehVsQcBIrgg5ySPqowdkBISxbT/vwnM
+9VD5DWX1me6Yvi54CLyhjL6RKKWUSFCMm8GH5zJQEomWpFILHFzK9mlj5l23fGakFBfZrJKE+DDG
+sIV4/gLJqCUfH+vW8UXDaRQqT5HSY5PbedvKV44q/khE8P2yandm5vs7vWeAOMNFoslGQgis+yDY
+kUChtJ18lSKlULl1V5aVycwnHEh6vFh54u6Ny+EujebhAgdrDJByaRibVA4yNr/Goyrja7/DB7Sa
+L6vyn4WCLcDzf/CUIKUUKABxURmzuFfwSIJifBFDeB7KEKVIv9rb1CI4x2OKmVa27Hv9NSjye+fN
+01DGzvmee4Id1ejCgXfuZTZT3By3vJBh2B9DgQTfm3b2cabw3mkbdSABJKKUd4rl3i/dtXymuMfv
+LxOMSAjFJY4mAwQJRbZCRCm6sFlu7/5orL2rOZD0Hb5yj7NOu9HvUU3DXRrNxwUO1hhSwlwSaejZ
+XTyqMp7IU0ck8Trc7bg8jovYK3hIAQhLyuillFLa39RCwX/n+o43tUwxXeSrVa98mLXzz87z9/ay
+hdICRUpNvatPKREA/hmVmursjZPGUE4lRZHS3qkpny3ulju9x3mnxR8YJlgjf5nZOwBAQmYW0eqF
+6OPW7k73G6XURzYzs5JHU/e6N2y2xAXZ03GXxniR1/7zfwz5njljZ0Mxkkz0jTbDLzy4qv+jVTAD
+PKoyNqJzXxdz7ZWDd1MpJZKu/+SkPI5B2c/xCCGsk+dNLdOGYqQU41OT2XOtm6YYKYn0/9kia+SW
+jbJyz9oz7RtNLcAM28ExFGX09Yv8O1S98ueslV0BtbceNvpIKfi/cejoZKq6vT+aPPs9rwMeT8HH
+X3xZPlNJLqrcLuAUv3+XO/21Tis/tUttGh3XpSERBPC/14X4fkUapUSthv7vxx0crDmGuCr2MGPz
+axWPqoyVBNLu3yXdd5E8jovaz/EwClfe3dTid0QkA5g+EJKDSyfRXuho/G0ow4Y6x2YVQIRQVoqI
+UtMuikKMlOVWTltx460xlE7+cYZwqQt8RJxL6c29ItQIZQgcOjqhEgnJPRzjS2mcU7p1j2JMru++
+kkRG2+zWtAWSRu8p1+YaFzfe4C6NycEFDtYYw14Ve5iy2Wr01boaQccIG4CUrosjQlpAq/myX3Yv
+msdxUWfZ1CJF+g+p1AIXPCaDNmbeldU/ZZBb5wkdlVqtBBe/Mxk0645+oDXdNucauxlnlxpDOQmA
+CD6so1av30uy3HLo6CTjn+jYA0Rp2/kdipSCc+vVTtm1xtzFKcnpiKV/altFIzsLR4WzNCYXFzhY
+o5CQQ10Ve9D+VhWItMWjKmPimIE6nWfXym7/y7yd3a4rKPG0TS3JxwQi8aaWMWcye9P3+n+EIvv9
+We98ISK40v1bG/W7pgR5+sq9zDvFR9NwV+os21AuA0GI6IU7/HUOHZ1QSTj+YU4OQJCQZyvKUoo+
+vii3d58rY5ZtZq7UfWzDEn0ko7RtWlfhKHCXxnTgAgdrFglDXRV72N6oyu6DvLBTHbA3DkCgIIqb
+IHDxqD+XNvuk3y0fFp28ET/Ldza1vAoupRhfUAj/CGWo9ja1cHDpuNFF/odet/+gaOdnHnEDxLsU
+wiYafeTrd5QoJkKFfwXV7O0ul/HOGIrCoRUZ9lfFWpG982ccOjp5khDVqK5R2OhIAKksLKFRi68C
+Se9rKd83uV2QE/b+HMtq3baKqehe5i6N6cQFDtYoIMWVYa+KPUzZfDW4akOZ4WY4sEsCIRKln4UQ
+R35ABCkhglkdRR7HRUgppcS9TS3imE0tQoo2oLjFBY/mM0W2WvbKx3krP9MHV6URXFn+d96AAkfw
+br2Y7dyt+ziGIfhI5N26yqwrOq3bAxtDOcX+qtjDXT1SSjB59mkoyw0OHZ0MSSTBd3onl5RSKqPm
+lFFfUIip1y8fT1IgaYyRtNJykrs3uEuDcYGDNYoEXBzFqtiD9kZVgPCIi1PWNCdXv1AjlH2fjTqP
+4yL2Cx4CxRxqvKPz7K1NLcHxppYmAylBGf2pL8OGPmPoaBLiwxjDFqKq7bUZfCTTyrNJy4UIpXsZ
+k3hmW9k1HMIYyqkOrIo9jENHGRtPoFDmnb1A0lD5dd8vk7bmFurxzemIvWrdFpPVvcFdGuwwLnCw
+ZgEQkeg7QBzpnS5js2Xf27lviuyLUT4vOwcAET3t6He7wN/ShDyOizpuUwsRbbhXwaUg0wcCeVNL
+E+xtVnFXwYst1KcXLZSxc77nnmCnxtEQojVjTSPGuC6LYiTv4yYI+MG0i4+GOYZyKpBLIh1fgOXQ
+0cmQUiLgO8BTBxAlFLhCRCm6sFlu7/6YWTt2gaQxRkIJfhLOQdylwU7CBQ7WPCRGtknlIGmLz4Kv
+NpRu3ngD27tjniieaYCpaXkcF/VucCmllJKguLepRVICkYiDS2ukjZl33fKZkVKctlllb1NUWqBI
+qY4LTF/65/lM/tGon3fQ6hpDOcnhVbFH4dDRCUAkpIJO3YfB6gEAEjKziEYtRB9f9He63yulPrKZ
+mZVjcMMh9qvNIs8/qfs4LoK7NNh5cIGDNQogQnTltrC6lufmUZXmO8uWnabncVyUhL2WFMB3N7XE
+EH/0fS94U8vomVa27Hv9NSjye6d1DaFWi75yT22RjXQ9H8VEyqp/gFJ3Rvm8g/TWGEo7X2nUDPkR
+q2KPwqGj442EEJJ3xE69/UBSZfVS8PGX3m5vTUn5XpMDSVOMBAJfANZfED4r7tJgF8UFDtZAUo5q
+VexhPKrSbOSpI5I4etD9kHHK47iotze1iMWUvwkujd59x5taRkcX+WrVKx9m7fyzk74PECGUlSKi
+NMoP6KFy6635zkiLKoNAMZKv/CaAqn8M5QTHrYo9jENHx9xehYOx15TGOTXb+pxCTGXfPZKJCm2z
+W6ib9X7r+9VmnuWNDpfmLg02KFzgYI1DEtqjXBV7GI+qNJgUQpy1wiEO5nHY29PQlfN2cGl+J6WU
+REqC4qtNLc5XglKHN7UMB1p9z5XVlyazJ3ZJSK1WgovfmQxGco4JPpCdac2P0+/AW2Mos51GjKGc
+5KRVsYdx6Og4IwESbN1HwZoHFErbyVcpUgrOrbvtsjK5+aQJgaQpJQISL7CB51Hu0mDDwAUO1jhS
+iit1Pj8ggvNAiDyq0jQJpD1uU8FxXuVxrBWdk++sTyIppRRSCoRXm1qEeB1cGkNcd87tbWqBdA1Q
+zXLB43L2Qkfjb0MZNtQJm1UQEVzp/q2N+t1IgnBTeqiNanxXGqVEVPmtxo6hnOK4VbFH4dDRMUVC
+AI6mMMnGEyBIyLMVsm8CSY21d3WNgaSuV20VRTO6N7hLg42CvPaf/+NMoX2MjQp5T0qBBMRaT3SR
+R1UaJzhHxWzr3K8NipE00N8mKY9jUA5uagm8qWUgXL/60Vg9c1LoaPCRtIG/o9GLwzwWX/rn+Wze
+BlRzw3yey3h7DCX7CBXOjuOdu2q3/3U2U5xrRS2Hjo4XX3lCBIla8c+LnUlKKUUft1y/+qauQNJq
+u3u/M9Op7Xr2yC4NjQsSQPC5b3r4fkUa5UjOn1zgYI1DMZIU9Ddd84gI+UhSVH9XergfQNjZBe+o
+6LQkqPMXv7wrfyxyNQN4+jrPafYmuJQ2gvcvZaDEm1rOz/f6fzRF9vuTOhB8Vd7PZ9pDu+ikGAkQ
+vzFFdmLwZV0OjqHozN6uu6h9WVWv/DlrZVfOc35KKVG503vCoaPjwfcrQqMlXuA9iLEYYnL98rFK
+clHldgFH0DVZ9auXhTISNY6syH1cl4ZEEOPUlccGa5QFDh5RYc1U06rYg0Aj+FL+C5EWeFSlGUCg
+SCltCyHOXaTQJrtW9conWQvu8M/zeAeCS28oow8WPF7EEJ77vhcgxRWJeJ0LHsfTRf6Hstdfy1v5
+sXfnkxAfxhi2cEhFN+/D03Yrb1SwKKVEsfJbNKZjKCc5y6rYwzh0dLxQpE0lBN/0YBeCCmXead2j
+GJOr3FeyT2bogaQ+fIt5PvTuDc7SYE3CHRyscSglSlW1Zovs87qPRQghYm/3oSns1OU3NBHFSNqq
+b3RmL3xHOlb9h9OYxzEoKb29qYVccFKKq7yp5V2UEoWyepK38iPvzlNKRN4/yTrFwO/eexdemiLr
+aqMaESr3egxF6xcmt8vjOoZykuAjCUHf2At0zJT96mcFgBw62mxVt/dHk2e/H/duI9YMFClFFzai
+8z9bY+7igHM6qtK9LEBJNIMfUeQuDXZe3MHBphpICTHFVNeq2HdouxyCf6EUj6o0w+VqslKZe6Hy
+G5zHcTGHN7WIYi/Hg2LaijH8GJzfCy6V4hao6S54gJSgjP7Ul2FDHxE6ClJCpLRAMaZBf2CSIn3b
+hGDR4COFGJ5aa2wx17kF2LwU/0E566rYo3Do6HhIJCTviWWDshdIam4oq1L08UW5s/uD0uZDm5nB
+hO2X/s8wO7gbdNylwcYFFzhYI5HETp2rYg9Cred9Gf6IwKMqtQMQFGLvUg+BCKXzWaHkFudxDIYE
+kK82tcyJzL67qSUmC5g+AFSzAqYruHRvs4q7KkN6rpR+58M9arPo+u5x1j66y+MiqtI/b822auuA
+2x9DEUn8Wbey963Ob0/DHb3zrIo9St4pljl0dAzwT4YNmASQysKSsnopuPDL7k73vpbyfZPbBXnB
+mwSx8pTn2XuXOZfwxhM2rrjAwRoJpGjUnnm02Yrv9x6awjRibGZagZRAlMJlH4fzOIZLwl4JAxSu
+6MxM/aYWbcy865Y/yRy2Dm9WAZRAnjIiSoMoAoQYyWb6JSCMvFPi4BiKbRfLoPCzafugfp5VsUfJ
+Z4u75U7vMYeONhSl3lS9oNnIKaPmlFFfUIip7LtHUqQrOrPXzxtI6iv3OOu0z30e4S4NNgm4wMGa
+CfB6SqkxN0pASoja3ORRlWYYxPgS2OzTfpfzOEbhdcFD4A1l9I03waVxM/jwfBo2tZhWtux7/TUo
+8nsS3n7tSq1WgvPr5hLZMvuSj491a/CZHicJzlMgmooxlFNJUaR08Zv8HDrabCRFbEJnKZt8oFDa
+Tr5KMaZQ+XXfL5O25hbq03M6oveUm+zaWa6TuEuDTSIucLBGkgJEItoUiI0pJqDW877Hoyp1oyCs
+SGIgbcKcx1GPA5taFpUxi3sFjyQoxhcxhOehDFGK9Ku9TS1iYnI8dJGvlrv9+/lM8VY2BiKCK11X
+m5QOFz/Owzv3Mpspbl7mMc7q3TEUNRVjKKcCuSTOuUnlMNQIZQhXhfNbHDraMESS72KzUQJECQWu
+EFGKLmyW27s/ZtaeGEjqy/A4OybcWgju0mCTjwscrJlACCLxMzZsHRvmPKpSu0RGDKjCAYhQVfEq
+qMB5HDXaK3hIAQhLyuilg5taKPjvXN9NzKYWlZvPXFl9aTJ75+DXAfEuhbCJ5mIdYpQSAeCfUamh
+npsOj6GgHu7zjZuLrIo9CoeONk9KiQQAbx5ktQAACZlZRKsXogsv+jvd75VSH9nMzMoDY57Re8q0
+nj94I467NNi04QIHayYAQd7vCKHrPpK3gJQQlb4Zg3+ORwQGshFAmS7TAn6Ysma+v1v9sejA77kz
+pxne3tSCd3Sevc7xCCGsj/Omlr3Q0fjbUIYNdWCzitIIrld+n1+wwBGd38hn2kMbtwrOUwjxqc0t
+j6GcBEAEH9ZRq0uPG3HoaMMQCSklXzezWkkppbJ6L5DUx196vd4TleTifiBpLP26bRUr3KXBphmf
+qFkj7a+Krfs4joLGzPte/BGAFvkD8eglSiuXXRV7mMrtH3rd3v1Wp6h9rSY72n6Oh1G48u6mFr8j
+IhnA9IGQzQ8u1cbMu7LqyiC2UL3pHEogbsYYtvCc3UQhRtLWuEHf6T80hvIej6Gc7jKrYo/CoaPN
+QUIIUFDUfRyM7VMa55Ru3dsPJA1llQGJXpfSA+7SYNOMCxyssSjJziDCJIcB82zFu/5TY+F23ccy
+daQYdH1DCCEEKPuZL92fdGYufeeVDd9ZNrVIkf5DKrXQxIKHyew13+v/URbw+/2igTJ2rupWj4oZ
+db5OjEBrul0MrHsj+EjR8xjKRVx2Vew7j8eho81BQjTwcoQxAQplUrBMQvwXRdKtdnZbAjTqPY+x
+UeICB2ssQEgiJdHExHKQEqJUv4kxbiEiZzeMEAgUKaVtIcRA/90BEVwVF1FzHsc4Om1TS/IxgUiN
+2tSii/wPZa+/lrfye1JKCVKCTGKJYkyAeKYTn6/cy7xTfDSIQvDBMRTb4jGUi7rsqtjDOHS0Kaju
+A2DsHTFGcrvlQ11kH4vctM0VdaO/23uUtYp73HHHplXtF3iMHQtwZRBhbcOCxsz7kjYSUXMPchKB
+EBTjD8N46L08jvjf/DMdfxKkBESpjFnMWsW9bLZ9T3fai2D0Jon01JX+vi/ds+AdUYy1fXLReXa3
+7JWP9/8/arPo+u7xSX9nH6VEqPCvoNTcRZ+fUiJfupe+H+6rzG62r8zcNkW+ctYCCzvCq1Wxg5Tl
+dt47/w+KfG6qDQmBqK7VfRiM7at2es+p8t9kM8XnSuOcSKkSUgo7W6z2+70vYwhbdR8jY3XgAgdr
+LClACJG26z6Ok2CRf+J9fFr3cUyf4V3j7+VxlA+G9gSsFlJKCQhSGb1kivyOnWl9rtutG2iL7STh
+qeu7B650X4+64AFSgjL6U1+GDSHEXmdJpIzOUGQLlVs3RX73Is8bfKSqWz6LgZ7YTmuumG9/oa1Z
+4lyhARjAqtij5J1iudztP0pNrvxPMBJCSDnYzkHGLiL6SL2t3Qcqs21dZCv7HXwppt5+M1/WKT6t
+XP8f0XORg00fHlFhzQVCxJh+ABSNzUQAKSFI5FGVUQIQFGJvqE/BeRwTr0mbWvY2q7irMqTnSukl
+qdVKcH7dZPbY11/wkUwrz84bLBqcpxjTY5Pp1qsxFC5oDNigVsUehUNHa0QkhMK6j4JNuXK39wwR
+XD7T+uzwaCKJGA9+zbZby1Wv/IsRQijNo7dsenCBgzUXgEjO9Zq2KvYwZey87/a+hAJuNzEQddKA
+lECUwlCfYz+PQ4UtUHxRMC2O29RCRBvuVXApyPSBwMFvatHGzLtu+ZPMYQsVzrrSdbVJScIx5xSi
+NW30mYJFKSaK3m+JBN/qln0/0+oed2oM0QBXxR7GoaP14l8aVpfoPVWle5gV2edHFaZTSgTy3a/b
+IrtZ9t3PyYUNbficwaYDcKsjayqQEhLRUD/IDgoW+SfeBR5VmSDKmvl+l/M4ppkEkKBQKqNvZJ3W
+53amdVu1W3Ng9HfBxzVf+jXfr54HH4liuvRYi2lly76s/pwoJUC8SyFsHvV9vnIvs05+arDo6zEU
+4jGUUUIQQsTBrYp95/E1QhDyanCeW89HiGLc4AoHq0O523tGMX1XdFpfHNd1R0RCKegc9WdZbuaj
+EFd9WW4M90gZawZw/fJRipHfJFkjJQF2HIpwICUkib+Jkfh3aQQoCJto+K8Llds/9HbKh8N+HjYe
+JMCr4NK9gofptO7pTmsRjPp7FOlx1XeXLnjoIl8td/sPlEZwver7w39OMZEy+m8nBYsG56nquzVU
+8E1xZeZGMdO6h4pHUUZFIoIPrhrmc3Do6OilJCru4WCj5Er3sre1+8Dk2Q2dmRsnfjPRiS9PnZn5
+qOCqK6s/DfgwGWscMK2Z1RDS36P3XNVjjZNAmmGEtQ2DMnbel3FjHAoyYy+RGWbQ6EFg7CpfELCj
+HNzUYot8dX9TC1q7fZlNLSo3n1Vl9VUCcfNwCn6o3LrJ7e3Df4fi29tQWnPte3vbULhbow77q2KH
++RwcOloD/m1iI5BSonKn+zVI2S1m25+f6TxOQoDCWyd9izZqXlj4uN/tPRrYwTLWQCCEECrLbybQ
+V12/fMBvlKxJpMRb4/SSxMx+4l34qu7jmHgoR/ayAETwQS4Sr1tjp9jf1IIa5/Y3tZjOgU0tzt8/
+y6YWQIQE4jeQ1L+rXvXt/teDj2Q7+dWDIyb7YyiU6DGPoTTIEFbFHiWfLe6Wu70zrRVml5S4vsGG
+ryrdy3K7t2Za+Yqyeumsf4+IhDhDDBwigi70p72dLhc52MR6HZCGSs9j3l71ff8Vj6ywpgDZ/FWx
+BwEiJCF/zaMqw5UorYyqg0MIIZThPA52flJKKWGv4KHz7E7WaX9hO60VlRUygfrmdcHDVS8PFzy0
+MvOeQpaJrDNoAAAgAElEQVR8nKcY9153iR5qaxaFeHcMJe+0VnkMpUGGtCr2sIOho0N/smlHafcs
+HyAZu4gUI5Vb3S8RQOazrc/hnEXqGOPGWV+eEhHMTPbp7tYO39hmEwlnbi7/z/3/I6WUaMxC9OEn
+CvGfoPBqjcfGmEgipUTpO0T8dd3Hclag9Kwrq6dKwRJvVRkOopi0MXKUd6lBq/+o+v0Hxur3RvWc
+bPK8Lnoo/LWy5j00+n8HpbMk4Tvv/LPowv9KMeSUpEWjZoJzz5OQPwoSyRZ2IfhQUhBPdWExa2Uf
+KmN+feymFVYfShYQ5ChGhABBuhCloOQAMRv2800r5/wPJrN8/mcDV/arl+TDt6aV3UaF+UUeI1Ru
+E7U68/uBlFLq3Fzrb/UeKaMW+XqVDRuFmBDkaN4Xj/oi2uya1PYD1y8f8B1LVisAIWIcWhr9sCib
+rUYX1us+jkkFAkVKo+/sAWU/4zwONkjvbmppv9nUEukJKFNt/bRTUgz/JRD/ms+0eQxlHLxaFTuq
+p+PQUcbGT4yR+tvdNaWUtK38znm7Nt5+sOQuUqLIrhSrZbe3FgN377PJcWSBQ4i9VntddD4PVfwy
+8ew5qwlICURxqGn0wwCI4IWcIx5VGQ4QgmL8YeRPy3kcbMjeBJfqG1mruGc6rXszv77SytqtLO+0
+VoHHUMbCsFfFHoVDR4cnpUSSEzjYAFU7vedU+W+ydn5PaTx2K9ZZRRGrixa97WzxWeV6/4ier23Y
+ZDi2wLFPFcWnkeS2d57vWrKaAIzjBZux+bWqCt+M47GPh3r+WTmPg41SjP6Xzq9mP9Az7bu9bQ6F
+GxejWBV7FA4dHRIiARpm6j4MNv6ij9Tf6t5XmW3rIlsZRCfeXgHu1I90J7Lt1nIV3d8DFznYBDjT
+bwPa7Boo+7Hr9e/zRT0bNQJZjMuq2MN4VGVIAIRIVNvoksrtH3rd8kFdz8+mA8VEOjN/Ra3mhBBC
+F/k9LnKMj1Gsij2MQ0eHg4QQ3MHBLqvc7T2j4L/JZorPcQBdG68RCdR46QKcLbKbLrpt7/j8wcbb
+mct9gAi6NfOFr+hrHllhowRSLtV0s/7SeFRlOEBKCJ7KWo9B2c9cv/qyzmNgky3GsJ63i7sHv4Z5
+9mm53eMixzgY0arYw1AjBCGvBuf5fWdQ9iocjF1I9J56O937Jrc3dJ6tDDrQk0iIQSUy2SK7FoS4
+6rlIysbYufuZdJH/ISaIvuSRFTYaUsJcGtcKh9gfVfE8qjJhABF8lL8N3j+v+1jY5Ak+vGxdac8f
+bl8GKUHmlosc42BEq2KPwqGjg0anfwtjRyh3e88opu+KTusLwCFlKBEJiXBtUA9nMjMfFVzlUHU2
+ri40sIXGzoPhkRU2IgAiRhrrMQ9l89U4wkT9aUCUMFG9RSNlzHzZC10+D7JBopRIW/yzNnrpqD8H
+KUFazUWOhkPEuTrr2hw6OkAkhFLqVt2HwcaHK93L110bmbkxzOciIiEBZgf5mNqoeaHh436X32fY
++LlwIs3+yErw8a8UIt/BZMMzpqtiDwJE8IlHVQYqpqKuoNGDdJ4v93bKh3UfB5scKcT1rN367KTv
+AcS9IscOX3w21ohXxR6FQ0cHg/s32FmllKjc6X4NUnaH2rVxAIWwOYwnQY2gC/1pb4ezn9h4uVzk
+rhBCZcUyJVmEfvkV3yVgw/BqVWyteQuDYGx+LVSOuzgGRYrGZM+Csaucx8EGIfjwMp9rzQOePlEN
+iCANFzmaqo5VsYdx6OiAEAkx2NgENoGq0r0st3trpshXlD26A28YkhA/D+v1KRHBzGSf7m5v3+fP
+eWxcXLrAIcTeyIrM2/+X61cPuFWbDQMJiZNwYpW2+Cw4zxeaAxClWGpCB4cQnMfBBkchfHvcaMpR
+3hQ5+mvDPC52fnWtij2MQ0cHg8sb7DgpRip3ul8iQDefbX1+lgL1QJ9/yPU3KSXkc+0vetvdR8Sf
+89gYGEiBQ4i9u+ym1Xk1shJeDOpxGRNCCCFhbFfFHrQ3qgLEhcDLAyEGt2JtADiPg11W8P5ZPtf+
+/Lx/b6/Ioe5ykaN56lgVexQOHb0covgnrnCwo5T96qUr3VPTym8ro0bWtXEQpbAzig6j7EqxWnZ7
+j/g8wppuYAWOfSorlkmo3JclB1uxgQEprjTkZv2lGZst+9I9qPs4xh0IbEoDx2ucx8EuKvhI+Uwh
+L3rnb7/IUfVKHpVqkppWxR6FQ0cvLpGQ3MPBDooxUrnV/VIpJW0rvwMw2q6Nwwa9evY4drZYLavu
+X2MI3BHGGmvgBQ4hhECt5yFrf+r65aMUI/8CsEuTgIvjvCr2MGmLz4LnUZVLASFiaN5mGs7jYBeh
+UD40mb1U0j4gAgn5W1dWfG5pihpXxR6FQ0cvgesb7JVqp/ecKv+N7eS3lcZau0lTjKS0ykb5nLbd
+Wq5c/x/Bc5GDNdNQChxC7I+szKyGkP4e+YMcuywAEYm+q/swBgUQwROPqlxe8/753uRxOB7VY2ey
+N5rSOvdoylGU0fORxFUucjRD3atiD+PQ0QtKwnF9g0Ufqb/VvY+ZbesiW5E1d20IsZd/C1KaUT+v
+bbeWXXR/9879ddTPzdhphlbg2Key/GYCfZVHVtilURr7TSoH8ajKJQEIkaiR64P38jjiLs+pstNQ
+3B9NGdwqQS5yNEgDVsUexqGj55eEqHiLynSrdnrPKfhvspni87q7Nt5GQko5X8cz2yK7GQT9ynPB
+lDXM0AscQgiBam9kxff9Vzyywi4CEIGC3677OAaNR1UuDqSE4KmxRS+d58v93fIhF3bZiVJau+xo
+ylG4yNEMTVgVexQOHT2fJNLIMg5Ys0TvqbfTva9zu6jzbKVprwMiISTCQl3PbzIzHxVc9X0ucrDm
+GEmBQ4i9DyO61boTo9gOFX+gYxch5aR9WNwbZ+BRlUkFJl91/epp3cfBmslX7nnrSvujYT0+Fznq
+15RVsUfh0FHGTlbu9p5RTN8VndYXoAbXZTdIMcatumsu2qj5ZPCDfrf3qNYDYeyVkRU49qHNrklt
+P3D98gF/qGPnQRLaTQprGxST8ajKRRERJmruiwJQQiD1G87jYIdRjJR3ipeg1FBbnfeKHMRFjho1
+ZVXsUTh09HQpJYK6P0GykYrVXteGye0NnZmBd9gNVIw/NmF8CjUCFvrT3k6XixysdiMvcAixd9da
+F53PQxW/TLxmiJ2RlOJK3ccwLFIXnwXv+UPweUVRNDFo9CBlFOdxsHeltGYKe2sUT6WM3StyVI6L
+HHVo0KrYwzh09AyIhFTQqfsw2PCllKjc6X6dhNgsOq0vBpmNNFQNOUpEBDOTfbq7vX2fO8NYnWop
+cOxTRfFpJLntnf9TncfBxgMALk7q+RI0QojyX029y9dYDXlTP43O8+WS8zjYK96556259kejnOVW
+xs7HGLnIUYeGrYo9jENHT0ZCCDkubzbswqrSvSy3e2umyFeU1Ut1H89ZJUq7TWowklJCPtf+orfd
+fcTXtKwutRY4hNgbWQFlP3a9/n3+RWAnmrBVsYehzVZ86dfqPo5xEqVYGpeageQ8DiZejaa0i5eg
+hzuachRl7Hz08ap3ntf6jVDTVsUehUNHT7BX4WATKsVI5U73a5Sym8+2Pgesf/XreVCKqWnBp0II
+kV0pVvvd3iM+p7A61F7gEOLVyEpr5gtf0dc8ssJORKKxWzMuC6QEoe1yCDyqclYgRINWtZ2M8ziY
+EEIkik9NbkYymnIUldn54MKvuMgxQg1cFXsUDh09DgmQYOs+CjZ4VeleutI9Na3x6trYl2IkCajq
+Po7j2Nlitez3vo782Y6NWCMKHPt0kf8hJoi+5JEVdgQAQcFN3KrYg1Dr+RB4VOWsQGDTIzjewnkc
+0y1U7mX7yszvJNR7h/BNkSM8r/M4pkVTV8UehUNHj0BCAML1ug+DDU6Mkcqt7pcIIG0rvwM1n5Mv
+ioQQGqGo+zhOYmeKP1Su/4/gucjBRqdRBQ4hhEBj58HwyAp7F0gJQggx6XeX9kZVwsO6j2MsgBD/
+P3v3+97GceWJ/tSpqq7uBkBSUO5N1rIyk0kkahJr/MSyLEp6f+/cfbH77P2fJVG27HksWzdm5Ozs
+xLLsdcZiSBCN7q6uU/cFSIqkQBIgAfSv83kmY+sXWRZBAP3t88MV1b8zehTP42gncp5ML/xLGa0p
+k6jQ9G1m94jvrC1clVfFnsRDR99FZR+AzVU2TF8VWf6F6UV3VFCN5+MLIwJAUfnqItPtrOcu/6Gw
+HKqz5ahcwAHwtmWlsO7PVDj+ZmCHSMhelYe1zcO4VSW4xa0q06rf40EE0UaWjPguaYt4sl+YKLxT
+9jmO0pG5lY7sDxxyLF6VV8WexENHTyCCKqzhZJfjrKPRzvCRDHTXxNHHZVfSzQPVqLrIxOEt64vY
+5hyessWrZMBxQIXxOnkRF6P0c77byQAAUEDlk+p5kFr3i5xbVc6FCOCpFqXfR6EU6Hxwo8gsv9C3
+QGHz7U4FWlMm4ZBjSSq8KnYSHjr6Fjl6XblvXDaTbJC8osK+CFfiB0rLeldtHFWz8C0Ig74DuGpH
+HHKwxap0wAEwblkRJv5jPsoe88UeA5Q32pJ1yYhbVaZRWKrl4FkVqH6aFkTO8YVlg5H3pMPgz7Ii
+rSmTcMixBBVfFTsJDx3dJ/zPvEWlnpy1lAyGj1RoujoKb1dx28hlEBVf1e2/SIdB32m8OhomvDWQ
+LUzlAw6AcctK0Ontt6wUXLbfYgIQPNHrss+xDCgEgtK3XGG5TesUB3NZ6kpH0Xo6SP/U+guIBnO2
++Drqxp+UfY7zcMixWHVYFTsJDx0F8ASC98TWT7qXbFHhv417nYeySVUbR3gCUacKjgM6UH0Z60+S
+wfBp2WdhzVSriwMVxusEKrJpyncU2goBiOBN2cdYFhkEfWvhB65eOgORqPPzgTDxJzyPo5kKW2x3
+rnT7VWxNmURH5laSZD9yVdEC1GRV7Ek8dHRfLb6DGcDbqo0gMjd1FNws+zyL5Mnv1bUoRUqJwUp4
+d7g7eFzn93CsmmoVcACMZxNg2L2bj9Knnt+EtQ8ikHODso+xTDKM7ljrvij7HFVFDrp1K/0+iudx
+NBN5T9rIP+lAv1/2WWZh4mg9GaYccsxZnVbFntT6oaPkk3peQraL957SwfC5d/6HuNd5iFI2/stG
+3vk6t90IITBc6zxIdgdP+UYem6faBRwA47L0oLOyURT0o7N8UdAmKASCd616EkQhEIT6jeMLjslq
++9L+Fs/jaB5fuK/Dbud+2ee4CA455q9Oq2InafPQURLg6tgG0CZ5mm+nu8lmEEe3VRhcK/s8y+C9
+JxTNCHHCK92N0TB5ShxysDmpZcBxQIXxukd9lVtW2oW86LUt6ZVB0LcpveTH+bs8+CtN+GvheRzN
+UdiCorVOH2U9WlMmMXG0nuxxyDFPdVoVO0lrh44SiTrfJW8y7xylg+FzFGIYrXYe1Pk5d1ZEBEph
+r+xzzItZjTfSJHnueA4Um4NaBxwAAFKNW1bsyH7OLSvtgBJbsSr2JBlHH9m84FaVk4RozN0ansfR
+DErik7q1pkxiOhxyzFXNVsVO0raho957AsSaf9WaKUvz7TzJPw060W1l6v98OzOiRlSwHmVW4g+z
+fPSjsxxysMupfcABMC7h153Ox87BLrestECLVsUehUKgF5JbVSZpyMOB53HUX2HtVrTWeVD2Oebl
+bchR38qDyqjhqtiTWjd0lAiEEKrsY7C3nHOU7gyfSURhetEG1mSI89wRACr5QdnHmDfT7axnLv+h
+sC2d+cPmohEBxwFpwusgzW/zUfq4zmWg7GwCEAD8btnnKIMKDLeqnIAowTn6tuxzzAvP46ivwjqK
+VmLRtOF2phOtp3vpJvdHX05dV8We1KahowQAqDAu+xxsLB1l20Waf2F60R0VqEaufp0WEUFTZ8OY
+OLxlvXM2b0mQyuauUQEHAABKiTLqbhSZe+a5j6uZEMA5/9eyj1EWGRpuVTnJU1r2EeZJR9F6upf+
+yVMDroZaREnxJAhNI9cS6k54Px1wyHEpNV0VO0lrho4SAI/fKJ9zjkY7w0dKKWE60cd1Wb29SM65
+l01+aAZh0HcAV+2IQw42u8YFHADjUn4Vx3cdiV2b26/KPg+bM0TwrkjKPkZZUMr9VhXiAA8AABEa
+06NyhAjjT7Ihz+Ooi6a1pkyiO+H9ZMCT7i+qzqtiJ2nH0FEq+wCtlw2SV5TZF+FK/EBp2eqqjWO8
+zxo3hOMEHQZ9p/FqPkqflX0WVi+NDDgOSBNeR2X+kCejR9yy0hwoBHqiouxzlGncquK4VWVfkReN
+a1lCIdAjz+OoA3KOwk6UN601ZRLTiTeSQfKUX1NnV/dVsZM0fugoAUiprpd9jDZy1lGys/dYhaar
+4/A2b7I5zpNP2vA3ogPVh1B+NBomT8s+C6uPRgccAOO73bqz8tBm9JxbVprDA5q2X9zL0Hzk8maU
+O18GCtHY5zHUqp/mzvE8jorzftN0wttlH2NZTCfeGHLIcSF1XxV7UtOHjhIACAGrZZ+jbdK9ZIsK
+92282n0guWpjIvLOtaVVR0qJOtZ3k8GQQw42lcZeGJyk4+hD59HZlFtWmsCjCOo+jf6yUEp0INa4
+VQUAiERTAy9twls8j6O6bJa/6lzp/r7scyyb6cQbw92k4e0JC9CAVbEnNXroaIMHOVaRs5aSwfBR
+EJmbOgoaOc9oHrz3JNpzCQcA4wo4sxrdG+7sbjYpJGaL0arvDhmYPgbcstIEiPIDfl8NoEx0Pc+K
+F22/yCAH3SYHXjyPo5rIOYp68Taqdk7zN914Y7gz5JBjFg1YFTtJk4eOcryxeN57SgfD5+T8t3Gv
+87AN7X6XQUQgtVwp+xxlCK90N0ZDngXFztaqgAPgbctKYd2fqXCvyj4Pu5g2r4o9SZlwo/WtKg1/
+K8TzOCrK+80gNh+UfYwyccgxm6asip2kiUNHybmXTX99KVue5tuj3eFmEEe3dchVG1MhgHY0p0xm
+VuON0Sh55nj0ADtF6wKOAyqM18mLuEjzZ016MW6Nlq+KPQqlRAtijVrcquK9v9L0b2Oex1EtNs9f
+dda6v+fBd/shx/Ye90ZPo0GrYidp2tBR76HxmyrKclC1gUIM49XuA5RtvmSfEREIia0efhv24rtZ
+PvrRWQ452LtaG3AAjFtWRBB+lI+yx9yyUjOI4J1r7arYkwITXc/a3KqC4lrZR1gGnsdRDeQchd3w
+R9TtbE2ZxKx0NvbeDDbLPkfVNW1V7EmNHDrKl91zl6X5drqXfBZ0otvK6PfLPk/dEBEIxNYPvzXd
+znrm8h8KDjnYCa0OOADGd7+DTm+/ZaX4vuzzsOmMV8U6V/Y5qkSZcMM1+M7guVpyyc/zOMrnyX1h
+ovBO2eeoGrPS2Rhs7z0u+xxV1sRVsSc1auio53xjnrxzlO4Mn0lEEfU697AlW0DmjYriNf/FjZk4
+vJVR4WzeoFCVXVrrA44DKozXCVRUjNLPW3sXvHYQ+Wv1FkqJ1rezVQVRgnP0bdnnWAYUAgnNXZ7H
+UY4iy7e7V1Z+15b1fLMKe/GDZJdX+Z2laatiJ2nM0FHye7xFZT7SUbadp/kXphfdUQFXv12GB3jD
+j8u3wijoO4CrtkmVY+xSOOA4QmrdF1H3j/kofeq5z73yCEXcxGn0lzFuVbHtbFXxlJZ9hGWRWmKa
+upDncSwXOU+mF/6FW1POpuPoHoccZ2jgqthJmjB0lBA8z9m5HOccjXb2NpVSwnSijzkcngPnc35U
+HqfDoO8UXs3T7Kuyz8LKxwHHCSgEBp2VjaKgH53lO6RVhkK835a2hFkoE7WvVQURWtOjsk9H4fV0
+mL/keRzL48lya8qUZBTe5ZDjFA1dFTtJ04aOstlkg+QVZfZFuNK5p7TkYHhOHLiMg6J36UD1weAf
+RsOEX3tajgOOU6gwXveor9o0rfXdhyYTAhu7bu8yUEq0JNZ83UuDZ1TkRevWBgsTfjQapk/KPkcb
+FDbf7nBrytRQCJRReDfd5TeaJzV5VexJdR466r0nwRM4LsRZR8nO3mMVmq6Ow9tcBcOWRUqJOtZ3
+kwEH7G3GAccZpNJ9DLt381HGLStVhAiOqF2VClMKwui6zfLWDPtDIVr5XIZCIGCwwfM4Fou8J230
+nyS3pswEhUARGQ45Tmr4qtiTajt0lAhQ40rZx6ibdC/ZosK+iFY69yVXbcydd46UVmHZ56gyISUG
+K+HdvZ3BY75J3U6tvCiYxbhlpbfhHOxyy0rFIAI419h1e5clTHy/yNv1mG3jCxnP41g8Z4uvo17n
+ftnnqCMUAoXRd9MBhxwHmr4qdpI6Dh0lAOAKjuk5aykZDB8FkbmpI67aWBQiABQiKPscVSeEwOhK
+50GyO3xKDR/qzN7FAceUpAmvgzS/zUfp46ZPP68LFAKJXGsGS85qvFUFqS2PV7LUa0tf+0k8j2Nx
+Cltsd650+9yacnEoJYqAQ44DbVgVO0ntho6OEw42hXQv2SLnv417nYcoJf+tLRIRCCH6ZR+jLsIr
+8UY6TDZdwTeB2oQDjhmglCij7kaRuWe+KPgbpQIIhKzNm6USBCZct2lLWlVa/paK53HM37g1Rf5J
+B/r9ss9SdxxyHNeGVbGT1GvoKJV9gMrL03w72dl7HEThTR0GN8s+TxsQAAiJ75V9jjoxq/H9LE9+
+dJav3dqCA44ZoRCo4viuI7HLfe8VgMirYs8hTHy/aEF7lUdh2vxQ4Hkc8+cL93XY5daUeXkbcow2
+yz5L6VqyKvakWg0dJQCl1AdlH6OKvPeUDobPUYhhvNp9gJIr3JbFObfD3T+zM93OeubyHwoOOVqB
+A44Lkia8LrT5bZ6MHrXxLkxV8KrY8423qrSgVcX7G21bFXvS23kc/AJ+WYV1FK10rvIb9/kahxzq
+k9aHHC1aFXtSXYaOcv3GZFmab6e7yWbQiW4rw9VtS+fcd8ABx4WYOLyVu3zX5jUIWNmlcMBxCSgl
+6s7KQ5vRc25ZKYcQuOZbflE7jda0qvBDAXQUXs+S4s+ND7QWTEnxRIf6WtnnaCKUEr1Sn+TJ6Kuy
+z1KWNq2KnaQWQ0eJgC8k3/LOUbozfCYRRbTaeYA8l6gUnmfDXIqJw+sFwFVbhyoydmEccMyBjqMP
+nUdnU9vaN2ulGa+K/bbsY9RB01tVECUQuddln6MK0IR3R8Os3XfIL6Gwdita6zwo+xxNprREB3gt
+T7PGPiedqWWrYiepw9BRvo4cS0fZdp7mXwS96I4KeF12mbynAbeoXE4QBn2n8GqeZnzd1lAccMyJ
+DEwfA/MHbllZMkQA8rxJZQooJVrX7FYVT/5N2WeoCqGCezyPY3bj1pRY8CaAxVOB7juCq20MOdq4
+KnaSKg8dJXJftT3hcM7RaHe4qZQSphN9zFUb5fNAwCt4L08Hqg8a/zAa8uDrJuKAY44OWlZcTs+p
+cK/KPk8boBBIhd0t+xx1EYRNb1VpbHYzM5QSU8vzOGalpHgShIa3ASxJW0OOtq6KPanKQ0c9gWhz
+DUc2SF5RZl+E3eie0pKrNirAO0dKq7DsczSF1BJ1rO8mgyGHHA3DAccCyCj6kLyIizR/VuXSy+YQ
+gv+eZ6DDfy4K+33Zx5g7RHCWBmUfo0p0wPM4ZmGz/BW3pixfW0OOtq6KPanSQ0dbmG8462i0M3yk
+QtPVcXhbcNVGZRAAIIig7HM0iZASg5Xw7t7u7iO+lmgODjgWRAamL4LwozzJnvAbmMUigd22TqO/
+CKl1vyjEfzbtcYlCoPfN+m+aB57HMR1yjqJevM2tKeVoZcjR0lWxk1Ry6KiHvG1PBtkgeUWFfRGu
+xA8kV21UDxEAClP2MZpGCIHRWvdhsjt8Sg17b9xWHHAsEEqJQbf3oLDuz1QUzbtjXhFCwBXuTJiN
+NOFtm9pGXvRyAv8unscxBe83g9h8UPYx2mwcctDVPMvb8Vht8arYSao2dNQDZG3ZouKspWQwfKRj
+c01H4W2e8VBNRAAo8UbZ52iq8Eq8kQ6Tp5UKWtmFcMCxBCqM1wlUVIzSz6vywt0kiPIar4qdDQqB
+oM1601pVyFKPHwrv4nkcZ7NZ/qpzpft7flNfPhWYvnOuFSFH21fFTlKloaMefCuGOaZ7yRY5/23c
+6zzkCraKI4IWPCRLZVbjjTQb/tkV/H6pzjjgWBKpdV9E3T/mo/Spd46/aeaJV8VeiNS6X+QNa1UR
+ADxodDKexzHZYWuK4tWHVdGakINXxb6jykNHmyZP8+1kMHwUROamDgMerFwDREXrN/ssg+l21rN8
+9GNhOeSoKw44lgiFwKCzslEU9KOzXC4+VwS8KvYCZBTetmnxpOxzzItHYfiG6OnQhHeTYdrgLToX
+wK0plaQC03fWXbW5/XPZZ1kUXhU7WRWGjnrvCRt6q9x7T+lg+ByFGHLVRr14AtGWtqmymW5nPXf5
+DzbPG/sa1GQccJRAhfG6F/qqTdPK9JrWGiJQkfOq2AsYt6oEtxrTquL9Da7gOBsqc9+m+Vdln6MK
+iizf7qxxa0pVqdD0i7z4RVNDDl4Ve7rSh44SgVDYK+VzL1CW5tvpbrIZxNFtZfT7ZZ+HzcaT3+OX
+q+UxcXirAPqF5Yqy2uGAoyRS6z6G3bv5KOOWlUtCIRCAh0teVONaVZrxX7EwKCXmFq61fR4HOUem
+F/4FNbemVJkKTd/mxS+a2g/Nq2JPV+bQUQIA0aBeAO8cpYPhM4k4jFY7D1Dy6tc6InKtmAtTJUEY
+9J3Cq3bEIUedcMBRonHLSm/DOdjllpXLISF7PI3+4prSqoIggci9LvscVadM0B/tuf/V5gsrT+4L
+E4V3yj4HO58OTT8b2R+oiSEHr4o9U2lDR8cJRyOko2w7T/Mvgk50RwWKqzZqyntPQkpZ9jnaSAeq
+7wP529EweVr2Wdh0OOCoAGnC6yDNb/NR+rjNFxyXgQJ4L/gloBAISt9yhX1V9lkuBQE8+TdlH6MO
+VI2Muo0AACAASURBVGQ+bOs8jsLm250rK78TyHcx60JH5lbaxJCDV8WeqbyhowQosNbvK5xzlO4M
+nymlhOlEHyM/39UaEYGWGJd9jraSWqKM9d1kMOSQowY44KgIlBJl1N0oMvfMN+0N3DKgvMEdKpcj
+g6BvLfxQ/5Ct5sdfojbO4yDnyXTCv0huTamdJoYcvCr2fKUMHSUAlHhjaZ9vzrJB8ooy+8L0ojtK
+S36uawKixlQV1ZWUEoOV8O7e7u4jbouvNg44KgSFQBXHdx2J3SLjlpVZCETwRNyacEkyjO5Y674o
++xwXhgjO0qDsY9RFG+dxeLLcmlJjjQs5eFXsVJY9dJSW8UkWwFlHo53hIxmaro7D21yl1hxEAKgk
+b/wqmRACo7Xuw2R3+LT+NwSbiwOOCpImvC60+W2ejB7xN8/0iIBbEy4JhUAQ6jeupoNvUQj0nr9n
+ZtGmeRyFzbfjtZVf8Zv+emtSyMGrYqe31KGjRFC3dZzZIHlFhX0RrsQPuGqjgWr4mGyy8Eq8MRom
+T0vb9MTOxAFHRaGUqDsrD21Gz7llZQqIQM7xnfs5kEHQtym9rHP5XZ3PXgYVmQ+TQVr7IbNnIe9J
+G/0nHrLXDDoyt5Ik+5FqGsYe4FWxs1nW0FFy9Loul5LOWkoGw0c6Mtd0FN7mLRvN5Jx7yV/ZajGr
+8UY6Sp43dctXnXHAUXE6jj50Hp1Nbav65GeFQiB4xxe1cyLj6CObF7VsVSFLPR7DMTsMzEaeZo19
+nnG2+Drqde6XfQ42PyaO1pNhWvuQg1fFTm9pQ0eF/7kO8w7SvWSLnP827nUeopI1ODG7MO8zruCo
+HrMSf5jlox8LyyFHlXDAUQMyMH0MzB+4ZeVs5EWP/37mA4VAL+RvnKP6PWELAB40OjuUEq0V15pQ
+9n9SYYvtzpVun1tTmqcRIQevip3JMoaOegJR5YmOLhtXbQSRuanD4GbZ52GL58kn1X1EtpvpdtZz
+l/9Q2KLemwgbhAOOmjhoWXE5PafC8TfQBCjrvdKtalRg+jZ19WtVQVG3E1eGMkF/NGzePA6t5Tc6
+0Nya0lAmjtaTvRqHHLwqdmZLGTpawatJ7z2lg+FzD/A67nUeouSqjbYg7xyH9NVl4vCW9UVs82Wv
+tGaTcMBRMzKKPiQv4iLNn9XuwnPReFXs3MnQ1K5VxZO/zRUcF6ci82EyTB+XfY55cbZ4Hq50Nso+
+B1ss06lvyMGrYi9moUNHK3i3PEvz7XQ32Qzi6LYyHNi2ifeeUHCYVXVBGPQdwFU74pCjbBxw1JAM
+TF8E4Ud5kj1p2p3WyxCAAOB3yz5Hk6CU9WtVEcD5xiWhMvebMI+jsI7ClShEyXe92sB0ovXR3ujP
+tZtqz6tiL2xRQ0dJgKvKvAPvHKWD4XMpxDBa7Tzg57P2ISJQCntln4OdT4dB32m8Ohomm2Wfpc04
+4KgplBKDbu9BYd2fqSi+L/s8lYAArvB/LfsYTVO3VhUECd5z0HUZKCXaov7zOJQUT4LQcH96iwSd
++G66l25SjcJ/XhV7cQsbOkokqrCNJEvz7TzNvwg6XLXRagSVbJlik+lA9WWsP0kGw6dln6WtOOCo
+ORXG6wQqKkbp53W5AF0YRPBUJGUfo4lkaD5yeU3uMCIAOcdB1yWpoN7zOAprt6K1zoOyz8GWT3fC
+++mgPiEHr4q9nHkPHfXeEyCW+thxzlG6M3wmEYXpRB8jz15oNyIQEq+XfQw2PSklBivh3eHu4HHr
+r89KwAFHA0it+yLq/jEfpU99DfuP5wWFQE9UlH2OJkIp0YFYq0+rCr+WzENd53EU1lG0EgsewNde
+uhPeTwbJ07oEdLwq9nLmOnSUCIQQag7HupBsmL4qsvwL04vuqECtlXUOVh1EBAJxtexzsNkIITBc
+6zxIdge1eS1qCg44GgKFwKCzslEU9KOztrXDbTyg4aR0MZSJrudZ8aLyf7+IQIXjSp45qeM8Dm5N
+YQAAphNvDOsScvCq2Eub19BRAgBUGM/pWFNz1tFoZ/hIBrpr4uhj3pjBDlBRvOYHQ32FV7obo2Hy
+tC5VhU3AAUfDqDBe90JftWm6mMniFedRBLxub3GUCTeq3qqCQiCR50qeOanbPA6b5a+iVW5NYWO1
+CTl4VexczGXoKAEse/xGNkheUWFfhCvxA6UlV22wYzzAm6oMvWUXY1bjjTRJnruavJeqOw44Gkhq
+3cewezcfZa1rWUGUH7Qw11kalBItiDWqQatKGwO+RanLPA5yjqJevI2KW1PYW6YTbwx3k0qH/rwq
+dj7mM3SU5negczhrKRkMH6nQdHUU3q7CYFNWQc7n/MioP7MSf5jlox+d5ZBj0TjgaKhxy0pvoyj8
+D21qWeFVsYsXmOh6VvFWFSrA8BiO+VKR+TAZpE/KPseZvN8MYvNB2cdg1WO68cZwZ1jdkINXxc7N
+pYeOEoCUauEDHdO9ZIsK/23c6zyUXLXBzuDAZdyy1Aym21nPXP5DYeczFJlNxgFHw6kwugXS/DYf
+pY+rfvd1LhDAOV4Vu2jKhBuuym/GPQU8aHT+MDAb+Sh7VvY5JrFZ/qpzpft7vgPKTmO68cZwe6+S
+IQevip2vywwdJQAQAhY20PGgaiOIzE0dBTwriJ3Je7+8kiK2FCYOb1nvnM3nvN6aHeKAowVQSpRR
+d8Omxee+6b1fiOAdD5hcNJQSra9wq4oUFbyEqT+UEq0T/1RY+6rssxz1tjWFNw6ws5mVzsZwe+9p
+2ec4iVfFzt+Fh44SwSLmHXjvKR0Mn3vnf4h7nYe85YlNhQiU1itlH4PNVxAGfQdw1Y445FgEDjha
+AoVA3el87EjsFllzW1bGq2IdD5hcgnGrin1R9jkm8eRvcwXHYqgg6KdJMaxURZj3nwZRwK0pbCpm
+pbOx92awWfY5TuJVsfN30aGj804e8jTfTneTzSCObqswuDbnD88ajAiAm1OaSYdB32m8mo/SSlbG
+1hkHHC0jTXhd6Ga3rPCq2OVRJtooclu9FaICON9YIB1F61WZx1Fk+XZnrXuL+5PZLMxKZyP5+6AS
+j+FDvCp27i4ydJScezmvhMM7R+lg+ByFGEarnQco+XmKzYgIBIorZR+DLYYOVB9C+dFomFSusrDO
+OOBoIZQSddx7YDN63sSWFV4VuzzjVhUM/AX6nBcJQYL3PGx2kaowj4OcJ9ML/4KaW1PY7HS3cz/Z
+HVbnTSWvil2IWYeOeg/ZPGo4sjTfzpP806AT3VZGv3/pD8haiQBAIHLVT4NJKVHH+m4yqNDrUc1x
+wNFiOo4+dB6dTSt4B/4SUIj3+e798gQmXLdZ/rjscxyDAOQcD5tdoCrM4/BkvzBReKesz8/qT8fR
+vaqEHLwqdnFmHjp6iXzDOUfpzvCZRBSmF20gV5exS3DO7fDs7OYTUqJZje4Nd3Y3m1phv0wccLSc
+DEwfA/OHPBk9aso3lBDIbxKXTJj4fpFXbbYLPwYWrcx5HIXNtztXVn7HrSnssmQU3k13K1AezKti
+F2rqoaP+4vlGOsq2izT/wvSiOyrgyjI2B859t4iht6yawivdjdEweUoNuSYrCwccbNyy0ll56PKG
+tKwggiPiN4lLtN+qQpUJyRCBCt6mswwH8ziWOfeGnCfTCf8iuTWFzQEKgSIypYccvCp28aYaOkp+
+b9YLSuccjXaGj5RSwnSijzl4ZfPiF7PUh1WYWY03RqPkmWvCNVlJOOBgh2Q0blkp0rze03wRAZzj
+N4lLFphw3abVaFVBIZDI8zadJdmfx/HFsj6fc8XX3JrC5qkKIQevil28aYaOEoIXM/QEZIPkFWX2
+RbgSP1BacujK5sp7GnDC0T5hL76b5aMfneWQ4yI44GDHyMD0RRB+lA3ru2VlfHHr0rLP0UbCxPcL
+W7VWFbZoKCUWhL8pbP79oj/XuDWl2+c7pGzeUAgURt9NB+WFHLwqdvFmHTp6GmcdJTt7j1VoujoO
+b88SijA2LQ8E/NhqJ9PtrGcu/6HgkGNmHHCwd6CUGHR7Dwrr/kxFsfALlkUgEJJXxS4fSomWqtGq
+QgUYT/wYWJbxPA63N/UQvwsg70kb/Scd8EYCthgoJYqgxJCDV8UuxWlDR733JKaYwJHuJVtUuG/j
+1e4DyVUbbEG8c6S0Css+ByuPicNbGRXO5tOvumYccLAzqDBeJ1BRMUo/r11YgBjzur1yVKZVxVPA
+g0aXS0fRerq3uHkcvnBfh93O/UV8bMYOlBpy8KrYpZk4dJQIUOPKaX/GWUvJYPgoiMxNHQU3l3JQ
+1lpEAAgiKPscrFxhFPQdwFV7RmsdO44DDnYmqXVfRN0/5qPssXeuNiVSvCq2XJVoVZGibrFcI4gg
+Wsg8jsIW29Fap4+SW1PY4r0NOUaby/y8vCp2uU4OHSUAmFTB4b2ndDB8Ts5/G/c6D1FKfh5iS0Ag
+UPTLPgUrnw6DvlN4NU+zr8o+Sx1wwMHOhUJg0Ok9LAr60ZV90TolIXDNc8JRGpQSrSu3VcWTv80V
+HMuHUmBBau7zOLSW33BrClumccihPllqyMGrYpfqnaGj44TjmDzNt0e7w80gjm7rkKs22PIQAQiJ
+75V9DlYNOlB9MPiH0bACa80rjgMONjUVxute6Ks2Tc/fI182RHCOV8WWKQjDdZvapd79PEYA5xsl
+UYGa6zyOwtqtcKWzMY+PxdgsUEr0Sn2Sp9lSwn1eFbt8x4eO0uHPH1RtoBDDeLX7gKvH2NIRAc8X
+ZUdJKVHH+m4yGHLIcQYOONhMpNZ9DLt381H2tNItK4jAfcwVoM16UdhSBtUiyDI+Lds3r3kchXUU
+rcSCLy5YWZSW6AiuLiPk4FWx5TgcOmrJK6U+yNJ8O91LPgs60W1luHKMlcMVxddTzLxlLSOkxGAl
+vLu3M3hc+RvOJeGAg81sv2Vloyj8D1VtWUEhkAq7W/Y52k5q3S8K8Z+ltKrg/psDVpp5zOOQwm8G
+oeGycFYqFej+skIOXhVbjqgXr+9t7362+7c3n3tb+CAI7nrrvLOWnHXj/7nx/7xz5L0n7z2d/5EZ
+uwSu4GATCCEwutJ5kOwOnxK/XrxDlX0AVl8qjG6Rc5SPksc6NPert6dbCO+9r9652kWa8LYdJU+C
+OHiw/M/Oz/llQimwyNVvpM2/Vzq4NuufL6zd6l1d4a0prBJUoPtFbiFPs5dBaG4s7BPtr4rlF67l
+cNZSkdmXzvmfw050PU/Tn1ACAnrhHb32zv8Mfv/L4QFo/3WFLA0AhffgAYgEIPrDAaUeegBw7Dai
+EODBi1BK+faxg3j8t+GRHx39x/7vE0LwjckW8eT3+C0sO0t4Jd5Id5InJop+L5VcLfs8VcEBB7sU
+lBIh6m7YJPlcB3hDKFWZby4S2AXvOf0uGQqBTge3isJ+r5Se+SL34p8YATxxL3vJxvM4Rltx1+2g
+nP7Fl9xBawpvK2DVsZSQg1fFLtzRUEMH+h9UaG4GUgqXWVKRwsLa/y2k+Jsef42nft06LBc/+Mfh
+/zvyL/7oT739Ok8KUwAACvDHw5QjBAgQ5I0XIngnTAEAier24U9ODFP2/wVP/hRymFIB5B3fpGPn
+Mqvx/WxvuGV8BFJX5zqsTBxwsEtDIRA7nY9dln4Hmf1JGb24O1szQAFX+AZ+NUit+zYpvpRI7wlc
+ziwFFAIL61IdLeOzsbPoKFpPB8PNaDW+N+2bNRTiSRCah4s+G2OzWnTIwatiF+O0UOPYb0IEKoo3
+Ubdz2+bFm2Q3eRp1w0+mfd06fH47+McsB9RwDRYQprz9NX/0z+54R3+dGKY4SgBEMW2YAjAOVI6F
+KQAAiFOHKeOPwYHKUd57Eij5Oo1NxXQ761mSfhMAgOKQgwMONj/ShNcPW1ZMcH9ZF7KnESiv+cNX
+b1Y2GZXZqsLKJkz8SZaMPg078b3zfq/N8lcrv1j5wzLOxdhFjEOODPIsfxmYYL4hx/6qWKlPXDCy
+mbnMUmGPhhrhzeCsgcUIhxf7OlB9peXdZDB8GsbRP1ftzuilwhSAtf3/Tc1774+FKYf/clqY8jYg
+Iee+2v9FcTRMAQ8Zkc8mhSlAXoIQ8aQwBYT8tRTi7dfjtDBl/x91DFOICLTEuOxzsPowcXgrS9Lv
+vC9+0kFYiZvNZeGAg80VSokY9x7YZPSl1vSPpbasIIIj+haP9ruy0qAQ6JReaqsKkZeevBfIJZ5l
+QymwcMGNIrMvz6ryIuco6sXbqBRvLmCVpgKzkJBDIoCzvCr2Irz3RHkBM4UaRyAAOPKHf/dCCIxX
+uhtpkn6jyP2kzQJnr1ScEEJcMEwBqdW/zPL7ZwpTxn/g8M9eMEwBEKI3KUwRBFdRqfcOf/Joq88i
+wxQiABTmQn+WtZaJw+t5mr+BNH2pw/aGHBxwsIXQcfShy7M3PrVf6VCXdxeKIC3tc7N3yCDo28Qt
+r1XF+Xj8FojzjSpQgeqno9HfYoWnz+PwfjOIDQ8WZbWgAtMv0gxymF/IIaREO0ozA+E8PlzjvRNq
+mODXs4QaxyCCc8U77xvCOLx1kZYVdjFLD1PG//JOh8/RgSmTwxR6CeDTo60+xcEQWud3xz91Ygjt
+QZgC8M4Q2qNhSp5bkt7/BrUkKWXlK05YdQRh0Ld5AT7NvgpC08pKQA442MLIwPTJubU8GT7SoXmw
+9DcEiEB5ugtGL/XTsrMttVVFjN+L8DvR6jhrHofN8lcrV1d+z0PVWJ2ocBxyWGH/rAM9l5XGB6ti
++UJ6sqOhBjn4WRl98VDjiLPutle9ZYVdzNFWn9nDFJjp+/3cMGX/Hx4ANKBIfvz+MVIndkJlHoUE
+oa+gCm6gQkBEEBx8sFPoQPWdcGujYfI0mqI1uGk44GALhVIidlYeutHoS6mW27KCQqDjVbGVc9Cq
+4pzbkTNs1bgIJ+B9XhVbPZPmcRy2pmhuTWH1cxByAMB8Qg5eFfuOg1Ajy+0XgiA/CDXwkqHGSQIQ
+TnvfwC0r7DJmCVOkkpLWVlSg6Z9c4f7dhOaPHpzwlADl9LIgeEMOHEjd80JdV1qvgkLgag92QGqJ
+iHA3GQyfxr1Oq0IODjjYUsho3LICaf5MhcHHy/q8vCq2mmQQ9O0o+QyN+HiRdyhxxiFqbDkmzuPw
+/tMgClr1AsyaRYWmb0fZTxLFDl42zOdVsQAwDjWKvACb2y+EB6dMsG6i8M68Q41jBPbOe9/ALSts
+GYSOr0s9uqIDXBsNh1/oMLyhtFqVWt48qE0mIu8pA6Bsp0iL73KLu4fVHkF4AxG42qPFhJQYrIR3
+93Z2H3V6vQdtueEr3v/v/41fQdnSkHNUjJLNIFrOlhWXpVuBCW7ym4/qIe/J56N/C4y+s7DPYR2F
+vVCgkvz1ryA7Gm3F3eBXVDjqXV0RqBUHUqz27Cj7Joz0f7lMyFFklpRRQmrVuueuSaEGKlzFJb2O
+p4PkuYmD29OEKN57Gg2Gn3LLClsE5xzh6OcvTKQ/BgDIR/kbV8C/m9h8dNbwdE9+PKeVPJCjl7bw
+296Lgqs92i3dTjajXnxvWc+lJ9lRRlqKpbyuccDBSlGkyZaUootKLXSbhrOWtEKBJ3fds0pwef5G
+SpKLalUh50gb9UK3dMhSHaS7O497V7pBtNr5CECMB88jAtZgjR9jp7lsyFFYRwD0wsRhK567vHNU
+FFRaqHFUOky+NKH+l1neN6RJ+o1SKLllhc1b/vf/3Ox08N5BoOGco2yYHVZzzPKxxtUeHrzz3zvv
+tguLu16gAVS9cbUHAiJwtUeDZTvJZhjH9xZaBXcKDjhYKzhr34BN/12G5qNFlUyRcySBfpB6OWtJ
+2ezsMHlmYnVnEY+BccAhX+iwHRcJdVJYS9b6TSGVWr0S3hRS/OQdZAAA4Ipd8B688BKFiAEApIbr
+AtUqCgGAAg6ue5DfiLGKukzI4Z0jZ+nfTC9cWIVb2aoUahyVjzLSGmeu/LN58cZl9puwGy6lQpW1
+g80sGf/3wckwIx/lb8iL/xmY4M5Z1RznOVrt4Rx9XRQ+cQQOVdDlao9myvaGWyaIfiWXOBcRYLkB
+B8/gYKWRWvdJqbU82XscGP2BWNRdfII3EoADjoqScfSRzUdfLKRVBRHAUz73j8suhJyjInevQQV/
+RbVyKwhIqk70safRCx0crbIxALA/cX78f+D3p8478uAL95UnL7ynoXCZAwDwAgwKCIQSRiLeQNx/
+L7Z/R4qrQtiy6cjcSkfZN2EEMGvI0dRVsUdDDemxQKNumTi8U3aocdJF7vztb1nZSAfJ50Ec3uCW
+FTYPKlCQ7dA3SsOxGVVBFPSdc2vpcPj5Rao5DggU45GnEkBqeTuA8Wuv9wSeMvAu/d4VbjufVO2h
+8MzNQ6yaTLeznu0NtwIfwUUfN1XHAQcrFQqBQaf3sEiTLST6SWo93/JORCBrBwC8KraqUAgshPyN
+c7QjJc71iRaFwMK6VEfz/KhsVoUtiBx8IQIDaiW8AwDveec/DXrdDfKebO4GwYQ/J4QQk6fNq385
++qOjQQiAB/IA5D04R6+B6A0AALh8F7wHQAAB0AMAkAH2hcD3uCqELYqOzK0kGW3F8ewhR1NWxR6G
+Gqn9QorqhhoHJCJcdMCrEALDlc7H2d7oO+ItK2wOhBDoMQzJFf5kW4GUEuOV+ON8lL/JCvfsstUc
+Rz7nuKgWAUDB+wrU+yY8qPZw4GkPXE5fFwlXe9SV6XbWsyT9xnv63zoI5rLevEo44GCVoMJ43Vn7
+xqbpU2XMJ/NqV0Ah0HnHbVgVpwLTt8PkGcZiIa0qbPnIeXKF3fFe/Qnj7q+1UncEoqCi2PZC/CXo
+RRsA+9+jBKeuZZzGaUEIKrgGh9VbU1aFgMtEkWUAb6tCUEqPEm5zVQi7CBNH60ky2oo7AnCWSsUa
+r4r1zu0PCnWHoUbYDe/UIqxBAE/uWwB14XDCdKPrzloa7SaPuWWFXZaM4tvObr9GiROrkQ+qOUaD
+4eMgDj9Y1F35U6s9iMB7rvaoGxOHt/I0fwNp+lKHYaPCWA44WGXst6zczZO9p4HR/zyvlhUSsteE
+u2BNJ0Pzkc2zzwOj57pGmIikJ+/ncVeDnY+co6LwL0EG26rTvYdKPjj8tbzYFlr+TZ9cFY3Y9eRB
+LGEW8LRVIQAAnmhcE+LfVoWQ9zs+p+8AAIjyAZL3IAQI4XsAAChFH5U8rArhwakMYD/kGI624k44
+fchRs1Wx3jnK8mKHrN2SKJUM9J2wq+sRahyD4AjSy75BllojKsUtK+zSpNY4Gvj/0Ob0dmspJXbW
+4odpkn3nCvfXIAw+WMYNIyGEOHztPqfagzwWQire5FIhQRj0bV4AjNKXOmpOyMEBB6uU/ZaVjSId
+fYNk59KygmL/1i2rNJQSCyf/ae6tKg7icUd1zd5j14zN821yuCU7nb6O9DurmYs835aB/psy75ZC
+ehF8UMULuYP/hqP/IQiwBhr219m+WxVytEWGrHvpnc/GVSG0XxVyzuBUDkIay8TRerI32oq704Uc
+Uso1X8Hvi6Occ2SPhBrKBHcw0PfqF2occfEOlXdwywqbFxF0rrsi9fKc4bdhbK47566NdhdbzXEe
+rvaoDx2ovhNubTRMnkad+N75f6L6eIsKqyxyjlyWbOrQ3L9MCs2rYuvFJsNNE+l787rz4PL8ebzW
+vV3rN9wVdXRoqArj3wslVyd93Yos35ZmcrgBMN6oEkv7gwyav+3oaFUIHAYifscX46oQ710iHBVH
+q0KEEkZKeYOrQpohG4624m74q/NCjqquij0WakipZBDcQRTQlOdY7z3lg2QzXIkenP+7p+esJZsW
+m9yywi7CWUcq//mFDvXUzwdpkn0HgH9fVjXHRU3a5HJY7SHNdSWRqz2WwDlHxV7+WdzrLCTkWNYW
+FWctKS7dZ1WFUiJE3Q2bJJ/rAG+IC64zEoDgPb0GkI2/eGoCacJPXJ59rcz0L+JncQLe995z/cYc
+HQwNRRMZtRJ8gFK+f9rvzdN8y8Tml6jVqUOsEBGco1ZsOzq/KmTsvKoQAJg8OJXX6Vae6UxXySER
+wFmoxBaow1Ajt1tSSaWCBlRqnEIIgbSA2V3cssIuQ2qJ6QCHykw/r6oq1RznObvaIwHv/Gtn3Q95
+gZkXaEDqX6E273G1x3xJKRFXwrt7O7uPOr3egyqHYqfJkmzbg/2bqmJZMGMHUAjETudjl6XfQWZ/
+UuYCLSsIQA7eSNX8i6cmQCmxKMSamFOrCsLxC0d2MeQ8OWt3APX/J8LuPxwMDT3rz+TpaMt0Or9E
+Jc/8GqCUWKTFbhBxN9mBUwenwtGg6OLrdHlwarlMJ1pP99InYS/cOG2bSNmrYtsUaizLsZYV537S
+IbessOmJqHOT3BCkklP/mbJmc1zWidke1xSoawYOqj0K8GTB5fS13fMDL9ALqXpCmQ9QIQBytcdF
+CSEwWus+TLaHm3EvrtXz/Wgw3JIGfqm1vqlcbj9XkZzrUD/G5k2a8Do5R/koeaxNMFt5JyL4Ik94
+VWx9KBNdz5Ph4zDSl2pPAgBAkPutAOwinHVEzn/tVZCobvceKvlwmj83bbhxgISUXFF4MZcdnOo9
+fU85bQOMB6cK50FI8AdVIScHp3JVyHzoTng/HZwdcix7Vaxzjmxmd8gWb0MNE8ytZbA+cKHPR2+3
+rOw9Nt34flVX5rJq0UGwlg53P+0oOXMLwdFqDhNHH0g9n0H+y/ZOtUd4otrD+teFdT/knqs9LiO8
+Em+MdpLNMI7vnVxPXEV7OzubYaxvHbznVORcfpn1fIwtC0qJGPce2GT0pdb0j9O2rIzXUFKx6POx
++VIm3JhLqwoCuKL4GpWsVB97lZEfV2scDA1VSs80w8Sm6bOw1/2dQJy+eqbGKzHrZFKLDAC8LzXs
+txlNGJzqPRCcsU4XvUQQMVeFzO7ckGMJ3xfOOrL2RKgRmhaGGm8JxHjRo6kPWlayQfK5jsMbVW0f
+YNUhpETvtSQif5FQ7Gg1R1Fgbao5zvNOtYdR1wCmq/ZARBAc1k9kVuONdDf50oThP8oLjglYW0gB
+XAAAIABJREFUNOccpXt7m1HX3D+6LVEVSeKlVnT45hVPfI33f8xvTlhV6Dj60OXZG5/br3Qw3cWv
+BzQc5NULSol5IdbQ0Q5eulWFSzimcWxoaLT2e6XkzBc5+Wi0Ga50Zy5r9FjNTSptxet0l0d3wvvJ
+INnsTCoHXtCqWGcd2TR77Z3/D9RodBDcES0PNd6xhKejw5aVJP3Oc8sKm4IMex85u/0aDV647bop
+1Rznmbbaw5HIPcqAqz3eZVbiD7O94VbgI6haCGtH2XYB+atoJXxnILT41b/+3z+j1mvjFzX/vSd6
+QwTi8Jnd+8z78Xq7Y4h6sP91F0IAAngS4tcAsIpHXx9PCUwAODRhl0POkRvtbero/InkNkufhybg
+TRo1dNlWFfKetBYvdFitTQRVcnRoKAbBBxfdOHTRcGN8Bksh2h+0af4mlbY6OTj1cIsMuZfewf7g
+1GIXvD9/nS40r0UmG74bchSZJWXUXKbOHw01VKD/D9TyhpAIHGq8K91Ltkykby5z+9r465NucssK
+O4/d/ulJZ0Xfn8fHqsumlUU7ucnF5lztcVSWpN8EMugqrU4dKn+eeW5RGSXplkAnAjN5gL341f/z
+r18qY2a68PMHi9lP3lU48uP92zngiV4C+PR4aEKJ9/5Yy4AnAAHj0OTg+2s/NLmNJ7/fODRhR7jR
+6Eup4MyWFV4VW1/kHAmXvVBTVuu88+e9J+Hdk2ilO9XsiLY4PjQ0+gep1LXLBIB2NHxsVlcvHkQ5
+R5pGL4LIcBDF3mmRAQAgT++u04W3g1OFEkYi3kDE2laFZHvJZmflbchx2VWxB6EGFe6v2phfcKgx
+nXyUkdIopFr+e4Z0L/lMh+Zm1e6WsurIBrtbHWNvzms2grOO0mH2pMnVHBcxrvbw4+Hdbr/ao8Wz
+PfI0f6MAftZBeKFKs3kFHKPd3Wc6lL9DrU5tgxb/57/+X0+CKC61LPEwMBn/4OQvjv9x5Mee6CXR
+/pq8/V/xRIN3/rDzEoSPj4YmAGBAiBscmjSLy7M33rnvT9sPTtaRUn6Akt8w1FGejb4zClcu2qri
+qXjEAcfYsaGhUXTvsqEfeU+U55+Zle6l96b74d8fxasd/jqxqZ1WFeIcvQbybwDgsCqkLut0s71k
+s7PauSeEEN45cpb+zfTCO9P+eQ41Li/PLCn0c7nTeBFZkn4nJabcssImcdaSzLb/EkQX2Cx4hjTJ
+vhOg/q5D1epqjvMQkQcPraz2sGn+Rjr4WUezhxyXDTi8czQcDDbDnjm3yk0JAFf2g/jY5z/lKCd+
+9uZ5C5JmD03cV8eqTIjAk9sFAHBH/yx5A+CDg9AEx8UnV0GI96YNTTgwmT8ZmD45t5YNk8dBNGHL
+CgI45/+KEvjucA0FJrqeJXuPo9i802c3FSLR5hkslx0aeurHdY584eYSbgAAOCENb1Jhszh1ne54
+Lfh+u9OU63SPDk4tcZ2u6cYbw53hOOSYclXsyVBDh+YGKnnhUuK2kwDgvd8FgFJuipg4vO6s4y0r
+bCKpNaZ74m869L+b5/uaMDbXnW3+bI7LOvx+PG+2h8cMpO55gf2mVHvoMOjbvIBimGxGnXhjWZ/X
+Znbb2tFWvBpNdR0g/st//a/PVGimvjPQZqeGJhNacwBgx5P767HQBOAwNAEPAsT+L0w7zwTgeGjC
+VSYTFWmyJaXoolKHvfzkPUGefRZE4VwuxNjyXaZVxWX58/hKt3UzWA6Hhurwe2XCdaHk6rzeDJFz
+5J3/NOhFc3uBc6NkK45xqX3vjE1ydHDqQVWI9/Q9FX5/nW4xHpx6pCpk3oNTs93hZrff28gGo81o
+7d0BpM5asql9W6kRyBv8vTMfzlpyRfHCVKBljltW2CR5kryJZHJlUW1UB9UcQXTJTXYtR0Tekwfw
+sOMcfWdzPyBERFRxnas9nHNU7OWfxb3O1NdVF63gyJJs24P9WxDpifM2JlEeIJjlk7TZjJUmawBq
+bepKkxNVJjh5nslrAP/zYWhCdDgE9miVydF5JvvnbtU8ExXG687aNzRKP5eh+UgIIcarYh2viq2x
+8VYVDORF7vC37C1/YQtyBJ/KIOqoleADlPO9k0tFsS2EeKXnGG4AAHiUN3iTCquCC63ThfEWGUce
+vHMvvfPZuCqE9qtC3g5OVYH84LyqELPS2dh7M9jUgTpcFXsy1NCRuTHv728G4/dCFXkqCrvxXd6y
+wk6SxqwVo73PpZIfL+LjH1RzJDt7j00c/YGrOS4GEQWMn9XXpJZrJ6s9yPqXzrrdt9Ueso86qHy1
+h5QScSW8O9wZPI573QvPXzvPaDDckgZ+qfX04QYAgJJafbCIA7HpHD4gznhcHPmVawBwbc6hyfF5
+JkSHQ2BPC03qMM9Eat0npdbyZO9xEAYPBKLgVbH1F5hw3SaDR0EczjSnwYO/4r1vdM5BzlOR29dC
+6v8QYfcfAqUutM3kPEWeb0ut/6bCYP53dRDBufxbVJLfxLNaOGOd7jtvxs5bp+u9HQ9OPbJOVyi8
+svOff/87oH8FBN/pkEONZUAAqNIdEW5ZYSfJ8U2fIiDvxTtvxOf0ObTEzlr8IE2y71yh/srVHPMh
+hBBiv/BGKripjQKAg2oPB0D5jivoO7tX7WoPIQSGa50HyfZgM+5dbIPeabz3NNzd/TTsBPcuMkxX
+vP/f/xsJLmlkZ7j4PJO3vzLNENhFzTMp0mQLEZDIjXhVbP3tt6r8RQXTD9cqbE7xSqeRW3TGQ0Pp
+a6/MXIaGnqXI820Z6L8pE8yUpE+LnCNVjP7NdLhtkrXXyaqQwd/ePO12DK7+au0uB/TL4b2nbHf4
+JFqNKzf0mFtW2AGbWTL+74NlPBb2N61scjXHch3d5ELu3WoPpYP3oALVHtlOshl24ntnha/Ttqg4
+6ygd7X0Wds0nF33NU2dVDjAGcJEhsOpfLjoEFo/8+Mx5JvtDYI8NgAWYOARWCHm1KIrQDgY/BWtr
+JLQXdVobyI7bb1WhmVtVKlJuPA/kPbnc7hDhlux0ryulFh7c2TR/pcIgUWa2MsFZoJTo0iI9KP9n
+rI2OVoXkg+HTqNeNw5XwdrI9fBpPmMXB5k8IgZ5cJf+euWWFHVCBgmyHvlEaFj5f7qCaY7SXblGh
+ftJRwI+9JZim2qMoiu/snii12sOsxhvpbvKlCcN/lOrigVuWZNte5K+i3uVmJnLAwUqxzHkm4D0I
+p6iwhQcTPJcmUK4oBlQU3hXUE6K4LgBXBeJCJ+Oz+QlMuJ4lg8dhHE41TRlRgnNU+9aHY0ND4866
+UnIpK77zNN8ycfhL1Isvi+dNKoyN5YPh06DXvWeTvU0hAHQ33kj+nmxyyLEcAqWvalvrQcvKcGfw
+KOp1HnDLSjsJIZBktEbO+ouU8V9E1A3XnXWU7Ow9Crvxg2V9XnbcsdkeINfMFLM9lA7eg4PgYwHX
+OmYl/jDbG24ZH4G8QFXRaDDckho62ly+BVpV8YmbsYs4bZ6Jy7NXqHTSWV1VXgEqYz7QUSTelgF7
+AO/BWfu1L4qECle4wvUE+L4Q/j0OPqpJmnijsNlLpadsVfGULvhIC7PooaFnydPRlul0folKri3j
+8wkhe02fl8LYeQ7CDQAA4T0dBBq6G28kO8lmtHp2KTCbA4E98P7MGWllklpirLsPs0HypYrMP3LL
+SjupMLrhbPoaJV47/3fPx341x8PRXrolUSFXc1TDVNUeafGdzRdX7WG6nfUsSb8JwIPSeurnpNHu
+7jMdyt+hVnN5r6nm8UEYqyqbZs9NZH7tpXwPXL6pw+h2kedf6zC8fXI4HCp1mBh6In8s+HBuSLZw
+rrA9kGiQ6AYHH+WaqVUFEerWo7KsoaFnWXa4AQDgUd8AX6Xxfowt19Fwg5wjGehjPVu6E2+MdpMn
+YTf6vVTcC78w+02x1Yw33jK9+MN0lL9xhfuqCmtt2XJJrTHdg/+lDSwt4DjA1Rz1MHu1h7qutF4F
+hSAvEHqYOLyVp/kbn7uXOgjPDL+8czTcGz4Ju/rSlWjOOQICoII44GDNRN6Tz9NN0+ncF4jCO0dS
+6V+glJjnntQ5F8UC3445PRl8HFR9OOdeeud2Kctyci7wKHqC6MbB6j+syJTjJptlq0qRF7s6XMap
+LufY0NCV7r2ytiXYbPQk7HX/WSAuLdwAAEBEKKz7OjjyfcdYWxwNNwDGi800iuDk79NxfH80GG5F
+vQgu0+/MzoDg32l5ragwCvrOujVuWWkpHf/aFamXavmD1Lmao57OrvbIACjbKdLiu9ziLgkhBeor
+qIIb01Z7BGHQt2kOMEpf6mhyyGEzu23taCteMVMPc/beExGBLwg8Abgi+xrIJgLICeWNEmJFK7wh
+rv+//6Mez96MTYlyuw0CtnQcbRz8XJFbMrERKKUg58gX+QsdhnO7gDoMPgDAFcV+8JFn5J30TsRC
+uA8QEAA5+Jg3co4EZX85r1XFU/EoWulWbiI+wLtDQ6VS75XZY5+PRpvhynxXfk2LnCPMk88uO2CK
+sbo5GW4AABSZpTA8fep8PhxuRd3oVxfpd2ZnS5P0jQnkFSzhovEyuGWlfZx1hPl/vjCLWN8+4znS
+YfaEqzmaxZPf7+ofb3IpnH9DDtw01R42L96gpf8ZROHHR7eopMnoFYBLgmjy4HrvxkEGEYF39jW5
+4o0nOxCChFSipyVeBxSr42J8ASdXJXMFB2sUl2ZbGGihTLBx/BeKr4UYBxrTVnHM4uDjiPHHH3+z
+xvE4+AAA7z14516Tc29cmu1OCj643eViUErMLZKU53w9iUTVBsaRc1QU/iXI4O+q01lXcjlDQ89S
+ZrgBMP56enLco8JaZVK4AQBA5HaE0KdWUQWdzvpob7gVdS821I2dDoVYq+MdQG5ZaR+pJWYDOQxM
+ue9xjlVzSIU65GqOJhAoDhv6pYKbev/nJ1V7eBQSxNtqDyVxjaT8aDRMniqUdwH2h4ka+KXS+v2j
+bSXO5S/B2YEAlwF6qSR2tBIfgBbXhIFrQiiY9vHNAQdrjCJNnwVR+Duh3h1QgwIHRy/YVGAOZ3Es
+8kxHgw+Q8poEuKajCI4OOPXkvqfCbb/d7OJ7QtjrCGqVg4/pBGG4bpO9J0Fs7p/2e8hBtyoD4w6H
+hpqoo8LgA5TVuENoR8PH4erq/bJDFvKyx5tUWFucFm4AAADRdyDEmW1iQaezno7Sb0IADjnmCfHd
+rWw1wS0r7SOizk1yQ5DqvJ2Di8ezOdph4mwP8t57dzjb46DawwvZ3dvOn4HLXLQSdnzivnFADrVf
+UYh9qcR7gRY3x9UY+tKPFw44WO2NW07sk6ATP5h0QUTOEQZy5ejPLaKKYxbHBpxK+b7U8L4GOB58
+eNohW3zHK22npM16UdjvldKTB22V/PJ6dGiojHp/kFJWZtUjeU+U55+Fa2tTrd1dNC/lFU8e+NHN
+moy8p2Iv+ezUcAMAhKBkmrhRh+GtbJR+owEGWqtS5vY0jUQAInotYfnDG+eBt6y0iw6CtXS4+2lH
+yUq0d3I1RzudVe0RCEHZzvBJFOkPUOHbISALwAEHqzXK7bZA8RfdPWO2AhFgGFw/+dPLquKYxfHN
+LnJNKr12MvjglbaTSa37Ni2+lEgT51d476+UsX70YGgo6DBXK907ZQ0NPc04IHSfmZXTL7KWDvU1
+AO5SYc01TbgBACC8d9MGoSoMb9k0fwOueKnDsyfXs2kgEBVvoKYBx4HDlhXrvjIxt6w0lZASvdeS
+iHyVKnaOVHM8Drvxfa7maCdEFDoMhPYm8nny0vmwowK9sPfDHHCw2nJptiVD05FafXzW7yNHL1GI
+d4bYlF3FMQteaTsdacLbdpQ8CeLg3UoEFEt7k3owNNR79SeMO/+glLpdxccYOUfe+U+Dlc7G+b97
+eXiTCmsy8p6KYXZuuLG/Inam3U/KBH2b5wBpyiHHZdVvu/ipDltWtgePo5UOX2Q2lAx7Hzm7/RoN
+ViqU26/meMDVHO0mpMDCibS7qu9ko/xNntBXwYJCVw44WO2Q9+TT7FPdiW4JKc9fYSngZ8DJ1/VV
+rOKYFa+0fQuFQKeDW6e2qiz4zerJoaFCytLnWZyG8mJbSPFK96JKhRsAAKAQXOqSso/B2Lwdhhvd
+6NyKqdNWxJ5HBRxyzAMCgHXUmOchqSXGa90H2SD5Uv3/7N37dxtVljf8ffa51EWS4xhm0kMSnnmn
+yaUb8vYaIMQJf8Xz/EXvP0dwQshaQ4duTMJa03QIPJ0hal+kqjp1zj7vD7KDE99kq6S6aH9+I9jS
+gdiS6lv7Ept/V0Zzy0rHyEijHcKPOmpm1RHP5mCEZkDehShRa6p0q6Pt8n7U7919ewvKrDjgYK0y
+Kad3G3rKXwaiQEqhPO4is01VHGf1xmYXpd7c7NLhlbZS67VyfLhVBVGC9/QMlaz8A78rS/IkGjc0
+9DjO2qHU+qWqeaXccVAIDBRc07beMDaLs4Qbk28gkEZ+dJ7nmoQcjkOOGYiObnSKBumfity+8uOC
+W1Y6iFS8Rr4MTQ0PeDbHchMq+iiEycuq1ApXVuHe9tZoQyfJH6SSlYWuHHCw1iBrh0Lic93vTT8I
+kQjwlIFrXajiOItzr7QF/xGKdqy0lckxrSqB8qqeg7wnZ/3e0NCVRg0NPYmzdiiNfqkic+Tu8aag
+IAdN2XrD2KzOHG7A6StiT6OMWiutAxrnj6I0PrGVky2XKDZr3u9tWen3+E56h6i4d80Vvz4zCTY6
+OOBqjuWECsGV/plUv/18rlzQ6+Od8Wbpk3/oSFXyc8sBB2uFMss3TRpfwjP25HtyL7RMTizV63IV
+x1l0aaUtCoFe6TdbVbCahurXQ0NNbNVK3LihoScpc/tcxWasIt3ocAMAICh1hTepsC44T7gx+cbT
+V8SeRhm1Rt6vZjvjB8kgbc4g4ZYQQYiuVpJJKTFd2duywi0rnSG1xHxXvNRx+KDpP7dczbF8UCG4
+XLyK3vrzdGBuFHnxKh/7R3EazRzIc8DBGo1CIJ8XD6N+eq6744L8L0KcPlxy2ao4zqKtK22lMWvl
+2L/RquKs2z7byL6JtgwNPYnN7WaUxpdQtySQkWqVqNxGqK5kkbFFO3e4MfnuqVbEngalRAK4zSHH
+OaDshxCg4deJM+GWle7BqHeT/BikknUfZSpczbE8hBDoSISjguMoVmvK0+poe/SF6Sf3ZtkGxAEH
+ayxybghE30eD3p3zptCIWE5zIcpVHGfXhpW2MolvuXz0UCfRHRQCwxkLON4eGopKTd8e1SA2zzaj
+Xu8SqimG8jYEAgJ5+hEA+AM3a6XZwg0AhOlXxJ76WK9DjtGDZNDjkGNaAjqzSeUk3LLSLTKKVl22
++7VUsjWtaVzNsTwEmouBShBHjKuTEnFlFT/f2R5/JeP4ulLqXDe5OOBgjeRt8RyVHqskPvcHMfKe
+UKn+tF/PVRzVaNJKWxQCvTTXvPdbUk4qAaYpN349NDTprelEX29z6NXGcAMAABRCmfudM6+QYKwB
+Zg03zrMi9jQoJRLGt8c7owcphxzTERAtRcIB3LLSJVJKtA6doRCq3k4xb0k/vuEK9yrbGt+P+jGv
+NO4gYcy1QBbghAKjwYq+nWf530sX/0PHZ5/LwQEHa5wyy76J0uR9oU4eDnoa8gQ6jaaeQM9VHPNX
+x0pbacxamY2/wkh8SiUdO7hyf2goKPOjii/8UUpsxdDQk5RF9mU86P9BILYr3IC9cIqmC6QYa5JZ
+ww2A86+IPQ0KgRgld3Zf7dzvXew3do11U6CU15Yk33iNW1a6QSQXPvP+n9sKz3cHvE4qUmsqUvfy
+nfy/hNbvmkg3cu0tOx9EBOfoidTyxNeXONFXy6J4lY3KB1Eaf3aW9ysOOFhjUAgUbL4x2YdcwYWl
+90+EEGd6c+YqjnrMe6WtjJNPSps9lgL02//OlY7Iw2NhImjb0NCT2CzbiFf6660OaRD7gcKRZYyM
+NRF5Ty4rZwo3Jg90/hWx0zD93r3xcGcjvTg4dwvoUkCctFsuGW5ZaT9lFBRb9J3S0NpqrXgQ/8nl
+XM3RNVJLLEewGyWnf62O1JpSdHtnd/e+Sad/LeKAgzUC2XIoUPyg+4PKZhygEDtnvbjjKo5mqXKl
+rRfq/yGXPw8BIPhA3u0PDe3/L63UJ136+94LN1pfgRKEugJLeHHB2qmycANmXxE7Dd3vr4+Ho410
+9XxDvJdBO0Y0zge3rLSbEAJJJqvky9DmYEDFak3FXM3RNR61DlO2UAmJuHLBfL67M9rEKPndNHM5
+xNX/87/50yOrlc+LTYyMUKa61ZXkPQmAxyaNzzxgibyn4Oy3XMXRPsettIW9lbZ259ds5d13LmIU
+DVWcfIaqe6UBZTa6H1240InSc1eWlMhyhz9Ys6Yj78nl5UPTS9areDw7Gn/TW4lvLeLCpByNN5IL
+6Z1ZJtZ3lS9L8s59GyXL3apR5PaVCPATt6y0iy9LUuXwZ92RUMDl7pXN3XdczdF+RZb9va+LK1Kd
+7e+xyMpXNsS/RqfM5eAKDlYrl2WPTJp8IJSq9k4VEchYf3Ceb+UqjvY6baWtSc0TM0g/OOscjzag
+EIis/SpeXW3lppejIPImFdZ8VYcbe49ayYrYaeheup5tj79MBuk6XzS8rXNvFeey37IyHu7cj1d6
+fHHZElJrzHfhv3UEnQg4VKzWZCTXi938G67maDeJ6nKgfBsAznQDK0r0miqL1dHu3lyOYypA+JWb
+1YK8J1/kX5h+75PKww0AIE9PUeC57/ruz+Ko8kysPkIIEbwPJo3WOhlueE/Bll9FK/3W9toeBaVE
+Z9123edg7DjzCTeqXRE7DZ2md8fbo++9c1uLes42QATuktsjpcRktX8vH4+/L617Xvd52JR0733v
+fGd+ioUQGA/iP0kISbY1vk+eOvPftkyEQigtPTvP90qtcDCA28Vo9MB7f+R7Vuc+6LPmI2uHAsK3
+pt//fF4f4ASEIeD5f7xRSvQUaH/WA2u/UJYbUuv36j5H1ch7Cj48NCvdXPtIQsqwjFP+WOPNK9yY
+x4rYaZhe70a2k/3CIccBiACOduo+RpMk/d4N731qx/mjus/CTqei+LJzvnM37FSs1pIL0XqZ5d/Y
+ovyp7vOws5FSovciP+/3C4G4ckGvh3z8i7PlocCVAw62UD4vNmVkRmqO8y0oBJJKillnEHAVR3dY
+mw9NGv2xC3MpDiLrhgLgWzOo9gKrUQSkgXNG1jDzCjcAJiticQ4rYqfxOuQoOeQA2BvUGLpz97sq
+UWzW0KiPx8MdvoPecFJLtIUcBerejQKu5mg3QjOgGX8u04G5IYNN83Hx54N/zgEHWwgKgXyWb+g0
+voRKzXcNpydAPftzcBVHd0jvvkNdfStUnZy1Q2HkS5V2exhuQPMR14izJplnuDF5AgKp5rci9jSm
+17uRZ/ZnDjl+w1Vkh3HLSnuIpHfde9/Zdk+u5mgppa9UcQMrStRaL6EP8+3d+7R3zcYBB5u7yXwA
+u6H7vTtCyrlfZFJZbgkpK2lF4CqO9ivH2XPTSztV4eCsHUqjX6rIVLZ5qLEQwXt6UfcxGANYQLgB
++yti6y0203F8s8jsz2XJF64IMuKQ9XjcstJ82pjVwtJ3dZ9jng5Vc/DNycaTSq260p9rDsehx5KI
+K6v6nh2Pv/bOb3HAweaKrB0KIZ6Zfu/eNLuOKyHgh6o+HHIVR7uR96QV/oKyO+tgy9w+l8YsR7gB
+k00qgehV3edgbBHhxuSJ6O/QgG46Fcc3y9ylZZ4/rfssdQooDH8AOBm3rDSbkBJD0HIZLvpfV3OM
+uZqj6RARnBOVfr5bWdGfgst+5oCDzU2Z5ZsyMmLRF2KIUFY5vJSrONqLiuKJSswndZ+jKja3myaN
++yrSSxFuAPAmFdYMCws3Js82Fg3Zwqkis1aW8M6yhxzQ+cvC2b3RspJbvrBsGBkPPvalX4pqSK7m
+aAchBRIJX3ULYJLqmxxwsMpRCOSL/Iuon17HOayAPfG5vSdUql/lY3IVRztRWZJOTLzIVYvzZPNs
+M+rFl1DPv82raUhIyb9/rC6LDTf2VsTW3aNygIrMWumWN+QQAi5yi8r0kn7vhg8hKXbyr3l2SXPI
+SKMt4Me6z7FIXM3RfAHNO/MYJM8BB6sUOTcE5x7qXu9eLReWRCC1rnw4G1dxtA+V9qHU6lrd56jC
+JNzoXUK1fOEGAEw2qfDnZFaDvXDjwaLCjbpWxJ5GGbNWOlzKkENIeZlffc4mis2aTNR/Zv/c/ZI8
+b6FpCtLplWVrIdqv5hDBczVHAwljrnHAwRrN2+K5QHyp02S9rrtP5PwTgdX/WHMVR7tYmw+jNL7Z
+pLug51UW2ZfxoL+84Qbsb1Kp+xRs2RwIN+4u7DmJalsRexpl1Frp8B371jq+zkMEruA4u99aVjJu
+WWkIFSWXna1mqGPbmMS8ruYoy3Lphyc3xWQOB1V+A5kDDlaJMsu+0VHUr33woRC786oc4SqO9pDe
+/6ULa2Ftlm1E/f66QGz9f8tMEMH75fxQxupRR7gxeWKodUXsaZRRayTww2x3vFH3WRZFAgARb3I6
+r6TfuxG4ZaURpJaYl+Llsv497FdzgPcpV3M0g9QSywJ2q35cDjjYTMj7vXkbvVtiwfM2Dp2FAkkt
+o3k9PldxtEM5zp+bXnKv7nPMymbZRrzSv9OVGSKzQEQgF3jQKFuI2sINaMaK2NOglCik/izbGT+o
++ywLgQhEgTc5zUDHZk0n6j/zrfF9blmpF0a9m+Sp7mPUar+aw47yR650W3WfZ9l51DpQtaEbBxzs
+3MiWQxHCY9Pvf96IizDvQBr1+3k+BVdxNNtkLaxo/VrYMs+/iC8MONzYs7dJpaj7HKz76gw3Jgdo
+xorY06CUKJS+ne2Muh9yIPAWlQoIKTG+kH7OLSv1klG0Whb+cd3nqJsQApOV+Hbwzue7+ddczVEj
+qS9V/b+fAw52Lj4vNoVWL1USf1r3WfZ5X75AgRfm+RxcxdFsbV8LS96TK4oH8YXB5132nwfEAAAg
+AElEQVSYH1IlktLw7x2bp9rDjckpGrMi9jQoJQoT3x53PORAAAAKtu5zdAW3rNRLSokl6VD1HfO2
+MolZi1P9n1zNUR+p1OVA1VbpcsDBzsxl2SOdRJeU0fXO23gLAj5fxJ0vruJoJvKedKREW6seyHsK
+zn8VrfTv1H2WJhJCDvizMJuXZoQbzVsRexoUAlWU3Bm/2v6i7rPMDSJ47/K6j9El3LJSL0wGH3vv
+ue1zj5BczVEnoRDKkird0MUBB5vaZN5Gcd/0+5/UPW/jbRQCSSUXcnHLVRzNRDZ/KE31K4IXgbyn
+QOGBWelxuHGMgPoabzJg89CUcKOpK2Knofr9z0evtje6eEdeCMGfleeAW1bqo4yCIqfv6j5H0+xX
+cxSj8ddczbE4Ukr0TlTahswv2mwqZO1QQPjW9Hv3BDbw7pInEEpeXNTTcRVHszibD3VsrrSxeoOs
+GwrEZ6Zf78VV4yGA98SbVFilmhJuAExWxEqJg7rPcV66318fD0cPuhj+C0DoYnjTBNyysnhCCCSZ
+rJLv3u/qrIQUmK6kn+5Xc3Arz2IQmgFV+P+aAw52Kp8XmzIyIxXHt+o+y3GoLLdQqWuLej6u4mgW
+4fxflTFX6j7HWTlrh8LIlyqueb1yC/AmFVa1snRDZ93jJoQbAABAAChxYe9j86D76fp4a/ygcyXe
+AgdcQTY/3LKyeCpOrnnnef3xMfarOfLRiKs5FgH1lVDh2wYHHOxYFAKVWb6h0/gSKtXsi0cBPyy6
+bZmrOJphshY2/mPd5zgrZ+1QGv1SRRxuTAOlRO+4D55VoyzdEHx4aRo0KBuCe9Gi8RvH0r10Pdse
+b3Tq7rAAzjfmjFtWFktqjVkh/lb3OZqMqzkWRxq16nx1gRsHHOxI5D1BWX4VDXp3hJSNmrdxFARR
+LLo9gas46kfek5ThJ2zYTJjTWGs3pTEcbpwRBTng3zc2q/1wQzescop8eNWGFbHT0Gl6d7Qz/sY7
+3407nwiBd8UuBresLI7Q6VXvuGLmNFzNMX+ICK4Uzyt7vKoeiHUHWTsUQjzTvfROG6a5k/eERq7U
+8dxcxVEvKoonJo0/q/scZ2FzuxnF8SUVNWsLURsEKS/y5102i6aGGwAAKMJuW1bETiNK0z9lO+Nf
+vGv/BQGivMX5xuLst6yMt3YfdOHnp6lUEl92zvNn2ClwNcd8CSmQvPBVhZoccLA3lHnxjYqMaNWd
+ZSKQup7tGVzFUZ82roW1ebYZ9eJLqJtfFdVIqC9znTg7ryaHGwAAECi04abCWZhe70a2k/3iO3DX
+k195FktIiemF/nqR5b+URVHpCkk2IaVEW8gRX6xPj6s55gh1v6o5HBxwMACYzNvwRXY/6iW3mrYC
+9jTk/VOB9f0ocxVHPdq2FnYSbvQuoeJw47wmJYx8t4mdXdPDjUlga2qpRJw30+vdyDP7c5tDDonI
+QzhqkvR7NwLBO9n2+AG3rFRPJL3r3nse4H0GXM0xJyb6iAMOVhlybgjOPdS9/t023Q3/jfi1zr5l
+ruJYPFeW1Ka1sGWRfRn3+9c53JiRQvDOj+s+BmuXpocbAJMVsQJFVPc55kXH8c0isz87W7Yz5ECA
+QJ7XVNdEx2YtSs1tblmpnjZmtbD0Xd3naCOu5qgWIoJzVMlNLA44lpy3xXOB+FKnyXobS2OJAkkt
+o7rPzlUciyWc/bIta2Ftlm1E/f66kO0IY5oMhcBAwdV9DtYebQg3AKATK2JPo+L4ZlF47wr7fd1n
+OTsET8BbnGrELSvzIaTEELTs3GrnBeFqjuqgQigL2K3ksap4ENZOLs8f6Sjqt2rextu8A6nlpbqP
+wVUci2OLfGjS+MO6zzENm2Ub8Ur/TlsqTdqAN6mwabUm3ADozIrY0+jIrFlL75Z53q4LVO5QaQxu
+WamejAcf+7K6FZ3LyCRmzaSSqzlmIIRAjyiqCIk44FhC5D35Iv/C9NJP2jZv423ely8Eyst1nwOA
+qzgWgUIgFcL3TV8LSyFQmeX34wsDDjcqFqS8WFWPJuuuVoUbMFkR26UNKidRkVkrHbzTppADEQEc
+7dR9DjbBLSvVkpFGW8CPdZ+j7aSUr6s5iqx4xNUc5yDjy1XklhxwLBmy5VCE8Nj0+5934cILQT5v
+yl0vruKYP19kT3UaNXotLHlPZO1X8ergXt2tU52E+jIR8UA0dixr2xVuAExWxNY5S2rRlDFrpcPW
+hBxCCKTg+b29QbhlpVqk0yvk+fNrFUxi1nSEH3M1x9lJpS6TDzN/xuOAY4n4vNgUWr1USfxp3Wep
+AoVAQgE1KajhKo75Ie/JKGVRysb8fb+NvKfgw8NopX+n7rN0FSICeeI7TexI1rqhoHaFGwDQyRWx
+p1FGrZUO37Hj4s91n4W1137Lynh7/IBvMJ2fipLLzvIg3arsV3N4V24XWfFnruaYjlAIvoLPeBxw
+LAmf5Rs6iS4po9v1oe8knkAq/W7dxziIqzjmxxf5Yxk1dy0seU+BwgMzSNbrPkunKYTSeS4VZ4e0
+Ndzo8orY0yij1lzAD7Pd8UbdZzkdSn5vbyYdm7U4NbfH26MHbV5HXCepJealeMlzTaoVp9FVHeGH
+2c7oPldznE5KiaUVXMHBTjaZt1Hc1/3enbbP23hb8G4LlWrc1Hmu4qieK0syifm3JlXrHETWDQXi
+M9NP7tZ9lq6bbFIB4A9h7CBr3RChfeEGQPdXxJ5GaYlC6s+ynfGDus9yEoGY8otOc+23rFhb/swt
+K+eDcf8mear7GJ0jpcTeavr562oO/vxyIkIzoBkrXjjg6DCydiggfGv6vXsCu1f6Goj+3sSKXq7i
+qN7eWthGDJN9m7N2KIx8qVp4YdVaAfs8aJTt2w83lGnp7+ASrIg9DUqJQunb2c6o0SEH8MtO48Vp
+fDMAcsvKOUhjVsvCP677HF31uppjm6s5ToT6yqyf8Tjg6KgyyzdlZEYqjm/VfZa5EbDb1Dv6XMVR
+nSavhXXWDqXRL1u9armFglJXeGcjA+hAuAGwNCtiT4NSojDx7XFTQw4BEScc7aCNWov7k58lblmZ
+npQSS9KBOBiaG67mOJ00atX52dYWc8DRMXvrKTeiXnodlbpS93nmhbwnZfSg7nMch6s4qkEhkAz0
+1yauhbXWbkpjONyog1SrvEmFdSLcgOVaEXsaFAJVlNwZ/XPnft1neRtKeY0vRdpDCIHpCresnBUm
+g4/J8/vrvB2s5vCl5xDuAEQEV4rnMz1GVYdh9SPvCcryq2jQuyNkxz8tEYHUzR04CcBVHFXwWf7C
+pHHj5lrY3G5GcXxJRR0a2tsivEmFdSXcAFi+FbHT0Gnv3ujV9kaj7m4iAleOtQ+3rJyNMgqKnL6r
++xzLYL+awznL1RwHCCmQvPCz/P/ggKMjvC2eCyGe6V56ZxlWzZH3T5v+n8lVHLMh78kYOWzaWlib
+Z5tRL76EWjauqmRpIG9SWWZdCjcAYClXxE5D9/vr4+GoMRelEgBCCHxnu4W4ZWV6QggkmaySb8bv
+3TLgao4joJ5p1hoHHB1Q5sU3Oor6S1UqL8SvgM3/8eUqjvOjonjStLWwk3CjdwkVhxt14k0qy6tr
+4QZ5TzpezhWx09D9dH28NX7QiJkACOC5cqy1uGVleipOrnk32wwEdjZczfEWFX3EAceSohDIF9n9
+qJfc6toK2JMQBVIKZRvueHEVx/lQWZJO9DtNGiJbFtmXcb9/ncONhkDepLJsuhZuAOytiBXLuyJ2
+GrqXrmfb443aQw5EnjHaAdyycjqpNWaF+Fvd51hGcRpd1ZqrOVAhOEfnvkHMAUdLkS2H4NxD0x/c
+a9JF4EJ4B20aoMpVHGcXynJDav1e3efYZ7NsI+r31zs/26ZFApqPuB9+eVhrOxduAACviJ2STtO7
+463xI+/q+8CPwPlGV3DLyumETq965/lHvgZS/1bNYbNyKas5UCGUFs7diswBRwv5vNgUSr7UabJe
+91nq4AO9EFI25uL3NFzFcTbW5kOTRn9sSoWOzUYP4pX+naULEpsOEQIRl9AugUm4IboXbgBA8CWv
+iJ2S6aW3s53xL97VdEGKCKH0PIOjI7hl5WQqiS875/nmXI3iNLqqNCxlNYcQAr1ADHS+cIcDjpZx
+ef5IJ9GlpZq38RZB/pe2fSDkKo7pSe++Q11/y9XeyuX78YULn3G40TyICN7Tq7rPweZrEm5gJ8MN
+AIAQgFfEnoHp9W5kO9kvddx1F0JgIM9/WR2z37KSbY/v842o30gpsSzl6LwXmKwaS13NIePL5/3P
+5YCjJch78kX+hemlnyzTvI23UQiEiGXbLji5imM65Th7bnpp7ZVJ5D0FW34Vrw7uNaWShL0JpURn
+Hd9N7bDfwo3urmPmFbFnZ3q9G3lmf64l5EAZluoCY0loo9aifrye74y/5paVA6Lede+5aqkJDlRz
+fLks1RxSqcvkz7e5igOOFiBbDkUIj02//3nbLuwrRwTSmHfqPsZ5cBXHych70gp/qXstLHlPwYeH
+ZqV3p85zsNORkJJDw25ahnADAHhF7DnpOL5ZS8ghcMCzf7pJCIHxSu/TMrfb3LIyoY1ZLXL6ru5z
+sIm9ao57+9UcdZ9n3oTCc2+u4oCj4XxebKLRI5XEn9Z9liYgT4BKtXIgG1dxnIyK4olKzCe1nsF7
+ChQemMFyzrdpHQEpX2t0z7KEG7widjY6jm8WY7vtCvv9wp5U8KDRrov6yVUhxO+5ZQVASIkB47j2
+DUbsDfvVHOOt3U7P5pBSYmkFV3B0CYVAPss3dBpfkro9G0Pmzrsnbb7ZxVUcR5ushTVxnRVKZN1Q
+ID4z/eRuXWdgZ8ObVLpnWcINAF4RWwWVxFetpXfLPF/MHXeEwK853Se1Rm5ZmZBResuXngd6N8yy
+VHOQUBGdYw4MBxwNNOn/txu637sjpFzaeRtHQYE7bW7T4SqOo1FpH0pdX2WOs3YojHyp4m4OMuys
+yaBR/uDVEcsUbgAAr4itiIrMWungnYWEHAKvcgnHcuCWlQkZabQFnKtNgM3fgWqOLzq51ldG/xHO
+ccnEAUfDkLVDAeFb0+/dE9jiUoU5IO8JjWx9OS9XcbzJ2nwYpfHNuvrQnbVDafTLZd5M1FaICOTo
+l7rPwWa3dOEG7K2IbW9e3yjKmLXS4dxDDhRitXtXEOwk3LICQDq9Qn45/9vbYH/TSlkU35eZ7VQY
+J41adf7sFUQccDRImeWbMjJCxfGtus/SSESAWl2t+xiz4iqON0nv/1LXWlhr7aY0hsONlkIp0TuX
+130ONptlDDcA9lbE8n2Myiij5h9yIAK3qCyfZW9ZUVFy2Vn/rO5zsJMl/fiG1OL3463dL7oSSCEi
+UAlnvpHFAUcDUAhUZvlG1E+v4xKvgD0NeXqKAi/UfY4qcBXHRDnOn5tecq+O57a53Yzi+JKKluui
+qmu8kBGHhe1l8+UMNwB4Rew8KKPWSi9/n+2ON+bx+BIBiLgtbhm90bKSL1fLitQSC4u/8ork5tuv
+5rB53olqDiEFOgfFWX/2OOCoGTk3hLL8Khr07rR5tsQiCAhDwG78yHIVx/5aWFHLWlibZ5tRL76E
+mmfctJ0QcsCfudrJ5naIuJzhBoVAvCJ2PpSWKKT+LNsZP6j+0RGIwqvqH5e1RdRPrgoUv8+2d+8v
+03YRkfSuk6e6j8Gm1KlqDhn1zzqHoxtXiy3lbfFcIL7UvfQOf8g5GVEgqaTo0v+nZa/iqGstbJnn
+30S93iVUHG50QUB5jUvG22eZww0AACACXhE7PyglCqVvZzujakMOBN4Ty/ZaVtL1Ymf8tVuSlhVt
+zGpZ+Md1n4NNrzPVHCr66Kwf8zjgqEmZZd/oKOpz7/+UJvM3OrUud5mrOMh70pESi65aKovsy6jf
+u8XhRodMNqlwb3CLLH24AbwidhFQShQmvj2uMORAACBP46oej7XXfsuKs+VStKwIKbEkHZapaqUr
+2l7NgQrBlWebAcMBx4JRCOSL7H7U790SPG9jalSWW0LK9+o+R9WWtYqDbP5QGv3RIp/TZtlG1O+v
+C8mtYF0y2aQStus+B5sOhxt7eEXsQqAQiCa+Pfrnzv0qHk9IiYG8q+KxWDdEaXxVoFyKlhVMBh+T
+I36/baE3qjnydlVzoEIoLbw80/fM6zDsMLLlUHj/2PQH93jexhkJ+qFD3SmvLWMVh7P5UMfmyiJ/
+B2w2ehCv9HnOTQfxJpX24HDjN7widnFQCNRp797o1fYGD0lk8yC1xHjQu1eMskddbllRRkGRh2/r
+Pgc7v6Qf35CqXdUcQgj0AjHQ9K/fHHAsiM+LTaHVS5XEn9Z9ljZCxLKrF6fLVsUhnP+rMmYh7UYU
+ApVFfj9ZXeVwo8N4k0rzcbjxJl4Ru3i6318fD0cPZn2tEEEIDkrYUeJ+ervLLStCCCQVv9OWC2N2
+tDZWcwhhLp7lZZcDjgVwWfZIJ9El/mB3PuQ9oVL9us8xL8tUxTFZCxv/cRHPRd5TsOVX8cqgljW0
+bHF4k0qzcbhxGK+IrYfup+vjrfGDmVoJUPb59YYdp+stKypOrnnneVVyB7SpmkMYcy3Q9O3IHHDM
+EXlPvsi/MP3eJzxv4/zIE0hjFjqvYdGWoYqDvCcpw0+4gN8F8p6CDw/NSu/OvJ+L1S+g5k0qDcXh
+xmEUAgEEXhFbE91L17NZQg4BvEmFnajLLStSa8wK8be6z8Gq0ZZqDlQIztGPU3/9PA+zzMjaoYDw
+ren3P+fS+Bl5/6TrnwOXoYqDiuKJSePP5v48zg0DhQdmkKzP+7lYMyAiuNJ3OiBsIw43jkEEOtK8
+IrZGupeuZ9vjDe/82S8+BUSccLBpdLVlRej0qneefwk6pOnVHFJKLK3gCo46+bzYlJEZqTi+VfdZ
+ugCF2FmGkKjLVRyLWgtL1g2FlC9NP7k7z+dhDYMA3gVe3dggHG4cj4hAoFir+xzLTqfp3Wxn/It3
+Z7vDjlJe43yDTauLLSsqiS+7kr6u+xysWk2v5iChIppy0CgHHBWiEMhn+YZO40uo1EKGKHYdeU9C
+q6jucyxCl6s4FrEW1lk7FEa+VLHhC6olg7y6sVFsVmxyuHECIkDEzq09byPT693IdrJf/FnaCBCB
+Z3Cws+hay4qUEkuH7ixbLVh7NLaaQ0b/EaY8DgccFZkMNLQbut+7I6TkeRtVIQJp5Ad1H2NRuljF
+4cqS5r0W1lk7lEa/VBGHG8uKghx0MRxsG5sVm1IrHqp9kuCf8orY5jC93o08sz9PG3LIeR+IdVaX
+WlZE3L/uvZ+6ZYC1SxOrOVDhqvPTDbjlgKMCZO1QCPHM9Hv3BHZ8WMSCkaenKPBC3edYlC5WcQhn
+v5znWlhr7aaKohGHG8stSHlx2mSfzcd+uCF5qPaJyEPR9blSbaPj+ObUIQcCOMczf9j57LesjLZ2
+vmhzy4rSerXI6bu6z8Hmq0nVHFIpoBJ+meZrOeCYUZnlmzIygi+u5kNAGAIu149pl6o4bJEPTRp/
+OLfHz+1mFMeXpOGWsKWH+jIP/qsPhxvTQ0E7vCK2eXQc3ywy+7Mr7Pcnf+VyfSZh1ZNaYrrS/9zu
+Zt+0tWVFSIkB47jui142f/vVHGWWf2OL8qe6ziGkQOegmOZr+VX6nCgE8kX+RdRPry9i7eUyohBI
+KimWbZVeV6o4KARSIXw/r98Pm2ebUS++hJpbwhhvUqkThxvToxBIyOV7X2sLFcc3raV3yzw/tiQb
+EXgrNatENEj/VJbeF1nx57rPch4ySm95N13LAGu/eBD/SUJIsq3x/dqCLRn1p3luDjjOgZwbgnMP
+da93bxm2e9TGEwglL9Z9jDp0oYrDF9lTnUZzWQtbjvNvol7vEioON9geheCd500qC8bhxhkRgVI4
+qPsY7HgqMmulg3eODTkQARztLPhYrKPixKxJKT9sY8uKjDTaAn6s+xxscVSs1tLV+F5t1Rwq+mia
+gJkDjjPytnguEF/qNFnnOzDzRWW5hUpdq/scdWh7FQd5T0Ypi1JW/jtis2wjWund4nCDHYRCoKfg
+A683WBgON86OV8S2gzJmrXR4ZMghhEAKnl9nWGXa3LJCOr3CbSrLp65qDlQIrvTPTv26RRymK8os
++0ZHUZ/nbSyIgB+WOUNqcxWHL/LHMqp+LazNso14pX9HSK6cYkcIss+144vB4cY5EYGUklfEtoAy
+6tiQAwCAw1RWtTa2rKgouezs6RecrHvqqOZAhVBaeHnq1y3iMG1H3u/N2+jdEvxhbmEQRLHMLUBt
+reJwZUkmMf9W9d+dzUYP4guDO8v8M8FOFpS6wptU5o/DjRkE/xT4Faw19kOObHe8cfDPEWTEYSqb
+h7a1rEgtsbD4Kwd+y2uR1RxCCPSAeNrPGwccpyBbDkUIj02//zlfWC0OeU9o5Erd56hbG6s49tbC
+Xq7q8SgEKov8frK6eofbwtiJpFolou26j9FlHG7MhlfEto8yak1I/Vm2M36w/2cBheGrOTYvb7Ss
+2LLxLSsi6V0nT3Ufg9VIxWotuRCtL6KaQ6C5eNrNLA44TuDzYlNo9VIl8ad1n2XpEIHU1bc4tE3b
+qjiqXgtL3lOw5VfxyuBeVY/JugsBgTzxwLM54XBjdgieV8S2EEqJQunb2c7odcjBW6nZvEWD9E+l
+I1+Mm92yoo1ZLQv/uO5zsHoJIXAR1RzCmGsccJyTy7JHOokuKaN53kYNyPknAvnHE6A9VRwUAslA
+f61qLSx5T8GHh2ald6eKx2NLQCGUzvN2gzngcGN2FAIJpXhFbEtNQg5zO9sZPRACLnKLCluEODFr
+UskPR8Od+lZznkJIiS7o0IaWGjZ/867mQIXgHJ14XcRXkG+ZzNso7pt+/xOet1EjIXa5JWiiLVUc
+PstfmDS+W8VjkXPDQOGBGSTrVTweWw4oBAbi4X9V43CjIrwitvVQShQmvp1vj1+4oiTvuS6fzZ/U
+EtPV/j07am7LiogHH5PjFlE2Mc9qDiklllac+LPGAccBZO1QQPjW9Hv3BPIdlroQBZJaRnWfo0ma
+XsVB3pMxcljFWliybiikfGn6SSVhCVsyiH0eNFodmxWb0nC4UQVeEdt+FALZ3ezFaDf3xa/PH8ns
+H9+6V//3C7v18pHd2dksi5J86SmEwMEHq1w0SP/kfDNbVpRRUOThL3WfgzXLvKo5vFAR0fE3s1RV
+T9R2Pi82VRL1UKlbdZ9l6XkHMta/r/sYTYJSorWBFFFoYmULFcUTM0hm/t1x1g6l0S95FTM7ryDU
+FS4dr8brcENyuFEJIpBS8YrYlrJZMSyK8q86Mnd1HP23TkiH0o37K/HngUIIYQyBRuDL8MTuwA4J
+hUGqFHX6ESoERAQhJd9YZDOJYrPmvV8dbe18kfR791A24zOhEAJJxWvky9CUM7Fm2K/mcLl7lW2N
+70eD+C7Oei2j9aVABcAxDyMv/OEP/99MT9ByFAK5vHhgesm/o1L/Wvd5GIAri59MFP1LEy/k6yQQ
+/5VK+61U6lLdZzmIypJUJL1UaqatNxxusCpQgEgL/zNK3sI0Cw43qkfOfq+Neoff29rFFSWNtsZf
+CiX/VUfRNe8paEOFcOWOjvQd8v6Z0vIdgUKgRCEVXjIRXjUmXDbSX9KQCXTjZ77YfeZH47+VZflP
+X5IRQURBQJj5gz5bOogodGTet7vZNyBEglLGdZ8JAEAgrgk3/lkqfv9lh6HCREXysh0Vf6YAfqaf
+E4IBhvzYn7WlruAg7wm8/yoa9Hj9ZIMgyOcgRGVrRruiqVUcoSw3ZJLO1E5ird00UdSTRnG4wWaC
+iOA9vZIA/BpyThxuzAeviG0X8p7y3fFjQv1v0SB9vcnLWfsijdU1DyoXUgjv4J0yd091rK4d/H4h
+hBB7XZtSwXW9/7hkQyALwdFProShs7hNEiOQye+Ejt5DRECFIITgag92omiQ/qnI7Ss/Lv4cpVHt
+FehSa8x2xd90xO+/7GhVVXNIpcBn8Asc87O2tAEHWTsUSr1UvZQ3NDTIZMo8UJMu4JtkfxaHjuPa
+38gAAKzNh0ka/XGWgNDmdjNK40uoJV9MsZmhlOhyt20SHuNzHhxuzA+C3+H3tuajECgfjZ+SF1ZH
+8Sfqrb8z4d2PKOMrXpkrgSwoo9dsZgGwfK6NvnLa4yOiAAQAhVcUwBWIASYtLiMItLPlS/j7fosL
+qOiiUNE1bnFhx2lay4rQ6VXvsiDV7DPZWHepWK3JSK4Xu/k3GOl3tD79tfMgIQU6L/JjH3/2I7ZP
+mRffREn0vlB8t7hxPIFU+t26j9FUTavikN59h/r8w0Btnm1Gvd4lVBxusOqQkDKEELgy72w43Jif
+/RWxdZ+DnWwyZ8N9ryP9mTKHL9Bc6Ukb8S4AgJB61bv8mVTymk7MWp7n/0D0W1LJC2d9XoFCCBAA
+ElelhlXzOvTIINAYfB6eOh+GLqAnGfVBJVeVlhc49GAAk60S6Ur/82Jn/F8qNv+ujD7zz2BVVBJf
+dtnoa6nkp3WdgbXDfjWHzeyrbFyeuZojoBmQd0fOfFmqgINCoGDzjajXu9uEi0N2WPBuC+Pk2ulf
+ubyaUsVRjrPncT899xrXcpx/Ew1673O4wSonIA0UQPANpKlxuDFnvCK20VxRUj7Kv5Sx+TBK42Mr
+e50tXqTRpBUFEcHZ8Mrs/bsojm+Od/PNdAAg5dlDjrf9FnoASA3XDUxWYAeyEEIBwYYXpQs/Oy8L
+r8xAoFmT2rwHCkFy6LGUmtCyIqVE69AZCoE3UrJpmMSs6TicvZpDRR+F4I7+V1UesMnIuSGEsKl7
+/bt8V6+5AtHfhRD8AfsETajiIO9JK/wFpTxTSdk+m2Ub8Ur/juBJ22wOApqPeJPK9DjcmD/yBErz
+itimcaUnOx4/BqV/Z/rp56d9vfDuR1TxFQAAlAIdCX+wWizqxTfy3ezLZCDW5zE89OBcD1BwWe31
+n+/P9QBPW2UJf3cWt4NEGTC+KEx8jed6LI8mtKyIuH/d+51thaq2ShLWLm9Uc3HrxikAACAASURB
+VOTucdSL/vO011BUCK70z6TCQzfGlyLg8LZ4jkqPVWTOfbeZLQYK5B7lKdRdxbG3FvaT83zv63CD
+/57ZvCCC9+ULVJIHnZ3CZuNNaSION+Yt8IrYJiHvKdvNngRAoaP4k2nejw62p7x+nKD7geiNajGd
+JndH29lG/0K0sAH2r+d6AK5KgNXf5nr8trrWjcLYgXKEesCra7ut7pYVFUWrxdbWV0oDzzlkZ2IS
+s6ZNWM1H+SMVm+tKHx+SoUJwuXh11MS1zgccLs8fmST+QCh1rjvNbHHIe0LDq6WmUWcVB5Ul6cTE
+53lem40exBcu8NYiNleICIHoFfAmlRNxuLFAwT8FwXO/miAfZ89LSz/pKPrsLHe3g7MvlH5zU0rQ
+5qNAGYB882ujXrI+3hp/2Vs9/4yqWb3V4nLr7RYXsuGpc2F7v8UF0FxV2lzgFpfuqKtlRQiBAeP4
+uPkIjJ1ESIHJSnzbZvZVXrivTWo+PqqaQwiBjkQ4auZaZwMO8p5CaTcMz9toDyKQsfmo7mO0RV1V
+HFTahybpnSmVpxDI22IjWV29d/pXMzYb3qRyukm4kVySEjncWABeEVu/Mi+Gxdj+ZTJnw5z5zjKV
+5Y8ijt4ITRERfElPpJaH3odVnNzJtrMHyUrSmLvYh1bX7r1EHtXiQhIjwHjALS7ttt+yMh7u3I9X
+encXFTjIKL3l3fAFSuQbDexcTGLWgj+5mkOguRioPDRzrZMBB9lyKFD8oAcDvphqEfL+qUDkO1xT
+qqOKY7IWNr55lgoM8p6C81/FK/z7yBaHhJShIduGmobDjcXjFbH1caWnfJQ9RK2uTDNn47jH0Ea8
++/Z7HyqEMgs75ojvEVIgmOh2PraP4tQ0eqPENC0u+6trg1Qpt7i0i5QSk9X+vWx3tKmjuKfN/Kva
+ZaTRDuFHHXElJTu/06o5hDHXAtlDVXSdCzh8XmxiZIQyutFvJuwIQvwKfIfrTBZdxSG9/wvqZOoP
+iOQ9BR8empUez79hiyXkxRAC8CvKmzjcWDxeEVuPN+ZsxNFMc5+Oak8BAEAh0AfAcMzGCCklOk//
+UebuqY4Pf3+THWpxiQ+3uJQ+vPJOem5xaYek37tR5PZVGLtHJo3nfp1EOr1CvuA2FTaz/WqObDT+
+Wsfxtf1qDkQE5w5X0XUq4PBZvqF7yU0hee1k2xAFkkpGPJvhbBZZxVGO8+dxP5m6CoOcG4YA35lB
+fT3IbHkFlNd4k8qbONyoCa+IXbjJnI3wXEfRnSourqgsn7/dnrLPo7kYAoE4Jk5VRq/ZzAKg+16b
+ds9hOdTisvfn+y0uwdFProTh6xYXmfxO6Og9bnFpjkW2rKgoueyK8TOTHN5ywdhZCSkwXUk/3a/m
+iNLoY6kllmOxHSVvfm0nAo5JCbzb0P3eXd653E6U56SM/BcKgZDfAM9kEVUck7WwYuq1sGTdUGj5
+UseGww1WD0Tw3j5DJfmDFXC4Uae9FbEX6z7HMiizYlhk9i8yMR9GqaqkcpC8J61BHXcDBtFcIxpv
+o8Rjp/3rxKzlefEPgW5Lqe6tznzd4qLwigK48luLywgC7Wz5Ev6+3+ICKrooVHSNW1zqs6iWFakl
+Fjv4q47DB3wDk1Xlt2qO0dc6jq95oaL9KrrgiZyj9gccZO1QSHyu+z3u728RCoHAOSDyT6XCX2Vs
+3gdf/iKIXpB3QB6uoML3QCngwONki6jiOMtaWGftUBr9UkWm1XeqWLshIpAL28BzRjncqNtkRSz3
+oc+RK0vKd4uHMtI3zztn49jHtsVWrPWx73+oEKgMP4KGE28yRHF0Mxvnm2lPgJSycyHH235rccFV
+qWHVvA49Mgg0Bp+Hp86HoQvoSUZ9UMlVpeUFDj0WZxEtKyLpXSc/Aqnk6V/M2JSEFJgMko+znexV
+sVPmkSifG0k/GR1gpSevtDrgKLN806RxD5Va6BYJdj5EgcA7CESPlVZepsllVPK6QBRlkT1PLqzd
+LkfjB2ql/xmEIMj5F76wz8kWgQOPk82zioO8Jx0pMU14wuEGawqUEt3YFVFvuRMODjcagFfEzs3+
+nA0hZKzTeC4ryEPpNkUcHbsJBaXEIqPtowaNvi1K4hvZbvZVOhCfHrX2sOvemutx/e3VtcGGF6UL
+P++vrhVo1qQ27/Fcj/mZd8uKNmY1H20/7CnZmG1CrF1CCESOgCgAuHILRfl3JcodI0AMemFQovuX
+wSpeVlpf2X8PaGXAQSGQz4uHUS+9I3hwTaPtbdDYAgg/qEg7Gac3UeInb18si4CvBMDlaGWwXmzv
+bOg0uaMic1lF5nIgCiEEOBh4uEA3FKoLHHhMzLOKg2z+0PTTU9+YrLWbURxdQs0f5FkzkJRmmTep
+cLjRDLwidj7ycfbcl/SLNNEn85ojcFp7yuuvAxkRUZgmtDBpcnu0k230B9Edbqt+c64HKLis9rZu
+HLW6NkiUAeOLvLq2Wm+0rGjT17GprOJMSIkhaDnt7wdbXicFGUaHgYrgKgpcFQJWBSLsvy4HZ+9r
+Y24cfKzWBRzkPYH3X0WD3lySejY78p7Iui0hYVNFRqk0+USgOBRqHLL313kw5BCIQuDkEwBK+Xbg
+8dTl4/9xlgwB/X7ZA495VHE4mw91bK6c9ndn82wzSnuXUPOAX9YcQsjBsm5S4XCjOXhFbLX252yo
+OLqnEzPXdZdUllvmhPaU11+nzCUgBzDlp48oTdZ3t0b3BxdTbq8+xjSra90ojB0oR6gHvLp2dvst
+K7STf2360cdVXWfJePAxuX9uozl+Tg1bHucNMo7iS0dRLN99+89bFXB4WzxHpceqd/rdZLZY5DyR
+sy+kkD+qNH5X9pJrAvEsIZQ9+A9vhxwH/92BwOO6isx1Djwm5lHFIZz/q+qdvDnF5tlm1OtdQsXh
+BmuWgPoaBFf3MRYu2x1vmoTDjSbgFbHVmeecjeN4azeFOb49ZR+iuuzJvkDAqe98m166nm1nD5KV
+hD/TTunQ6lo4vLrWubC93+LCq2vPbr9lJfvn7pfxSnoXpZz59QuNguKf4S/KAA+eXyJVBhnHKS29
+SNLDw+RbE3CUefFNlETvCzWfSb/sbN4eEqqi+F3VT66JKbdsvE0gFPDWz3W0Mli327tfqiT+ozhh
+OvnUgYcyF7Djb3BVVnGU4/x53Iv/eOLX5PmjeND/QCBfSLEGQgDn6JlRsDSbVDjcaBheETuz13M2
+5PzmbBz3vFqDmqaNBKUC7+gXbWDqgEMIgWCi29lO/iAZxBxynNOh1bV7Y5eOanEhiRFgPOAWl5NV
+3bIihEBS8Rr5MsxzLS2rxyKCjOOQ9z+ilId+PhsfcFAIFGy+EfV6d7nEs177Q0LJ0xOpcVenyfv7
+Q0JnfvAweY96+4/NSv+u3R1tKmNAqOmmjh8ZeBABOXrqivH/eEeGQPxeSdm5wKOqKg7ynqQMP6FS
+x37oslm2Ea/0D1XYMNYUiAje0iuI6z7JYnC40Ty8Ivb8KASyu9kLRzDUUXRr0e8107anAACgFFhm
+IT/rS42UEp1X14rcPY1itTRB7CJM0+Kyv7o2SJVyi8thSb93o8ztq6KClhUVJ9eczZ8Zifxz3lJ1
+BhlH8aUjZcTgqOdpdMBBthyCgE3TH3CPYk3IeyJPIMLe5pNeegMlVvpBg0IgEBCO+/em37thd0eb
+CqYPOQ7am+MBqOC6irsfeFRRxUFF8SQeJJ8d9+853GBtgFJiIL8UPSocbjQUr4g9lzIrhvnY/lWn
+0V1zzsrQWZGbrj1lnwc1OM8gRWX0mrMllIV7qiMOOebpUItLfLjFpfThlXfSc4vLhI7NWvB+Nd8a
+348G8b3ztqxIrTHfFS9NvDwVlW3VtCDjOGVJW0miPjrq3zU24PB5sYmREcro9brPsmxebz4RYVMZ
+o6I0/kTg4c0n1T0hgYyjlZO+xPR7N+xotIlgQJ4j5Djo1MCjpD4AfIRKQRsDj1mrOE5bC2uz0YP4
+wgUe8stagYIcdH2TCocbDcYrYs9kb87GlzLSH0aD+gZwkvekEPSZtpwocyWQnXrQ6JvfqteKLAch
+YUspxYMYF+hQi8ven++3uARHP7kShq9bXGTyO6Gj95apxUVIifGF9PNZW1aETq96lwWpZp/rwWbX
+liDjON75TZRHrx9uZMDh8vyRSeIPhFL8YW1BJpUa/oUU+DdpZLS3+aRRd+hNr3fDjsbfQQCQeraQ
+46BjA4+yfOIKu+2dH0DLAo9ZqjiOWwtLIRBZ+1Wyusq9wqw1gpQXu7xJhcONZuMVsdPZn7MRUL2j
+0/he3R+kqSy3jNEfn+V7hNSr3uXPpDo88G4aJonXsiz/Lk3EzDdy2Oxet7govKIArvzW4jKCQDtb
+voS/77e4gIouChVd63qLy6wtKyqJL7ts9LVU8tN5nZEd1vYg4yjeExmNx67wblTAMakcKL80vfRe
+ky6su4qcJ/LuqQTxq0rjd6VOrgnEy/X8YE/3lKaX3rSj8XcA1YYcb5zkdeChbqkkgTYGHuet4nBl
+SUethd2r6vkqWulzuMHaBfXlrm5S4XCj+XhF7MnqnrNxnLO2pwBMZv6Ull6ZGZ43iuOb4918szcQ
+KzyMsXl+a3HBValh1bwOPTIINAafh6fOh6EL6ElGfVDJVaXlhS6FHrO0rEgp0Tp0hkI4U3UUm0oX
+g4zjlIXfimN57IykxgQcZO1QIP6g+/2FrP5aRm9vPjFJ8r9QJtdFBSugZjoXERgtr0779ZOQI/8u
+BPq/yui5l/4eG3hY+8TldscT9QHxI0RsVOBxnioO4eyXKn3zd5C8p+DDQ7PS43Yx1jqICK70T4xS
+M28WahION5qPV8SezGbFsCjc9zrSn9U1Z+Mo5D1JAHHWCzCUAj2hDyGEWS4col58Y7SbbfQH0R2+
+CGy+t+Z6XH97dW2w4UXpws/7q2sFmjWpzXttnusxS8uKSC585v0/txVyK9Z5LVOQcRxybhOVOTaE
+bkTA4fNiU8ZRT2rFJUsV2998EuiNIaHVbD6pSgAAEGd6oTO9+GaZF6+ctU+VMQsdWPRG4JGmEDyF
+EPYCD1tOKjwaEHictYrDFvkwSeMPD/4ZOTcMQvxgBgmHG6ydFILP/bjuY1SJw412IEegeUXsIa4o
+KR/lX8rYfBilzVuPSo5Ax+rGeb7XB/1OIAIx432jKE3Wd/852uhfTHjeVQsdnOsBCi6raLI++KjV
+tUGiDBhfbOPq2vO0rCijoNii75SGxv3uNw0HGUfznkhqofGE/95aAw4KgUJePNS95KaQkj+oVeS3
+IaGwqYwCGac3Uc5xSOisAp3r23QcrZV5AXWEHAcJiULAfuABjQo8pq3ioBBIhfD9wbWwZN1QaPlS
+x4aDR9ZaKAQG6k6PCocbLRIIpMSpqxO7zpWe7Hj8GJT+nemnja3W9TZ7HPXMVOth34baXAuUAcjZ
+zxENeuv5zvhBspLwhWBHTLO61o3C2IFyhHrQhtW1Z21ZEUJgwDgm7wK3YU1wkHE23hEYI39/0tfU
+FnBMLsLdhu737nIJ3uz2h4QKCM9VZFQTh4QeJwC9ACHONZFZx9FaaesPOQ46LvDwefm1KzJLAd4B
+xGuLCDymreLwRfY0TuPXa2GdtUNp9EsVGZ7+z1qvK5tU8t3RI5OkH3C40RKBQHAZNlAIlI/GT8kL
+q6O4uTdbYG97igB/7jMigi/pidSykpY4NMntbCd/kAyaV+nCqnFodS0cXl3rXNjeb3Fp4uras7as
+yCi95d3wBUpcqhXaHGRUw5fl4zg+OYSuJeAga4dC4nPd79W2AqwLyHkiZ19IIX+sf0jo+YmArwTA
+uV/ktInWvC3A5fapipsRchz0OvDoq091P5kEHuS3fOGeLSLwOK2Kg7wno5TdT91dYYcy4nCDdUeQ
+8mKgAO0o+j1asTv+0iTpOt/xao9A9GcQ8P/WfY46HZyzoUzzV0PO0p4CAIAKoczCziyDRg8SUiCQ
+uW3H9s8mNZ2aI8SOd2h1bTT586NaXEhiBBgPmtDiMm3Liow05kP4bx2d/7N/k3GQMT8hEKEAj6cU
+Ryw84CizfNOk8SXs2MC3RThmSOhl0aDhXOc24++2NNEaQHNDjoOERCEkrqLWCwk8Tqvi8EX+2AzS
+TwAAbG43ozS6hFpxuMG6Q+nLROU2QjtXLxa74y9Nmqw3+c43O4zIl8v6ubXpczaOE8rsMerztacA
+TFrifAAMFW6JkFqis3RZ5O6pjlWjP9+w+ZqmxWV/dW2QKq2jxWW/ZWW8tfsg7id/kOqYKjadvk++
+aHWbCgcZi1daAhPLU0PohQUcFAL5vHgY9dNWtE00xcEhoajQ6jR5H5Vs1pDQ2dkqHkSaaA2wBDvO
+NkzanqGYxwce9pkrCksB3hGI18QMgcdxVRyuLMkk5t8EorB5thmlvUuoeR4O6xYEBPL0IwC0Lljn
+cKO9JIRi2f7eXOkpH2UPUasrTZ6zcRTynhBmaE/Z4yG6HIIHAdX91Suj12xmAbB8ro1u/00tVplD
+LS7x4RaX0odX3km/qBYXISWmF/rr2e5oUxv9Dx1Fh4I5FSWXXTF+ZhJsfGjHQUZzTNOeArCggIOc
+GwLR99Ggx9Ogp/B6SCiEH1SkXeOHhM5IIBSzVnDsk0qviQQ/s+PxA5OmrblrdNDBwEP10hCIAIj2
+Ao+yoEDvnjXwOK6KY38trM2zzajXu4SKww3WQQqhzH1lZeOLwuFGe1EIJKVqxKa6RSDvKdvNngRA
+oeOolTeyZm1P2YdKXyZfbqPESivGdGLW8jz/B6Lfkqqd1WhsMQ61uOz9+X6LS3D0kyth+LrFRSa/
+Ezp6r+oWl/2WlWx7/CAeJJ8dvAaUWmKxg7/qOHzQlGtDDjKabXJBBPa09hSABQQc3hbPUemxStpT
+olgH8p7Iui0hYfPAkNDOhhpvCJPX4qoeDqVEnSS32xxy7Ju8SUkAKfcCj3DuwOPtKo79tbBlnj+K
+B/0PBPLgQtZNKAR6mtzVassHEg432o0cgdaY1n2ORcjH2fPShuc6iu60utx8xvaUfagQyIUfwVRf
+MRbF8c3xbr6ZDgCk5JCDnc3rFheFVxTAld9aXEYQaGfLl/D3/RYXUNFFoaJrs7a46NisKe1vH9Wy
+IpLedfIjkKqCtUNnwEFGOzlLEMfy/Wm+dq4BR5ll30Rp8r5QisvpjnBoSGgvuSYQl6rKhUIgEBCq
+ftwuhRwHHRd4kPc/+aJ8TjYH8uKKUPje24HHwSqOIESQgf7qyhLjlX4r77YxdiYB+4ECiObPOeRw
+owuWYEVsmRfDfGT/qlLzxyhVrWkLPQqFUEl7CsDkvbbIaHteFWNRL76R72ZfJgOxjvwawWb0W4sL
+rkoNq+Z16JFBoDH4PDx1PgxdQE8y6oNKriotL5wl9DiuZUUbs5qPth/2lJzL53QOMrrFe/c0iqeb
+ETiXgINCoGDzjajfu8sf0H7zxpBQif+jovhfVD+51okhoedFBDKOVubx0Cgl6l7vtt0dPTC97oQc
+B+0HHijlFWXMlRDSEwOP/SoOoHBRSlDxSv82/46yZRCUugKh8iy1chxudESHV8QenLMRDdJObMOj
+0oGOZm9Pef14QkdEFOYVQOg0uTvazjb6F6KluinGFuOtuR7X315dG2x4Ubrw8/7qWoFmTWrz3mlz
+PQ61rEiJIWg56+8KBxnLIVB4Ne3Pibj6f/53pZ/4yJZDgeIHlcSfVvm4bbU/JJQ8PZEad3WcvI9K
+XuYPrxPkPaGW35okmdvwPwqByt3RV10NOU4yeUN6M/DIdnNSofAXrvzuHkgpsKZ1YowtkitLSmS5
+o4xu7EUnhxvdYUfjb3or0a399dtd8MacjUh/1KWf03J3+1Gcmsragm2Wv7oQlxdRzff/kR2Nvuiv
+tmuYK+sWIgqBAIBoq6TJ6togUQaMLx63ujZMXksexv3kD+DDQNM/d5Q5PRA+LsjQ+0GGhqso8IIQ
+AAIFBxkdUpaOJLifTWymWi1caQWHz4tNjIxQRi91uEHeE3kCEeix0srLXnoDJd7q0oeBas33fwsK
+gdGgf6fY3tnQvXSp7nYcVeGhByWFvPgvCvIvLrM7IhACilSi+Ahw0mtZxXpaxpoEsdmbVDjc6JYA
+ZLv0VtOVORtHqbI9ZR9KueqpeIGAU30YPy+dpnez7exBspIs3Q0c1gzTrK51ozB2oByhHuyvrk36
+yWd5lj/VRv+jyMP/KAN39x+TKzLY23zpn5pkuvYUgAoDDpdlj0yafCCUWspBha83n4iwqYxRURp/
+IrC7m0+qQkRgtFxIn3K0MlhfxpDjICGEUMZI630P/3/27v25jSPJF31W1qsbDZIy5DOzV7R8Ivau
+Ht4Zno2wRxIl//22KY+PIo7HnhmOPBG7skzp3J0RTRJAd9cj6/5AUZZkUgJJAP1Afn5zmALKFtGo
+zq7MrzE3szwXKaUERJBSghRpjyi+cFV9KFKyQsEaCnGDCx+s8xDB12Fsctv0Sn6Fixv905eIWF/W
++3Xp/qwy+8AO+tlOSz6AtGquhQiUCmKg59rAQgscQggEY+9UU/dNNjAr/XCRtcevomvh19G1IaRD
+HWVdl9K4aeUU+hcKw1MuZLDTUIj/lErP/Pd/6QLH8Y29/8oMhw/EDLEtfXJ8UiPuSYH/JY20L5NP
+eGDjeSQAALG0I+OvihyDfKX/nlSW3QjT8muzNjwu9kh5fI5GwSYAbKo8h0SUUkoAKQFRfEw+HLqq
+rkVKFmX6F4HqGiICKARuc2Fth0JgBCnalqRSjyc7ZjDg4kaP9CEiNnhP1bj+Wlp92wz73QIRnXts
+cjnzk8FZoBToy1Rl83zRM0gpMUT6V1+FxzpTN5bwloyd26+ia18+axhQTFNMYUP9/LgYZltcyGBv
+iz6QzeSH5/kzl/oCJuf2hcSnejjs9Zff6yhEohgeSxD/VIPsQ6nzGwJxkz+MF5Ro6W/JRY7jm70g
+8Ab5cID69L5H8VrQNIK6CcaCAniz8OHDd1SFKVEMIqU1qeA6SLmBwIUP1kICBm1KUnlZ3FjZ61Bf
+dTki9mTOhpAy04Os96cdKSVCCi9Qzv5kcFYR1BpFSsto6VFGj1zpAER4rC0XOVh3IKKwRkkjxVoC
+AOz5NYedn3e0lw/kua5rFy5wxKreVbktUKlW9jPPyxvJJwr/afL8f6LMb4oeDQ5rUgLaAyEWeoTz
+NFzkAFBZNnKToy+yjY1zFSjfKHy89vlPRClRAkh0QCH8GCt3BJQSIKzxfA/WBgnN79uSpMLFjR7r
+aERsNS2fRk/PpbGf9W3OxlnIB1C5XsjfVdL571MqF/HSp9K5GVVV/f8JGQ6U6meCD+uvbKCvTab+
+68HQ8jwZ9gaK4QlKe657xXMXOCglilX9tS3y20LKXs7bOEk+SfRySOgg30Qlb/JGdP5EwhcCFtuj
+eha7vrbtDsdfqTz7dyFxJTcDQptPonM/STPbVOJ3vhaenNeQV1DrKwpyeGO+R0o/UQj7rqoPBSQp
+BHyAkud7sCVChBj9HirZyDXnBBc3eq5jEbGvz9nQuenlnI2zLKI95QQiQgz0g1Tne/J4GTazt8tp
+tTsoBEgpO/M7yJgQAq0RN6KPB1Lz7y47dtKect7ThOcqcBzP2wg7dljc79u8jV+GhMKuMgpkNriN
+koeELkWDv0pmfXjfjSe7yhgQavUuqMrYkZtOdjKlri3id/2N+R4AH4HWH71vvsfxYFN5AxEBELjw
+weYGESERvYCGiqoAXNxYBRTidyDaf7r15ZyNr6TVv+v7nI2zLKo9BQAAFYKv6IVZxIu/g82zW+VR
+9X8G6+J/IV9nWAckABAIkA/0aP9F/UWh5Upej9iveU8HeX7+IvHMBQ5ybl8o9d96WDw475u01cmQ
+UAHpqbJG8ZDQRrimF2CGxS03nuwqWM0ih9TmbnT+B5XZpT1lmnm+hwtTojqIlNZQpZEQPNiUXRxK
+iaEKh00lqXBxYzW0PSL2ZM5GQnVVD7IHfZ+zcZbgAykrP17U66MQGAljE4ONTZH9x+So3Bmu2Xt9
+eyDJ+m0wwE98HX7Sc042Yt0UQ9xFKc/dtjRTgcOX1a4dZL8Vavb82baiEImC25NCPuEhoc0TCHWT
+JzhOmGFxy00muwgG5IoVOaTW6CfTqTQ6NX3jNdt8j/hjrOpf5nuIl4NNuc2FzYCElIlo6b/rXNxY
+HW2NiKWUyI3LvUCwr63dauMalynW9WOTL3ZfG5O+mogaGWxsB/n2+GDy5doHg948mGT9ZzM9Kvfr
+HanlNeTi3EqLkchoVBe5R39ngYNSouTqr+xw8KCrX4RvDwlVNvtQDfMbQvYzz71z0nFyVNPLAAAw
+RXHLTaZ/hQSwav1/MrNbsa6/U3neymPVv57vkb023wMgJXptvgdJQDHgwabsVAIGKQEs86LDxY3V
+QTG2MiLWlfV+Xfu/aGvuG97/AMBi21NevYc2NxKVAHKR73I2Uwy2y8PyYb6e8+BG1hnDobw7rfx3
+WW5auSdly+HreJBl8rOL/Nkzv4QphH1IaVcXReeOL74+JBQVOj3IP+Yhoe1DKREIaEekwUumGNx2
+k+lfAVaryIFSonf+CsaYsCMJQW/O95BvzPeA46GmZ873AAQufKyoZSepcHFjtRBBqyJig/dUHlY7
+Kjf/bgc5P8l/adHtKa8gQvT0ndSykRs1IQSiye+UR9XDfC3jIgdrJYP1nwDgf538s9IKsSqJolpK
+zDJrJwphF5W50HXr1AJHdPVTVHqqrNm+3NKW59WQUEh/V1YHHhLaAUQgM7ve9DLedlzkqP6aEv1f
+ZXTn27JmJTO7Gabl12Zt2OlN0MlnXsA75nuE8Dj68MJVdeT5HitmiUkqXNxYQS2JiH19zoYZ5ve7
+9qBq0VJwj6VZfNs1KoR6QuNlDxp9nZACU1Q36io8tpla2qwtxi4jH9it8VF4lA/NhZ7gs26LkUhq
+ofGC312/KnD4svzWDvKPhVKtP8JIMRK5cCAk7L42JJSLGuzSTJHd9lX9DRme2AAAIABJREFUIjj3
+WBmzEhsCFAKDwBvkwwHq7kQczuqt+R43AQA0vDbfA44Hm76a75FgTSqe79E3iAgU6DnYxSaplIeT
+nWzIxY2V03BELKVE1WT6mKJwPGfjHbx/gXm+8P83KARGIUSilJoc9qmMHgXnwdfhsbZc5GDtJyWi
+VuE3MVCSiq9jqyYGAmPk/3vRP/+qwHF8AsJ/ZYdFq+dtvDkk1K7JIv+9QLzHTye6qr1/bTqzI1/V
+sEpFDpVlIzc5+iLb2FiZiK5f5nscDzZ9e77H8WDT8CPP9+gHlBJjFSqAxSWpcHFjdR1HxOpG2hGO
+52yEv2mr7yrTjVbDJgQfSGby6rLeL4LdTCmCaHi/o4we1WUFQsKBUv17iMH6ZzA01/df1F8U69nK
+7EnZsej9oyy7+OkdBQBAzu8LFH/Xw2HrfoHeGBIq8R/KZv+Dh4T2AxGB0bLxo7zvojM78m61ihzC
+ZPejcz9JY1Y2ouut+R7Hg03z/LXCR4IUaY+Cf8bzPbonCmkXlaTCxY3VdhwRu9z3DLWnalJ9JTPz
+OzvgOQvvE5zbGyyxVQO13qToD1Fi40UFk2ejsqz+OsjFyiXGsfZKlM6s/+UD/CS4eKAM/76uihiJ
+UEC8TIqOilW9i9YIZfQf5rm4yzgZEkqRvpMax68NCb3V9NrYHCUAANH6C5Y2dhRdDaFyj1XW/yKH
+0hrddPJjptQ1vkl70xuFDwWbYM3mr+Z7vDnYdA1lGgnk+R5tIoRcSynN/XlqeTjZydYKPlG4wpYZ
+ERt8JDedPgKl/8UMB617QNVWIoYnKLOlPSRDiUAhPQEDrUiEsFl2ezqudos1sc4DHFnbZZke/fyi
++lLqjGcJrYgYCEwmL3XPr3RufyuUujKvRV0UxUgUCUSiR0qrKIvBLZTI/aN9lqjpFcxMGjsCWKUi
+R3Y31u47lWet2JC13RvzPd4ebPrafA+qwpQoRJFg+Pp8D0AufCxTQnlj3tcfLm6wZUXEUkpUjaeP
+iYTTNuO5Y+cQfCBtxIfLfE+UEuuSDpscNPo2W2S3JuNyZ7hm7zU5G4SxWRRDte1c2NNWr+zJ4lVy
+2fYUAADVZHHjVfKJgF1ltDJ59m+cfLI6EtAeCNGZi5U0dgTowU3LHTPIO5MwdBGoJfqyJhljEh2J
+jW2jt+d7AMBxm0tKkCi9mu8RnTsCIuT5HkuCCDGGH1DBXIqVXNxgAMuJiH1jzgZfm8/tuD1FL/0h
+BQltiShhi/a3dpBvjw/LneGG5WsXazVtFFbT8h+k1bXLtC2w9kuJCADcZf+eF/6k4W3HJzXinhT4
+X9JI+zL5hPuVV5BI+ELAYpMM5k0qPRI53nXT6UMzGPS611kau+Wr+pEpBhzRNUdCCAFCwHHh4+V8
+DzhlvgfFF66qD3+Z7yFucOFjPo6TVNLhPOaMcnGDvbLAiFhf1fv11P2Z52xczrLbU04Q6n8F8gAt
+u3LbIt+eHky/Kq7k95teC1tt7xvCOyjs1qT032UDwyeLeyw4giyTH1/2dZZS4Hgz+ST7UOr8hkDc
+5A0hgw7+CqCUqPP8Tt+LHCgleud/QyEmVPykcNF+Nd8DYFPl+bvme1iU6V94vsf5zStJhYsb7HUU
+5x8RG3ykalJ+jVp9xHM2Lif4uPT2lBMo5ZUY6z1U2LqHOirL75VH1cN8jQtnrL2kRsQqmBgpSZ4d
+01sxhsc2Uzcv+zoLKXC8kXyi8J8mz/8nynyTk0/YW1zTC7ioVSlyyMxuuul0J1tf46c7DXnnfI+T
+wser+R4xiJTWXs33AC58nOWySSpc3GC/QvOLiKUYqRyX3yVAoTPLp1znIAW3p/Ty0lNeh1JBDPRc
+t/DUqpACgcydaur+xE/HWZsVA3Xj4Mh/PRja3u67V12i9GIerXxzK3CcJJ8kejkkdJBvvkw+4S9l
+diqBUHfxBMcJlBJ1Udxx48lDU/SzyIFCIKG8Rd4foNatT7xZJW8UPl7O9wB4bbDpyXyPyh0BpQQI
+azzf4zVC/vaiSSpc3GCnmVdEbDUtn3qXnmpr73HKxfyQ908wX357CgAASoG+TFXWxJvPQGqJwdGm
+r8JjvcQIXcbOQ0hEo+Fa9PFAao6N7RvvA1krLt2eAnDJAsebQ0IVyGxwm4eEspklEF2/QUAhUA/7
+XeRQWTZyk6Mvso0NPh7dAb8MNj1jvkdKP1EI+66qDwUkKQR8gHIF53ug3oQUzv3HuLjBznLZiFhf
+1vt16f4sc/M7O1C9HmS9bE22p5yIYNcoUmpr0UoZPXKlA0D/VBvNJ67Z0qQEMOvThkFhru+/qL8o
+tOQ9ac9EHx+b/PLtKQAXKHBQjEQuHAgJu8oaxUNC2UVQSgQCUtPrmAcUAu3a8F59eLSji0Evb3yE
+ye5H536SxrTueC17vzfmewB8BFp/9L75HseDTeWN4xhb6F3hAxEh+Pidee30y/uUB+OH2fqwl59x
+djkUI0l9sYjY4CNV4/JrNDxnY1GabE95tQZtfp9S2eQS3kvnZlRV1f+HGA+k4ifkrJ0GA/zE1+En
+bRXvSXuEQvynVHou+6uZvox/NSS0yG8IRN7ksYsjApnZ9aaXMU92fW27r0UOpTX66fgZKnWNi5n9
+MfN8DxemRHUQKa2hSiMhejDYFAGii9NZf/xlceNu3z7bbD6IALQ8X0TsyZwNIWSmc56zsUjk/ROR
+2UZvhhARYqAfpJKtbgGxWXZ7Oq12BwWAlFzkYO1jMz0q96sdqSXHxvZE9IFsJud2yu7UAsfbQ0KV
+zT5Uw/wGDwll7N1eFTkGee82q1Lnn8bafafyjIeQ9dxs8z3ij7Gqf5nvIV4ONu1ImwtKiYlm61Ep
+D8YP8421XragsTk5Z0RsNS2fRk/PpbGftbVloS9O2lOaLk6iQvAVvTBNLmJGNs9ulePyj4M18Yd5
+DPxjbN6KQt2t6/CDyXWrC4ZsNt6FvXwwv1N2rwocrw8JRYVOD/KPeUgoW6x+/mr1tciBWqIva5Ix
+JiE5NnYV/Xq+R/bafA+AlOi1+R4kAcWgzYNNKcm19yWpcHGDzWLWiNiTORsqsw90bvih0RJQqA9M
+w+0pAMftrJEwppRS08WWWZhBfmdyWO4MN2zvTqWydjEqjgHkuf6MNgqraTmlKFs714bNjiI9kQrn
+9p2ogvMkEj1SVgceEsqWhYjAaDnz066u6WuRQxq75afl12ZtyDd8DADenu8h35jvAcdDTc+c7wEI
+jRY+kpQfJEpwVpMNFzfYzN4TERu8p2pcfy2tvs1zNpYr+bArsnbESsakryYiEB15RmCLfHvy8+TL
+4QeDB02vhfWXgJQu8okYFHZrPAmP8qH5bO6LYksz7/YUAACVrxVCoOCiBluuBAAget3badfXtt3h
++CuVZ/8uJPbivxWlRA94jUJMqDqyQ2ONOPlOEfCO+R4hPI4+vHBVHRuZ74F6E+D0LhUubrDzOCsi
+9tWcDSkzPcj4SfiSUYykNai2/H9HbW4kKs/7sLpRuhhsl4flw3w95+shaxWpEbVyv4mBklR8H9tV
+3tNBns93NpHimxTWiERNr2ApzPrwvhtPdpUxIHoykVzn2XWOjWUX9dZ8j5sAABpem+8Bx4NNX833
+SLAm1WLme5yVpMLFDXZeEpJ7+0FRdTR9Gik9V9byQ6SGBFcfZFq35+kuIkRP30ktOzPLSgiBYOyd
+auq+yQbmD02vh7HX5bnZPDisdwZr+f2m18IuJoa4i1LOdc91oUgzxi4rAe2BECsR72SGxS03nuwq
+6E+RQyjzCXl/gFr34r+HNe+X+R7Hg03fnu9xPNg0/DjX+R4KwVfx6PWhf1zcYOf1MiL21TN5X9b7
+1dT9Ref2vrY8nL1JbWpPAQBQWmI9pnEXBo2+TkqJIdK/+io81lnz80wYOyEkorXyVnDxQJl+7LFX
+SYxERuPcT9lxgYM1QiR8IQBWosAB8LLIMZnsIhjoQ7a8snbkJuMv7bq635ajv6x/3prvcTzYNM9f
+K3wkSJH2KPhnb873EDdmKXwcD/0DOBn6x8UNdhEnEbEv52x8Ja3+nV3jmQVNa1t7ygkCqROlJDoW
+b6mMHnnnAerwWFsucrD5usznNB/o0f6L+gtlJJ8s7hhfx4Msk3M/ZccFDtacbn23X5opiltuMv0r
+JACpu1/kQGO3yfk9ac3KFKpYO7xR+FCwCdZs/mq+x5uDTddQppHAU+Z7JBxCSlAeTri4cQmUZug7
+pPm0Js7+MjP8YJrhZd7zM74sQ8RYo82f6UH2oG031KuKvD8wbWpPeYmE/m1KEUQHk+SU0SNX1hMh
+w4FS708NYmxZhoW87+rwk7aK96QdQiHsojJz33txgYM1xTW9gCaYYnDbTaZ/Beh+kUNqjX463UOt
+rnF/OWuDN+Z7nDXY1IfvqApTohBFgqF3foOeH309uLpxJ9T1mXfEs9xUE6XHQkD17h96/11NnOWm
+ewaJ0jSBiJd+IQIBOFMp4N3rEUIIKdfe93MC5jVmRQKId69bSLk1043mKT+SYqRQ+b8nYepMBmOs
+5o11i1Bwu8K0pz3lBGq9SdEfYkeHj+vcXi+n1e6gECBlt/cxrD+0VTgty2dSy2vYsdNRqypGIqmF
+xgU8FOACB2uEQKhX7QTHieMiR/XXlOj/KqNvNr2ey5Dafhbr+juV550ZmMZWz1uDTbcAjttSUgjk
+yvIrOfrNAy/eU6STMMups5uzVAHed0ONxz80HzNcZ/nEwfn5snxKFH7Sw+wuSinC+HAnESUu9rYD
+xUhKgmpjGwhKBArpCRjo7PemzbNb5bj6P4Oh+F8o+XeeXdIMhf9ZFIX+dFr577LcdPaztUpiILBW
+frqI1+YCB2tGArHKm2pTZLd9Vb8Izj1WxnS2lxW1RF/WJGNMQnIiE+sO8vXP5OOuKXJUxiw2jpb1
+RqjcfvTVn/Ugf6Cl/WWAqM3vUqj3pEE+xdECbW1PATiOW6+m8cgMdNNLuRQzyP5jMi53hmv2XhsL
+SaxD5nBCEABAaYVYlURRJS68tV+o/aMsMwu5TvOmji0dpUTvOza8CnRmRwDianDucdNruQxp7Jaf
+ll83vQ7GZhWqaj8R/Lc09q5W8sOm18PaL3hP1dHhl0KBsGvDz/Gtgq7SGqvS/2dDy2NvoeB2BbZ3
+i0tCD4mo8/sgO8i3xwflV02vg7ET+cBuVaXnPWnLxUgkJcRFtRO19+rP+osIZGbXm15GG+jMjgC7
+XeRAKZEAr1EIB02vhbH3ceV0F1D8t8qymzHUe6g5DYCdjXyk+mi8A4n27LC4L5W6cubP6vwTCvOa
+oMIuimIkhaDbfKogSfPRLDNwu8AUg+3ysHzY9DoYAwCQEtEouBZ95D1pi8VAYDJ1a1GvzwUOxhqm
+jR0hiquh6m6RQ+fZdTeZfNf0Ohh7Fzee7ipjfquMvQkAkLx/0uanvKw5FCO56fTbGOrvTZHdU0Z/
+9L62Smntlapy/OSwYeT9gTR6IX3d84JKX4mR9ppexzwIIRBNfqc8qrjIwc4tzZLAdU6DoblelZ73
+pC0WvX8k1eIGLfPOjjWktQ9WGiGNHaHqdpFDKPMJec8Vc9ZK9Xi8o3P7W5THT+ApRpJSmlWeBcR+
+jVIiPy2fhrp+pK3Z0nm2NevgUBQCY9JXKPIpjiZF7/6OLS9cIiLESM+bXse8CCkQpLlTV6GzexjW
+L/kAPwmOT3G0UUpEKBbXngLABQ7WACICpeX1ptfRNtLYERp51U3LnabXchHK2lFdVn85zuNkrB0o
+JSoPxg/NYHBPSPmqvYB8fSC1bOUQQtaMUFX7fjr+o7Rq0wyyP4gLDKmTJrvhXeAnhw2hGEkJiG1u
+TwEAQCnQOVE3vY55klpijHDV11zkYM3LMj1yteM9aQsFR2CsXOhAbi5wsOVLAACCs9NPIZUe6Ty7
+66bTTh71lNrcJed7ceyWdR/FSGEy/WO+Mbz39lN4cr7VQwjZ8oTK7VcHh18KJYUtintvDxA9D9QS
+vYdJ6sEAyS6iQKAW2Nc9TyT0kGK/fk+U0SNXp6uBZ3KxFigKddfX4Yem18HeFGN4LPViE8d4d8eW
+b/7tdr2CUqLO8ztdLHJIrdFX7h+8uWdNi67ap8o9NMPi3tv/jmIklELP2nrA+ullMsqOUCCyjeED
+qeSZA0TPxeZ3KUQu9DYguvIR4uL6uucpafP7Pj5c1rkZlWV8FgO3B7AZEIDVkC/ipbVRmIKfEvXw
+g9ZhidILXPD+iwscbOkS0B60+/Ro4zpd5MjsVqxrPqLNGhOqaj+B+G9V5PdP+/cUAiitWj2EkC0O
++UjuaPotUHxmh8W9dyWjXITSGsvS/9c8X5O93y/tKd0oXCIixEC9fLpss+z2dByex8hFDvZ+CpNe
+1GsPCrvlKh442hbeB7JWfLzo9+ECB1s6kfBFJ3YfDUMpURfFHTfpVpEDpUQfyPCgPdaEVzGwL5NS
+TkN19YjbU1bP68koujBbyprNRQ2ZTTq/HT0f01+mLrWnAACgQvCBXjS9jkWxRXZrOvZ/IT7RyRok
+NaLCeCX2rB2sq6KPj6VS1xb9PrzDY83gExwzQSFQD7tX5FBZdiNMS45LZEv1dgzsaShGEh16yssu
+j1IiX5ZPY119fd5klIuS1l6pa//XRb4He1Py3WlPAXiZuhNF6vMQRDvItyeH7mGf/xtZ++W52axL
+z3vSFiCK/5Bq8fsvLnCwJrimF9AlKATateE9N57sdGWTgEIgAV4jfoLJluRlDOzNkxjYs1AIoGx3
+nvKyywlVte8m4x1p1KYe5NsXSUa5CBQCI5hrfJJtOSglQuhe4TJK80Hq+YNlW+Tb04Oqk+lwbPEI
+Fj+XT0hEa8SN6LllqkneB7JG/o9lvBcXONjSCYSaT3Ccn11f2/aTaWeehOg8u16PJ983vQ7Wb5QS
+VYfjL1/GwL73wkKufoQoO/OUl11M8J7qo8MvhJIiGxYPLpOMclHS2k2OjF0OcqFT7SknEM2Nvhc4
+AABUlt8rj6pOnURl/ZIP9KgqeRZHk6ILe0rLG8t4Ly5wsOVLIBbV99x3r4ocHelpRWNuR+d+anod
+rJ9OYmCz9eGDWZ7cUkoEiVzXnvKy2R0XNsY7kGjPrg0/n1syygWglBhCqrtyve6yrrWnvIII0VPv
+b7qEFAja3Kmm7k9Nr4WtrmEh7/s68J60IRTpyTLaUwC4wMGWjFIiEMCbvUuw62vbflp2osihrB25
+qv6xK6dOWHdEV+2Tqx+dFgN7FvIBlFELn97Nlo/iq2SUH0yR3VNGf9T0mgAAkhl8Gj1Hxi5SV9tT
+AACUllh7Gje9jmWQUiIl3PRVeNz0Wthq0lahd+FHjo1dvugD2Ux+uKz34wIHWy4ikJldb3oZXdel
+IofU5m50vpdReKwZr2Jg88EfzvUHa/dYSrW5oGWxBlCM5CfT3eheJaPcbNONrtIaq5q4yLtA5Ls9
+V4dA6rQiN1zK6JFz6ap34W9Nr4W1xOJHcLxhOJR3Xc2tKsvmHS2tPQWACxyMdZZdX9sO02onRWr1
+0CSpNYbKTbtQjGHt58rprpBy8q6klLPE5F4sa8gkWzxflk99Nf2jzPTNZSSjXFRS9iaFeNj0Ovoq
+ufKR6GJ7yksk9G9XYQ7HCZ2bUVVHCoGHkLNjy2xaV1ohQiDi2NilijE+xSWOwuICB2tAK/egnWTW
+h/dDXT9Pod2ToWVmt2Jdc8WcXcpJDKzU528/CN6T1prbU3ogVG6/Pjr8Ao0a2qK418QA0fOQ1lxx
+Zf3nptfRR8dzdcBhhwuXqPUmEa1UAcxm2e1yGp/H2O69C+unfGC3Ko6NXZoYiYxGtcz5i1zgYEtF
+RKC0vN70OvrEDItbwblWFzleDtu7wpGJ7KJmjYE9S3JuD5W8Nu91seX5JRkFhF0bfi5lcwNEzwOF
+wIDZRxT4+jdv5AOorNtzdVAiUEhPml7Hstk8u1WO/d+IT3eyJZMS0Si4FgP/7i2Dr+OBtvKzZb4n
+FzjYciUAANHZo6RtZYbFreDd89jiIofM7GaYllwxZ+dy3hjYM18n+idtf9LPTkc+vkpGMcPigVQX
+K3I1SVq76Wv/v5teR99E5x5LxE7P1UEpsfardYLjhBnkdyaH7iHPqGHLNhia69XUfdn0OlYBhbCL
+arnbLy5wsOVKS54mtEJMUdwi759F384iBwqBSeAN8tx3y2Zz3hjYM1/HB9JqedO72XxQjOSm029j
+qL8/SUbpasQ4Sok+ouZZRPOFFF50uT3lRAS1tqonGWyRb08OSr7RXGnNfITzAX4SXDv3zH0RI5HU
+QuOSv7u5wMGWKgHtLXWa0IoxxeA2hfYWOVSWjdx0wrM42HtdJAb2zNcK9R5qtbTp3exyKCXy0/Jp
+qOtH2pqtNg8QPRebbXFk7PwE50nluhctr0maj5adJtEmejC4Xx6WD5teB1stWaZHrnZ/4RNEixNc
+BGvlp8t+X6TIT1PZ8oiEL7q/S2234yJHfBacb2UMm9Dmk+jcT02vg7XXhWNgz5C8fyKQ6/ldEKpq
+30/Hf5RWbZpB9oc+pd5wZOx89aE95QQqfSVGWtnilxACwdg71VG90/Ra2GopCnU3uLCyn71Fiz48
+Qrn8/RemEJ9FH54u/Z3Z6uITHAtniuw2AHwYnHvc9Frepowduar+kY9qs9NcJgb2NBQjSSlNV1sb
+VsVJMopQUnQhGeWiODJ2fvrSngIAgIgQIz1veh1NklIiobxZV6F1+xa2OEQAUopRU++vjULy/h9E
+XHietxiJpISIuPz9F+picBsQBm28EWK95JpewKrQmR0BiKtt/Gwrnd2NteNWFfaGy8TAnoV8fSD1
+cqd3s9kF76k6Otx5lYyiupGMclE6s6Nqyte+ywo+kLKy0+kpr0Mp0DlRr/rpHmX0KEa46msucqwS
+gaLRhLNBYbdc5fm6PGcxEJhM3WrivREAQFs7khKv+in3v7HFEgg1n+BYHp3ZEWD7ihyoJYYQKHFs
+LHvpsjGwZyHnd7k9pX3IR3JH02+B4jM7LO51MRnlokjZjzky9nJiXT+WSvUq9pmEHiY+2AjK6JGr
+KQuBW+jZckiNiCKZGPkDOE/R+0dSYSPJma92fdLakS7yO34y5bgmtjgJBB8VXy5t7AhRXA1Vu4oc
+0tgtX9WPml4Ha9a8YmBPfe0YCaXQvRhQ2ROvJ6PowmwpazZX7TtBGrtZV54jsy+hT+0pJ5I2v+ft
+9zGd2+vlND6PsZ0D01n/FAN1oy75ujwvKRGhaKY9BeCtFBWUEu3G2j0/nTzk/ng2b5QSgQD+vWqA
+NHaEql1FDpQSieA3/CRzdc0rBvbM1w8BlFZLn97NTufL8mmsq697lYxyASglRsCM+GnhhfStPeUE
+IkIM9EPT62gLm2e3ynH4T/6c9F074oOERLRG3GhrCmHXBEdgrGxsCPSp53azjY3t4OtvOGGFzRUR
+yMyuN72MVSWNHaGRV920bM2UcpnZTV+WXzW9DrZ884yBPQvV1SNuT2leqKr9+ujwC2nUph7k231K
+Rrko1IOt4APfzF5ACq537SkAAKgQfKAXTa+jTcwg+4/J2D1MPACy19pyhi8f6FFV8iyOeYgxPJa6
+uZSrM3d+thjeoeCfRy5yMNYbUumRzrO7bjptxbwdFAJB4G3yfJ1ZJfOOgT0NxUhCQFzVUwJtELyn
+V8koa8PP+5qMchGoJTqX/smnZc+PnPtn39pTAI6/D2MUidvE32QH+fb4Z54RyJZjMMBPfB1+anod
+XZcovcAG91/vfLRliuGtROmwbQMKWZf1bk/SOSgl6jy/05Yih8qykZtOuGK+IuYdA3sWCgGUbWZ6
+96o7LmyMdyDR3ioko1yYze9Gjow9l+AD6Vx92PQ6FiVK8wEPGv01u1Zsl4dc5GCLZzM98i78yLGx
+F+d9IGtFo22E7z27a/LsOkq8GqrqT8tYEOsvIgKl5fWm18HaV+QQJrsfneOKec8tIgb2LOTqR4iy
+kendq4riy2SUGH8wRXZPmcX/PXeZ0hqrif++6XV0SXBuT0l1o+l1LAqiucEFjtOhye+UR1Ur9ixs
+jtoxguMNw6G862puVbmo6GPjbYQzNScra0cqz37nJ+24GWIdlQAABN9wtARKiboo7rgWfK6V1uiq
++kc+rt1fi4qBPQ2lRJDIcXvKclBK5Kfl0+heJqNk5ib/v59NstltHrQ8OxHDkz62p7yCCNET31id
+QkiBIM2dugp8qrx32vWRVlohQiAecHsxFOI/pWr2Oj3z9DWUEvX68I6bTL7gmxB2IamFZdoVh0Kg
+HralyJHdjbXjjV3PLDIG9sz39AGUUb1LWWgjX5ZP/XT8R2nV5iono1yU1OYKR8bOJvhI2ojetqcA
+ACgtsfbEbUtnkFpijHDVc5GDLVg+sFt1GR41vY6u8T6QzWXj1+lzjZdHITDbWP/cVyXHyLJzS0B7
+rRmVzF5BIdCuDe+58WSnyeFmqCWGEChFfprZF4uOgT1T7R5LqRqb3r0KQuX266PDL9CooS2KezxA
+9GJQSgxJXeEnhe8XXL2ntO5te8oJAmk5NeRsyuiRc+lqCDycnC2OlIhapd/EwNfm84gu7CklG71O
+u0m9e6H8vGx9fTv6+m8cI8vOQyR8wTvg9rLra9t+Mn3YZJFDGrvlq5or5j2wjBjYM987uRccRboY
+vySjgLBrw8+l5AGilyVNdsM77vd+n963p7xEyvyW53C8m87NqCzjsxgi34d0XJt/0wdDc70u652m
+19ElFOlJk+0prnb761d0caECB8DLhJUQn0Ufns5zYazn+ARHq70qcjR0QgulRCL4Dfekd9syYmDP
+fG/vSWvN7SlzRj6SO5x+AxSfmWHxQKrFz1JZFagleg8TPhl7tlVoTzmBqDaJuE3lfWyW3Z6Ow/MY
+ucjRdeLCd6OLl+XyVnD8OzaL6APZrLn2lBSJNKS/GKs+utSvlC4GtwFhwDGybEau6QWw97Pra9t+
+2lwbms6z624y/rKJ92aX58rpLiopFh0De5bk3B4q2ej07j6hGMnRxnwRAAAgAElEQVRNp9/GUH+v
+h+YzZc2mEFypnjub36UQ95peRlul4PaU6m96yutQIoQAvK+egS2yW9XY/5m4OMgWJMv0yFXu+yZP
+N3eFd7SndHPtKXXtvlv7ILsPcM4ZHKfR1o6k1lf9lPOp2bsJhJpPcHRD00UOocwn5D1XzDumHk+/
+Vcb8FpVu7Ok+Rf+E50Fc3kkySqjrR9qaLR4gulhKa6xK/59Nr6OtyPsnQrb4Me8coZTofaybXkdX
+6EF+f3LoGm2vZf1WDNV2cIEL0O8RY3yKDW2/XO32P/gg+xjx+EZzLt8WUquRLvI7Tffvs5ZLIPjJ
+X3fY9bXtMK12UqSlFxqUtSM3Lbli3iH1eLxjcru1jBjYs5APpFXz07u7LlTV/kkyihlkf+B5JstB
+Ov+E2/N+7aQ9ZZX2DxHUGp9KmJ0t8u3pQcWzEjpIpPbPc9RGIYWwRzz890wxEhmNqonrdIxEmca/
+a42v9p9zK4ejlGg31u756YQTVtivUEoEotWzhNgpzPrwfqjr56mBQV7C2G1ynivmLUcpUXV09MUy
+Y2DPEkO9h3o1jrEvwkkyilBScDLK8klrr1SV48jYt6xSe8qJJM1HPGj0fFSW3ysP+TR512gZnzS9
+hlkMBuYzV/Ew6LP4Oh5oKz9r4r2Dc48Ga/qN9577eb9sY2M7+PobTlhhbyACmdn1ppfBzs8Mi1vB
+uaUXOZTW6OvqGRdM2+tVDOza2udtaF9I3j8RuBrH2OcpeE/V0eEOYJrYteHnUnEyShNQCIxgrhFH
+Zb9hldpTTqDSVygmLvCfg5ACwdg71dR90/RaWP9IjYhAJnKk96kohF1Uy98GVlP/9MqV7N/wrZMj
+C/nGsMXwDgX/PHKRg7FeMMPiVvDu+bIj2aTOP42144p5Cx3HwPrvm4iBPQ3FSFJKs0rH2C+LYiR3
+NP0WKD6zw+KeMvqjpte06qS1m94Fvua9FHwkrWFt1T7XiAjeE6cUnpOUEinhv/oq8JBWNnd5oW/U
+pedTdm+JkUhqod8uMiz8fX2g4UDsv96acmJhJXFTDG8BUeSEFfaLldqf9I4pilvk/bPol1fkQC0x
+hECJn2i2yi8xsNlW02s5Qb4+kLqZ45Fd8yoZxdXf68JscTJKe6CUGEKq+eTaMQr1gdL6902vY9lQ
+CgwkIs+hOj9l9Mi5dNW78Lem18L6RUpEo+DaMvfBXeDreGCt/HTZ70sh7gyG5tR96ELP/Ok8H6HE
+q6Gq/rTI92HtR0SgtLze9DrY5ZhicJvCcosc0tgtPy25Yt4STcfAnoWc3+X2lPfzZfk01tXXnIzS
+XskMPo2eI2MBAJIPu6vWnnKCkh7yHI6L0bkZVTVRCHySvO0SJdGl55+DobleTd33Ta+jTSiEv6Na
+7nXalX73ysjeP+vfL3w1ytqRyrPf+cmUB/+ssgQAIDaaXga7vOMiR3wWnF/K0xGUEgnwGqcLNK8N
+MbCnoRgJpdB8s362UFX79dHhF9KoTT3ItzkZpb2U1lhV/r9W/ek9xUhaQyNT+dsgafP7Ff8VuBSb
+2dvlND6PkZ+2s/nKC3nb1+GnptfRBjESSQlxme0p3gUaDoWQ79jHLKXcglKiXh/e8ZPxl3zsckUl
+anoFbI5Mkd0GgA+X1YKm8+y6m4y/XMZ7sdO1IQb2LBQCKK2WfjyyC4L3dJyMgsKuDT/nZJRuSDq/
+TSEeNr2OJpH3B0rrlW07Q0SIgX5oeh1dZvPsVjn2f+PIXTZPWaZH3vkfOTYWIAYCk6lby3xPkcJX
+WW7eeYp4aedJUAi0GxsPfFVyjOwKSkB7sJoPYXpLZ3YEIK4uq8ghlPmEvOcnMUtGMbYmBvYsVFeP
+uD3lTeQj1UfjHUi0d5yM0r7CFDubtPZKXfu/Nr2OJkXnVrY9BQAAFYL36b+bXkfXmUF+Z3LoHia+
+GWVzVBTqbnBh5QuQ0ftHUuHSTujXZfXtxgfZg/f93NK/ObL19e3o679xjOxqEQlftPLOiF2KzuwI
+cDlFDmXtqC6rv6z6se1lIh8olFVrYmBPQzGSEBDbur5lO0lGoeh/MEXGySgdteqRsavengLw8neA
+APnG/PJskW+PD8qvml4HO12nhnC8pI3CFPx0lU9xpESEAiLicq7Trnb7G+tmJGfY7zVSGjfF8FYK
+8RknrKyY1d2n9Jo2doQoroZq8Z9nqc1dcp6H7y1BcNU+hdCaGNizUAig7HKPR7YRpUR+Wj59lYyS
+mZtc9Ok2ae2mr/z/bnodTVj19pQTUZoPuKY/H6YYbJeHJc8DZHMzKOyWq/zKxnoHR2AyuZT9V4pE
+BuFvxqqZHto0dvZPF4PbQuLSjrezxrmmF8AWRxo7QrX4IofUGn3l/sFtbosVquk+tCwG9izk6keI
+cqUHGPuyfOqn4z9KqzY5GaU/UEr0EfUqXu8oOE5FAgBEc4OTVOZDCIFg7J3qqN5pei2sH6RGVBiv
+xLiaH9IYw+Nltac45x4NN+zdWX++0W8Pbe1Ian3VT7mi2ncCoeYTHP0mjR2hkVfdtFzo5kFmdivW
+9cpWzBftOAZWty4G9jSUEkEit6o39KFy+/XR4Reo1dAWxT0eINpDNttatchYipEUghZLOvbcZqgQ
+oif+vpsTKSUSypt1FfjhKpuLPDeb9bReyfanROkFLmH/VZVu/8qV7N/O0wrTeHlcajXSRX7HTyZf
+cm99jyUQq9xLuyqk0iOdZ3fddHGx0Cgl+kBmVXvTF6keT1oZA3sW8gGUUR83vY5lC95TdXS4IxSI
+4wGishN/X+z8lNZY1fTjKu2PyPsDZTSnIsHx913taaXTdOZNGT2KEa76moscbZASQAdHcLwiJKK1
+8nb0qxVH7H0ga8XC918xEA0s/l1rPNc+p/ECB8DxBdxurD/w0wknrPQQpUQggP9eVwRKiTrP7yyy
+yKGy7EaYll8v6vVXUX043jF51soY2DPV7rGUarPpZSwL+UjucPoNUHxmh8U9TkZZDUnZm6sUGcvt
+KW8ikJYHjc6XMnrkaspC4MADdnn5QI+qcrVmcUQfHkulri36fSj4nWLt/POYWvUNkm1sbAdff8MJ
+Kz1DBDKz600vgy3PooscKAQS4DXyfK24rFcxsMP2xsCeJSb3Qsj+t6dQjOSm029jqL/XQ/OZsmaT
+T8StDp3ZkSvrPze9jmXg9pRfI2V+y3M45k/n9no5jc9jWK0n72wxhoW87+vwU9PrWJZE6YVUi91/
+VVP/dOOK/feL7HdaVeAAALDF8A4F/zwGzxccxjoMpURdFHfcZDFFDp1n1+vx5PtFvPaqIB8oVtXX
+bY6BPUvwnrTWvW5POUlGCXX9SFuzxQNEV1eQ2UcU+t+WF0MEye0pb0BUm0TcprIINs9uTcfhOa3o
+kMg2wJ6EEGirMHj3bBViY70PZCxeXeR7RB9oOBD7Sp2vNeVE6wocAMcxspBS5ISVPuE9+SpCIVAP
+F1fkQGNuk+di6EUcx8DG73VRbDe9lotIzu2hkgs/HtmUUFX7bjLekVZtmkH2h1U4qcLOJo3d9LV/
+1PQ6Fo1c9Qi5PeUNKBFCAN4PL4gtsluTsXvIbUDN0CrUfflyKwr9qav736oSXdhTSt5Y5HskCl8N
+hubCSX6t/RbReT6SEq+GqvpT02thl0NEoLS83vQ6WDNQCLRrw3tuPNmZ96A8Ze2oLqu/rNIAvnn4
+JQbWtj4G9iwU/ZM+poYEd5yMIpQU2bB40Mf/RnZ+LyNjVZ+fNFOMpAREbk95E0qJ3se66XX0mR3k
+2+OfOdGRXY7SChEC9fk6DQBAkZ4ssj3FlX5340r24DKv0doCBwCAtHak8ux3fkFPf9mSJAAAsZSc
+ZNZedn1t20+mD+ddjJDa3I3O/zDP1+yz4xhY04kY2LOQD6SV/LDpdczTSTIKQJpwMgo7lc22gg+9
+vdZRIFCZutX0OtooglojHsK/UHat2C4PucjBLicf2K2q9L0dgh99IJstbv/larc/HAohL3lqtdUF
+DoCXffzrwzt+Mv6SE1Y6KlHTK2At8arIMcfPstQaQ+WmfH14v19iYLudvhFDvYdaLfR45LJQjOSO
+pt+eJKMooz9qek2snZTW6Fz6Z19PrCVfPkJEfhhyiiTNRzxodPHQ5HfKo4qLHOzCpEQ0Cq71NTbW
+O9pTejHtKSkSaUh/yXJz6QdwrS9wALw84r6x8cBXJcfIdlAC2gM+ccpesutr234638+yzOxWrOve
+9z1eRn043jGDvFsxsGdI3j/peowkxUh+PN2Nrv5eF2aLk1HYTHR+t4+RsRQjIUDkIbqnQ6WvUEx7
+Ta+j74QUCNLcqavAM0+WqG/ffYOhud7X2FiK8QkuqHO2rt13ax9k9+fxWp3aIWbr69vR13+LHCPb
+KSLhi15dudilzbvIgVJiCOkKxf6nDJzXqxjYteJeH24eKEaSUpoub4h8WT6NdfW1zPVNTkZh56Gs
+xmrqerdx5vaUd0NE8J6eNr2OVSC1xBjhquciB7uEfICfBNevUxwxEmmNC9l/udrtX9kwI5zTDKZO
+FTgAXiashPiME1Y6prv3ImxB7PradphWOynSXL4AZGY3w7Tsbd/jRbwRA9vhgsDryNcHUsvPml7H
+RYTqeICoNGpTD/JtHiDKLoKU/bhvkbHcnvJuKAUGErGv7Ulto4weOZeueue5qMQuJMv0yNWuV0Pw
+fR0PtJ3//itGokzj341Vc2vR7VyBAwBAF4PbKPEqFzk6oxcZ12z+zPrwfqjr5ylcvsqNQmASeIM8
+n/AC6H4M7FnI+d2utacE7+k4GQWEXRt+zoUNdhnS2M266s8QO0qJ21NmQEkPeQ7H8ujcjKqaxnEO
++xO2mopC3Q0u9Ka1LIawi2r+l+ng3KPBmp5r4aRbu8TXKGtHUuurfsoTj9tOINR8goOdxQyLW8G5
+uRQ5VJaN3HTSu+Pb5+XL6dOux8CehmIklEJ35UaIfKT6aLwDifaOk1G6P/+ENQ+lxAiY9SWKkFwA
+Zbk95X2SNr/v0cPgTrBZdns6Ds9j5CIHOz9tFJL3/yDq/gc3RiKlhcY5nwauSv/0ypXs3+b9up0t
+cAAASK1Gusjv+Mnkyz4dAeqdBKIvx+PZYphhcSt493weT0qENp9E536ax7q6yJXTXanNsMsxsGeh
+EEBp9WnT63ifk2SUGOrvTZFxMgqbO9SDLe/6McQu+fIRSm5PeR9EhBiotzHBbWWL7FY19n/mmF52
+EYPCbrmq+9dqX8cDa+e7/4qBaJiLfa1x7g9/Ol3gADh+kmE31h/46YQTVlqIUiIQwH8v7L1MUdwi
+759dNlpLGTtyVf3jKl4P6vHkmz7EwJ6F6upRm9tTKCXy0/JpdPX3emC2eIAoWxTUEr2HSdevc9ye
+MjtUCN6n/256HatID/L7k0P3kB+msvOSGlFhvBI7fuKOQvj7vNtTKPidvNC/n+uLvtTeneI5ZRsb
+28HX3xAnrLQLEcjMrje9DNYNphjcpjCHIofO7kbnV+pJ18sY2M/6EAN7GoqRhGjvjZAv66d+Ov6j
+tGpT59mWkO1cJ+sRm9+lEDvd302e21NmhUJgJMDUg+PuXWSLfHt6UO00vQ7WPXluNuuyu3OTYiSS
+EuI820hc6Xc3rth/X9QJ/94UOAAAbDG8Q8E/j8FzkYOxjjoucsRnwfm/XfQ1UEsMtZ+mFYiNpRip
+Ohx/2ZcY2LNQaOeN0EkyCmoc2qK4xwNE2bIorbEq/X82vY7LiK7+TnB6ysyiNB/wIYLmqEF+rzzk
+2X/zklKiptewDEIiWiNuXPbhXVNiIDBzjPH2LtBwKIRS829NOdGrAgfAyxjZlCInrLQJ7/fZ+Zgi
+uw0AH17mcywzuxWd63zf47u8ioFdHz7o+5wbcvUjRNmaG6HgPVVHhzsnyShSyV6enGHtRjr/pKuR
+sZQSYaIx8mmnmSGaG0R02PQ6VpUQAsHYO9XUfdP0Wli35AM9qspuzuKI3j+San6FaJHCV1luFjon
+rncFDgAAnecjKfFqqKo/Nb2WVUdEoLS83vQ6WPfozI4AxIXjoFFKDCFdoZ6e4giu2qcYfuhbDOxp
+KCWCRK4NJ1TIR3KH02+A4jM7LO5xMgprkrT2SlW5Th59Jh9AZerjptfRJagQyKcnTa9jlUkpkRL+
+q68CP0hl5zIs5H1fh04NwU+JCAVExPk8RHOTenfjg+zBPF7rXXpZ4AAAkNaOVJ79zk+mfJSsSQkA
+QLTmqSvrFp3ZEeDFixwys5t+Wn4173U17VUMbJb1LinlNOQDKNPsjRDFSG56nIyih+YzZc1m30/N
+sPZDITAm3clCbnTusUTcbHodXYJSYu35BEfTlNEj59JVX3ORg81OW4XehR+7FBsbHIHJ5FzaU1zt
+9tev6EIu4WFVbwscAMdfBHp9eMdPxl92fdJ4Z61Gex1bIG3sCFFcDdX5ixwoBILA2+T7M3y4zzGw
+Z6rdYylVIzdClBL5snwa6vqRtpyMwtpHmuyGd6FzR5+RwgtuTzk/Aml50GjzdG5GlaMYQn/2F0tH
+AIVNKxVEMBzKu67uTqtKjOHxPNpTUiTSkP5irPpoHut6n14XOACOb3DsxsYDX5UcI9uABLQH/JCT
+XZI0doTqYkUOlWUjN5105svkXfoeA3uWmNyLJlJJQlXtu8l4Rxq1aQbZHzgZhbVRFyNjg/Okcs3t
+qxdAoP5HqAM/PWoBm9nb5TQ+j7GbwyPZ8imtECEQdSQ2NlF6gXN4qOOcf7T2QXZ/HmuaRe8LHCey
+9fXt6Ou/RY6RXSqR8AXfEbB5kMaO0MirblqeO6ZNmOx+dK5TfY9v63sM7FmC96S1Xmp7SnDHyShC
+SZENiwecjMJar2ORsdyecjH1tHzqJgc/0+HzL2g6/jb6yIWOhtk8u1Uehf+kDhUYWbPygd2qy/Co
+6XW8j68DWSsuvf9ytdu/csX+27zmeMxiZQocAC8TVkJ8xgkrS8YnONicSKVHOs/uuun5ZusordFV
+9Y9desJ5YlViYM+SnNtDJa8t471OklEA0oSTUViXKK2xLP1/Nb2OWXF7yvkE5/bdzy++MOg2s4H6
+eO3K4PONfJpdUT9/z4WO5pki+4/JkXvIrUNsFlIiapV+E0O796QxhsfKqEvtv2IgyjT+XevFRcKe
+ZqUKHAAAuhjcRokXHlrIzs01vQDWLygl6jy/c/4iR3Y31t2KjV2lGNizUPRPFn2CgmIkdzT9Fij+
+YIvBPWX0UnpEGZunpPPbsQPzhoIPpKzk9JQZUIxU/bz/DfjJxBb6c5QoFNATZSS6ID9USnz8mw/C
+1nGh4/AbLnQ0xw7y7fFB/4aaLxLB6v66DobmejV1Xza9jneZR3tK9O7rYk1/Nq81zWrlChwAAMra
+kdT6qp+WnLCyYAKh5hMcbN4uUuRALTGEQKkjaQOrFAN7FvKBtJIfLuz1YyQ/me5GV3+vC7OlrLm5
+iqdkWD9Ia6/Utf9r0+t4n1jXj6W63FPBvqOUqJpMduPk5++zXH6mzeuD+ZIAANBWj47G/nlKCfKB
+2vrNB/TZVXPwTJQ/73ChoxmmGGyXh3xvwWaTD/CT4No5v8X7QMbi1cu8RjX1T698kN1u4gHdShY4
+AACkViNd5Hf8ZPJlSnykbGESiFV98swWC6VEXRR33DmioKWxW76q29/3uGIxsGeJod5DrW4s4rV9
+WT6NdfW1zPRNTkZhfYBCYARzre2Rsdye8m6hqvfdz//csTLcNLnZEm/3rRO8av3NivzW4c/1w5RS
+QhTCZHLz6hW4x4WOZgghEIy9Ux5VXORg75VleuQq930b70OjC3tKyQvvv6IPNByIfaWW25pyYmUL
+HADHN0h2Y/2Bn044YWUBKCUCAfz/lS0MCoF6OHuRA6VEIvgNhfbeAKxkDOwZkvdPBM73aypUxwNE
+pVGbepBv8wBR1ifS2s02R8Zye8rZgo9U/by/gzQV+dA+OKsIJBDc6//CFNndyaH/+uSff1XomP68
+E2sudCyLlBITqht1FbgVnr1XMVTbwYXWDYimSE+kunghOlH4ajA0W/Nc03msdIHjRLaxsR18/Q1x
+wsp8EYHM7ErlW7PlQyHQrg3vufFkZ5YquM6z6246PXcSyzKsagzsaShGklKaeZ0AezlA9EuhQNi1
+4edc2GB9hFJiCKlu60ObFBy3p7yFUqLqaLKbqp+/z3J5T+p3X/8N+hpeu3oJgZikvFO/FaN+Uuj4
+cAT3PswP97jQsTzK6FGMcNXXXOR4J+IcAm0Ukvf/oBYNqI0+kM0u3h7sSr+7cSV7MM81nRcXOF6y
+xfAOBf88Bs9FDsY6yK6vbfvJ9OEsRQ6B8hb5dn3WVzUG9izk6wOp5aUHU5GPVB+NdyDRnh0W9yUX
+j1jPJTP4NPp2RsaSD//k9pRf+Kre94f//KPV4abJTmlHOU0CeLvwK7XCyuHV4OPTt39cCCG0xY9e
+L3T42nOhY8GU0aO6jldD4Ien7N0Ghd1ylW/NyTvvaE/pi7WneBdoOBRCNnyd5wLHa0wxvAVCRE5Y
+mSfex7DleVXkeM/TS5VlIzctW9H3uOoxsGch53cv055CMZKbTr+Nof7eFNk9ZfRHPA+IrQKlNVZV
++K82XN9eF3wgneHChgZ3SfCR3M/7XygqRTaw9+ZR9NFWj8ZHNAnh9KGFrxc6fpOP93T54gtXV/uX
+fV92NpNno7KMz+IZfyeMAQBIjYgimRjbcfKOYnyCFzzkijE+zHLTeIs1Fzjeoq0dSYlXfVV+0/Ra
+uo6IQGl5vel1sNVi19e2/bR8b5FDGLtN3jf6lJNjYE9HMRJKoS9S8KGUyE/Lp9HV32trtniAKFtF
+See3KcTDptfxuuDcnpKLGRrcFRQTlUfjb5M7/MEM5APU8lwnyigmQpnUWf/eFObW+Cj85V3H3U8K
+HR+M5Of/MpgKLnQsls2y29NxeE4tuXll7VQM1I26/GWWTlNiJNIaL9QeXJfVt+tXbSuS/7jAcQpp
+7Ujn+af+HOkM7BQJAEBsNL0MtnpmKXIordFX1bOmetU5BvZsFAIorT49758LVbXvp+M/Sqs2dZ5t
+CT4Kz1aUtOaKK+s/N72O14kYnqxye4qblk/9eP/rTMctY9TNixW1CTTC4F0/YQbZ9viwnmnOlDLy
+ypuFjpILHQtgi+zWZOwephbNWWDtIiSiNeJG9M2e9vF1OND2/O3Brnb7G+tmJFvyQIkLHGdAKVGv
+D+/4yfjLtg7rar3ELZ6sOXZ9bTtMq50U6cwvC6nzT2Ptlt73yDGw70Z19eg87SmhcvvVweGXQklh
+i+IeDxBlqw6FwIDZR21JjAo+kjZiJdtTjttRXnyhoR5mA719mSIPEcy0cxdK3yun/k+zvu4vhY6S
+Cx0LYgf59vjncqY5YauFv65P5AM9qspmZ3HEEHdRne/vJEYiq2DXWPXRgpZ1blzgeAcUAu3GxgNf
+lQ85YeX8EtDeyo9HZo0y68P7oa6fpzP6X1FLDCFQisu7CeAY2HejGEkIiLO0lbxMRtkRCkS2MXwg
+1fmOezPWZ9LaTV/7/930OgAAgqv3lNYr1Z5CMVF5cPgtuMNnttCfn7cd5SyzzCGVWqELYvO0oaPv
+clLo+H+KXwodKfHTqnmxa8V2dVQ13obA2mswwE98HX5q4r1jJDIaFZ7zdFlw7lGxbu8tal0XwQWO
+GWTr69sU/PPIRY5zEQlfcHmDNc0Mi1vBuTOLHNLYLT8tl7Lh4BjY96MQQFl1650/4yO58fQboPjM
+Dot7nIzC2P/P3t3+N3Fk+6JfteqpuyVZRpDMHAyzz549YJLByb0hgCH//gUMyXA+M/HshDhz794T
+4uTMmcHWUz9V1ar7QtjYYINl66HVqu+b5ANYKttSq/vXtdZ6F3KOxqGswi7UZStPKdLspR3uPY8j
+vyGVWJvkYyNnZ+pt9qGmo+/D5ZugQ+V7T1yevQxBx2Sgiu9m/TyUwAcn0pHsmNL+NI+xsaZwY5en
+5Fm5t7oa/WHcUGTaQsBxRqrRXAeiX8KElTFV6/UeLCnVbKxbU/56Uidz5BwJ8Oq0t3KHMbBnQ2Xx
+HJGf2Lvn6GQUmag7Qqu10Jw1CN5DRxvzHhm7TOUptiz3ilf/eqxY0dSx/HLiDY7JAbKz9zY7S9PR
+9zkIOj5u5WuxefV1CDoujnGGwNXdMi3PXEJUV0QAXJwtsFsmzSa/Zwv746yfl6wdqzzFWaJmjC+l
+xMqd14aAYwwyjm8hx8sh5Dizct4LCIIDqtFYJ2N+OamBk4yj6+Vw8HgazxvGwJ4deU/gqXz750Te
+k8myl67In4XJKEFwdkJKzAv6aZ51/96Wu0LUe3oKOUf5/t43YIbDqKUe4pTK5Qhg7BtH4zQdPQ0X
+yFba4v6xoMOFoOO8uORoPa6Z3C799QQbI7BbFkIKBDDpLCfvOEfEObBxdmKQNVtxQ96e5rrOKwQc
+YxJad4RW/2HSLGwv+wCGUIQdHEGVqEZyi+zJIQcT6hMyZqJlaGTMXhgDe3ZkLAglfnf0z2ye75XD
+wRZXYk0m8WaYjBIE4/FC35znyFgy5u+M1/d0Mx+mL91w/69RjHekmnKTvXNe7jClx2o6eppjQYd7
+9bUbhqDjvISSnbL0l01pxuqTEiyHONEbRWafz+r5nCVQ0fvLg4/KU/Oyvao/req5bX0/caYIOUfZ
+iO+a4fBx6Ib8Hh5YVV/4wfIahRzuF1uaH47+udC6U6bZXyf1nh6NgXX/J4yBHUNR7nA+qle3ZblX
+9HuPmOAsajYehskoQXA+MtKdPJ39tCiAN+UpdTwXsHmxV+6/eqS5WVOxmsmuMgnm2/P8JDlHLImt
+lYWbSPPCw6DjUr6W+L1nIeg4HxmrTl7Q4KTy2WC5cY4ohf/Y2dns4nDGPOcCz7SbxhlLKy2WClG9
+0pQDIeA4J+QcdXvloUmHT6vQwKtqyHsCdt57DUEwXaoR3QKAK2+Xm6HSm1SaC9erl1nxIoyBHZ/z
+5StHzuf93haAH+pW86swGSUILo6E/t08RsbWsTzFGkf5/t91ZjoAACAASURBVN4WUsp0Q3412+ap
+/tzPJaXspEMa2BN2MJ4X58haLb55NOhwzoWgYww6im6lqf3VuWUMOcJL5X3iWKwV2cXKy87CeyJk
+4PAsI5oAgJzdimJV6fPbEHBcUNRub5qi+EsYI/sWIuCRXpn3MoLgNDLSHQB2rKcOlxJNXv7zIqFl
+maUvhOS/CWNgP4ycIzKWrDFUDAbWDlOgsvhBJfFdoWRl5qkHwaLjSq8VuZn5eMo6laeQ95QPhy98
+vv/XKOb3uZxDw2iCCzVvVw21Phicv+noaY4GHau4/1efDf4Sgo6z03G0ng/Mf9IS3jCt396uyWEc
+UWu+bsvphl+2JFARP1N5SjksXqx2ogfTXM8kiHkvoA6iVvNzM0y/d94DFzI0ywmCBSEj3TFlAbYs
+d4RSNwAAeKQ3XFFsizjeGPfxikH6RMbqk2WflEKvT2yJaNQmffT/O558AeRLD74AABBSaACmAblm
+yP8DgQQiGJtmTz14zwBbKPl1YLyNiAACARmrx9VSEMwQco4WMCJHflY7Dsg5khJUHcpTbF7s2az/
+nY7lA1Rqrt/PRZ9cJdFmfz971O5EX01kQUdwjixOcENr44ui2O5l2pOKb3Nek5RrimQSPxj2sq1m
+W9+vw3smmIw4kZ39V/ljLqMH03pdGGO2dSQ/eM5bFuXeyqps8AVo8h4CjgmRjeSWKYpXRy+Ugsq/
+/oMApNIdVxZg83JHROoGco5lXipUzo/T96HoDbZUM9ms83SPY8GFBwBP4K3bJYBXMLoh2PfeA+ec
+M8QGINfIxQ1gDJCxmwwAgDE46WdkiUhe+ehLmw6eRc3koffeg/fgvQcgD84W21RQCt5bAGwxhA4T
+6ioiAuDoAm6mP4wgWDAokw1r0h8Vn805ii2LbiTlnVk817RY48gOe8+UgltxUz+c93q0MH1gFz91
+x0g/SNPymyRRX05gWe8+/ltBRzfV3sv4NpfhOP0+uhFvDveHj5uXkrm/1oLqaDTEZlnaXanl2qQf
+23siBjDED5y7ekckwX+ntFiI12YIOCZIat1xRQEmz76RUTyVD41FQUSgJA+zrYOFwJXuALwJOUSk
+btg0e6Zazfsf+lpyjkyaf61ajYW960LeExAdDy7I7RIdDy6Qo0DkCSB6RNwAxgGkWhMAa8DYKLy4
+0M+AgWi17+aD7tOokdwHxkYxKQdAKQ7vLniiUS9YPwo+vIOh9c4RYIsj00zIG4AAiBiCjyB4DSXH
+cuD/JRX9YRZBrDf2BYv0B4+hVUTOU5EOtwUzUZTw6hzbPVzwGDvCOaIx+PsiNzs6klMLvELQMT7Z
+SDazXvY0XokX8r0zllDEdCZSC0yz7BcuxdWz9sk4K1sSRNGHr9eKoty+ciWufGnKgRBwTBjXusOE
+WDWD9KlsJPU/OJ3GAwCE2dbB4uBKdwANlGm2pZJ40wBeJWu7KMSpr2MyZs+V5QvdquaklIPgAsgD
+eQ/gCYBc1xH8NAoufN97eBNcAAMU/DYwDgBqTbBJBRcf5sl+C4J/hoyhaB4JOU7AjnzCozg5+CBH
+O86UPeuoAM8049higt8AxBB8BMtLx/ecLXpCna1b/nm9Lk8RlQkGxmDyYo+K/g+RlveQi4Vb/1lJ
+KTtZXv6Dc9cVkk/19XAYdETWF/l+CDregzGGoPTdPC2/iaa0w6ZaavsWm6hGQ36RZmY7StTY5dPv
+45zd0ZF4b8+4sij3Ll2KfjfpcGWaQsAxBcg5ypXmXdPrPRZx8qDOW9ZPFaaFBQuIC9lhMd4r0/Sp
+SpL75bD/KGq3T6xTtmW+BwRzGQN7puCCgDGOwDlvvQ4urgPjbQC1yhmsziq4OCtPb85ykDEUSetu
+MRw81Y2z38U6HnzA4Qf2m+ADgJw7FnyAYAq5uB2Cj2AZCCkx7w7+2lRyqtuMyZiuWrDyFGsc2UFv
+S2v2KSbV23lC3hOb8AWGitStfj//ur2KX87i4gWRsTgRh0HHIONDK1r3QtBxHOccraPfm9zuyKhe
+U4iC8xFSIOYZkRMT7aPkyb96X3mKc0SRxL9JiQsVtoWAY0qQMdTt9sO819sSWn+C/PS7wHXkgXaB
+sYnXigXBtCHnKOP4bpmmT1GoT8iYLsrjzYPLLH2BnDMRTXZSysnBhQdHtH10xwVDZIzzFi5AcDEO
+duRODnKOkDTHDjlOfNxjwQc/LfjYJWteWet6BMCRYxKCj6COvNLXyTqP4uw9hsblyvIFU9ULCU5C
+zlMx6G9L4S5HDT61Rn4XRgCKU2vSD6sb0d3+fva43YlmVlv/Jujw3pbd3W6KP4Wg4zihZMeUBqCw
+O1KHkCMAiBO90e+bZ0lzMsdWYyxpzX73vn/jSvOsfSVaiGP5USHgmLJoZWWzHA5eeADgSxRyMI+v
+GEAIOIKFdBBymCz7usisj4Q4rMEuB+kLEanfoDj7pJRjwQV4OPh/B/QtOM8AfOo9OMYYMCFWEBgw
+gZcYk2sADJDBBlvg4OJMvH9np+pByGGGwy3ZiCa+U+at4GMNXh+zPJEHD+C9ByL6mazZOxZ8IL8O
+/PVkFwyTXYLFMhoZO3gWN/lUTloPy1MWYDtzkWYvmc1+jSN+h2HVy1EIYEpHGoz05jSbjp76vMiY
+ivjaZeWvHgYd2LrHdQg6AEYhR5kVQ8ZtV7ynXHZRLd1M3AviHFEJuOqM6/IJlJW50u6qRJx6rZan
+5uWlS/oWLuB5Zwg4ZkA1musmy763rvzHUk1YWbz3QxAcQs5RNhp3i/29r6k0u1yrtWIw2JJxdOvo
+GFhyjsYKLpB1mJBXXwcXnx18bixlKdsZIOdIUeNeWWQ7Ss/m+Hnwu2AAgMCvAchrAADeew/kwYMH
+T75LZfETWeofG2nLeRshjLQNqgs5R+PF6rRGxi5CeYotDVHaf6I0/hFjuRBbr4kAgE/nsWfVdPQ0
+7wQdQ/zJ8hB0AADIWF/P0vxF0mDA+XR7pcxD+JQcT9JU1/deFY8akl94zDM5+jsXeO2kv3PGUjNh
+e1Ke/PdVFwKOGZFxfMsu1xjZct4LCIKLQsZQtVfv9H/59RFX8qVqNC6ZrPg7+OJHD74AABBSaADU
+gKhRjE4MkbEQXEwQSo4A0WVb5DtiRiHHSRhjDPjhZJdVLkdB1zvBhyt+opz6o20p2GIcOoyHkbZB
+dXAV3TDlcFvHeqIN6wAAyFa3PIWco2Iw3JbCdXRDXvgCYdYQoTOtx55l09HTHAQdV7S/asvez/sD
+9jIEHQA6jtazfv7npMU+m0YoGSyWOMFPbOm6Qp3/feqMJR3xK6f9PVm3lVyKF2Ik7ElCwDFDQusO
+ObdqhtlTmdR7/BNDKMIOjmARkfdE1oK3Zhc8vWSITDWSf2ecv5JJfHN0a5+F4GLCGJg+MHXq36MU
+HesVVDEkfm/w4T0cHWlLjlLw3gJgiyF0mAjBRzB7KDmaAQyVJj/JYxk5RwJBVrE8pUizl2jTvTgS
+G9UvRzkBOeCcX53mU8y66ehpGGNManbtivJrB0FHyRv3pJZLe4xUjejz4SDbarb0/Sq+v4LZiSLZ
+2d/Lt7iMzj3C2pS0Gyf8xHOpMjMvLnX0woyEPUkIOGZstO09vmsGw8ciSarbzOqiPLDafm9BrRwE
+GuBMl5z/G3LmuJDXWBSvMWRrDJGhKIhKw8D7HqthHWwVnGXuklCqY0uoZMhxEsYYA/amdeppI22d
+Lba9g6H1zr0ZaStvAEJocBpMj47vkS12ucKJ9csiY7pKyS8m9XiTYMtyj9LBf6qIP8RYLeR2a4DR
+MXIWJ1Wvm44+aneiue9wORp0ONPv9gfw1yEmnyodXZr32uZBJ/HmoDt83LqULOyd9aMEMzsAMNFm
+7cui0RD3isL+qM5ZUkbO/R05f+fYb0pLzSZjfMF3CoWAYw6Qc9TtlYd5t7sl4+R+3e4Ek/cELPQO
+CqqLjCVyZZec/xtDVnKprqCObzBkd057P4pYXyvT9HG0sjL3k766Oksoumghx2mONzg9OfggR6OR
+tsaWwLgaBR/8RpjsEkyCkBLz/uC/GkpOLuCoUHkKOUdlv/dcSPjtIpajvMPDzHqbiUg/GPbLp42W
+qsTvkjHGhOKrlzrwVatM9/uD9NGyBh2qkWxmvexpvLL4O8GRUT7vNSwqqQTmaZYSCT/ubivniIRi
+rZPOuZi3T6I4WfjjZQg45ihqtzfz/uDPQsn/WasxskTAI70y72UEwYE3gQb8DQBKoeUVoaMbDPHU
+QOMkIo4euML8zPXkLgiC8dUl5DjJ8eDj9Z2t+J2RtjvOloW11PMAnIWRtsE5kYw/mdTI2KqUp5D3
+VKbpDnd5GcXyzrzXMymCmR3GZnO3m3FES3hjXk1H3+do0NEdpI8zjD9ROl6aoIMxhqjiu1k/fxq3
+Fm98ZzA5SUNvDDOzHSVqrF5KprDdKBK33/7zIsv/0rk8u3HR0xQCjjmLWs3PzTD93nkPXMj6hBxB
+MEdkLBE5IGu3AdjgvIHG24SUWPSH/0SBVxm/+AVBcH5CqY7NAWxpfhBK1n6L61sjbQ+/32MjbZ3b
+JWteHRtpeyT4CCNtg7dxrVfzrPssaV78bjBZAqnEf0xiXedl82LPZv3vdCwfoFK1OkYzP2psPStC
+yk6WlcN5Nh19H6H46uUOPHQm2+/1s0dDjD9dlqCDcYZA6m6R2x0diUoFUMHscIkoinLVOfLjlJQ4
+615wcXxMeFmUe+0V1eE1qSoIAUcFyEZyy9Ruwkot3h/BgiDniKx9HWj4vpBqRSh5m0V6Y9IlYDKJ
+NkyeP1ONRrhzMiHkPZ3nqltEByGHfSmUWNja+os4NtJW8DUAWAM4MtnFeyCin8mavcORthxbiGGk
+bTCaFGVAXSXnPF4wtHVl9lw39FzGw1rjyA57z5SCW3FT1+IO5DsIZlaickDF6np/mP+5vYKfzbPp
+6PtwOdrRsXIk6JAqarOaH9O45GhLumwKuyP1YoYcnnwlX1OLJI7VWrdXPElaZ5t44hyRkiiOlqd4
+R6QQflBa1Oa8NgQcFSG17riiAJNn38goXoiZ7KchIlCSX5/3OoL6Ogw0nNsGT30h5SjQ0Gpj2jsr
+kHNEzm6QMV2UYdfVRBAB4/xcZW0iUh2Tun+gsV2UNSr1u6Cjk10Q+DUAeQ3g9JG2HrxngC2U/Dow
+3kYMwcey4FqvjUbG8nOPjCXnSDBwsy4HIe+pHKQ7HPIyimXtp0vM45vTcfR5bz97vNqp9tb1o0FH
+f5huZT75Heroap2DDqFkp8hyYBy6YlEboNf6HTt9jCNqzW8547r8DDutTOG6UcSPBdFlWT6/fDm+
+N71Vzl4IOCqEa91hQqyaQfpUNpLFTdE8AABbzANtUElvdmjQDnj3L6FkSyh5m7HpBxonEVHcKXqD
+x0qI+k5CWiAyiW+ZNPtegoUQcrzfWUbaevJdssVPVBwZacuhw3gYaVtHyDna3BeKzj8yliyBjMT6
+pNf2PiYv9qjo/6C1vIe8XuUoJxHCDWBO1+oy0ptVajr6Plzy1dVVeNiyuR8O02dDStbqHHSoOOpk
+Wf59EjPgonqlRMH0xYns7L0qHjUk/2BzULL2BYo37+M8K/curUZ/qOoOrfMKAUfFIOcoV5p3Ta/3
+WMTJg4WcsOLPMvAxCE5HzhERAZX2daAhlFDyD0zjzar0vuCx3nRF8aOIooXcGlo1F/2ljkKO4feS
+WcBFvZM1R8dG2h4JPgDeM9IWsMUQOkyoq2Gk7WLzKvnCmWJX6PONjPUme45SzaQ8xRpHNOw9kYr9
+EZNqTGyZBe7JMzafz78qNx09DRfIVtp4v3EQdJhkDaPoKuP1Czp0FN1KB/mLRout4IKP9wzOp9ng
+D8rC/iy1OPUY7hwR58Dw9Y05Z4kSjX+TEhe6cuAkIeCoIGQMdbv9MO/1toTWnyzahBUPtAuMhSkT
+wZkdBhrG7gC4fwohtBDyD9CIbl60LnxahJRYlGnKnfNVCV0WFnmYxD5VmTRumeHghYQQckzSmUba
+WtpxvuxZRwV4psNI28XyemTsfzeUuDrurjRyjhDATfuGDDlPRTrcFmgilfCHYffcbFW96ehpjgYd
+aZY9HQzja3UMOnQjWh8Osq1mS9e+VCt4l9QCh2nxE5f86mm7MZwlUEd22pE1W43L0YPZrXJ2QsBR
+YdHKymY5HLzwAMAXKORgHl+x143uguAkB4GGN2YXgF4ichBK3QIZ3WSINxflxFUm8UY5TJ/oZrPS
+tcnLRDaa6yHkmI0TR9rCW8GHczvOHAk+EFtMhuCjiryMb5F1PT5mmdcsylPKNHvpTfYy0vw+crEQ
+nw+TRN5TFXoVHDYdbbHPFm2nABfIWi3YTJLcp2k9gw6dxJuDXrbVbOv7i3Iexarwwq6JZpPfS3Oz
+HcUnj411xjyPotFOuzw1Lzsd/emivE7GFQKOilON5rrJsu+tK/+xUBNW6vl+Cc6JvCey9ligwZW8
+xmS8xhDXFvUAi4whF/xWaDh6MQR+oocM2Wium34IOeblw8EHHBtp6wE4e2ukbQg+Zo9rvVpk3a8T
+OV4n/WmWp4zKUbpPpMI/YiI3p/EcC4EAtPDnasQ8aTqOPu91s8ftS3ohe1Bxfjzo6GfqElPxDV6T
+Y45uxJtpN33SWI1reWc+OJ2QAjHPiJzwbweQ3hMhA4fImDOWVlosFQJrO30uBBwLQMbxLbtYY2TL
+eS8gmK/DQMOaXfD0kiEyLuQ1FsdrDNnawvWWIQ/AT/4rEUWdot/fUpzfX7jvqyo8AHJxe5IPKVuj
+kEMxB4wvznbqOjsefBwZaUvkwcOxkbbWuh4BcOSYHI60RQTAMNllWs4zMvb1iOeJl6eQ81QM+ttS
+uMu6IT/YOK/+CKBCr3oZ6c10YJ4tQtPR0xwGHc74sii2e5n2pOLbdQg6RBTfz/r507gVLezvJzif
+ONEb/b55ljSP9yeyJYGK+DoAgCf7JIqTWh9XQ8CxIITWHXJu1QyzpzKJK33AYghF2MGxXA4CDXCm
+S87/jSErhZT/xqIFDTTGJKP4nivKbRFH5x6zGEyebDXXy37/axWzL+v+GlxkB7+bU0fajqa7dKks
+fiL71khbztsIYaTtpIw7MpZKC1JPtjylSLOXzGa/xhG/w3D5ylFOQgSnhuzzsIhNR0/DObI4wQ2t
+jS9qEnQwzhBI3c3T8tsoOblcoQq8n/cK6odzRCXgqrPkuXhz3mNKs60juVFm5sWlio98noQQcCwQ
+5BxlI75rBsPHIo6rO2HFA1vEbYvBeMhYIlceBhpcqiuo4xsM2Z3KvjYv5PRvCaVAa0s1zp3P4AhP
+k+gxeiLZat0tu70nqqE26/m6rK9jI23hrZG25MHD65G2rviJcuoTOEAQzWMjbUPwMRbkHE3GSOmz
+jYz1JnuOyWTKU2xZ7rlB/zsV808xlrXr6n9RHFHPew1HLWrT0dPgW0FHN9Xey/g2l4sZdHDJ0Za0
+ZnK7IyNR3RAqfCpPXNJU1/deFY8aK9FXAKPyFMZgYI3dbzaR8QXrn3MeIeBYMMg56vbKw7zb3ZJx
+Urkt8a8bYYVMtobeBBrwNwAohZZXhI5uMMSaBhrjUXGynvf6j6KVlVpv+1tEsr3yoOj2tnRDVe6Y
+GYzvWPDB3wo+Rrs9DkfaUkEpeG+PjrQdlbpA6PNxGh1tnGVk7KTKU8g5Kvu950LCb6OWqv2dxfNC
+zip3kapidb3Xz16stusznvQw6IisL/L9hQ46hJKdMisB0LyUSta230LwrjjBT2zpukLxti0JlGLX
+JPjvong5jrEh4FhQUbu9mfcHfxZK/s9KjZElAh7pSjTCCi6GjCUiB2TtNoDvC60/CoHG+4lYfeJK
+8zNXMkwRqhjVXtkMIUe9McYYsDc9+U8baetsse0dDK13jgBbHJlmQt4AhNDgFF6PjB1kPzWUf+/I
+WDIXL0/Jh+lL7rK9KBbhc+V9yFX2RnfUiNe7++nWaidamMkdZ4HIWJyIhQ86ZKw6eZ7/A9F1uVj8
+nTbB2USR7Ozv5VtcRvedszsArmj9JlmaxrMh4FhgUav5uRmm3zuCPpciJLPBhZBzRNaOAg3vB0Kp
+llDyNov0RjjxPBshdafoD75Bwa+Gn9kYyAPMoLJHtVc28+7+VtSMa3UiHnzY8QanJwcf5Gg00tbY
+EhhXjGOLieUcaeuFvknWvndkrCvLHRXzm6f9/fvYvNijfPifOuIPUalw/vIBBFDp6XSqEd0b9syz
+Zntxm46e5mjQYYr9nV7GX1nRurdIQYeOoltpmr9IGgC8Qk23JaO0Ut1za6bREPfK0u5mafaP69da
+/37kY7D2QsCx4GQjuWUqN2Flad4/C+0w0HBuGzz1hZQrQsnbTKsNFvpInJtM4i9cUWyLOK5sY6/q
+sTvAznehNC7dXg0hR3DoxJG28TsjbUfBh6NiWUbaykh3ysHwSSzFiXf8yHtC7/6FXI71HrLGkR32
+nikFt2SYjnJmzLtdeD11qIoYQyTO7xZ5uaOjqpyLThYiYzoWNy9r723Z3e2m+NMiBR06jtazQfZ1
+0mJfYkVuwCAnx0LAMTVSCXz1v/f/d7PFmx7gqiksAQIgvC7ThFHD4HmvcxpCwFEDUuuOKwowefaN
+jOK5NuYiIlCSX5/nGoKTvdmhQTvg3b+EEkoodYexEGhMEnKODspVsraLokLlYxXmCfJZPt9ByBG3
+ks1ZPm+wON4aaXsYvh0baevcLlnz6thI2yPBx6KPtLU8ukbWeRTvfj6QsSAi8buzPhZ5T2Wa7nDK
+yyiW99kS3UmcBAH0L8aqG3AAAHApMC/85bo0HT0NImMq4muXlb96GHRg6x7X1Q86VBLfHfayrWZb
+h4C/5kxhiXn37Df/I2q0VnRHa8GsoW+99+z1psXCFK4gcgyReUeek6cEAAA5eiL/O8ZYmzF2GIYs
+UjgSAo6a4Fp3mBCrZpA+lY1kflsEPQAAq+0H2yIh54iIgIzdAToINOQfmMabIdCYLhnH10PD0bPz
+dLRzwmzo9upm3tt7FDUb4XcUnNmxkbaCr8Hru+rHgg+in8maPbKu5wGAcWwhLt5IW670mikGz7Xg
+70xJGac8xebFns363+lYPkClwmfPufiF+LlJLTt1azp6mqNBhzO9n/cH7KXl1Q86dCPeHHaHj5qr
+SfjsqxnviIqSuprTf662xb9Jre578t5Z/7+U4mtK8c9O/Do/GthLHgC8H13K+deXdKPe3bBo4UgI
+OGoEOUe50rxb9nrzm7DiaeZPGYwcCzTA/VMIoYWQfwAZ3WSIENL62RJR9MAV5meuQ8PRD/J+LpVt
+auXSV3lv/2nUnGMoHNTCseAD+DWA0cSC00baevCeAbZQVjf4QM7ROBTSkX/7YhXJvvpQecrRcpS4
+qZeic//UEFS6B8dRdW06ehpExlCza1eUX7PlYgQdMkkeZL3sabwSh8++GrDGEjnaiRTuf/yRvCcE
+vgmvOGN5WhTeS3/a+/Hgz/nhp9i7Jh2OvO4sBKXznMHkw5EQcNQMMoajCSv9J0KpT2c9YcUD7QJj
+4YJuBg4CDW/MLgC9ROTAlbwmRoHGzWU4sagyoSQW/eE/UYaGo1UmWu27eb8bQo5gKs4y0vYw+Dg6
+0pZDh/EKjLTV0YY1+Y+Kv+mrYEtDQvNTy1PIeSrS4bZgJooSvhQXudPGmEsXqVdBnZuOnoYxxuTR
+oKPPfi5EdFPp6NK81/Y2xhiC0nfztPwmStRcS9vD8eH8TGEJPD1vNbnWsb7NT9k1xRhcJvIwjc3b
+VQ1HQsBRU1Gr9aAcDl54AOAzDDmYx1eswo2wFhl5T2QteGt2wdNLhsi4UmtMxmsMcS18SFSPTKIN
+V+TPRZy8s8U7qAZkDEWrfTcfdJ9G8yzvC5bKsZG2R4IPgHdH2pI7EnwgdJhQV2c10lZIieUg+5fU
+/g8HnzGj8hRxYnmKyYs9Kvo/RFreQy7CZ9KEKCTHcHFKS5eh6ehpjgYdzqTd/iB9NMTk06oFHZxz
+tI5+X+R2R0diqX5Hi+ygDEWA/W71kvqdVOrOh6ajcM5vjAKOWa3ybKYZjoSAo8ZUo7leZvlP1pX/
+mOmElXCdPREnBhpCXmNRvMaQrYVdAdU3ajgKH5MxXZQy9KY5jbcDYGpuT4+MoUhad/NhP4Qcwdyd
+ZaSts3bbeV9YRwV4pqc60lbG98iWhyNjTypPscaRHfS2tGafYqLDeyg4bDqK6LpS1bfp6GkYY0wo
+vnqpA1+1ynS/ikGHULJjSwOmsDtSh5Cjypwhsq7YjZX8+aPLcl2qs5f9CYFQ5m5bSl6b6X4fCkdC
+wFFzKo6u29mOkS1n8By1dBBogDNdcv5vDFnJpbqCUXwjBBrz5bz7FkGcmCJ/iIzj63l38FiviAdh
+l83JGBsl8fOEnKNIWneL4eCpboS65KB6zhJ8HB1pO6ngQ2iJeX+w3WiLr6yxx8pTyHkqBv1tKdzl
+qMHDMW4KyHuaR4+iSZBadoaD8kWrzVZO2z6/DI4GHd1B+jjD+BOl40oEHULJTpkVQ8ZtV8x68tvC
+vrJnx5SWvLXbKyuS6Ti5zTleG/cxuETMhmWvMY0FVlQIOJaA0LpDzq2aYfZUJtM9cWcIRdjBcXZk
+LJEru+TgbwBQCq2uoI5vMGR3QqBRMRf4bYhEb7qi/FFEOtwhOcGof978DxzIOULSvGuGwy3ZiMII
+2WAhHA8+4NhI21HwAUDO7ZA1hR1NduHsrZG2Hwo+SOjfkXXe23KHq1F5SpFmL5nNfo0jfodhKEeZ
+GgJQ0kfzXsZ5qYZa7+2nW+1L0f0PbaWvO6H46uUOPHQm2+/1s0dDjD+tQtAhY309S/MXSYMB5zPc
+bYMw95sbVVUWdg/JvmhfUteVSjYu+t7x5FuOvOdL8h4MAceSQM5RNuK75WD4SMbxw6ldPHtgVbhQ
+qap3Aw15RejoBkMMgUaNCSmxKNOUO+HDiN5qQ86Rksa9EHIEi+548MGPBR+HI22d2yVrXlnregTA
+kWOCTNwGMQo+AEeTXbjSa0U+eCbIEHHhbX//sdL4iBHqeAAAIABJREFUR4zlXBsULgcCxmB+NXwT
+oBrRvbS/XE1H34fL0Y6OlYOgA+JPZRS12RynKOk4Ws8G+Z+TJvus7iN+q8o5Imvsrhbs751L8lMp
+1cSaNDOB14g8LMuvNgQcSwQ5x6i98lXe7U5ljOzrbZQhjT2CjCUiB2TtNoDvC6lWhI5uh0Bj+cgk
+3jBp9kw1GuEEr+KQc6QouWmLfEfo5WqQF9TfsZG2gq/B68bghyNtR9NdulQWP5F9PdKWY6scFNjA
+IUjOd3VDfvW+5wgmhwgAKtYccFwHTUez1HwbJ7I2fQAu6mjQMUzTr4eUrKGOrs4r6FBJ9PlwkG01
+W/o+W5I7/VVwUIaSJKK81NZ3hBi/DOVDBLJVKu2PIJbjnCYEHEtoNEZ28Geh5P+c6BhZIuCRXpnY
+4y0gco7IWiDntoFoIJRsCSVvs0hvhEBjuSFjiJzdCA1HjyPvqYrDD1GKDkEEIeQIlsWxkbbw1khb
+8gCq/JcE+rtUeuIn38H71eFak0uBZWHWpHEvheThNXQEl3x1pQ33Gzb3w2H6bJ5Bh07izcH+cKvV
+ScIOxikrckvc22ftVdmROt7gU7xOEAIhL90rnUzrGaolBBxLKmo1PzfD9HtH0OdShA+aczoMNCzt
+ALh/CilXhJK3GVMboRQheJuI4k7R728pISa27XDhEQHjvJL15ShFx3oFM2zSHASVcxB8cPS7Uoh/
+s8Z2hZxxM8IlxwXenvcaJkFq2Rn0y//TXIGuEMs3WeVDuEC20sY3QYdJ1jCKrjI+26BDNZN7WS97
+Gq9Mr2+f956m9dhVdlCGohD++3JH/XGSZSjvwziitcZ77/0ynH9W8cZZMCOykdwChMSW5c7kHrXe
+7xlyjmxRUDnMXpSDwWNw5rlQoqcb0c1oZeUrEccbKAQL4UZwGhnF91xebM97HRVT2fpyoVSHUF2e
+7HEyCBaPhKwvY33ZFvRfniiUo84KuVqdWamGWh/07XdE85+eVVWjoEPc/3g1X0v83jM3zF56N7tA
+gDGGqOK7WT9/OqvnrDtrLJks/4vm9OyjK3rt8sfxV0rx1RmHDWtuSQ7dYQfHkpNad1xRgMmzb2QU
+X6hZGBGBkvz6pNZWBeQcERGQsaMdGkJooeQfmMabIcQIzgOlQGtLRc55DK8hAKh+LCqU6tgSwk6O
+YGmRc6Q5RQAcdEtvFMP8SZToh/Ne1zIgAKjbdDqVRJuDXvZkZTV6MO+1VBkXyFot2EyS3Kdp9nQw
+jK9BpK7yc4x7HhfjDIHU3SK3OzoS4XPvnExhiXn3rNkUDZ1MtwzlQ4Tka2R9DzjUfvdU2MERANe6
+I+P4CzNMn45myp2TBwBgC/2mIefIGkMmTV+W6eAROPNccOypJLqpm62HIk6+RCFXQ7gRXISKk/Vy
+mG3Nex2VQB6qH3GEnRzBciMi4Jy1AEb9hKQSt4wxP897XcuAeded9xqmgQl5P0vNt/NexyLgHFmr
+xTc/vpSvNX33mc8Gf3HOTX1HB5ccnYPLprBT+dxDtgAf/ufgHVGe2T1flo9W27h75Tfx/aSp5hpu
+AAAIiZAX7sd5rmFWwg6OAABej5Fdad4te72n556wsoDldAc7NLwxuwD0EpEDV/Iak/EaQ1xbhjq1
+YD6E4uvOmJdcytADZ0EIpTo2B7Cl+UEoefPDXxEENTEKOA7v4golO9kw/zNHuhpGSk6XAPo7Y7A6
+73VMWmg6Or5R0AGbDWd8URTbvUx7UvHtae7oEEp2yqwExm1XiEkOJgCIlW9N7PEqwBpL5GgnUrj/
+8UfynhBYqWlTnCPmaVFUuCp4YkLAERxCxnA0YaX/RCj16bgTVjzQLjC2Nq31TQJ5T2QteGt2wdNL
+hsi4kNdYEgKNYLZEFHWK/uD/Rc7XlnnCDoFfqN3XIlIdmzsI03CCZYIu2wbBjo33jBvR53lv8Eg3
+k0qdxNePX6Aj5HhC09HzQY4sTnBD6yNBh4hvczmdoEPGqpNl+fdJzICH39M7TGEJPD1vNbnWsb7N
+Kxz6MoCmc+SrvMZJCAFH8I6o1XpQDgcvPADwMUIO5vEVA6hUwHEQaIAzXU/04jDQiOI1hmypLyyD
++ZNJ/IUrim0Rxxsf/tc15QGQL1bvHhHFHZNm30uwgGGaRLAEmM0HLH7341LE8QNTmB2pZajRnxaC
+2vXgOGrUdDTfWmnjfazDPNwZejvo6KbaezmdoENH0a10kL9IWgCch5DDO6KipK4A+93qJfU7qdSd
+RXj9csFvE3ngfN4rma7QgyM4kWo01z353tj15hV4b1tjyObpXjkcfuPybAsZ+1HoeFU1mvdVo3mf
+a72GgrMQbgTzhpyjB79K1i1HW+tTLV7vHpnEt4zzv5CxtayPD4ID5D1xtPykHY5CcnTeEy1La/45
+YAhl3U9WRk1Hi9CX6pxGQYfY+PiS3VgV+3+ldPAXZybfo0M3ovV0YL6jJZ6i5AxRkWcvOaOvP7os
+2cf/o/FQR/LaIoQbAAAoAEzhaj/JLwQcwalUHF1HjuM01SunuqBTkLGvA430m3KYPkYGPwodr+pm
+445uNh8KrW6GQCO4EJpeIywZx9fL4fDJtB6/8jwtQo/RE8mkMQo5bAg5ghqzBEJgctpfx0m0brL8
+8SyXtEwUmmJRj5HjYEqHpqMXhMimHnToJN4c9sqLDSUAAILF6ttnSktlmv+lEfu/fvxRsrba0fel
+woXrjSOlwCJ3g3mvY9pCiUrwXkLrDjm3aobZU5nE99/3bxlCMYsdHGQsETkg654DQCm0vCJ0dIMh
+3gkhRjAt03xhiTjadKX5mStZqRKv4MNk0rhlhoMXEizgJBuwBUFFEBEIwW6/79+IOH5Q5uZbFcnl
+LbebFg+wDP3BOEcsDVvjhftZaR4+Cy/gIOjQkfW27O52U/zJita9SZWu6Ea8mXbTJ43VuPZjfsvC
+7iHZF+1L6rpSycai7NR4H++9dOQ9r8H3cpqwgyP4IOQcZSO+WwwHj/37tqV5YNP4ECZjyRYFlcPh
+X8rh4BF4+qtQkulmcidaaT4UWt9EIcIOjWBhCSXRFsU/3/v+CipLNprrxtCvYSdHUEfMpTsf+mgX
+8rDcLrwHgnOTUnbSnPrWhNfRJCAypiK+dnkV7l9W3V9Ytr81qR0dIorvZ/386SQeq2qcIyry8iVY
+87hzSbCPfpvcjyK5VodwAwAAOPu9r/npZgg4gjNBzjFutx+aPHt60kUYeU/AYCLvFnJuFGik6etA
+w70ONBob0crKVyKONkKgEdSNTKINV+TP572OmSMPC1ujcoRsNNdNQb96F07Mg3pBl++d5d5FlETX
+i8z89aJb14M3yHlC7pdqt7WK1K1+z+wQhdfRpLwTdKT7W664WNDBOEOQ6m6elrUpKzooQ9Gcnn90
+Ra91rkQPleKrddtBJQWuOud2572OaQoBRzCWaGVl0xTFX8i9daeSCHikV87zmIeBxjB7UQ4Gj8HZ
+UaCRxK8DjTgEGkHtjRqOwsdkzJJdINudGuQbAAAgW831Mnch5AhqBYEcO+Ody6ipN01ua9/AbnYI
+JMKp/U/qSjfjL/v7RejrMmGHQccluH8l7u1eNOjgnCN5XDO5HW8gAQAAVWIuAQAAFLklm+Vb7Rb7
+8aPfxhsrq/pLIep7zYECIc/cy3mvY5qWKhUOJiNqNT83w/R7R9DnUlwb9+vJOSJrgSztgHf/Ekoo
+oeQfmMabjPPaHlCC4ENkHF/Pe/1HkZRfzXsts+IJ8nmvYZJkq7ledntPVINthlA2WHTkHEXSn/nm
+BXKOyM0aGddFGUZJXhQRAMh5r2I+MNIP0rT8JknUl/NeS90gMoaaXbui/Jotez/vD9hLy1v3uB6/
+R4dQslNmJQDaH6QSN6ex3mlwjsgau6sQ/vtyR/1RSnW/bjs1TsM5Ym6N9977un7PIeAIzkU2klum
+KF7ZstwRSt0Y/enJ7xFyjogIyNgdAPdPIYQWMgQaQXASEUcPbF7siEjfmPdaZsETMFaXLRyvyfbK
+g1HIoULIESw0IgLB4fo4XyOjqJP1ht9oHt05686P4HTL+iPkHNEY/H2Rmx0dyaX4PJw1xhiTR4KO
+7sD/PefJJ0pHl8Z5HBmrTp7n/2AIXVHxZtvWWPLWbsexSC+19X0hcOwbtXXAGFxy5EHU9DIsBBzB
+uUmtO64owOTZN4yLL5Tk1wHeBBremF0AesmFEELIP4CMbjLEm3VNC4NgEoSUWJRpyp3wSxEAel+H
+FhzvkO2VB0W3t6Ub6n4IOYKFZcpdpnHsiRa6kXxRZsVznag701jWMkHOxgqY6kRK2cny8h+cu64I
+O4Km5jDo0HDNlul+f5A+GmLy6ThBh46iW1mav0gaDDiv3u/KFJaYd8+aTdHQSbzBl/xzmXN+g6zv
+AYfK/a4mIfTgCM6FvCdyjpgQq4Lz/6vc2/9TMUx7Jh1seVM+45ztyiReU83WfREnX6KUq8j5VKas
+BEHdyEhvmDx/Nu91BBej2iubxbA8sTFzECwEZ16d51MbOUMh8N+tMbWu8546coCM1fIC5KxUpG71
++/aH0HR0NoTiq5c6/KvfJimT2atHZZHtnfVrdRytZwPzA535M2+6lwTeEeWZ3fNl+Wi1jbtXfhPf
+T5pq6cMNAAAhEMrSjd87ZUGEHRwBALyegkKv+wwRwejY5MF732XgfwIP4AFKjlAAADDkgnGeADDA
+JO6gkl+4PH8uV9v3EDEEZ0FwAaM6dnaDjOmilEt9crvoVHtlM+/ub0XNeGnqe4P6kJD1GZ5vJ5mI
+VCfr5T9xTmthF9P5EEB1OjHOkW5Ed/v72aN2J1qa/lTzNgo64KtWme33B9mjIcafKh1/cEeHSuK7
+w1621WzruX3mWWOJHO1ECvc//kjeEwLD6+YtXCJmw7KY9zqmJQQcNfVOYPH6vwAA4Olb8MA8QMk5
+FOABgDGGQrYAGDAltES8MfpQZauMwerBB+xpJykeGaEUq2Wa/klF0U2seA1eEFSdiOJO0Rs8VkI8
+qPWFsbeDunfR0+3VEHIEC4ecI80pAuDnfgzd0hvFMH8SJfrhBJe2PMKehUMY6QfpoPxT0gxlT7N0
+EHSsmGy/1z9b0KEb8eawO3zUXE1mGiyYwhJ4et5qcq1jfZvzEKy+jyffco58HX9OIeBYECcHFqNd
+FuD9DoAvgDygYP1RYAGAQo06nwvupeAbrwMLAAafHZ5jMwaTOOFGRHDG5LrRuFtm6QvpPYQ7z0Fw
+MTKONl1ebIs42pj3WqaFMe+X4Q7lQcgRt5LNea8lCM6CiIBz9tuLPAYyhlKJW8aYn6WUY/fyWHYS
+zLeMwWfzXkcVcI5oCP89NB2dDy7fCjog/lRGUZsxduKubZkkD7Je9jReie+f9pgMmb7ourwjKkrq
+CrDfrV5Sv5NK3cFl7cw7JsbZbfIXibCrKwQcc0TuzexpIjoMLLz3uwz8K/AAjEH/MIsQQjOGGjgH
+Kfl1YKz9OrC4yQBG2xgnFFiMDRG8dX0AABUn6zbPfiKifwi9HJMggmAaUAq0tlTknMeaNhwlgPkc
+s+ZAt1c3i+7eE91qPJj3WoLgg0YBx9WLPoxQspMN8hccyWMN7xROlw8/ryNC09H5Oww6bO6Hw/TZ
+kJI11NHVt4MOxhiC0nfzfrEVtfQ7wT4RAOfs3NcIzhBZV+zGSv780WW5LlXYJTYuIRFMYX+UQtXu
+Wi0EHBP0nj4Wh4EFMJ8iYw7geB8LodUlhmx0d4OxNQawNtfAYkzIGHp40wBKRPF1WxavbJZ9K+K4
+tnefgyUxx95mIopvmGH6RDeb9fzwpjrOUDmdbF96kPf2n0bN5NS7WkFQBeiybRBsIp/fcTNaz3uD
+R7o52y3rC2+UAM97FZUyajqaf91exS/Dnfr54QLZShvvN44GHTK6yviboINzjtbRzSK3OzoSE7mI
+NuVozOvKimQ6Tm5zvpxjXidBIEKe2n8mDQgBxzI5rY/FaY033+ljwfnrFwxbY+x1YAGn97FYdMwD
+90T+4PsTSnfI2NVyOHyqGo1wMh8stjmdRyFjyAW/VduGo7h8Veai1b6bD7pPo0YIOYLqYjYfsHhy
+xz0Rxw9MYXakDuUF46jlCeMFhaaj1fFO0JEnaxi9CTqEkh1bGjCF3ZH6/CFHWdg9JPuifUldVyrZ
+COHWxTGO6L2X3nu/CDfTx7FUAcdZGm+CP6mPBXu7j8UqMFiddB+LRecZS97+M5QCQfC7ebf/WLca
+D+oa7gTBNIko6hT9wTeK8zt1eg+R97SMI5eQMRTNEHIE1UXek0DLGVMTO94IyTEzhrgLpSpnpYXp
+A1uqU/UzE5F+MOyXTxstFY6hFXAYdLjcp2n2dDCMrx0EHULJTpkVQ8ZtV4wxhMA5Imvsrhbs751L
+8lMpVWjUPWGes98450GIev1YF/6oeVofi6ONNxmy/mF/Tf66j8UosPjdkT4Wn829j8WCYwjae//O
+3QZkDPVK82E56G+ppHGf1bSXQBBMk0ziL1xRbNeq5IsIPMOF/xw6D2QMRdK6WwwHT3Xj9CZsQTAX
+lkAIfOemxUXFSbSedoeP41Zcz5K7SfPL06NoXIwjWsIboelotXCOrNWCzSR5E3RApK7KWF/P0vxF
+kjDggrcB6NSNsQdlKEkiykttfUeIUIYyLYLjmnNuVwisVRPoyp1YHt1lcVrjzbf6WHDGeQOAgYzU
+68abAMDY/BtvLhnk4sb7ehWoZmuzHKQvZKR+W8ut9kEwRcg5Ol+uknUeRX1CQsR3d34tC+QcIWmG
+kCOoHCICIdjtaTy2SqLNMjffqkjWJ6wN5kJI2cmychiajlbP0aAjz9I/DTKthIpvpwOz02ixlZO+
+psgtcW+ftVdlR+p4g9dox2pVCYmQZ+6l1vWacjX1gOM9jTc/2MdCKNlhHK++/vOFa7y5dBh+sBmj
+aibrZZZ9z8OElSAYm0zi63mv/yhaWalN3fGyH8gPQg4zHG7JRhRGyAaVwFy6wwS7OY3HFpKjNWaV
+rOuiCBelpyHviYU+Ax+kYnW9P8z/3F7Bz0JfhurhHFmjiV/GzviiKLZ7qP1g325FibwHAOygDEUh
+/PfljvpjKEOZLc4Rc2tc3fpwjB1wjN/H4q3Gm4g3DvpYMAardW+8uVQYgLNuG+X778qoOL5ly+KV
+zfMdEUUh5AiCMYhYfeJK8zNXNUjbaen6i54IOUdKGvdMOvxGJtGX815PEKDL96Z5rhsl0fW0mz6O
+mvigTifVE0UAilNr3stYBDqOPu/tZ49XO1Eofaoo5MjiBDe0Nr4oaPvXf/b/n1Lh6sqqyi619f1Q
+hjI/jMFlRx5qtDkYxMmBxcl9LMADYxz8qPEmvN14c9THIjTeXFqICM65M/3bMGElCM5HSN0pBsOv
+UfCr9QiGa/AtTAByjqST39si3xG6fjPpg8XC0XmG0+06FzX1ZpmbP+lYhVDvRASwjF2Yz0lGejM0
+Ha2+g6Djtx37Smn2/8WJ+ESIOpzLLC7O+Q1PHoDPeyWTI6DMnzBxauPN0MciODtE8Nb1z/zPpUBA
+djfvDUYTVsLrKwjORMbRHVfkz0Wc3Jn3Wi6CwM9r+m4loRQdgghCyBHMEzlHikNz2s+DnCPn5vdk
+XBdD/4R3EEGtLjimLTQdXSxa4svVK9EXZUZ7Re7+lLTkFxiuA+ZCCIQyd9tS8tr0RULdbn+lGo0v
+ZRJvyDj6DKVcRSEYCs6Qc8Y4ZwyRhYvP4EOQMfQfasLx9tdwjrrVeFj2+k+9c2G/ehCcAXKOHuBj
+srY777VciAdgDDvzXkaVoBQd4uqyLcudea8lWE5EBILD9Vk8l4yiTlmUO57GO3dYFogQjo9jEFJ2
+shwia9xifzYuASFggIxB1BAdpfj/3XuV/8mU4fc2D1wilsb15r2OSQqb34KJYgy4p/EL69VKa7NI
+878s/AVbEMyIjOPrZZpuz3sdF8XwdSPp4JBQqkMYQo5gTky5yxBntqNCN5Ivytw8n9XzLQxywDkP
+x8cxjZqO2v8iF5o8VZX3RFzA4c1zLhFbq9GXZU4uHZTfeh8Cz1nz5FuuRkFzCDiCifKAyZibOA7p
+ZvK5KctfnDEvJ7ysIKglEUcPXGF+nvc6zs1TaMFxihByBHPj8l9nuWcXOUMh8N9t+Ow/hiAcHs9L
+x9Hn/V75JFwoVxMRQJzId8rgooboCMH/uL+XPw67OWaLCbx2jvvTlRUCjmCikLFLF3l7qDi+RdYm
+Ni/CSX0QfICQEm1Z/DOUd9WTUKpDEEKOYLYklMWsGxiLSHVs4f91nh2gtTWaRDjvVSwsofXmsGee
+zXsdwbvIEggOl076Oy4RV9rRV3luemE3x+wIZKtU2h/nvY5JCQFHMFGM49p5d3AcEFHUAeYv2yz9
+ZkLLCoLakkm0YfI8nMTVlIgOQg7zw7zXEtQfOUeCUzSP59YtvVHk5sk8nruKBDM7Id84P8YRiY+a
+js57LcFxRABc8PeOuk8a+vrhbo7QU2XqhEDIcvo/817HpGDRHzwO6VgwMQwByF+4UQ1XusOk+qLo
+D5+G12cQnA45R+TsBhmzeCcA5CFswv4wEamOIxaTCT2KgukiIuCc/XYez42MoVTiljELXHY3Qcz7
+Yt5rWHRCyk5essuh6Wi1SKRtdoZb7Ie7OTLTS4dhN8c0MY7oiLAuP2OUSfKw6A2ehm2BwSQgY+Cc
++/tEHotzFI34btnrh9dnELyHiOKOyfK/LtoHkye3O+81LAqZJNeNY7+EkCOYJuZMl3M2t8aWQsmO
+M34QGkTC6yYcIQC+KKllp9c3v4bXVHVwhHSc4ZxJQ19Hzv64/6/0SdjNMVVrdXmbIACAajY2y14a
+JlgEF4cMRoWjk3o4hqMJK+k34fUZBKeTcbTpimLB6if9v8IGjrOTSXzLOP9LOBYG0+JN+dO8L6rj
+ZrRusvzxXBdREeHwOBlRI17v7hdhR3BFcMEcjpNwAICUAlcuJQ/zzPSyNPSlmgYh+RrZi+/Cr4LD
+DUKylXxe5uUvrgxdrIMLQASyduJvDt1o3DVl8etCbsMPghlAKZCso0VqOOoJGAun8GORSeOWsSHk
+CKaD+3zAZttf9EQijh+YYrl7JwjhBuHwODmqEd0LTUfnzzmiOBEr5/36pKGvM2T/0X2VPXJ12W5Q
+EUIi5IVbsBtlJztWAaXi6JYLEyyCC0B2lqq681Fxsu6scbYIr88gOIloxDfKLFucJn3hZtq5yKRx
+yxj6NYQcwSSRc8TRcjbmndVpEJKj856WuayAe/JV+F3UBWOInvO7RR7u/s/TqM+P1xd5DCkFNtvR
+V4Ne8UPYzTE5nCOa0tai9887F6NC6w54ulwOBk/nsaCgDryeVs8MEcUdD/6yzbJvp/H4QbDIkDHk
+gt9aqJ1O4fT9XGSjuR5CjmCSiAiUwBNHN85DnETrRVosTmAbVB6XAvMSL5sy9HGYF7IAUokbk3is
+5kq0ziDs5pgkBtCsw8/yxLvtqHQHlb5b9AePQ3PHYGyMq2nemRVKd5iUfyyHwxDCBcFbRBR1TJ59
+F47d9ScbzXVT0K/ehZP1YAKIAAWbyIXHpKgk2ixzs3Q3NMh7CuHvdEgtO/1BaDo6Lxz9RMcfSx12
+c0wSF/x2HU4fTy0nQM5HE1b6w6eLVNMdzB9ydmnaO8+Rc+RxfDfv9kMIFwRvkVF8zxXl9rzX8UGe
+0nkvYdHJVnO9LN1/+XCyHlwQs/lO1SoihOTowa+SXbIQjwC08OfuUxC8X2g6Oj/IXH8afX6O7eYI
+1wXnhgLAFK76548f8MF+CarZ2CzTLExYCc6MMVyb5CSV0yBjqFeaD8vh4KlftpOfIHgPlAK9p1Wq
+eDjNmHPznthQB7LR/LxMy60Q9gYXgZTvVS3gAACIkuh6kZmFG4N9MXSGM/TgIkLT0flQkhfjTlA5
+q8PdHN2wm+O8pBRYlG7hJ6mc6fApk9GEFVuEF0twBgwBaHZjhlSztVlmeZiwEgRHyCS+Xg6HlR61
+SAAQmuhNhmyvPCiG5dMQcgTnQd4TR+cZVvP9GDX1ZpmbP817HbNCNO8V1F9oOjp7zhFFGqNpP8/h
+bo69/HHYzXEO3mtHix0onzkfVnF0i5y7HCasBB+CjIFz7u+zfE7VTNaNMb+ECStB8IaI1SeuND/P
+ex3BbKj2ymYIOYJzsQSCQ3PeyzgNco6cw+/JLM9uTY54oUkTwYeFpqOzRUQgJGvN4rmkFthc0Q8H
+3fIvRRHOg8bhGfu9X/DTiLE2wAmtOwD4H2HCSvBeyACIylk/rYrjWx78ZZvnIeQIJsvTYN5L+P/Z
+u9fvKI5kUfSRkY/Kqn5INHOP51qwz54HFrMHtu8xlhH47zcWNuO1xmbOjIxnrXtsBnPHNkL9rKrM
+jLwfGmEBequ7q6o7fh/mwwDdYdRUV0bF4yKUTnq+yH/kA+/qMGvd7XyUc5KDnQsRgZJwveo4TqKt
+7ZVF+SQ2/MniWaGs18DXZaUT3RsN6fkybI6oPQJQRi70c93uJh8GDylXc5ydVrgeSv9d1XFcxrk7
+/FBLRJNs5S/3ebgjOxJKiUQhr+K9lUl6AuUfeMMKmymxgKEyc6Kz9KNQFLUbGEUxEreYz0eytj5N
+cqzUzAJ2Kb54JhDXqg7jNEkr+6gYF8s/N4ECL1FZINMym/2XxUNakeRZVWIMz3AOA0ZPk1jVa7X0
+NldznI1SCHlJL6qO4zIudH+JUqLpdHjDCjtRVTfXqBXKJNnK+/3POAnHZqaeremnQnmwhaB+g6Kj
+QFV1DMsqWVvfzocTTvSys6HieRPG4aAUqI264Z17WnUs80QAjf3OaSrTsp+M+8XnVcexzBDEi6qu
+M0IiHq7m4GTW8YRE9J5ikx+SXOoBmmm3totR/i25+t04s6rFDlT47wKlxKTT+bQcDDkJx1aeTtPr
+5XhcryoOIkAUWdVhLLNkbX17MhjvVB0Hqz8NZVHXAaNvU9b0fBF/WeYHGCKGZ1XHsGqEQIxKb0/G
+7puqY1lWNhEDrPg6c1DNMdgvvnbOL3Wi9DI0lygEAAAgAElEQVSEgCtN7tq6dIWwaaWbZcEbVthb
+hIQqExwHTLezXYxzXnPMVp6y9l6oWWlmI05TDTet5BhzJQc7FoVAWsdu1XGcR9JJbhe5W9qn7Qro
+l2akm5aL1ApLLza8C3zwnbEYiZQStajaPKjmKCcx42qOo0klb5Bf3EbMWZtJC7RJ7U0i3rDCfiVR
+XKvL5SJpZx+6svwxLHlJK2MnUUajL4ufl/mpJzua6a7f5SQHOw4RASJcqTqO80AhUBt10xVuSe87
+I6c3KqIT3RsOaOQ9b1aZJfIExspaVW3a1rSao/8yf1SW/CD0MCURyjI09vo6sxlvyvCGFXYI4jrU
+aC6jSdOb5H3GSTi2ynRmb4ci/6rqOAAAgCJwDcfiqM7aVj7iJAd7lwhuX0rcqDqO81JG90KIRE2u
+oz4OAc/gqJBpmc3hwP+dn+zPDhGAMXir6jjeJiRiZ81uuTyGYb/8CzV47sQsSY3oXCiqjuOiZjrE
+/mDDStHv84aVVYcIMVCtekiVtT0Q8Wo54p50tppQSgQBvyPnKn9SQRA5v7FAKASqNic52LuiK39o
+6lk6bdtNN8kfVB3HrAkRxg39kSwNk9ntYb/g+8UZIQr7ooINKmdlW6pnrPxf/Rf5X7iaYypS7DR1
+ffLMt/ShlKhb7fvFYPSQ5x6sLgQBRPVbMSRN0pOJ+aQYjHiFIltJyqY9N8n/VofPvxDYqzqGVYJC
+oMo6W8WIt6uwX2mYDEQVuxtnRKXpvWVrVTFIoSlDX5eZMMldHjo6G1KIH+r+kZYSsbNuP+Zqjikh
+xa1mpjfmkOA4YNqt7XJcPOcNKysKBQBRWXUYR0Ep0bSzu2V/8JArjdgqkmmyHYryu0qDiAAC8f1K
+Y1hBKCXKrM1JDgYA0wGjUlAtBv9dlNISQ4xEPDOBzZiUiKUXG2URajWgu4mMhmHN8xuvHa7mcOXq
+XleURnC5r9cGvjOaW4ID4PWGlT5vWFk9KCUShbzqOE4y3bAyfsSVRmzVKK0xBD+udIVyJG5RqchB
+ksONci6/XnFEBEqLRg0YPUqa2c1iUtaiMu2yKEbia2N96ET3xiMa8tDRi4uRSCsAIZqS4vi1mqPM
+KYyH5aNVrObQWmGRh2HVcVzEXBMcAAAmtdeJwlU3mXCJ14oRAFD3m42k1dpyZfG8DjMJGFsknaW3
+y8lkadcsspOhlChs6xOXF/zdvMqIQEpxo+owZsFkdrupTxvfQABGR1t1GOxXPHT0cogAkkx3qo7j
+ImxL9ZSSH+2/KB6uYjVHjFHX/Sx3lLknOACmG1aEVH/mDSurJYLoQAP+TZg02wzeBd6wwlYJCoFS
+yZuc3FtdqCUKnW5wleXqwjB5vCzbOpSWGEVcJ9f0QwiBEGCqjoK9iYeOXhx5Aq3wetVxXJTUiN31
+ZLvMfX88LL9p4oH/oqIU71VZ7HtRC0lwAEyfFqFNecPKKhECmnINUDbtRRGveq40YkdoyMf43JS1
+PZdP/l7JlzWvia0F1KpH0lzlJMdqEqEY13mzwXnZzF4vS//32OAn7URVR8COw0NHL4Yo7KMUa1XH
+cVm2Za4rJf/8ci9/4BqfSD0bo3AjhFCrrZhnsbAEB8D0iaFute+Xg/EOzz1YfhLxFjToFkOZpCe0
+/nM5GnGlEVsZ2qafhLyooKyb+DugJpQx0yRHyUmOVUIxksRATeqLP4skM5+Uufuq6jguo+7bJlaV
+lIgliY0iX66tPfOmUfwgFnrinB+pEbtr9tN84laimgMVQj4JT6uO47wq+bjpdnavzHnDytJDAdCk
+DAe8Gr6Xplv5/oArjdgblu0QcAC1QoJgaME1iJHoey7gqA9lTI+QkxwrxRMoCY3siz8JSolSwe98
+g+8xpcJbVcfAjqa17k0KCH5FnuDPgsQ4XrakXdZKrqMSS1/NISWi9xSalsipLJ9m0nTTl2Xgstgl
+hggUQrWrKC8AhcCk275fjoYPudKIrQKTZpvlaLLQ3uJIIARnOGqFkxyrhYhAKbGUB2ltbc8X7kkj
+H1RQ4CtjzRlrbg767gkPHT0bqTAs40MirdWv1Ryjcmlbl4SAq6Fhl9JKC4aUtT2gcLUcjx9VGQeb
+D0SESFTrVbEnMe3OtpvwhhW2GpSRm6F0/6o6DlYtZUyPwFz1pfu26ljYnPni2RKeOV5LWtlHxbj8
+ouo4zosAYFkGvy6zpJ1+PHhZPKg6jroLgShrq27VccxT1kquoxR/3vt5tJTVHFLKG+Rjv+o4zqPy
+jig0SQ+V/qgcDh82rfyFnS4GGlcdw2WYdrbpXPjRF7xhhS03ZW3PF/mPC3viGSPPGK0pZU2PQP/G
+l75xfbfsHKh4vswJDpQCtVE3nGtW4lbE5TsgLSu0yb3xuOSHtCcgIlACelXHMW9aK+xeye6Ph+Xz
+yXi5qiCVQnBl+L7qOM6j8gQHwOENK8OHjSwnZEdCKTFG8lXHcVkmTW5GiFd9ni/VBYuxt+ks/SgU
+VQwcZXWjrOkFEkOelbW8NJSFWLbG+Lcoa3qhiD9Tg+qrFdD3y/1TWR5SIjrC3/PQ0eORB5BGvl91
+HIvS7tpNgeIP+y8mn4UGXXdOIjXipPCDquM4j1okOACmcw9Mu7VdDsePeO7B8hARxDJU5iiT9ATK
+P/CGFbbMUEqMENfJL2LgKJXzfw92GTpLb7ogfuQkx/KhEEjruNRl4weSTnK7zMuFzhi6nMjpjQbh
+oaMn00iPVy1hp7XC9pr9dNgvvl2Wag4EaIcGzZypTYLjgG5lW9MNKzz3YBlEIdrQnH8PJ0KtUCbJ
+Vt7vf8aVRmxZ6TS9Xo5Gn8/7fQSEgvvM62+a5Ig/8oOH5UJEgAhXqo5jEVAI1InedEVDnrIT8AyO
+hjHW3BwM/Lc8dPQIgkqBq/l5bnftpgDxh5c/Tx40vZpDKLzWpKNP7RIcAK82rDjPG1aWgVyKAo7X
+UEpMOp1Py9HwYVzwWk3GFkWldnveA0en9/B8F98EOmvddJ6THMtEBLcvJW5UHceiKKN7IURqQquK
+QCj5wtg8Sctu8dDRdxktC1zh73qdKOxcsfebXs2hUKy7wjdmM2YtExwAACpJeMPKEpAoby9LBcdh
+pt3ZLsb513zDz5aRMhp9UfzMlUrsgM5aN52j53zNWw7RlT+s2pEjbdvNYjSZe3XaZRl0BQ9gbia0
+yb3xsPxL1XHURQhENkFbdRx1cFDNsf9i8llo4L2VUghlQT9VHcdZ1TbBAfDrhpV8wBtWWP0k7exD
+V5Y/Bud40wBbOjqzt0ORf1V1HKw+dKu96QpOciwDDZOBwNWrGzetbNvVfSBk5Oq2ppIS0QH+joeO
+ThERKCM6VcdRFzp5NZtjv3nVHEIiBiJsynm81gkOgGlLgMmyu7xhpaEQgUJoTEnTeZk0vUneZz7n
+NbJsuUwHjsL/mMc8JIqRav/lw46kO9MkRww8UK+pKARSklbyqarSEgFiIM+fXzYfPHT0EAJQWt6o
+Ooy6aXftZozi6v5e/qBh1RwbTenOb8w9pmm3tsv+mFsCGgYRIRLlVccxT8raHoh4lTesLLG4mgXD
+Ok2vl+P8b/N47Qir9/R4WehOe7PM/bexAfMM2LuICKRc3aeqJrM3i4n7Wx2fRFKIhDKqquNgl8ND
+R6cExCcrWCh2JolVvXY3uT/cL78uivnOPJsVpeVGCOFZ1XGcRWMSHAAAupN9WOblj6HkloDGQITo
+Q6N2J1+ENElPJslWMRhxOxVbKipLtmdeoUQEuMIHrGWgO52tclzucGVlA00THCv9VNW2k22X+8dV
+x/EuAo2QVR0Fu7ykZbf6L4vaz3yZJxRhwN1WJ2t3kw+Dh7QJ1RxKIxRFfF51HGfRqAQHAIBJ7c3g
+fcYbVpoBhcC4jFNGj4BSomlnd8v+gNuplo2Alf15Kq0xBD+e9dYgvuVpPr3WvVeMSr7eNQyGyeNV
+X0OKUiKKuE41ayMgggbembPjaJtsjwblylb3Gi0LxBW/2JxBYlWv1dLbda/mkBLRlb5owoPcRl5G
+X29YGQ5X9qLRJCKCXKUbYNPtbBfj8SNup2LLQmfpbZfnX1QdB6sfs9bd5iRHswifDwWXjYPO7PWy
+9H+PNWsj4PPg8hASMQi8sYpDR0Mg0lpwu9UZCYl4uJqjru1NQsDVJnzdNzLBAfBqw4pJtorB8EET
+MkmrLAqxcuWWSau15cri+TwGNDK2aCgEohQ3ZvZ5pghcw7E8zFp3Ox/l3J7XABQjSUm8peOVJLOf
+lLmr1bYolOJ61TGw2VFa9yY52JUbOkoEOpErd/9/WQfVHIP94mvnfO1GMkgpbzQiwdHkGxKUEnWW
+3S/6w4ezLp9msyMQkgZ/zC7MpNlm8C7whhW2DJRNey6f/H0W3xkEkfMbSyZZW9/OhxNOctSdJ1AS
+eP7NKygFKoW/864mFZcUAIVYqzoMNlsmNdcHI///0goNZiYCMAZvVR1HEx1Uc5STmA3286/qVM2B
+CqDMQw3nF70Jl2E8gmm3tsvxhDes1BRKdWMZPmcXoWzaAxGv+snkm6pjYeyytE0/CXkxky82ITCZ
+xeuw+jhIclQdBzseEYFSgg8dhyhrer7039ahzYoAYNXnoyyrJLUf9vfLlRk6GmN8xq1wl2Nbqpek
++v/pv8wflWU9zrhaKyxd6Fcdx2lwWUbn6Yw3rNSWQFjVBAfAdMOK0PrPvEaWNR1qhQTB0GUr5iKA
+QFzpLQ7LKllb354MJw+qjoMdTYTxE+5OeVfSTu8Uuav+8Lm6t0orYZWGjiLEFzxP5vKkROys2S2X
+xzDsl3+hOlRJxpiEGlWVHAXjEl1NX29Y4ZaAehEAwde/nGmeUEqUabqV7w8e1OEpEWMXpWx6oxxN
+di71IpG4RWWJJd21+/lwvBI38U0Tg+e1jUdAIVAbddO5ajcYaHDf8I9nea3S0FGbiAF/lmfHtlTP
+WPm/+i/yv1RdzRGF+H3djzJL0aJymEqSHgD+gTes1AciAj+WmN5AJd32/XI0fMjtVKypUAhURm7y
+AF12EtNdv8tJjvrRUBaCH6seSRndCz7+XO2chMg/myW3CkNHYySSGAUPM54tKRE76/bjqqs5tMJ1
+Kv13Vbz3WSER1TrAi0AtEU2yVfT3P+On5TWACNGHQdVh1IVpd7bdhDessOZS1vZcnj/h6ys7ieqs
+beUjTnLUBYVAWsdu1XHUWdqyH5Z5ebkKtcsg4BkcK2DZh46SJ0gyzcOM5+RwNYcrF58oUwohL+nF
+ot/3PBBCyKsOYh5QStStzqfFYMQbViqGQmBctlKhSzLtbDN41/cFt1OxZtJZ+lEoLjhwlNfErgQU
+AlXW4SRHTRARKAm8gvQU2iZ3XVFdCwFfGVdDktoPB/3y82XcPEUEoBXytWaODqo5ypzCeFg+WuTn
+SEhE7ynW+bOLRGFcdRDzZNqt7WKUf8stAdUSAiQ/7X2Tsun1CPGqz3NOcrDGQSkxxrhO/iIJZOLr
+8YpAKVFlna1ixNtVqiaC2xeIvIL0FEpLDDFSFU/XE+UGnOFYHSpJtkd990XVccwaUdhHxeuOF8G2
+VE8p+dHLvfzBgqs5NupcgIRA5KsOYt5MK90s8/JHX5R8kKxIBMy4iONdyiQ9gfIPvGGlvihGqjqG
+utJZer0cj869MSMSfc838asDpUSZtTnJUbHoyh+4++Fs0sxuukm++G1AEYDnFqwOIRGjlFvLNnRU
+o+BrzQJJjdhds5+Wue+Ph+U3i6isUFpukI+1XBebj/0eRiFW4sm6Se1NonCVN6xUA4W4svQfsgtC
+rVAmyVa+3+cNKzXFX9THU6n5UyjPt3kgEgjBGY6VcpDkcKO8uvkGK07DZCAQ+R/eGak0veeW7ODJ
+6kdqhXkpri7T0FGlYMizjBfPtsx1peSfX+7lD9ycP09KIpRlqNX10Tui/sviEUgYIUbMqg5oUZTh
+DStVERI3uILjeCglJt3O/XI05JkxrFGUTnq+KH7m5Bw7DUqJwrY+4WrKxaMQSEmyVcfRJEpLJIiW
+/GIOnhQj8Yab1aQT3esP3PNlGDoaI5FUwBtUKnJQzZFPXH88ml81h9SIzoViHq99EcNh8TQv/Fet
+NXPHWnUNo8SkxjNCZo43rFREIADVs5SpTky7s12OeWYMaxad2duhyL868x+IkSfprSjUEkHZq5zk
+WCwiAikFbzU4J5vZ68XE/W0hw/QIwEjin9GKsq10c/9l8bDOgxvPggggzXS76jhWXdZKrqMUc63m
+iBQ7oeKkXFl4evlL/iBJdLvdMR/LV0liRIk3Vu3J+uENK3yQXAwUAkII31cdRxOYdrbpyvLH4NzT
+qmNh7CxQSowA/4Ovp+wsUKseSXPVl5zkWJhpguNG1WE0kW0n2y73F9sYdS4EgPN/F1ZfpmU/afrQ
+UfIESsKVquNgAFqrN6o5Zv36QopbVaU3KBANB8VuIPhu7WpyTxtcP/zrCIgQI6zkk3XTbm2X4+I5
+Ob4pnzsUALBaibTLMGl6k7zPeGYMawqdptfL8fiMhwAq5xsNqztlTI+QkxyLgmHymIcJXQxKiSji
+Os25p514nPXKE+Jg6Ghzr4tEAFLJjarjYL86qObY+3n0YJYVF0ojLCb5+6Z87PeG+27HtvQHaaY+
+OKodChEQol/dJ+umlW6WRdnnctk5QwTyfiUTaRelrO2BiFd5wwprCpXae2dJygkIBR+2GCc5Fkf4
+fCh4vuiF6cxeL4vySaT5ljwjQm+er8/qbzp0FK8ueOXnzGikx4IrkWpHa4XdK9n9Yb/4djKezXeu
+1gqLPAxn8VpncXiIaPdqcl/J47/UcFoOt9ppY5Pa60ThqptMZl6+w6ZQ8OXuIqRJejJJtvL+8EHT
++zLZ8lNaYwh+fNqg3NX+xmGHcZJj/ihGkuglD/27nKSVfVTm7uyzhi5ASvn+PF+fNYNOdG8wbObQ
+UYkw5ktNfbW7dlOg+MP+i8lns6jmiDHqRZxP3h4ietrvR5QSybuVf7KuTNITQv2ZN6zMU0x4sOv5
+oZSYdFr3y/7gIf/9sbrTNrnt8vzUHmI+bLEDypgegbnqS/dt1bEsJU+g1OpszJsXlAKVwt/5ObU1
+EwWevcxea+rQUalEQP5+rzWtFbbX7KczqeaQ4vfzXP543BDR07x+qt60f0DzgFoi2nSr6Pcf8EFy
+DoQ0qzbQdpZMt7NdjMePeJAjqzOUElGKG+Qcf07ZmSlregT6N/y5mT0iAqXErarjWAbKmp4v/bdz
+uUeMANy6xw5r2tDREIjSTHWrjoOdTbtrNwVcrppDK1wPITybdWynDRE9DQIACBAdPnhOoRCoW+37
+vGFl9lCKK/wxu5yk1dpyZfGcDwGszpRNe26SH7lakWLkDhV2JGVNzwX8kQd/z5YI4yf8QHV2knZ6
+p8jd57N+XSXcE/4xscOaNnR0uo46JlXHwc5OJ5er5kCFkE/CTLc+nmWI6KlxTf8XecHFW0y7tV3m
+vGFlloTADf6gXZ5Js83gXeANK6zOdGq3Q1F8d9Sv8UAedhydpTddiJzkmCEM+R4nOGYHhUBt1E3n
+3L9m+boixmKWr8eWQ5OGjpIH0EbxOuoGeqOa4xwValIiek9hFp0g5xkiehp8Fd21yAfPd5iUN6zM
+lEAAiis/72UWlE17IOJVPxk/qjqWlcCng3NDrZB8IHq7OZMIhJRcwsqOpbPWNMnBVZQzgUBBnLFv
+mZ2NMroXfPx5pkMgCbhFhR1JJ7o3GtJz7+ud5JAYuQqpwV5Xc+yXXxfF2RO4QsDVy14KzztE9DTT
+FhUh1rlF5WgHG1bKMR8kLwuFgBBWdyXxrEmT9IQ2H/Ea2TkjAoHIB/ILUK30hptMZl7KzZafzlo3
+naPnnOS4HAqBtI58/ZqDtGU/LPNyZ5avyWdDdhzTMpvDgf87zXlV8WWgCANeR9187W7yYfCQ7u/l
+D85SzSGlvEH+Yg+wLzpE9DTTBAciENGRpcRsumEFlf6oHA4bN824VlAAEJVVh7FMUEqUabqV7w94
+MO48CcF/txeAQqBU8ubbM2P49oedhW61NznJcTlEBErC9arjWFbaJndd4WZS5atUGPLFkZ1Ep+aT
+Yb+YaVJtloyWBW9QWQ6JVb12N7l/lmoOpRBceb4H2JcdInqa1wkOCCGf5QsvG5SvNqzsD3lV5wWh
+lEjEn7NZQyEw6bbvl6MhD8ZltaOs7bl88vfX102KwCkOdla61d50BT2Pod6l2bXlymcCca3qMJaV
+0hJDjDSLVhUZKfL6bHYSIRCF0ncnY/dN1bG8LQQim6CtOg42W4erOY6rHpIasXThzBUcsxgieprX
+Q0aJwnjWL75sUAg0ndZ2OeRVnZfBVTDzYdqdbd6wwupI2/STUBSPAQCI5z2xc9Kd9maZB05yXERw
+L/jIPF9pZjfdJH9QdRxsNUitsPRiw7vZbq64LCICpUWn6jjY7CVW9VotvT3YL46t5ogUO+GU9qlZ
+DhE9DQJMD+7kKczrTZaNbmVb0w0rfJA8v8griefo1YaVvi94wwqrD9QKY4zrrweO8oGLnZPutDfL
+sfvfXEF5PhomA4HcFD9vKk3vufzirSoUI/F1kZ2VTnRvOKBRrYaOEoAykjeoLCkhEdvd5ENfHF3N
+IaS4ddLX86yHiJ7m9bY+IQXyk/WzM2m66UsXeMPKOQkJnOCYL2XT6xHiVZ/n/NlktaGz9Ho5Gj2A
+CIBS3ao6HtY8eq17rxyVO5zkOBsKgZQkLhlfAKUlEkRLFz1wEkCieBgsO7u6DR2NMTzjXOrys61f
+qznK8tduBqURXOHfmec5ryGip3md4MCIGR88z0dZ2wPesHIuEsU1/pjNnzJJT6D8A29YYXWiUvMn
+X5RnXj3G2Nv0WvdeMSp5FtYZEBFIKX5bdRyrwmb2ejFxf7vYw0I6dEfO2NmYzG7XZegognjBI2RW
+w0E1h8tjGPbLvxDFqBChLOing98z7yGip3l9OY0SEy7gOD98tWElH/CGlTNBXAfuwV8I1Aplkmzl
+/f5nfBhgdaB00nPF5Jlzpa86FtZcZq27zUmOM5gmON6vOoxVYtvJtsv94/P+OaJ5RMNWgTBJLYaO
+2kQMcEFP51k92JbqGSv/V38v/4sLNKBAJsYYFzFE9DS/VnBIvMEVHBeDUqJK062izxtWToUIMdCz
+qsNYFSglJp3Op+Vo+DAezD9grCLkPInRy0l88f3n4Zd/fR4G/V1flEQh8O09Oxez1t3ORzk/WDgB
+hslj4PPGQqGUiCKukzt/q4pETOYRE1tuUiKWXmyURaisOjJGIqWEqur9WXWkROys24+LcXB7L/P8
++bP+VwFoMO8hoqf5tSAOkR+sXwIKgabNG1ZOgyCAiF5UHceqMe3OdjnOv+XPJquKzyd75fDlo/bV
+9f9uXem2jIGeVeP3MnjZV+N/fxH29x75fLLHyQ52Vsna+nY+nHCS4xjC50PBPfELpzN7vSzKJ/Gc
+sxFQCh7QyC5EJ7o3HtGwqqGj5AmMlVkV782qEQJRUXga9ounL18UO0WI3zqPxmTmt/k4/PjLz5Od
+wSB/Wkw8hbD4GrXX2TYEBPL+MWp1e9FBLBPdyrbKyWRXmziQRs99SmzjoABwVFYdxioy7WyznEz+
+oWIcSM2fTbY4fjLaBYBUI3ltbS8M6R9Zx95xefmCQvyXbZnthEKMNIAyp7+4oHxU6TXU9n3UkjvT
+2bGStfXtfP/lTtrJtquOpU4oRlLopRCGMxwVSFrZR+Wk+CrJzJ0z/QEKvESFXcp06Gi+013Du4tu
+FSECMAZ5ePgSC4HIewJXhCfBw8+oVCIN/lanekNF+L8nY/dovadvWIvrSuFGjDESRSh8+Ndw5J4C
+AJhEXDNKva8MgpQ413u7X8uJEACAH5zNgknTTV8UL2KMT1RiOCN/CEqJjkJedRyryqTpTZ/nL2II
+T5S1/Nlkc1f2+490av5I+eh7Y809AICIpk2Boram511Yn4zGD2ya3kMlhVXy4yTGGGkEwQ2euFH8
+OcjW1ZikN1ArQCE44cHekKytb09e7j1Iu637VcdSG55AKeQnqhVBKVAp/J13fl9ptXba7ycA4HYi
+dlnToaOTz7vr9t4i35co7As0Cx0iyeYruFcJDXc4oaH+qFP9QYLi9VyN4IiK0n3ZWbPbxXjyVyGm
+w0SFEEJKAVLitSSBa4tOeBxKcCCQd32AdJavv7JUkvSoLKAcDh+advtu1fHUiQCAGGOsYugMm27/
+CWUB5Wj00LRa/Nlkc0EhkBuNPk8yez/48qWSsYcH/ZjS3opxAgDT9Yqo7HYxGD/UafonqXBNTL8Z
+AaX8QFv4gEIRKUz+VQ7i9yQSQ6b1ESoJKLm6g00l61fu5/2XD20742saTDeoKCX4iWqFlDW9yWD8
+pZT4sThlf6aI4RkAbCwoNLbEhEnujsfloywzHy/qPaUQP6AQnOBosMMJjdLFX7TRRh2R0DjMOU+l
+o4et9jShFgjEcaVopyY8IgSj4Tcm0TdmkfD4tUWFn4rNHJqkByFsFYPhA9Nu3eMD/VQE0YEY+WlF
+haRJekKGrbw/fJB0+LPJZiuU+R4U5a5tZ58CAMR89L9VO/304NcFIngfHkslbwNMv3/SbrZdjIrd
+SGqojHrjRh8lCpR4TRm4FslHCi/3XU7fuaB81K1NVGaNW1mY6qxt5YN9TnIAgAjjJ0KJD6qOY9Ul
+7fROMco/t1lyYnWRAvpFCE5wsMuTEtE5/H2RuyeJ1Qup1DUahnwX2SwHCY2i8I89yYHR2JVG3dKZ
+/sCekpAFAChzv0cgfmq1kjeqhY7NcLzluIRH6eP+aFJ8FwMUl0l4vDXxViSRKJ6WaWZnh1IiZtn9
+oj/cSdrZXSEl/90KATFG7jet2HTDSut+2R/smE77Lv+7Px6fnM/O5+M9jPCTbE1nIrjRaDdJzRs3
+91JLDCMavv1nk1ay6fLyRZmHb4xNjpwHJRCFRFiXWn6cUIyRBuBceOwnahBk9h9gzPtKa/6RrSAU
+AlVnbSsf7j+0rdVOcmDI9zhvXT0UAo7EYqcAACAASURBVLVRN51z/9Jan5DAiPzDYjOjte5N8vLf
+UoZ9peWpLVKXESORVtMD6zzfh12Oc568I3AlPfaEQ6NlRxp1K2nr29k57/8Pkhs2VW8k0WOA8qKH
+u18THrBuEvnxZRMebyQ4BKLhTSrzYdqt7XI8/qtO7X+iOr0fc5lJxFv8OasP0+1sF6PRl8baD1b9
+s8kuxw9Hu9LI91BNv/S8c6SEFyj1O195gaSOFKN4axiatqZHIawXg9FnppXePynxJlAIgRISJW8n
+AEBhHIMfPHMT+D9BZFejsTe4lWW1oBCoss5WMRo+TFrpyiY5JIYoUPGBowaU0b3JKP+rRHofj1ub
+SMBVrWymjDU3B4P8y7V1/HieQ0eJAJK27szr9dnFTBMasO9K/8NBhYZKklvWiNuX+TzkY78H+G5y
+AwBAIBSz+qCdlvCgEMtEi6s60TeUQlD6zYTHmxUcUl6LwE/W50Vn2YflJP/Hym9YQQG8k7heklZr
+q5yMd3WMgFpzkoOdW7n/csdk2V1x6AY+Tvqf60OtKYcJZd6L0YMA+c6voZRou9mnk0H+pbbmA6nO
+9gTqVSvLhk5gg0IRifJ9Pw7/cGRVTOwfUJs1TnYsP5QSIWuvbJKDQiAjoV11HOxXact+mPeHnyWv
+2vbeJkQYC64VZDOWtOzW4OXkwVrPzm0AM3kCrfT1eb0+O118teHEB9gvivDPCKLURv1GaXnDGrM+
+qwRXPvZ7QoqfEvtucuPAvCp5jkt4OB/3x0clPN76w+vA6+TnyqT2pi+KF5HoibLJam6xQAQK4TtU
+ajX/+2vKpNmmz/MXFFb4s8nOjUIgNxzuJK3s3uFqCzcePTWp/vNxf04ovUHBPUN5fN952rFb5aj4
+RyT6tzLn6yWeJjtgXWnJK2hX0EGSw41GO7plV2qFLBGBksAHjppRaXrPFe6JTt69lhmkIJBbmNns
+oU225zl0lCjso+QNKot0kNAoHe07F99IaGTG3JlHxc546Ha1le9pLY9MbsRAC13F+nbCAwAgEEXn
+4/4kL757u0UFiOgZ8iTnuVJJ0iPvVnbDCiJCcI5XxdbQwYYVPxk/Umm2sAncrJl8me8J55/azpvr
+OSkEklDuSZkcW6mGiOBLeq7Myd83ppXcdKV74caTv+gsvXOROA9aWXgF7WpBKZGy1iduPHqkM7s6
+1zNXPhMJ8n1czSgtceIcyUDx2FYVxmZs3kNHNYofBAInOObodULD0zNfxqcAgqRRv1GJvqFTcQfn
+PP9kmtxQ72mNx/6cCQCkfHu252JJRCENrBsjP34nwRHL8gVwgmPuUOkeCNwq+vufmXbnxD7zZRQD
+jauOgR1NmqRHIazzGll2Ej8Z7SIIIVP7zjBQP+x/kbbNiZ8dlBJDiMVZVkZro3sk1ZnmcpyGV9Cu
+FpQSKcl+74v8iUrMalSmhfw5b+SopzSzm2+3qlCMxL3hbJ7mOXRUYhzPccTHSgoHLSevEhoUUWgr
+rymjN7QVG/NOaBw2Hua7Jk3eU+r45AYAABCAViJbUFineifTQhT44LkgKCViq/NpMRit1IYVlBJj
+JF91HOx4KCVCmm7l+4PpGtkVS8Cxk5X94dc6Vf+BUr3zhefzyV5i5c2z9GFG1O1IEcQZLn0oxau5
+HJO/6iT5TzmjmzReQbv8UKsegYVVSXJoKAtud6gvlab3ytx9Y6yeJocJwOhoKw6LLbl5DR2VCgNv
+ULmcg4SGK8Iz7+GpUAhSyetVJDQOG/Xz3aR1huQGABAQ1OlO6Y0EB0qJQHzwXDTTbm0Xo8muyZLf
+rsoWCxFBnOXJLasOCoFJt32/HA52dJr9aVU+m+x403kbg3fmbRz+dRHyf8o0OVs7gLS3YpycK4a0
+k35YjosfKNK/9TnncpyGV9AuL9Sq56MBX5ZPlFneJAeFQIkkC0cM72X1oLRE79w6+bCPSq4BEAgB
+puq42PJ7NXT0s7WePXLY7XmFQNTtqu4sXmuVHEpoPAkefkalEmnwtzrVGwmKjTqcjYb9/HPbTv6k
+5OnJDQB41aMy35jO44heGcEHzwqYVrpZTvJ/KE3/XoUnTFGINsTIa9EawLQ727xhhZHzFCajL22n
+few0dpoMv0qsPvOcDIEI3ofHUsl32lxOYrLkuiv9i2I0eWgy+8k8vq94Be3yUcb0fAlLneQgIpBS
+/LbqONjJbGavj/fHD2wb71HNDgZsuSmb3BsPy79kbXOhmVaHEREoIXuziGuZBfcqoeEOJzTUH3Wq
+P0hQfFC3M/dwP9/Junb7PJU+BACJlLUZbv1OgkMA8sGzIia1N31ZvPB5sfxbLKSIMfJK4qaYbliZ
+/EBE/1bJkn822Tt8PtlDij+Z9vEzWXye7ykFvz1PO5PUEv0g9pMLFGdro3pSyq1yOH6gs/T+vIf2
+8Qra5bDsSQ4R/L5U4v2q42Cns+1k2+X+MSr8M88wYIsiJKIj/N0sho6SB5BG8vXmLYcTGqWLv2ij
+japxQuOw/l6+075i7567LYYABEJtHoK+k+CIEhM+eFZHmaRHLqwv+4YVifI2ryRuFmXT674sXvhJ
+/o06YrAkW05+MtqVEt9DY47de04xErjx31XLHlvdceyfBUwixSgucId/MJcjHxa7yujfzmoux+nv
+yytom0wZ0/P5ciY5oit+AC14o0EDoJSI0m2Q8/syw1tVx8NWx6yGjmqkx0LAyt8PHiQ0isI/9iQH
+RmNXGnVLZ/oD26AZdi9f5A/XevbuRRIwMRLUaRHdOwkOlHiDD57VQi0RMFnZDSusvqYJOL9aG1Zo
+da+H5f7LHZ3Zm0cNEz2Mxv3Hxpp7F3oTnfw+RgfiEjXatp1surx84YrwRC+4xY9X0DaTsgdJDvet
+MvrY5F3TyJgPBd8yNIa2tvfLv375wtt4R0AUANMV2oAAQiBfM9jcGGtuDkb5X9e6+N8XHjoqqFzF
+641znrwjcCU99oRDo2VHGnUraevbWQPPbDEQDYZuZ/1qeu6HVK9fo2a3yu/O4EAEqFmQq2jpN6wg
+AoXwHSq1VE/PVgFqhYBiK+/3P0vabU7ALSEKgdxo9HnSyk79+frSkcJ49aItIijVevDFM5TyUmst
+tTU978L6POdynIZX0DaLsqbnxn6Ezu0vw3whCoEUeimE4WtyzVGIFFyxL6J//P57Urc64u/GShN9
+LCgCFEXoRyCIkSAE6iAICCB6Isb3QQhABABEQJi2HFT938OaKUnth/2XkwfrvfNXXwIAGC2LqjZ8
+LNI0oQH7rvQ/HFRoqCS5ZY24PcuNNFUIgWg8cl921y/2GTiAInwjBP73rOK6rHcrOACBvH+MWq18
+yVEdvN6wkia/Rb08WywQEYJzedVxsItBKTHpdD4th4Mdk7WWLwH3jiX/zzvEl/meKP0/bTs705T1
+mPc/V+30whPZERFCHp7qRF8qwQEw3U6ACrfywfhhkqV35z2X4zS8grb+dJZdd+PJPzR4aPp3LBGB
+UXil6jjY8bwLBL78SivhExs/SKXQ7fXOdjGa/LVl5A2002tW1pn+/hhjnD4ZjRDjq6ekFCE4+iZQ
+FBShcGUoAADIkSRBGYKAQPG6EGKNkyHsNNom26NB+bDVMeeqyg2BqJ3i0q03jq82nPgA+0UR/hlB
+lNqo3ygtb1hj1pue0DgsOKK8dF901uz2pV+LQNTpVvmICg6A6SxUVhevNqz8oGiJNqwgQvRhUHUY
+7HJMu7NdDse7Ol2dFcfLzI1HT6UQY5nZM615daPRbpKay2X9pcQQRZjV9i4UArNutl2Mil1UqqWM
+unbZ15wFXkFbXzpLb7rx6B9aeGj0dYwIUInluEdYIt4FIueeaRm+b6X6P2RL3yHvX7ZS8VNipwcL
+Zc3tfFR8lXXe3GwhxMFV8c1LozLynSelFGOECPAqIwIxRogE+6EMP1AEcIHG5MkDAAQXkiiiQSGj
+D+E2vsp7vE6GcIvMyhAS0RPeOO/QUSICZbAzz9gW4SChUTrady6+kdDIjLmzTAmNw5zzVJbhi1b7
+8smNA3XKcBzZokLe9yuIhZ3ApPa6L4sXbpJ/o5dgwCMKgbF2HVvsIkw72ywnk39Iov9PnTCIktVb
+ORh9rRP5H6jOlhAgF0gJL1DqS3+jEZirkSKIGRYCJa3pXI4yp2+MNbW6ZvIK2vrRWWua5IDmJjmE
+z58IJfgaXAMUI1FR7ovod1MrWzpTt1CaawAALs+fdlo4NvbX2S9SShwX+D+SQFFetN1PiFfnizf+
++Lo28p0ZSkclQyjEf5GjPYoApaNBDNMBVL70HUQBRJCAgBuvq0KA54UsC6V1bzIpR+caOkoASsvG
+JVRfJzQ8PfNlfAogSBr1G5XoGzoVd1ah5aYs/V4I8ekskxsxQFmj/MYRLSpC8BCOmlq2DSsigoxE
+kWc4NJ9J05s+z1/4PH+irG3cF94qoxjJ9/e/MFl2V5zjxtpN9neyVnKxwaJvETq5EeNkFi/1hoO5
+HJPR+IFN03sX2dSyCLyCth501rrpRsPdpiY5kPK9Fbg3r7VXLSiPpYyTdkttSmnvHr7u+HG+u3ZF
+vaeUfCeRbJJkYzIaf9HuJnO/vzsyGaLgGiRwDQAge/V//dohc6hFBiIET094XshyMam5Phjlf13r
+iP8+S3ungPgEsf4J1fAqoeGK8CwEeEoRhbbymjJ6Q1uxsQoJjcPK3O8RiJ/STM/0wY9AKOr0F/lu
+BQcAAIiED571hFoiqHSr6PcfmHb7XpN/RlGI7PTfxZpCWdsj72ClNqw0HDlPYTL60rRb51oL5saj
+pzZV/zWrQZ4CEbwPj6WSM6+0UFqi0un9SX+8o9P0T1JhrQ+uvIK2WrrV3mxikoNiJIUhClSNvSdo
+KgqBfOmeyRi+zzL9P1Wmbx91QHT55NF6T/9RyncrKgAApBSYF/L99BJVHLP2a4fMWy0ySr4+2PK8
+kOWRpPbD/v7Zho6iCIM65gYOJzS8h6dCIUglr6tUbxhcvYTGYQfJDZuquSSmqhjufpwjExwC0XAR
+R32hEIit9v1iMNoxrfRPTboJO0wgJDHGOlU0sUtCpXsgcCvvDx8knda9Ol3s2Jt8PtkTIT417fMl
+oygEklDuSZnMbLaF1BL9IPaTOY4rS1/N5YikhsqoSw80XQReQVsN3WpvusFw14gAQp6xXLtqnkBJ
+aFcdxqqgGIlKDxD8V9YKaHXUHanMsdfEMB7vXLma3MVTHkolabIxHo2/6CygimPWeF7Icjjr0FGj
+ZVGH+RSHEhpPgoefUalEGvytTvVGgmKD70On8rHfE1L8ZO18kht1c3QFh5TXIvDBs+5Mu7VdTia7
+JoFGTn9HqW7wGI7lM92w0rpf9gc7ptO+2+Qqo2XlJ6NdFKIl0/PPpgjj4Vc21XdO/53nQ4BzrxxM
+WsmmK90LN84f6TMOUq0LXkG7WLrT3iwHw11jRfc8rVtVISJQEq5XHcey8y5QDO6JEuGXdqb/S0pz
+56TWtxgigZ98vv4be/8sBy0hBBYk3w+e9utebXYZPC+kvs4ydDQEojQRx3QBzFdwrxIa7nBCQ/1R
+p/qDBMUHnNB413jodlUiW8bIuSQ3YiCS8riukGocXcEhxDofPJvBpA3esCIQ+HO2vEy3s10MR381
+qf3PplYZLaOy33+kU/NHlOrIMumT+HyyZ4z441ySEDr5fYxu7ol1bXSPZFgvBqPPTCu939QEHK+g
+nT/daW+W+/3PTcts1/5z4otnwmIjKpOahkKk4Ip9jGE3S3VPZeoDlObUz0NwgTT6L9q9863Rtpm9
+PhyOPltbTy68fnuZVDUvZJWTIacOHSUCnciFtJkfTmiULv6ijTaKExpnNh66XW3Ve1rjue/5zooA
+QKl6jR04rkUFiOgZAvCXZQP8umFl8o1O01ptCziRAAg+PEY920E3rD6SduvDcjLe1TECas1JjgpR
+CORGo8+TzF7oUE8hkAj5P2WazKXyAaVaD754hlLO/XsHpUTbzT6dDPIvtTUfSNWQNoRj8Ara+dFr
+3XuNSHJQ8VwIwfdsM/RqYOhXWgnfasu7KPWZZxX5stxLNTxN2+ZCWwoI1J+WvYpj1uYxLyQCrey8
+kJOGjhIBGIO35vG+BwmNovCPPcmB0diVRt3Smf7A1vkaXEPjYb5r0uQ9peaX3ACYVhDKeb7BBRyd
+4ACEGMoXwAmOxlAm6VFo1oYVRIQQQtVhsDkzabbp8/wFBXqibNKsKqMlEcp8D4py17azCz8RpNHw
+cZLNvjXlACJCyMNTneiFfe+kHbtVjop/ENG/tTm6FLdpeAXt7Om17r1iv7+TtExtW+40lIXAGe5Z
+XlHeBSLnnikM/6eV6f8pW/rOaXMz3lYW5V4ng58Se/GHNyZLelzFMT88L+RsktR+uP9yvLPes28k
+92KMzwTOJqHqnCfvCFxJjz3h0GjZkUbdStr6dlbT620TjPr5btKaf3IDAKYlHDXLcBzdL4MARGG8
+4FjYJaGUCLZBG1YQIfowqDoMNn/K2l4oC/CT8SOVZo2afdB0Ph/vYYSfZCu78L5zX+Z7ysTePK8p
+KCWGKEKMMS6y5NS0kpvTuRyTv+gsnVsCpyq8gnY2zFp3O99/uWNbtnZJDgqBrI7dquNoKoqRqCj3
+RfS7qZUtnalbKI8fGHoSX+S76x35ntKXH+RHqP/k3TEtAmxhVn1eiGnZT0Z990V77dehowjxBV6w
+YuzNhMa0QkMlyS1rxO06DC1dBsN+/rltJ39ScgHJDZjmNxIpazUD6sgEB0qJQNNsJGuWgw0r5XD8
+pc7sB3WefYBCYOQhHCtDHlQZjUYPdZZ90pS+SWrwSik/HO1KI99DdfGbbYqRoBj/XbVOXxt3WQTm
+aqQIYsEPoqdzOdT6pD96kLTSe0eteFwGvIL2cpK19WmSo52ea63yvBERIMKVquNoGu8CRe+eKEkv
+2y21KaW9e9LA0FNfb5zvdq+o95Q6eg3seRlresP+6MFaD3kjWUMs47wQIRBJyq0iL58kdjrrzyZi
+cJZPZHy14cQH2C+K8M8IotRG/UZpfYMTGvMx3M93sq7dXujfLQEIhFqdN0+YeCrEop+ksdnRrWyr
+CRtWhAA5780JrD5QSoQ03cr3Bw9tlzeszFO5/3LHZNndy26AoHH/sbHm3qziOonQyY0YJ4t4q3eg
+FJitZfcng8lfdZL8p1zyp6a8gvZi6pjkEMHtS80DRs+CQiBfumcyhu+zTP/P6cDQy38PhWK8s95L
+7s48OWrstivKZ8YurnWPzV/T5oVIrTAv4lUpw75UoiMxiqOufwcJjdLRvnPxnwJEKY36jdLyRmbM
+HU5ozFd/L99pX7F3ccHfTTES1O1W4dgEhwBsQ4zv/ONjzWHSdNPn+QskelLXDSsRMOMijtWCQqBd
+62yXw9HnOrX/Vecqo9cadBmkEMgNhztJK7t0m5p3jhSCXVRFAyoE7/1jqWRlg4fTTvphOS5+oLg8
+czlOwytoz+cgyZF2Lt72NUvRlT8IAwspRW4qXziC4L+yVkCro+5IdbEWlLfFGClMxjvrV9N78zi8
+6UTicBB/uJLE9+uSUGOLVZd5ITrRvf5gstvJZDu5qjsAhxIanp65Mj5/ndBI9A2dijuLPmivspcv
+8odrb81KWZQ6HuOOr+CQIsYYm3Rfz46grO1RWUA5Hj8yWf1mH6AQVyI06vzIZsS0W/d4w8ps+TLf
+E84/tZ3WTNpJ4mh/R3WzubemHEAp0Y+hn9hFvePRTJZcd6V/UYwmD01mG9NONSu8gvZ0ydr6djHY
++zxptRZS3XQSDZMBDxh9l3eBYnBPlAi/tFP9X1KZO5dpQXlbCIFUdF+u/V/zvUaiTT5xefnMpFzF
+wU4273khElXy8/PRo26rtb5f0g5FFNrKa8roDW3FBic0Fi8GosHQ7axfTRd2r/ZODBSeCIGXnjs0
+S8dXcEh5u5YpGXZuaJIehLCeD4YPk3arVjfrQuIGf85W13TDyuQHIvq3SnjDymX4yWgXQQiZ2plU
+P7jRaDdpJQs/vBFgUoe2NW1UT0q5lQ/HD5MsnX3peUO8s4I28graA7pz5V7ef/nQtrPKNpdRCGQE
+qdqNsK8IhUjBFfsYw26W6t60BcXM/N+uL8s9o+M/2u35XyO1nlZxrNv4Ph8g2axcZF4IhUhaxgcm
+S24oIwV/HqsVAtF45L7srs9/RtqJBBR1e1J9/E0JIjR4th57C0qJKk23iv7wYSSqz09WIADFftVh
+sOoom16PEK/6Sf5N1bE0Vdkffi2VfE8mZiYZdHKBlChLlBU8FdbJ72NNkp4oBWbdbNvl5bfBhf2q
+46maQCFQSpFYc7vVxvttM95I/S8/Qv/5gzDo7/qiJAqBqo5zkVRnbSsfjR9W9f5EBEqLlR8w6l0g
+P558Lan4otuW6911e9fY2czXeFtZlHutFH5qtxczmwgAQNnkk2LiHi/q/Rg7IIQQKISIEWLw4Yv1
+daNMopCTG9U6SG501mxlCfbDRM0yHMcmOAQAkA98MV0iKASadmu7HI4fkfe1uFlHISCE8H3VcbBq
+KZP0hJR/Lkejyg4KTUQhULH/8oHJzG2UamY9+G7S31GJuTWr1zsPlGo9eHpWxXsfx7aTzUg+uKJ8
+UnUsdYIShU70RtbW91u2+CCDl301/vcXYX/vkc8ne6uQ7EAhULUrTHIQgZRiJavfKAQqx/lTykcP
+Wkl41l3Xt1sdsy2VPHIA4iz4wu12M/gpsXqh5dhSS5zkgohqkv1lKyU4TxToiyxL7qYt+aeq41l1
+wRHlufuiLskNqOGsgeMTHIgw3WzLlo1uZVtlXjwn56pPcqAALhViAACoFco03cr7/c9qVWVUU+Q8
+hdHwS9tp359lO4cbj57aRP5XVa1siAjBhadVvPdJtDU9lPiHYjR5GPmQ8Q6UKJSW67ZlttutcKeN
+g3WV//RV6P+848ejp+SWN9mBQqDKOlvFaLLwJAeGyeNVGgZPMZIvHIXJaCdB97e1rtrorqf3tVHX
+cM5tbX6c73a74j2z4OTGAZWY20XOVRxssUrn94TAv3W6dtsVxVdKIc9Mq1BZ+r3Sha9abVuLIdev
+DOr2LXRiiwpRGCwwFrZAJk03vfPBV/1EEhHIe25RYQAwPSgknc6n5Wj4MIbAh8hj+HyyB678zrRb
+M83eUwgkodyTenbVIOeFUiJFEWJd+lQOUVqiaSVb+Wj8MHiqPkFcUwKFQCWFTfXH7RbcbevRRuJ+
++g5e/jhtZSkdUYxLlfBAKVFm7YUnOUQoxmIFxsN4F8hN8l3hJl+2s9jvrtm7SWpuS7WY//hQjD9f
+66n3lHp3WOOiSC1xUggifgDAFqTM/V6i5E9Z29wOIZJBErzqtTpl7veIxE9py9RuaUSd5jsCnJDg
+QCEQ+CK61FSS9IDC1XI4rKwtAOu2OJnVgml3tstx/m1dWqnqxE9GuxJBSDubeRuHhfHwK210Ja0p
+h0U0V2NNv35QTOdyhLJ87ktfu0qTuhFiOrdDW/1B1jXTVhZ68QwH/98ODfYeLdPcjoMkhxvlO4t4
+P4qRJAaq243lrFAIVOb5XhiPHmQ6/LjWVR90uvau0mp9lttQThPG45219WRbyuqSGweUNbfz3HMV
+B5u7Mvd7iZU/Jem0YskV5X6S6Y+qjmtVlbnfIxA/2VTValtJXZ1yuBQJl4ovNzRJD02yVQyGD6p7
+Yhr5c8beYdrZpivLH31R8NyDV8r9lztSyfdQ6ZnfaPs83zNG/LHq7SUAACCTGzUs4HhD0ko2IYas
+zAsejnsOKFEoo65lbX2/lfo7LXjZf93KMpnsNb2VBaVEkbU+cYv4XHgCJaEz9/dZsFcDQx8p4b5a
+a6v1tV5631i1sehNRjFEEuXkwfpv7N15t7+clZQSJyWaEPieic1Pmftdm8nR4VkzsXC7VcwdZwD5
+2O9FUc/kRgxEdRw4e2KCQyAaHo+w/FBK1Fl2v+hX1BYgpOFVsewoJk1vRqKrPs9XOslBIVDR739m
+WtndWQ4TPfz6wo2/rbI15TBUCN7X/ymltqYnlfzzZDR+wHM5zk8gCqnluk31x+0M7rbVYF27f/8t
+9n964Eejp965RiY7UEoUOt2YdwsoEYFSovKKq1nwbjowNBajB+0k9Lvr+k6WmY8X1YLytuACSSi/
+6Fyx9+tWIaOT5MZk5L6oOg62nPJxuZu29HvG6GsH/59zgWwme3X7t7AKxkO3KyT+lNj6JTcAptM6
+talfol2d9ItRyCsRYt0Go7I5Me3WdjkY/1W37X+iUgsbIoRSXImxdgN4WU0oa3vkHZSj0UPTmu3M
+iSbwZb4nSv9P284+ndd70Gj4OMnMJ/N6/fNCKdGPoZ/YqiM5ndISlU7vT/rjHZ3aP0kleQDbBQgU
+QoCERMrbCQBQGMfgB8/cBP5PENnVaOwNVBJQyka0NaJWPR8N+KJ8ohIzny0nvngmlNiYy2svAIVI
+wRX7GMNuluqeytQNlOba6X9yvnw5XQObWFOnIX6vSSlwUsj300BRLriqhS23fFDudq4k78m3Zs24
+iXuWdnAltzVVaTx0u9qq97TGWjx8OhLV8/x24o0CSrHBT9ZXi+5kH5Z5+WMo3cJ6y4XADd6kwk6C
+Svdkkmzl/QpaqSKAkLKSp6RuPHqKgX5SmZ3bQClf5nvKxF4tWlMOIdCdJrWupd1sm0r3oy/dSlcb
+zcoyrKBVxvRImqu+nFMlBxXPm/hA9VULyteSii+6bbneXbd3jVUfLLoF5Shlke+108WvgT0vmyYb
+Y67iYDNUDMtHRyU3AAAwhh84mbZY42G+a9KaJzcAgIBOHXhRhZNDQgQieragWFhNmNTeDN5nPl/Q
+7AOBABR5kwo7EUqJSad1v+wPHjbp4HtR5WD0tVKyLZPZDxN9QzH8hzLVPzV9h1bX6j6H422mldwE
+Ea+6cf6o6liWSZNX0CpjeoTzSXJoKItFDtu8DAqBykn+lPLRZ5kOP3bX9e1Wx2xLJUVdyt79ON9d
+7ypR1RrY8xBCYEnyfZ7FwWZho00dZQAAIABJREFUMsp3Oj1756jkhisCpS1xvYq4VtWon++aNHlP
+qXonNwAAgAAQRa/qMN52cgUHIECILxYVDKsPlSQ9iLSQDSsoBIQQvp/3+7DlYLqd7WI0/nqRG1YW
+efdNMVK5/3LHWH0b1XxnYrjBaNfYWu1Sfw2lWg+evqs6jvPSRveUVR8Vg9Fnq5CIW7QmrqCdR5KD
+QiCtY3dWrzcPFCP5wlGYjHYSdH9b66iN7nr6qbFqoy5DOw/4Sf5190q1a2DPy2b2/2fv3rubONKF
+0de9+qKb5WR7dkgycyaTQDJh532TgA2zznc5f5yvOmADm7MmYXaikKx3DWEIazxBWFJ3V9flqfOH
+IQFigWxL6ovqtxabbMaoy1jqy1PP5b3Z1Nyoeh1BsxWZ2u8P07mNdE1Z3mWMNbYUrmmmR+qO7DQk
+uIEQAkCIUvJO1et41Wt7cCCCkAerEZJrWk5QJ0TIIXLuSjmd3RBpcm1lKewEI2RAr+S1g1aSnfQz
+XRTfcu8R4bw1PQ/AWHBFdlt00t1V72paY4AziwnltXrQeI4whlzunnDJq17KqRFKSdRL/lJM1W0e
+iY9CX47VwBhjTCkilH7EI/QRuNKDK/6pp/4BYClApJ/XpW8HE2JoFUJWm++YOH+GAAAgQtDWMta2
+bNY48NbcZxSedhJ2kdJot86ZJq7M9wdbcrcOJTKnBYh97CwcUUbCOSY4NTUtbwzeSq/Nu99wzgMj
+4EiNP79tMjtS+2kv2m3Sv/fxfkL9lvvaAAehlFhwal2LCeqHUEpIklwvp9m+7CS7eAUzogilxIT3
+WXBKIo4vWaWegIP7LJKNb35lVTHGzj8UnfU0UvXF5CbrxCtrXHpeBGNiPPHee1+XFPbTirvRFZ2V
+3wLAv7jgjX+P1h2hBBNK3mUCvevBenBPj4yC741j1vP0ImGiT3h1wQ4WLS/IgZ05opzUZlcVnAdr
+yiMK7psk4W+xpB49NV7Hew+uyPcH2/G1Jj1QvEgkcjg9mt0YbEfXq15L0BzOATjjbg/eTl/7vjGl
+PkoTXpsG5G02Gav9zla0W8eRq6/jPUJ1XDKxZfmGdE6M197UL6gd0Un3ykx9t8qygPA+C06LRdEQ
+Yb9ti7zRPQ9skY0I8hmLxeV1HM9k2UMZi9rfEGPCt3zDqzxEKi9hjLbLrFh5uV/wq7qOoGWRGDog
+AOZ811Jv9I91uKe0xoEtijsMl3f7HTroD+PrdWkY+jrOOSCuvD18O7ne1ODGc56LS9a4tZVsBs3m
+DIAzcLs3iN+4meJLM1rBvmbwiqdP1EG3gcENhBDy4O7XcdUEwE/0ZHa7zPLRSRd8jEgnTFIJEEJI
+pPFFrfRPtlxFR3jfDe+z4CyokEPMxec6yw6aGCTTk8kdyugOXVOjTzAOGNZj0oS7Fio/9ACNb0DM
+BRuKWF4pJtkNCE0B1w4TjAmlWEbictoh1zsivxDbn39Ck8fHfTtKDeucysKT+JJx+KfzBDk4KqZV
+TT6yxoHO1UNfZjdS6R71+vyLJBFfUtaAcwo6HgMrqb7b7ctWjB0XkRhmmb1X9TqC+nPGAkL+oDeI
+3vjeN8ZBlNBhUzMom+LoafnX/jC62th/Z4zKGlaoIEY5H1DOd70D76z9p82LB5ixbSb4h5Rzguhx
+AkcN1x5UQMTRJVuWT6wql1sWgCkKAY7grAilBMXxFXU0PYh6nd26jTw9CTgHJstuyiS6vs71mmKy
+n6Ti2rqOdx6EEWSte0A5W0tmyyoRiknST64Xmfob5+IPlIe+HFV5VspygUt0AVzpAdSRzd23BiLm
+ZfQB4aK/6r4dPIkvmTz7lmOLCGOnei+AcyApRAjRVS3vhGN6cKY8It6NkpgPWcI+JLSG05feQJd6
+3E3QoYxWN3q7Cp5G17TS/xQRr03ZUlAv2tixYPQwivlC139TmEdxl4TSyhXxDmCWmdv9rai2pcKL
+wjWMEvzSgwNTghkV7yIu3vUOvDX2kcmLf5iy3JIeARUcY0IQIgQRjCtv2BVUh0k5BOMGejY7EJ3O
+UnZAKMHvel/HNjVBUxCMSdTv7ulZdpPH0SenfWhYJ6fVGJV6FHWStV7YTJ4/jCT9pCk7BYRSYnM0
+kVHVK1meOI0+03n5I/jQl6MOjoMdaMA43ZPgvIcp0gr+2zhmPYvfJTx6Z1V9O3iSHgc50OmCHACA
+KMXdVazpVdY4QEbf4xznSUovUcZX3gB5VWypRv0OSfkSmrzWDZeUzKb+xy3p32nqzydYHa3sWEp6
+KOPF3/vEux9pA4OYTeAcQJ6Z293+mzNpas+jWj68ndhkFFOCCaL/aa2bUUQNOPcYaf8z8giDc1Pi
+kQeMKME0QQwPCaXvIEKOx8oSVIuO5cFqEU4JIvKKenp0Q/a655+wQsjg+FMSBOcjOuk1XeSjuk5Y
+sSofE48OaZqsdTwrOAfEl48pl43auQTEux7ANyErZ1Eike9Z46DMigORNDg1tWUwwRgTiiJGv5Te
+ew8ZcmZ632T+346m217GHxLOlrrJw5P0kslmo1MFOY4DHCsLjoFzYLV5xLD7RxLxP7CEX657T403
+sbkaNW0M7GkRIa8apR+JOGRxBL/Syo5lRA9ltHhww5QO4hS/t8p1bSpnAJQ2t7r9aK33gCs0rePF
+4cQAh8mKh8jZf7Iouuo7zCNr/j8moy9e/BoP4I+fRz3y3iNv3ZEF/SPyHiH7rGaa4C4iBGFK3sOE
+9DEhCIcgSGsQSonodpczYYUQ5B08QgyFC3NwbiJOLlpV/AgA/2KyPhNW7CwbUUF3CGNr30F0+exu
+FPMv3vyVNcPFux5K1La8QcYpIYxcUdP8QCZxI0dUttk6R9DytHPxNEEO4op7iOGllm2B9wDaIgz6
+lpSUpV32BWXt2L11Zb7fH4pLlLY3uIHQr1kcg8i/08RmhcHyqVyP0q7Y4fx09xymVPeSHm98aWjd
+aG3Hzvof0k5rghsIoePrZdVreNVLAQ6t9BiV5f+QKPozjY6bL2GEsFFFSV8Z1ffibtqz/xggxF+6
+eDwPghz/H4+csY8QwBPvIMPeO8AeEcy6iGJPGL387HVRKIVpluMJK8VIxPJ3hJ+tLIAgjBy4JxSF
+AEewHCyK37O6fGKL4msWx5VfqPXR032RJLu4ggdZq9RYCPynJmZBEEoGzsH3hNHaBKqWhWBMkl6y
+p2bliAn+u9CXo75WPYKWp52LZjobCewQpq9/H2CrZjhezkfZGgfemvuMwtNOwi5SGu3ihk8VeZHL
+8/3+ttwlDTz3nQWJ5FUbsjgC9Dy4IXc4P11gzzkPjPii6dOF6kYrOwaED+OUNyqLtqkYQghZY8Dl
+6iaV8s+0k/62JpyQbQQeoVNu0D+/mX7+t8jxw+svJ13vvUf+OPjxfPiB0/rrUArTPCKNL+qi/JYB
+/ItJcfoHEYIRMqBXsLRggzEhh2DsQGfZgUjTSmodwTkws9m+TJPzl3Kd5fjegzf5dzRtZq0nYQy5
+3D3hkle9lJWJOvKiUfqJKd19fpbzZ7BWmBBMCRpQTr+U4L33U2SMu2cLNnU0eR8J8Q7j/NT3J7zb
+uains7+JCP/XvEAoeA+MAsKYnflc8kvDUHDfJAl/iyX1H+t6Wt55IF7dHrwVNbZnyFlwTslshv49
+kP6d8IC6udRUj7pbcoeeoSTLlPooifnFVaxrUz0PbkTx+rN3V8k7qGTc+iJYOcnuUM7+k6fJ9XkX
+AUz5h97DcXnJEmGMMXp2yF+CIIz914tfE0phmkPE8pLV5RNTqK95HJ1qx5xQSgw4taq1BZuLcEYQ
+o1fU0fSG7KanDzJ4QOiM94lWqzE29mHUTa+f6QWWAKaTe1EirlZ1/PMiGBPjifevZBG2DY/E0Bo3
+KLL8RhTH19q0i95mmGCMEUWS0ssSIQQu985OH5kC/cPhZNuL6MPTlLLwbuczfTS5KVKxd+K5ygJi
+FJ2pwag1DpDVd4XEKO3QLwjl19r4mXLGASf2Vqc9Ne6nwqS4XKryXpyIyjMXg/Urs/Jmbxh9TM5Y
+kuVLM2KpaOSGSB2p3I4xxYdR1K7gBkIIAUJIStyreh0nYTyWX7zphp9QgsDYe4Stf1RfKIVpluMd
+87NNWMHoOKunjTdcQbUIxkT2Otf1bLovkvT0/WLO8Ja0RTYiCGN6ymDfMlmtxkz4YRNLU16ECd/y
+4BE+R5ufJjjuyxHtldP8gMfxx5SRULLSMMsYQcv7vWvl0WRfpuI3I68BADGGP110PdY4AGMeceoe
+pDF/n6b8izaXa1itx2mMDmUkNjK4gRBClFNSZBhkBL7NP+vgt4pM7fe3kr2z/tyNcSAjkob78OUo
+ZuYh4TSXEW1dcAMhhBDUcoAKQgghtsiNL6GUmKKYsries/pCKUy9EE4JYvGVcjK5ITqdhXfMPcJd
+5P2Zd8uD4E1Ep7unZ/mIx/J3qxwjqyezr3jM3ieUVdrUzqvsf1gnbvyMdUTlhx7yCaLtf+AnGJO4
+l+yVWTnywKZMsFY0etxE5xlBK/q9vZOCHNjl9zHDr71Z/qUExbtRHNGUJ+xTsgHjHo1SD7spycUp
+pkW0FYvEZaXKe0nI4tgYRab2+8N09zwNZk1hHkVdunAANZgvn5kRj9gO56S1515AgOr6hHziFJWT
+eII7TR3VF0ph1o9gTEjauV5Os32Rxh8v9DCJMfLe1zYaGLSD6CQXdVF8S51b+oSV434b08r6bbzI
+ZNlIxqKy0phlIowga90DytefRVgVmR735dDKfS0iuTHfd1udZQSt6Pf21NHT/agT/9JHwjs7nff8
+8qwE5R6lvuim/CJlfGP6T9hcjfrHY2Bb+zBxGpRSojIMUcjiaD3vAEpl9gfD9NwlZ97rB4zG4TN0
+TvlMjUQsdxgjrZ7chAAhTImsehknWTjAgTB91wMcl3W00NJLYSi9jHAohRGddE8XxUhIhN40YYUS
+8ulxkCkIVkvE8SWryydWqfssipYS5ABjwRXZ7ajbqTyoYI0BTiwmlLfixpZQSmyOJrKeSYQrwyMx
+BBf6crTNaUbQyv7gpSAHR7rE5NdaLXAOrDaPqHcPkoT/niX8ctsahr6JUcWdwZD/qe1jYE+LRdHl
+fJbf6vRk6KfQUs4BOAO3B9vn7/NlSgdJzH6/jHVtsmyiRjLdgOAGOu7BwTiuZWP0hQMcjNGBd/A9
+YqiW38g6nLoUxp+uFKatQRARxxd1oX5844QVghEKEY5gTZY5YcWqYkzAH4pONZNaXuWLyc1WlKa8
+ABDvNjWL8DwIpSTpxNeLSX6Hx9GHlIVRsm3zphG0POleVbPpgUzk1Yj7HngPoC3CoG9JSVnaZV9Q
+1v4SlJO4PN/f2qAxsKdBKSZFSd+JHXi6YUGvTeAMAHi41Rssp5mu1epe3N2cLMlVmB6pr+KufJ/R
+9gc3EELHEY6awpf+3/9noSdK8B6cyvdlp1v57mST/aYUxvsjD24jSmGsLp9ghP7J4/jEE6g1BpD3
+Pyy7bCAIXgecA5Orfdk9Ob3TliUQSjBhJ49ltEU2opTsEMZrcUEzefZQcNehFff/WDatyicpL7cI
+a3mn0dfQWfktZpQywcM5cgN48N57OB5Ba9m0mJZukM76UURmccw+oZT2NzWrxzsPYPP9wVbcykkw
+y+K9B1/mt7shi6NVrLFjjPC3aVdeW8breefBZNnt7iC8T85qdqT2457cpRsUbFW5hk6HYMbq9z0v
+nMFBMCbOY7KJO2jLtMmlMEzIIbj5E1YIIcgZE0bFBmtFKCWym17Xk+m+6Jxuwoo+errPk+hS1c1E
+nwPjgCI9plS2bjeXUDJwDr4njG7sw71I5SWjzROTqzs8ib6sej3Bar06gpYh+HHYlxfonMakm8I5
+B8yb2/1hEjbc3gBjTEqg77iQxdEa2tixYPQwivlSghsIIVRqe5Sk7OKyXm/TzI7UftKLdsmGBZyd
+g0cIkQtv/sr1W7wHB0IIYXwhNIFcvTaXwhBKCYrmT1jxDvIq1hUEotfdK2fZ30Qc/eFNTXHBOTBZ
+dlOmyfU6BXxNMdlPUrG0m546IYwhl7snXPKql1IpLvgQqBuU0+yvIo1r9f4LVksS/SPl4r2q11El
+q/U45uhh3Ak7zYuSsbwwmxU3+/12NJ3eZFrZsZT0UMbLnRTkTTmiiQifqTOYjNV+Zys61/SapsLY
+P8EYNT/AgRm7AA4eEUpr+c1siqZPhXk+YUVP85s8jT55/jBJKCXeg13VcYPgTWQn/UwXxbfM+ynl
+/MQsCKvVGGv7Q9RJatXjwqpiHEn6SVvTtQnGxHjivfe+rd/jogilJOolfymm6jaX4iPKQ1+OtrPG
+QS8hb1W9jirpUo+7CTqUEQ99Ak4BY0zA00vOwhFl7R+13VYqsw/jlOZyyWOQnXHAGWab+IB+XkdP
+yxu9rWijy+Tq+q2fKsBBCEHImsdI8BDgqLkmlMLwTnLt1Qkr2CMcHmCCKok4vmSVeuId3GfRy/1g
+TJ49pBjntGblAeAcYKd+oLGs1bqWDRO+5cEjvLltOF4Sd6MrOi9/BA//4qEvR6t5Z49YTDb2Z2xL
+Nep3SMrFch/uNoVI5HA2y/7aH8haBeaDxahcj9Ke3OF8+WOQdWkedVL2xbJft828A5hl5nZ/K9rs
+rCiPUF3LOk4X4KCUGFWUNDyAtkIdSmFEHF+0Sj0hAPeZFB96jDvIe4TC2yuoEIuiodMlskV+BxH6
+OUII6Wn2FZf0fcJY7fpbuHx2N4p5+29QqPwQIJ8QGnYhnxOJfM9o+6TMigORRFfDtbmduFcjQulG
+ppDbXI16W2yHsTAG9jyA8I+tcUcsZHw1isr1qNuTO3RF739w9gFrYd+uVXEOIM/M7W4/2sjz8Ysw
+8rO63nCcrgcHQggRso3AIxR20FpvXaUwLIqGoEuk8/wOopiHPi/rBd4vPugJljwTChYbCwynGR+8
+6Je++dseePD/q3w6/m8ecRR1Ol/iGjZps0qNhcB/2oReDIQR5Kx7wHgYZfciLtiQUnpFTfObMo2v
+kRq+T4OzA+cglZ5tYvDKlfn+YCh3w3v6/EQkhlmW/bU/oCGLoyHUVI+6W6sLbpjSQRKT36/itdvI
+GQClza1ufzmjeZvOI1zbhIdTBzgw5R96D8cPqMHGW2YpDHjHjSoMHiCYN5LzJQs+HCPvjgChB29+
+vVPEVfyiT9GLBQQ8QggDni76tQseGiOy+Jcv9M1TEmGMxaKvucQjP//SN34/BONtTMg7Cx33TYdm
+jPJI/qfoxO/UMbgB3gMy+Tc03Yw0SUIpsTmayKjqldQPoZgk/eR6kam/cS7+EPpytIezgHhK2p+h
+9QLvPbgi3x9sx9c2bTLBKoUsjuYos/JmdzveW+XYUWvM/bhDQ9nXArS2Y2Ph27QTtbKRe9ucOsBB
+KEFg7D3Cwg5asJhFS2Go98gqdVuNxwfp22/vvTEqSPGCpSx0QBBaOPqNF33gXsUlZ8H7uLpGTNsI
+Y/SA0uXXvS4D5JN7Imrn1JR5APFuGFc+X5xGnxmln5jS3edSbGzPhjZhLruLCd2YAMcvY2DfDmNg
+l01EYjiZ5PtbQ7Ib7iPqq8jUfn8r2SMrvM5554GCfUqJDO+DN9DKjgHhwzSVG3W/9TreLTule7nO
+EOCgxBTlhMWrWE6wiZ6Xwpi8GMn+4AtvygNXFLd4p7MbHmKCKoFxwIWo5eQCqw0w6ocbl7rNxbse
+SlTNoOtm4JEYWuMGoS9H84HzEDFwhPCN+BlarceC+287nfAgsSpEyKum1I9EFAYG1FExUQf9t9OV
+jx3V2qA4ZRdXeYw2eB7ciGIWMl1eAAghKXGv6nXMc6ZbRE9818Oi9QFB8GY6V2Mi+A5llCKPBEvi
+XZ3ld8C6o6rXFmwucPoIM1rLXXCvJjeZELXMLFklQsnAOfi+6nXUHeOUiFReUbP8AFy4XjcVgEUy
+ohvxEGK1HqcxOux0Nisrbd24pGSW+R/BL1xrG6yBdwBlrm9s/Udn5cENhBACo2+FscGvp3I79jgE
+N04EtR2gghA6Y4ADYfqur3dmStAgYAxQQg4pY8dlJJR+7gGQSOMrRhWPQ5AjqIo3ZoRrmCBhsmwk
+Y7GR6duEMWSMO6x6HU1AMCZJL9kzSn/nTDiPNhG25b1NmBpkSzPqxOhQRmEM7DqQSF61yj6qeh3B
+MecAjIHb/eF6yrKcccAZZusIpDRVMTMPMSWHMgrBjZMAgrNGEdbiTEtjjA48hB204PzAe3Ba36aR
++OUEQhhDTpv/RgghkcQXjSp+AmPDzXmwVuAcEEZ53cqkwDhg2GJCN3OUFcGYgCfEQ9h9XFTUkRc9
+WKeV/rrqtQSnI7DO2l6GZnM16vXwjgjBjbXhnJKZ8j9BOI9WzhkAcHCrN1jf2FFdmkcyZhvT1+e0
+8pkZsYh1ZBQasM4FCGFEZNXLmOdssRfGkNVl2EELzs1k2S2WJFdf/DNCKbHWaP8sfVIk8SVnjbOl
+vl/NKoNNBNYiKtgHVa/jVaY42ueb/iBAxIWQXX06PBJDysifiyy/EYJDzWCNgyii71e9jlUyqrjT
+H7IdtqIxmMF8TMjPS2XuVb2OTWaNHWMEd7u99Y4dBWcfsJYHTs8qn6mRiNkO5ySck14DEEKM41qW
+cCN0xgAHwZggj0nowxGch8mLkYiTkzt5Y/rei2VQTIqh927bqjIEOYK1AGPuYlKvUXomzx5GMfuk
+6nVUDXNxAQAmVa+jaRinJEqjvTLLD5yFkBVXd07fZ3yRkdfN5PJ8f2tLfEFpCG5UgXJKCoUhZHFU
+Qys7ZoweJt3oy3Ue15QOkojWsnl61bKJGolY7jAWghtvVPNOFWevnsE47KAFZ/a8qSieE0FmjF8A
+By/VhzIhhpigbT3L99ezymBTgfeACbg6laeAc0CRHlPKNv7CSwhBzkAIdp4BwZjEvWTPaf3YavvP
+qtcTzMdA/dzG8hTvPGBd3Bi8Fe2ucgxm8GYsFpdVyOJYO63sWEb0MIrXn41pjbnPJantzntVsoka
+yTQENxblPaA6t3A5c4ADM/abB9AgWIRTekzpC01FT8IYcqX+x6t/TBgbUsmu6ll2sNJFBhsNrEWM
+i1qN0LOzyS0u+KdVr6MOjsvYfFn1OppMpvIiwhBrVYa+HDVkjYMkIa3bZXXGAUX6Vncruh7GF1eP
+UkpUiQFCRvbaaGVHMqKVNNT1zgMF9zMNgcWXzCbqZtSVH4XgxmnUOwZw5gAHIQQhax4vczFB+4Fz
+AM58R6V47Yn9uAwKiZPKoAilhMbySjmd3vAhjShYAa/NfUJZbQIcVhVjGdFLdcooqRogHsaVnxMX
+fMgF/XM5zf4a/i1rxupHjLVrl9VqPY6E+3unJ9babyB4PRaJyyqzd6texyZQuR7FKd+palqQ1gZF
+Kd34MtcXzY7UftKN9kLQ53Qw8j/XOUR99gAHpcRZW4YHzOA0TJHvv9pUdK5n42JPQjAmIk2um+nk
+INyYB8vmwf57XvnUuoFzgJ36gfJQmvIiIsSnPnz0z41QSqJe8pcyL++4MJK7NhjSD0mLBiXpUo07
+MTqME3656rUEL6OUktyR/3AunFBXSeV61O3JHc6r6znjjL1LWfvHTi9qMlb7ST/aJaTOj+r15ABh
+VON/tfNNsCVkG4XzYbCgMs++EnF6bdG01BfHxc7DO509M5sd+HBhDpbEGgNciLerXsdzUMzuCsnD
+OLdXEYKcdWFc+ZLE3egKaPOT1Sb0NqkYOAex9KwtJRy2VKNBl+IwBra+hJQXiszcqnodbaWy8qtu
+T+7QCqcFOeNAEMCkJeeV83r6RB10t6Ld8O9xRh7VOsJxrgAHpvxD72veRjWoBZ2rh0zI90+zK/7q
+uNh5eCfd00X2FYTdx2AZrHmEGa1FarhVasyY/10oTfktwhgyFsK48iUSqbyEsN82efHawHKwWmDs
+ERekFUFNW6ivej22w0IGWq1RikkJ9J2QxbF8Rab2u1vx5SqDGwghZLQ9kgn/vMo11IF3ANNJeTDY
+jk+e4hgsxIPPaxzfOF+Ag1CCwNjQfTl4rWdNRfPXNhWd55VxsfOIJPnMqOIxmBDkCM7HW/sA0/Ml
+ty0DeA/I5N8wId6tei11RDAm4AnxYcThUnHBhyyS/zv05agOheIHQqo/B52XK/P9wRa/zCp+sAsW
+I2N5IQ9ZHEtVZGq/P0x369DfwVnzDW1R2dtZOAcwy8ztbj/arXotTYcJdnXOfjlngIMSp+1kWYsJ
+2ue4qagdvamp6DwnjYudRyTxRVPqn5w2D89yrCAA54AyLuoQ1Yd8ck9E4lrV66g1IsK48hUgFD/r
+y6G+ciFovFbgPEQMOdzgmnDvPdg8u9EfRLttHHPbVhhjooG+4yyEz/wSFBN1MBimtSiBMMZBEtG3
+6nBvUxVnAJQyt0JwYzOce4vAEx862QdzmSLf52ly9o7pc8bFziMScQmcTWypQx15cGpg9BERtPLU
+cGsMMOK3w8PB62EuLgBACLKvSNyNPwNrJib05VgbsBaJGF+seh1n5ZwD4srbw7eT66FxX/NESfTe
+bGZCZvY5eAeglTnY+o9ObUognDb3uWjXVKbTMMaCMvYg7URhgtMSeLdAan3Fzp8Diem7i5QQBJvn
+eVPR87zG68bFzsOkGHrvtq0qw015cCremBGuQWq4LyY3mRS1GVNbV4QQ5AyEz/kKiUS+hzHaLrPi
+IExNWz3s1D1CmjnlwGo9llTf7fZl2CFtMEDs45DFcTbOARgDt3uDuF6fAeue0A3dMNHKjp3D36ep
+DBmxSwIIIcFQVPU6Xufcd/KM0YEHCJ3sg5ecpanoXK8ZFzsPE2KIMf5Az7KDcx8/2AjgHGCKcNUN
+PU2WjWQsrle5hqY4bkTsy6rX0XZcsKGI5RU9y29AaEK4MuA9CGKyJmZu6VKP0xgdJmn0ZdVrCc5H
+JHIYsjhOzxkL4OBWb1CvEghTOohT+nHV66iCVnYMCB9GMQsTnJYJECIUi6qX8Trn36pkDFldhk72
+wS/O1VT0BIuMiz3x73GHmTdNAAAgAElEQVRKqORXQpAjWARYi5iUlaaGg3HAsNZk0zuBnQIg3g0P
+3av3vC+HUfq70JdjNcACiiL6ftXrOC1bqlEvRYcyjIFtDSD8Yxs+5wvTxo4xJn/v9upXAmHK8i5j
+zcwKOw+V27HHIbixCoBgGRGElTr38o5LCDAJfTgChM7fVPQki46Lnfd3aSyvqKeTGyG9Ongd0OYe
+JrTSmwBTTPaZFJ9WuYamIUJ8isJHe22ijrzowToT+hwtn9P3GSfvVL2M07C5GvV6bEfIENxoExGJ
+4Wxi/x7um95MKzuWjB4mHXG56rW8yjkPjIDbtH44KjdjTPGhjEJwYyUa0JliOfEXjC+EG8wAoSU0
+FZ1nwXGxJyEYE9lLr5vp5CAE4oKTgPeAsM+qLE8xefYwiukndWlK1hSYMOSsC2WSa8QjMSSUfBD6
+ciwXA/Vzk8pTXJnf7A/ZThgD21Ii2jOlXWiK3abSyo5lRA9lXM8Anyn1UZzwq1WvY53ymRlRQXEI
+bqwOIIQ4p7XejFtKgAMzdgHAh072G67Msq9Ecr6movOcZlzsPLzT2TOz2YEP6ezBK8BaxAWvLDUc
+nAOK9JjS5ZR1bRLMCDIWQpnkmjFOiUjlFTXLD0KJ0PlZ4yBJyFtVr2NRLs/3+wO5R2kIbrQVl5TM
+Mv9jCGKeTCs7ihKa1bk0y5dmtEkVr/nMjHjEdjgP56WV2pQMDkII8kaHHbQNpvPiIZPy/ZXtgJ9y
+XOw8vJPu6Tz/DmyoLQ1+5Y25jxmtLDXc5bO7XPBaR8PrimBMwBPiIdyErxvBmCS9ZM+W+jur7cOq
+19NoVj9irP5jHL3zgG1xMHgr2iUVN2QOVo9E8qpRIYvjVSrXozjlO0Lwd6teyzzGOIgSOtyUrNB8
+pkYiZjuckxDcWDHvAdX9bbWcAAelxFkbOtlvqOOmonRpTUVPcpZxsfOINL5oVPEYQgOt4Bnv7M9V
+Nfa0qhgLgf9U9fSWRiPiQthkrI5M5UXkXaKV/rrqtTSVwOoBqflOqzMOKNK3uv1od1MemjYd55TM
+cv8jhBPsL9RUj7o9WfssAVOYR1zUP2i6DNlEjUQsdxgLwY118IBq//y0tB6oHuNOSP3fPKtoKjrX
+GcbFziOS+KIp9U+21N8t5QWDxgLjgAtRSWo4OAfYqR8oD6Up54G5uAAAoUyyQjwSQ8rIn4ssvxGy
+aU4HnAMpsKhz0MBqPU4i932nJ2o3JSJYLRbJq2URxsYihFA503e6W3KHNqDvDPHuR9qgnj5nNZuo
+m1FXfhSCG+tDiHtQ36vVsaUFOAgTn3rfgKKcYKlW1lT0BGcdFzuPSMQlD+4tG6YBbDRw+ggzWsku
+B2Sze0LyL6o4dpsQQpA1EMokK8Y4JUknvl5m+YGzUPsdnroAY4+4ILU9DxilHnbiMAZ2U1FOSaEw
+wIYHLotM7XeH0RdNCG6Y0kGc4veqXseqzY7UftKN9mjIgF0rBwijmv+LLy/AQQkCY0OEd4Ossqno
+Sc4zLnYeJsUQe7dtlAqp1RvKGzPCdP0Dva1WYyb8MJSmnN9xmaRXVa8jOBb3kj2n9WOr7T+rXksT
+cK9GhKz/HLQIm6tRv886IgQ3NhqT4nKpNjeLo8jUfn+YNqbvjCnLu4yxC1WvY5UmY7Wf9KPdTRuB
+Wxd1j3AsMcBBidM2pAhvCJMXo5U2FZ3nHONi5yFCDAkmf9az7GCpLxzUHjgHlHG27tRw8B5QmX/D
+hKhtg7LGobwbpnnUh0zlRYQhNrm6U/Va6gycB0E9xjW8STeF+iqMgQ0QepbFUWKAJfRBaxo1LW8M
+hukuqXEJ2Yuc88AIuDY/+D99og66W1FjfiZtg73Pax7fWF6A4/jVsFxGE8ig3qzSY0IpXmVT0XmW
+MS72JIRTQiW/EoIcmwWsRUTQtaeGQz65JyKxtuynjUDFp2izM6hrhws+ZBH7vJxmfw33BicDa5GI
+8cWq1/Eql+f7W0N+OYyBDZ5jkbis1OZkajsHoJU5GLydXq9zf5xXmVIfxQm/WvU6VsE7gOmkPBhs
+x6HRcYU8wq7u//hLDXB4jP+47N31oF7AOQBwP6ylqehJljQu9iSEUkJjeaWcTm6Eue+bAYy5i9ec
+Gm6NAUZQRDag+dc6YcKQsy704agZQimJeslfyry848J47t+gTt0llPSrXsdz3ntwZXajvx3GwAYv
+o5SSQhPhNiBTzhkAZ+B2bxDvVr2W0/KlGVU0FG6lnAOYZeZ2tx817mfSOuBx3QNMS72zZ4wOPIRG
+b21m8+KmSOIvqzr+MsfFznt9kabXzXRyEHYc2w28B0zArbvMyheTm0yGevZlw4wgY+Gw6nUEJ4u7
+0RXQ5iejTWjq/Ax4D5wZXZdAgnMOiCtvbw2T621Obw/Ojkv5YZGZW1WvY5WcsYCQP+gNmvcgbYyD
+KKHDuj98npYzAEqZWyG4UT3vABDBtX8+Wu7WJWMItHmy1NcMakNn+R2eJterXscyx8XOwzudPTPL
+9r0LkwDaCqxFXMi1poabLBvJWFT/GWohgjFxQEUYUVpfIpWXMPbbJi+WNg2rycBaFEX0/arXgdDx
+GNiIuL93+zI8QARzUYqJAvpOW7M4tLFjyuj3aVc2soTUFOYRF6SSqXCrYowFZexB2onCiOoaAISQ
+YCiqeh1vstQAB8GYgPc+7Hy3j8mLEZXiT3WY+LDscbHz8E5yTef5Ywhp1a3ktbmPCV1bajgYBwxr
+TdqYO1oTmPKdMK683o77csj/XUyyGxvfFNaa+5SSyicd6FKP0xgdxh1+ueq1BPUXxfJC3sIsDq3s
+WDJ6GMUNzrD09h+0ReWvWtmxtf7vadrMgFMrAUKEYlH1Mt5k+cXnGF8Ijd7apcqmoidZxbjYeUQa
+XzSq+AlMCHK0jffuCV7jjYApJvtMik/XdbxNhLm4AM4vvQlxsFyEYpL0k+u6UF+5DT63Cq9+rroX
+jy3VqN9BmQxjYIMFYYyJblkWh1Z2LCN6KBsc3DClgzQlv696HcuilR0DwodxIkLgtUYAwSqiB0u3
+9CVixi4A+DAutiWOm4pCdU1F51nBuNh5RBJfMlpNbKlD7XhLWGOAC769ruOZPH8YSfpJ2+pi64YQ
+gqyFx1WvI1hM3I0/A2smm9iXwx7Xyr9V6RpyNer12A4XPIyrDk4lSqL3ZlNzo+p1LIPK9ShOGW56
+kM+U6h5jrPKMsGV4HtyIYtbon0krNSRJdukBDkII8kaHRqMtYbN8XyRRZU1F51nVuNh5RBy9573b
+DkGOljDmEWZ0LXWq4BxQXz6mvB4ZUG1GKCXgoKx6HcHiRCLfwxhtl1lxsFHTq6x+xFh1tfKuzPcH
+Q/4RY2EMbHA2gNjHzja7T5nK9Sjtyh3e8Ouzcx4Y8kUbmgOr3I49DsGNugKEEKP0varX8SbLD3BQ
+Spy14QazBXSW3+GdtJ51byscFzv3kEIMsXfbJi/urPO4wfKBsw/WNR7W5bO7XPIv1nKwAHkiOhvf
+26FhuGBDEcsrapYfbMrPTmD1gFTQjsd7DzafHfQH0W7V5TFBs4lEDqdH+u9Vr+Os1FSPuj25w3nz
+g3ym1EdRytbaNH0V8pkZEU4yGYXgRm0BQpig2ow2n2cld/ge447fkJuUtqpTU9GTrHpc7NzjCjEk
+nH6uZ9nBOo8bLA84B4zT7jrKRaxSYyFwbT9HrUTFp6EPVPMQiknSS/aM0t+1vS8HOAdSYLHukrXn
+Y2CHb6e7bdjpDarnubhkG/h5LbPyZm8od2hLMph8aUaUkdo/dL5OPjMjHrEdIWgomasx7wE1odp6
+JQEOwsSnoZN9c9WtqehcaxgXexJCKaGSX1HTEORoIjD6iHC+8maf4Bx4k38XSlPWCxOGjHX3ql5H
+cDZRR170YJ1pcTkgGHvEBVlrVpfVesyRvRXGwAbLJCIxzDLbqPNtkan97la8R2g7ghvOOJARSUkT
+njrnyGdqJGK2wzlpxc+kzZqyf7SaAAclCGyzTnjBsdo2FT3BusbFnnhsSolMo111dLQfxiI3izdm
+tI7yFMhm96JYXF35gYKXYEaQszCreh3B2fFIDAklH5RZceChKbdTi+NejciaSuQQOg5upDE67PTE
+3toOGmwMT6NrWpl/Vr2ORRSZ2u8P013SoqxKXZpHPKKNndCWTdRIxHKHsRDcaAKC3ddNCKWtKMBB
+iSttmKTSQDYvbtaxqehJ1jkudh7Z7eyZ2ewgBDmaAZwDTBFedcmI1WrMhB+G0pT1IxgTB5S38cF4
+kzBOiUjlFZXlB01vZPgicB4E9RivqUTEKPWwE6PDpk+ICOqLS0pmmf+xzk2CvQNQWXljMEx3m5zp
+cBLv7D9YQ/vpzCbqpuyE4EaTOEAYNeDdtrotBIJleOhrFj3N7vA0uV71Ok5ljeNi5+GddE9n+R2w
+zatD3TRgLWJSrr4RVzn7lgkR6kgrgpnYCWWSzUfwcV8Op/Vjq+3DqtezDGAtEjFeSzNAm6tRv886
+IgQ3ghUjQl41yq5tst1pOAdgDNwebKfX2zaq3ZQO4pj8oep1nMXsSO0n3WiP0RDcaJomRDhWFuDw
+GP+xxsHc4BUmL0Y0lo1rhrjucbHziDS+YlTxOAQ56g2MuYsJXWkjLjPNRiKKQip4hTDjF8D5ys8L
+wXLIVF5E3iValV9XvZbzok7dJXT1zQCNKu70h2wnjIEN1oFLSma5/xFqduPvDAA4uNUbRK3sPWON
+uc8FfafqdZzWZKz2k34Umh03kHdINyC+sboAB2N04J37flWvHyxPY5qKnqSCcbHziCS+aFTxExgb
+ghw1BN4Dxl6vMohnjQHOLA7jF6tFCEHWwuOq1xEsD4/EkAv65yLLbzS1/Ai8B8mMW3X9v8vz/a0t
+8QVtSRPFoBlIJK/aGmVxWGPHCPmDbq+dGw7eeaBgn9KGbUw+faIOultR60qFNgUmqGzCD251JSqM
+IdDmycpeP1iKJjUVPUlV42LnEUl8yVnjbIsnADQVWIuY4O+v8hi+mNxkMqSDV41QSsBBWfU6guUi
+lJKkE18vs/zANTBbDqxFIqIXVvX63nnAurgxeCtqVRPFoBk4p2RWoH9DDQKQ2tgxY/Qw7cprVa9l
+VbQ2KErZWsrdlsE7gMlReWOwHe+2rVRo0zTh57eyAAfBmIAHX5cHz+BkpigOmtJUdK6KxsXOw6QY
+eu+2rSpDkKNGvDb3MV3dw4XJs4cyFs3qYdNinogOuHD9aaO4l+yBNj9ZbZp1jrXmPqVkJecgZxxQ
+pG91t6LW9RkImoNJcblUptIpilrZsWT0MIrbvdkARt+ibPXlbsvgHMAsM7d7gyjcIwVrsdo5ZZhc
+aMzA3A1UzrJ9kSSNT92rclzsPEyIISZoW8/y/arXEhzzYP9NKF3JjT8YBwwdl3qt4vWDM6Di05qV
+gwdLJFJ5CWG/bXJ1p+q1LEpi9WQV5WtW63Ek3N/DGNigapRTUpQYoKLNTZXZhzKih7LlwQ1nHHCG
+WRPKPJwByDNzu9tvZx+UTeIdAKWIVb2ORaw0wIEZuwDgw7jYGjJ5MRKRvNS0pqInqcO42JMQxoZU
+sqt6lh1UvZZNB8YBF+LtVb2+KSb7TIrGzqFvI0wYstZVupMYrBYXfMgi9nk5zf5a92xRaxzIiG4v
++3V1qcdpjA7jhF9e9msHwVmwSFxWyq793KtyPUp7vLMJI5F1aR7JmH1R9TrexBkApc2tENxoBwCE
+GMNJ1etYxEoDHIQQ5I0OjUZrxio9xpymuIlNReepwbjYkxBKCY3llXI6vVG3AMwmAVs+wox+uIrX
+tqoYR5J+EtLC64VySpyFWdXrCFaLUEqiXvKXMi/v1LkvB5jyEedkqecgW6rRoIvxJjzQBc1BKSVq
+zVkcKtejbk/ucL4ZjXXB2Qes5s3MtbZjbd3f0047m7xuIkDQhAEqCKFVBzgoJc7a0OitRsA5QAge
+Mi7erXoty1SXcbEnIRgTkSbXzXRyUPddxrby1j7EdPmnO3AOsFM/UN6iYGGLOKC8qRM3gtOJu9EV
+0OYnU9O+HAKVD/ASn0dsrka9Htth4dwT1BCLosv5zNxax7HU9Di4QTdkJLIpHSQx+X3V63gdrewY
+AB/GiQiZZW0CaNXNLZZm5cv0GHd8aPRWG6YoDlgUte+EU6NxsfPwTmfPzGYH4fOwXuAcUMbZKjIs
+XD67KySvfZropsJM7Hhfv8yuYDVEKi9hjLbLrKhVWaA1DpIYd5d1DnJlvj8Y8o/YhjzQBc1DKSYK
+6Dtuxfc7ZVbe7G5HH21KcAMhhKwx97mg71S9jnm0smNA+DCKWcgsaxlACDFK36t6HYtYeYCDMPFp
+uMGsh7Y0FT1J3cbFzsM76Z4usq+gxqnUbQNGHxFBlx6EsEqNhcB/akMfm7bCjF8A52uZ2RWsBhds
+KGJ5pZhkN2ozRcfZI8bJuXv0eO/B5tmN/iDaXUWz0iBYpiiWF/JsdVkcRab2u1vxHt2ga7B3HijY
+p3X9nlVuxx6H4EZrAUKYoEZM7ll9gIMSBHb9zYaCl7WpqehcNRsXO49Iks+MKh6DCUGOdQBtf8Bk
+uac68B6Qyb8JpSn1RghB1sLjqtcRrBehmCT95Louy69cDc6z3KsROec5yDkHxJW3h28n1wkJ/X6C
++sMYE72iLI5iog76w3SXtPme9gRaGxSl7GLV6zhJPjMjTMmhjEJwo628B9SUdnNrCHBQ4kobJqlU
+SLexqegJ6jgudh6RxBdNqX9y2jysei1tBs4BZt4tO7AH08k9EYlry3zNYPkIpQQclKHB72aK0+gz
+sGZSZV8OcB6E8ByfIyhhtR5Lqu92+zJMIggaRcbywmxmby7r9bwDKHN9Y+s/OrtNGJG6bGD0LcpI
+7XbQ85kZ8YjtyIiG4EaLNelOaj2tQgiWdS8daCuwDkgLm4qepK7jYucRibgEzia21LVsitcGAIC4
+kEvd7bBajZnww5Ai3gyeiI4Pl5+NJRL5HiH4gzIrDqq4NoC1SAj8wVn//vMxsEkafbnMdQXBOmCM
+CXh6yVk4dyaVcwDGwO3+MLm+jLU1jTMOOMOsboGdfKZGImY7nJNWb6IGCBHsvq7Xu2++tQQ4PMZ/
+bMgzZ+sY1dKmovPUdFzsPEyKofdu26oyBDlWwGtzHxO61N0Or7L/YaL9AcPWoNGn4fqz2RinRKTy
+iprlB+vuy0Gdukvo2XZcbalGvRQdhjGwQZOJRA5nM3OuUnVnAMDBrd4g2tgsJqPtkYxZrZqaZxM1
+ErHcYSwENzaBA4SbMid2LQEOxujAO/f9Oo4V/KrNTUXnqfO42HmYEEOM8Qd6ltWq838beO+e4CVm
+WpgsG8lYbOTuUVNhQpC1LvSB2nAEY5L0kj2j9Hfr6ssB3oNkxp2lT8DzMbBChuBG0HxA+Mf2jJ87
+bewYI7jb7UUbdT/7KmfNN6xGmaPTI3VHdkJwY9M0JcKxnhIVxhBo82QtxwoQQhvSVPQkDRgXexLC
+KaGSXwlBjuWxxgAX/P2lvh6xmFC6WZ+phqOcEmdhVvU6gnqIOvKiB+vMGkoDwVokInrhtH/PlfnN
+/pDthDGwQVuISAyz7PQDB7SyY8HoYdLd7BItUzpIIvpW1et4bnak9tNe9AWjIbixUTxCDYlvrCfA
+QTAm4ME3pTdC021KU9GTNGVc7EkIpYTG8op6OrkRPitLYMwjzJY3K94Xk5ss7KY2kgPKPYTPVHCM
+R2JIKPmgyPIbK31fWHOfUnKqAIfL8/3+QO5RGoIbQbucNotDKzuWET2M4nDdtcbc55J8WPU6EEJo
+Mlb7ST/aDdOcNtK0KT/09WRwIIQQJhdQg3ojNBVYBwRvRlPRuRoyLvYkBGMie+l1M50cNDFIUyfg
+7INlZVuYPHsoYv7nZbxWUAEu/+h9M88JwWowTkmURntllh8sowHiSSRWTxZtRuydB6yLG4O3oo0b
+fRlsBhGJ4WTivllkA0crO5IRDf1n0LNzg3NPaA3OC0+fqIPuVrSRE2yCY7ghP/u1BTgwYxcAfBgX
+u0LgPRhVHDC5QU1FT9CkcbHz8E5nz8xmB37NDfHaAowDLsRS0jnBOaBIjyndvIyotiCUDZxtVm+e
+YPUIxiTuJXtO68dW26WO7LbGgYzo9iJf64wDivSt7lZ0vSk3j0FwFkTIq6a0rz0Xq1yP4pTvhODG
+Ma0NilP6cZVr8A7g6GlxY7Ad74ZzVNAEawtwEEKQNzo0Gl0hk+W3Nq2p6EmaNi52Ht5J93Sefwd2
+PQ3x2gScPsKMLiWd02STfS7Fp8t4raAahBDkjFvqA2zQHjKVF5F3iVbl18t6TTDlI87fnFJutR4n
+kfu+0xMbf+0O2o9LSmaZ/xHm3J+pXI+6PbnDeSjRes4Ze5exs01iWgbvAGaZud3f2szxvMEx7wCa
+lLmzvgAHpcQZUOs63qbZ2Kai8zRsXOw8Io0vGlU8hjV1/W8Lb8wIL+GjYFUxjiT9JOxYNBuhlIDH
+rulBz2B1eCSGXNA/L6svh0DlgzeVpxilHnbiMAY22Cwkklet+m0Wh8rKr7o9uUNDc91fOOdBEMBV
+9btwz4Ib3f7mjucNjgFCiAvUrXodi1pfDw6EkCe+G1Lul2+Tm4rO08RxsfOIJL5oSv2TXUPX/zYA
+54Awys8b7APnADv1A+Xhc9UGgMS2D5ef4DUIpSTpxNfLLP9vd47MOWscJAl5bYmczdWo32cdEYIb
+wYbhnJKZ8j/BC4HEIlP73a34cghuvMyU+kgm/PMqju0MgFLmVghuBAghhKAxA1QQQmsOcBDKPg2N
+3pYLrAOK0OFGNxU9SUPHxc4jEnHJg9sOQY43A2sRFeyD876Oy2d3heRfLGNNQfUwlx+GBI5gEXEv
++RK0+clqc6bzrXf2iLH55SmmUF+FMbDBJmNCfl4qcw+h4+BGf5ju1qGJZt2AMd9UMZleazvWxt1N
+O1EonQsQQggBgjVHDc7OOYD1BjgYQ2BPPwc7OBl4D65Ut2kkwg7QK5o8LnYeJsUQe7dtlFpanXgb
+gTF3MaHnqle1So05R78LJV/tgQlB1rpw/QkWIlJ5CWG/bfLi1A2ruVejeacOV+b7W1v8chgDG7SV
+9x6ce/7LHf8yDszzX6UDAIeOJs7PxvnNwTANUzlOYIyDOKJvrbtEVis7BsCHcSq+XOdxg3oDQIgQ
+PKx6HYs4elrus3UekFBKTKlmLIrWedjWMll2S6RpSB2b59m4WEwaEnJcABFiiIwb6Fl2IDrhZ/8q
+8B4wAXeewAR4D8jk37A0Cg21WoRySuzUT2S4/AQL4oIPgZJBOc3+KtL4+iLnFXAOYuE5fqVm3nsP
+SBc3+4PoelX19MFm889SqI/bkz3Lpn7xt18SrB16nmx9vEPkH1FMfgbv8S9/+GzriHIyPf6zF7Kz
+MUEUI8YFTRCmx3+EEEIEeexxRJ4137VTpVVutdH2qZB8a6nfbAs4be7HCVnrBqZWdgwIH0YxCxun
+wcsAIUrJO1Uv402mR2qUJPKTtQY4EEIIecI9gA87o+dj8mIk4jCu6XWej4sljLUqCk04JYigKyHI
+8VtgLWJcXDjXa+STeyIS15a1pqA+ABEZrj/BaRBKSdRL/lJM1W0uxUeUvz47DCwgmZCXauadc8C8
+ud0dxn9Z7WqDJno58IAQQjA38IDQcSzheWoqxfjrlwIPz36nDE0RJgh5QN4jjDHyCBOEsceRYF2E
+CEIY/1pTT5CnhLyPCO6/eFf57L8vIIQvPP9i/ML/iH/5z9Pdi6pc/dwbxqY7SP7vo58nN5yBP8Qd
+GUqtX2TdE0rF2q5VKrdjTPFhFIXgRvBb3gPCuN4bxkVhx5QwzDgZrD3A4Qn+o/e+UY1K6kYrPaac
+7eAqCvMahFBKdJlr5iPftkAQoZSgmFwpp5MbotO91rbv76y8NvdJfPaSLasNMOK33zT9IGgoLv/o
+vQnXn+DU4m50Reflj+DhX1zwuf01qFN3McW/9O6xWo8j4X5I0tCor4m89/BS4OHZby//0a+BB4Se
+Jzjg+wwjBd7jFwMPGGNNGC7Rq/3oMEFCIEkwlQjTlwIPBKFtzOg7JwQeEEL4v45/W07gYR2c82BK
+93/6g+RjyinpDDqf6FI/nE7M426Pt2pD6qxM6SBO8XvrOl4+MyPKKZYRDcGN4ER1b2HmHIAp7Cjp
+HfeNWXuAgzE6AAePCKXn2mXdVM+bilIeOq8v5Nm4WExp1StZOoIxEWl63Uwn+7zT3Q270gh5sP/G
+NLp45r+vJjdZJ+yythWhbOBsGa4/wZmIRL5ntH1SZsWBSKKrrz48gvcQMeMIkRghhHSpx90EHcoo
+Cg9tS3bWcgtA/ohj8mAZ5RYIIUQZvYzQiwGH5/+NP/r1i5/99uyLMKpn4GFdyqy8xwRDlOM+QgiJ
+iA+ddf+Skr2fTfUNEZE9zmm9t4pXzJTl3aTH1tLkPJ+ZEY/YDuck9AUK5vLg7mO83pKp05g8LW91
+er9uJKy/RIUx5JV6iAQPN5in9LypKA99Nxb2fFxsmx9oeKezZ2bZTZ6mn2BKztVcs8msMcCFePus
+f99k2UjGIvTdaDFCCHLKPeQyXH+Cs+GCDSmlV9Q0vynT+NqL2V5gLZIRvYgQQrZUo36HpFxs3mbE
+b7IeXo4//Cbr4cVyC4QQejXrwROUM0rcq4EHhBCKJO2dstxigBAeLLPcIlhcWeixiNkAWzgkL2zK
+xJ3oUva0+FvSj6/pwt5TeflulMiN7MvhnAdGwK2jV08+UyMRyx3GQnAjeAOMyrqmv06P1ChO5KUX
+z91rD3AQjInx4L33rSsbWLXQVPQMGENOFf9gLQ+o8U5yTWf5iMcxIux8E0Qay5pH+DWp468DxgHD
+FhPKwzmpxQilxHnswvUnOA9CMUn6yfUiU3/jXPzhl74c1twnCfnI5mrU26rfGNh5WQ+vVmAs2mRy
+0XILhH7bZPLVT9+zrIcTyy2e//3wmW027zwg57/BDH0sUv6b8ot0EH82+Tnb725Fu86Qo3xafJV0
+5X9VsdYqmVIfpc4qJEoAACAASURBVAm/uurjZBM1kmkIbgSLwzWMcLzYd+PFP19/BgdCCGG8hQAQ
+amHZwKocNxVNQlPRUyIYE3g2LrbtJRwijS/qvPiWyxiRNzTCayNv7QMcyzMFskxxtJ92wtSUTQBI
+bHvwCIcWRsE5xWn0mVH6iSndfS7FhxKrJ966g/5QXDrNGNizNpk8sdzi2e9vbDL5YuABoeOsh7nl
+Fic0mXwh8HD8/4Z7k+D1iqy8192KruUTdTNO+ImNvLuD5Go2yW91+vFuzNJ+/jT/q4zpNbpBJSu+
+NCOaipVuZk6P1J24K//EaAhuBAvyCNUtvuEcQJnb7zr93/a4qiTAgRn/EMBPKEUb9xB2FjpXz5qK
+tvsBfWVaOC52HpHEl3ShfqTA/8WkOFM2QxOBc0AZF2e5yTZ59jCK2SerWFdQP5jLD70vql5G0BI8
+EkNr3GD276f7PTr18aB71WqHDYLRSU0mEUE5fbXcAiGEMHlWboHQKZpMHpdbINSoJpPB5imVHccd
+MXTOeyH5W/Pel5hiEqfRlTzTd5JUfNkZdv6ST4s7xpoPorj9o2SNcRAldLjKz+3sSO2nvWg3jKsO
+TmlatzfM5Gl5K+2d3MC7kgAHIQR5Y+4j3q7xnasA1gElJDQVPYe2joudR8TRe1brJ7bU9zclyAFG
+HzFBT92QC5wDivSY0jCeblNgQpC19t7z3eogODdnHvX5JP+/Pti6yCNOQpPJIPiVdx6Qdd+Irrie
+T4qHcUe+9r6EckqYgz+WytyXEf8w6cZf6tI8LDL9rzjlZ24i3gSmMI/iLlnZfdtkrPY7W9EuCeef
+4AzqdN3KpuUoSuSlee/lSra0CaXEGVdWcewmed5UlEZnH3sZHL/frDXa+7oPOVoeJsQQe7dt8uJO
+1WtZB2/M6CwZOpDNbnHBP13BkoKaopwSq9Gk6nUEzWeNAa6P/jpMVPL+77c+dM4/ZIxiSimmlBz/
+Ise/CCGYYIwJPlb12oNgXVRe3ov78hpCCHmPfqQLZCOLiA+985HR9gghhITk70ad+KPZWO8792r6
+U3sQ7xb69zmLENwI2qIs7Bh5jF83+aeynH1PfNc72JgHzrMwWXaLJcnKGw1thGfjYjcJEWJIOP1c
+z7KDqteySuAcYIrwaXusWFWMucSX2t6bJfgtQER6CNef4GzAeYBi9tV2rH7aGoq/SOa/lSl714P3
+sEGB9CB4E1NakLHYpoRgU1qQ0W+bi84TdaL3SuUeu2fnakrJ/8/enTa3cWT5wj+51gYQXNx235bt
+vjPXknXb0p2IUduS5S/zvHi+qi1K1tUTo6btpiVHzNi02jFqGyIIVFVuJ58XIGWK4oKlgKoC8hcx
+MdEUBaQhbHUyz/+Q7jvZ3VLhI61Mf3GrrodRDpOMTPz4TOPwlfqqG4obwYy8Q2zKc8c7xCK330fp
+5Zv/tRU4KOO3/OoWYecWQkWrdTIutu51LBtljLJIfFoerW6RA60FHkVTHVtF55C48gcmeAjYWkci
++tdwHRrMwpblQZcNnry7Q25HMb9mlOpv9ORfCCEEKLnmQ90sCF6z2jyIEn4NAKBU9gmXdKog8E4v
++Xj0Sj08OYFLCCHdjeQeIfJlMTL7i1hzXYxSTzjnlU788w7xaKAe9rbi++F6IpgVAoCQ0K17HQAA
+g0P1KN2Irtz8r6/AwTmgtXt13X+T6bzsUylCqGiVOAen9H/VvYw6UMZolMV3y8PD3VXctUZt9gid
+bmoMFsMnMhJTZ3YEq4Eyvuns+hU8g9lZ41Dowy/f7ZlO1pF/pccnvwTFb4UcF0o559ecdeF5FQQA
+UAzVftZL7gMAOOeRATo6w4nJjZ3s3nBQ7J7+WZSKG3Eav3c0MI/9CrSsOOeRU3RVBn86hzgcma+7
+50yYCIKpYDMGqIyO1L5MLs7dOK3GExyMOmOGdd1/U6Ex41BRHnaWq0QJoXA8LrbutdQl6nbumeHw
+4So9Bug9AvGjadpMbFn2Ofd/DK0p64tSCs64g7rXETQfOo9YDp/uJKPnW9vyC37q1JfJ1UFvK3k9
+XppyClrZ8LwK1p5RDqOIk5M8CaPMYZxdvet6kTRL7uYj/UamGBNss7uV3slzu2uMa3WRwyh9GCfV
+Bag6g1iW5lEobgRVQMAaKwZjk+RunFbvcj0Vq3SxNS/0Hp3WIVR0UY7Hxa4z0cnu6VH+GK07rHst
+VUBrQUjx4cS/7z2Cyb/jUoapKWuMMkbRE7dOwcPB9JxS/YwOHr27RW5H8ZuTzLzz2MnIL6cDARkj
+1Dvvw/MqWHda690o/f01Y5XZZ2z2Sw4mGOWc/asqzLPTP6eEkO5Wdt97/rzMVWtzObwy+5yTqU6i
+XkRr2y+NfZh14ntV3F4QAAJQSrbrunvvEPPcfndV7sZptRY4PCWhD/qUECq6WCfjYuteR91klnxq
+yuKXVShyeGOeEc7+NOnvYz7Yk7H8fJFrCtoBQe6EvITgPNY4ZPrwyz9saNLtynv0nHZRNGov6ci3
+29wouRb2bYJ1VuRqv9tLXn/OGuNQxnJ73gwIGYttj79PVjktTsUNGSfkaKCeznMfdTDGYRTTrIqM
+DF3aPiJ5mWVR+J4TVAYBgDE68Xftqg0O1ZNsY7rndK0FDs7Z5joGP55H5aOnIVR0sdZxXOxFZJp8
+bMriH2je/qLQJt7ZXyljE71mrDHIKcTnXawE64eI6Hp4KwhOQ/97O8r2lrjPLwghdsZhpyPIeXkC
+IYcjWGfWOJTi99YUAABT6BciYteruP2zk1VO45Jvdjez2/lAf+la1LJiCvNCxmzucfW6tH0E8jJO
+eDgFHlSrxlfTcKAOZBJ9NO0Ul3pbVCgFr/Xa96vqvDzgMvowhIouwRqOi72ITJObzhpnlX529W83
+DxqHQsp3Jv19Pzrc5ZEIH/wBAIzzEmwIug6OOaX6Gb76+qQd5bLNBoL2UZTycy9IQg5HsM5MqR/E
+6Zl2Lg8/sQq/33Z6ycejgXp43khmSinpbHe+sMi+KYt2jJL1Xv847+NT5rbvSShuBIuBiFDH/rtR
+FgmQfNLcjdNqLXCM+6BxrftVXan7jNE8hIoux7qOi70Ij+S2927Hlqp1RQ50+pDwyXaFzGi0H4Uj
+m8EplDFqNQzqXkdQr+N2lN0/bGjS7cV3rzrhZZTub/Tk+xftJoUcjmBd5SN1kHWTT07/zCiLUSw+
+qPq+Nraye6Mzk1VOSzJ5m0s5yofNHiVrlMM04X+e5zaKoTkgjL6M4lDcCBYDcfnXTd4hDod2d5rc
+jdNqzkQFAEK2YE131NE5RGf3WRRCRZdmjcfFXoRLuU0o7OhhfuGXhSbyxuyTCULL0DjkROtJW1mC
+9YFAoxB0vZ7Qe0RV7G9Hw2+2t8Tdi9pRzhLUfSsjdnlIccjhCNaMNQ4jwfrszE5rqewTLum1Rdxn
+miV382F5Ya6ajMT7STe5kR/qL11DR8kaVe4JOXmO2Fn50OzzmHeimIXriGBhCPG/kSVXDGbJ3Tit
+9gIH4eI6ol/LXTRT5Ls8TcIIpyUK42LPRznfZhH/TA9HD+teyyTQOWRc8Ekya0wx2OWRnLu/NVhB
+IgpB12vIKdVP3OHuu5t4I07l7Umzr4wq+xu96JOrfi/kcATrRpd6N0rFG5+zznlkgO68rJoqMMEo
+F+Jfzk5WeeN3GCXZdna/VPhIl81qWfHOIwdfsBkfn3xY7suEvzfL8f0gmBaB5e0RDgfqQMbT526c
+VnuBg1IK3lz85rSqxqGi2echVLQGYVzsuShjlCXRp+ro6KumH69Ga4FK9vYEgzNMPjqIE/aX8DoL
+zkMZ33QWn9e9jmA5xu0og90/bGjS24zuTxM47L3HRML3k5z0CDkcwTrJR+qg003e+pw1yhzGSfTx
+Iu9bxmLbA+ycN1nlBCGEdDeSe4TJl8WoOS0rStvDOOMzPT6jQbkvk+g9zkNxI1gCD7Cs+oZRFj2Q
+XMj5ntv1FzgYo844Vfc6limEitYrjIu9GCWEyiy9b44GD5t8ygWNeULo5W9f6Bwy0H3GQr5NcD5K
+KTjjfqt7HcHivW5H2eQTt6Oc5pR+lnXjica4hxyOYF044zAS9K3WFAAAq8w+E7S36DXEabRtSveL
+Ne7SqXBRIm7EafzecGB2fQNaVrxR+4xP//gcHZZPoywUN4LlIeCHy7pgHR7Zh8mMuRun1V7gAADw
+1He9a+7FVJVCqGj9wrjYq4lO554ZDh828XWJ3iOh6MgVxzpdPnwipAitKcGFKGPUehouRFeYU6ov
+9OGXr9tR6PSnuZxz2O1wPdWkg5DDEawBVerdKH27BdQYhyIS2bJOT6a95ON8pL87b7LKaUywzc5W
+ejfP7a5R9Y2SPS4MZdMewR8OygfpRnQ7FDeCZfJA/DJey4f94nG2Ed2r4rYaUeCgjN/y9RdTFy6E
+ijZIGBd7JdHJ7uli9BTt5bsiy4bWgpCXH3u1ZdmXknx0VREkCAgVWz5ciK4cdA6hGDzeyfRoa1t+
+MU07ylnEmidRwqYqloYcjmDV5SN1kHbic1tATaFfyPj8UcqLsrGV3csPy6+u+j1KCOluZfc94c+L
+oaqllUwr80LE072nDA/L3bQb35s1syMImiw/0gcyij6iM2xCnKcZBQ7OAa3dq3sdi2aKfFdkaSWV
+qWA+YVzsZGSa/pspi1/wiqOfy+S1eUYou/BYJzqHxBU/sBmOoQdriEXXPeJaBl2vKluWBz0x/OYP
+O/yOjPnlE0+u4IzDjQ35P6YNSgw5HMEqc8ahYPQXIdm5n7PW+h+nOvFUkWQj/Xw0KCYKS49TcSNK
+k87RQD1d9LrOQmd/5FM8PoN+uZv24rtVXfwFwaS8W/xusDEWnYe5czdOa0aBgzHqjBnWvY5FUqNx
+qGjd6wiOhXGxE5Np8rFR+h9Om0Z8Wffe/XZZfg2OhnsyElcGkAYBwPhC1Dr3Y93rCObnjO4Lffjl
+e5vuWjJjO8pZ1JtdEU0/xjHkcASrTBX6SdyR537OGmUxyeSfl70mgPHrTkTy+mWTVU7jkm92N7Pb
++UB/6cxyWlaMcpgmdOLH5/CV+qq7Fd+dZ6JEEMwKASCKyMYi72N4WE3uxmmNKHAAAICnosmhhvPQ
+eXnAoxAq2iRhXOx0ZCpvorOpVbrWiUfWGBRS7Fz457rsc+m3Q2tKMCnKGLUawgmOFkPnENTw8U6i
+Rlvb8gvGq3n9j8fCytmnMIUcjmAFFbnup934whGOpbJ7XNKpi4JVmWSyymmUUtLZ7nxhkX1TFosf
+JWuNeSbk1UVT7xCPBuphbyu+HybBBbXBxQ5QqTJ347TGFDg8Jf+6ihsdIVS0wcK42KnwSG5773Zs
+qeorchjzgnB2/bw/Qu8R1PDvXMq5jqQH6wdBdEOxs51sWR50xfDJO1tk7naU07z3KBn8XcjZP7tD
+DkewapzzyAn8cFFrincemcei7pyISSernJZk8raMIpIPFzdK1juPDO2rqx4f5xCHI/N1txffXdRa
+gmASCLiwakE+Mv0qczdOa0yBg3O2uWqZCCFUtNnCuNjpcSm3CSH/Sw9HE/W4Vg2d/fGi8bBumD+T
+cRwyboLpCf5+CBptF2sMCn345bs928lS+ddpMzKuogv9YmNzvveTkMMRrBo1Kp/E3ejCFlClzGGc
+Xh4CviyTTlY5jUu+mWwkN0aH6iu3gFGyWhuIM37p4+MMYlmaR6G4ETQCAhCgUdU3a4xFdP6gytyN
+0xpT4ABKwTekx78qIVS02cK42NlQwSiLxKfLLnKgc8gF6553VNMag4JbMs+khGB9UcY3ncPnda8j
+uBo6j1gMn+4k5T+2tuUXXJy/kzwP5xxuZOSXeUMSQw5HsEpUcXlrCgCAtWafCnphCPiyTTpZ5TQ2
+bln53Cj3RJfVtqyg0Y8Yv/jxMcZiaezDrBM2a4JmQADggpx7cnoeR4fuQZzK21Xf7onGFDgoYxSP
+vwnUvZYqqNHoqUxDqGjjhXGxM6GMUZZEn5avBl8t6zWLRh9SIc4dq+aLwQMeiXBSKpgJ5Ryccb/V
+vY7gcrYsD7ps8OTdHXI7ivm1Rd2PN2YvuSBAcWohhyNYAc55pHBxawrA8WQVzrOmhWFOM1nlBCGE
+pBvpXwmTL4tRNS0r48eH8IseH13avnPkeZZF4dohaI4FXCINXpVPOxvyfvW3/LvGFDgAAICQLViB
+i02dF+NQ0RB02HhhXOzsKCE02sjum6PBw2XkF3hj9s9rTzGj0UGULPaNMlhtlBBqPV2ZAvuqscYd
+t6OYTtapvh3lNGcc9noiruo+OOfX0IYxxEG7qZHau2hqygmt9QsR83M3Iep0MlmlnHCyymlRIm7E
+afzecGB2/ZwtK1qZF1HCz30MdWn7CORlnPCwURM0ivcIVdYs85HpCyk/XPTI40YVOAgT1xF9q78I
+jENFWQgVbYswLnZuotO5Z4bDh94trsiBziFhQM4WDdE45ET3KWOhmBjMhVCxFXI4mgWdRyyHT3eS
+0fNxO8riP1cJmkcy4pUdx6WcgjE2tD8FraUK3U86cvuqop/T/kfe0M9iGYttmGKyymlMsM3OVno3
+L9zXRs0+Shad/ZGf0/ZW5rbvSShuBE1V3SbwonM3TmtUgYMyCt5MX2FtihAq2j5hXGw1RCe7p/P8
+e7STJ5ZPA60FHr0dXGaKwS6PZON2jIIWYtF1j2GnvSmcUv2MDh69u0VuR/Fy2s+MUv3eprxZ5UhG
+xgi1xqpwOihoI+88gvPfyejyCUVGOYxS+edlrWsWs0xWOUEJId3N9C4Q/rwYqqnzAo1ymCb0rcen
+zE2fMPoyikNxI2gmAv7Xqj4RB32zu8jcjdMaVuBg1Bmn6l7HrGxePAihoi0UxsVWQmbJx6YsfsEZ
+vjxcBY15Qih7I5jL5PlBHLG/hPnwQRUop2Cd+7Hudaw7axwyffjlHzY06XblvWUGBwuK384zFvYi
+hLCdUEMP2qgYqb2kd3UmhFHmGZf0T8tY0zzSXvJxkdvvccYXZJSKG1GadI4G5vE0f88a80xI9sbj
+kw/NPpOcRDELxY2gsRwCgQo+hQevyqedzeXlyzSqwAEA4KnvLvKo+6LoUf5YZGnIAWihMC62OjJN
+PjZK/8MqXdlJLPQeCfH6dHsKOofMq1/YEo6sB+uBMkZt6Y/qXse6Qv97O8r2lri/jHaU00yuDjZ6
+8SeLuG0u+PWQwxG0jSptP+nIbXZFa4p3HsHjq6t+rym6m8mno0P1YNa/zyXf7G4md/KB/tKYq1tW
+vPPI0L7x+OTDcl/E/D0hFn9UPwjm4mHuCkcxsn0hxYfLfI9oXIGDMn7LVz96eqFMXuyzSH4UQkXb
+KYyLrZZM5U2PbqeqIgdaC1yKD0//zOXDJyIS1Uw5CIJjSGUntKstn1Oqn+Grr0/aUZZ9Kss7j1lC
+fl7EyFmAkMMRtI93Hr11f7+qNQUAQGsLcfp2C2mTpb303rSTVU6j41GyXyCyb8ri8lGyWhuIM/76
+8cmH5b5MolDcCFqBgB/O84nsDKJzeHDZBKZFaF6Bg3PwDlvzRcCW44DDECracmFcbKV4JLeJdzum
+LP827215bZ4Rxl6PhLRl2ZeShIJiUD0h3w9Bo8tz3I6y+4cNTbq9+O4y21FOQ6P20g352aJuP+Rw
+BG1T5mov7UUTtVwbox9RQXtX/2ZzMEaoTONPZ5msclqSydsyikh+pJ5e9DvO2CeMjx+f0WBc3OA8
+FDeCdvBA/DybDoeH5sGycjdOa16BgzFqtfpn3euYBDqHiO6HECrafmFcbPWolNuU0E/0cDTzLgkA
+gEf7z5MpKeg9epN/H1pTgkWgjG66FhXY2wq9R1TF/nY0/GZ7S9xddjvKac447HQEWeToWYCQwxG0
+h1EWo0TuTHKc3BmHnHJOW5iFJQSjALCjtZ06NPQ0Lvlm0stujw7VV+5My4ozDiX3QAkhw0H5IO5G
+N0JxI1gXg1fl02xD1BLf0LgCBwAAeCracEzY5sUDmSZ/rXsdQQXCuNiFoIJRFolPZy1yoHEopPzD
+6/99NNiLk8XttAbrjXIOzrjf6l7HKnNK9RN3uPvuJt6IU3m79pBgZ55EKV/4JKaQwxG0hdXmQZTw
+a1f/JoDW+oVMeWvbReM02ralG80yWeU0Rinp7nTvG+Of6PL3lhWj7WGU8DvDw3I37cb32pJTEgQA
+AN7NfrS9jtyN05pZ4KDwXtNPcoZQ0dUSxsUuDmWMsiT6VB0Nvpr2iDZa9YJwdh0AwOqyz6XfDq0p
+waJQQqj11IdWguqN21EGu3/Y0KS3Gd2vqx3lNKMc9jajPy5j9znkcARtUORqP+slE3+3ddr/yI9P
+WLbVvJNV3ritjfSvVMhRMTL7AADOmu9Gr9TDtBffpbR9p1yC9YYAIDnE0/69unI3TmtkgYNx3uh2
+gRAquqLCuNiFoYRQmWX3zdHg4TRFJG/tAWHHb1Nq+Hcu5ZWBZ0EwD0LFVsjhqNbrdpRNXms7ylmC
+6gcyYkt5Twk5HEHTGeUwEpywCYuPRjmMUvnnRa9rGeadrHKajMT7cRq/1/+1fHTUH7mkIz/11ns3
+x254ENQCASgjctq/dvhK7daRu+EcYpGb/q//1F/xZd/5RCgFr80BSDHREbllCqGiq+tkXCzlPLQd
+LYjodO6Z4eiByLK/EHZ5KBk6h4wLTggh5mi0H8WTBZ4FwVxYdB0xH9Arnp/B1ZxS/ZiU3/Y2+X3K
+ZKM2BIwq+ztb0ULGwl7kJIej5RvewYqyWj9It7MvJv19o8yzpLs6GXSdXnpvdJg/zHrJ3Xlviwm2
+2dvp3MkF/Q/rxQ/KeOWNzR06S8EDUN8FAJDc36KUAqUAQAEopcAYbeTmc7B+EBDYlM/Go8NyP+tF
+ny9mReczxmJZuGfWkVdxKj/b2GL3G1ngoIxRg4Xz3s+V3Fq1cago/iDTOFwAryDKGNUq19zHjXre
+rRrRST/Xo3xfJAlQzi68iESjD7lkd6wxKLgllInwbxIsHOUUnHU/csGXvvuwKtA5pHr0ZKdL/ihj
+OfEF07J47zGR8D0XfO4LmWmc5HCwUDwLGmba1hTvPILHV6uUKUEYoTIbT1aJE3F93tvjnDIZif9J
+OGGJFD2A8Ua4HwPvATwAePSgLb5A438DRGWNUwAAlGAXCIBg/gNKoUfYuBBCKQUKACQUQoJFQwBg
+k/96MbJ9xnm2rPcFVVgscvuIRWJbJPGN+NT9NrLAAQAAlO4AIgCb4pFdMDvKd+VGN+RurCh0Dm2p
+/ofhEqn4fYuNAv29mev484QSEj5Y5iCz5GOdF38XUQJUnF/kQG1/IJG444f9B7yTNO4iKVhNlDFq
+cxhEU3edBgAAtiwPtlLVj7viDmloz7ku9IvNd+OlhxWPczjMcxG1N5QxWD3WOJRTtKYAAGhtIU6j
+jxe5rjoIwagzdkcr87OM5j9FHmfR9lE/f8wEu3OS9UPGfv8lBsAFuwYAr+/vJAjqpBAC6AHRH2qD
+PwEiOIMDDw4IwYgQkJz6iDG4Tti4+HFyKiQUQYJ5IADEgk0Uwu0MojHuh7QTLfQQgDOIpTYvVEn+
+K87EJ0lP3j0vR6uxBQ7CxHVEP2AMGrHToUf5Y9HJlnrkJlgsdA7ROnDWPfNW/9OVhfWAXeLKPxOg
+BBFfgPe/OvAEjjsn0ZMj4t2pHmoGwGgX4Pi1RQGAEE+ZvD3+0cnPyfEf0zeTbyhd22KJTJObuih/
+Yij+m0fyjd0SdA4J986Wxc8yEUs9Rh4ECKLrEX3IWZqcM7of++LbnU1+n/HmZuU453Bzg/cZo0tf
+I2OEqnycwxFOCQZNYUr9YGOK1hQAAGP0oyhJl3oCalniNNouhuXfLXWH/IINmGmkG8m/F0fFk2wj
+nriw+boEcvI2Md7r3RQRvNEej8enQcCPiyHoAbR2e+AAUNsj9M4T8IxQnzIGnhF/+6T4Qen4+2ho
+iQkuNEVqzOErtbuxNfkpsGkZZTEv3R4QpmUc3+nGl3+GN7bAQRkFb+2P0IBjwiFUdDWgdYjOgtV6
+DxweEc43COMfEI8febT/lBvdf/Na/xfljFDGCB1X0y+t4L8+Z/jmzwC8Pn5jOP4z6w8R8cfTxRIA
+qjx6BeCO/zcDT4ARSlMA8rpYQij/kBDae10wOfU0PHu6pG3FEpnEH1itf7NKPztd5EBEYJRdp778
+mbGosRdLwYoS8n2PCtr1aqoHOofUFk92Mt/IdpSzvDF70WZc2/eKkMMRNEk+UgedbjLVJoIzDjnl
+fBnTh+qSdOKbR6+Kr7Mu+Sud87s/Y4RSxv7FaHsoJK9005YSQuDMP4MQbPz+lp3TEnP8/43BZ86d
+nwsimP+AMdobZ4KEXJB15j3CJJcVR4flfrZRfe6Gd4ilcod57r+TCftznMa3J309NrjAwagp1IAn
+9a4jhIq2E3qPYC1Y4w69NT947zXhrEuZuMWj+DahlKBz6Mpij3Iay07nCwAAo8sfp/nMJud8uFzw
+tzcpwKXPoQuLJWDHdZKTgokDQMRn4FE5gNcVVo9kAODAeyCEgH/jdMnvRZCIUnH9ymLJ+HeXUjDh
+Um6j1mDy4rFIk78CAHhtnjk7+i3qJiFYNFg6yuimc/icHo8oDs5ny/Kgl6pfki6/Q2nzr9idcbjZ
+kzvzXrDMI+RwBE1hjcNIsD4T051mMsodynT126y6m8mng19Hu92t+O68J67Oa1VZlrdaYgAABDsO
+hz1TBAEYF0LQg7skF0Ryv00I/Ol1LgiElphV5BEO4Yprl2Jk+5SxbJoWt6ucDg2NEvnxxhab+mRI
+YwscAACe+lqPCYdQ0fY4/rcC1PaFt/rAAyFUiPcJY3+iPL5z9jmkS9UnVn8vkuiz039GvD86W7BY
+limKJUABrkwuP1swOe7ofPN0ybhY8jN4/9sbp0u8z72n9o3TJZRGhIB863QJPfmiTt5sxTle6Pj/
+X14soVJug3Obejh6KDvZXV0cvtzYSG6FY9xBHSjnYHL3UkTzB82tImsMJj5/sN1jn3AhW/P5SNA8
+EtH8ExLm+l3CXwAAIABJREFUEXI4gqbQpd7d2Eqn3nW1xn6XMrkWeXTdzfSzfJA/qmKyStqJ/r04
+UlO1qizLTLkg3gO6kAuyyih1PxJCLyxwOIeotfsh61aTu6GUxWJkHzHOMxHHt+I5iiaNLnBQxm95
+RCA1vRZsXjyQ3U7jj9yuo3G7iQOr1R4gDoFySTn/iHJ2DWR27aILY3QOXT56wGP5Cbvgi+6qXFSf
+LZhcUix5H8b/d6FLT5e41z8ZF0yc+9vlrTgAnjAg9NTpEkI8ELZD0N85+scvD2OOKaFkY4r/3CCo
+DCWEGk+pR++bGpRZB3QeQY/2drp+J2pBO8ppRqn+9qa8Wff7e8jhCJrguDXlL9M+B41yGMXinUWt
+q2lOJqsUuf5bksq5WtuYYJTqxbSqLMNbuSAAAHyyXBBr3N/QAUFtj5y3wAA8UN8NuSDN5hDIhRcP
+MM7d6G7Ec7WmOIdYluPQ0CgVnyQb54eGTqvZBQ7OwTt8DhyWvoumj0aPRZauRYW66U63m6AzP53k
+Z1DOX7ebTHI7Os/3GfFaZMn98z7U0TlkjIXZCeeY6nQJ5//nsts63gSAt0+XOAAGQNQRSVP6ri/N
+E2NBEyY7IKJbhHIgvH05I0FLUXnN+ys+3deILcuDXqx+SXba0Y5ylqD4rZC8EUWZkMMR1MkZh5Gg
+U7emAAAYZZ4lXXnlCdJVIgSj3uE1VZpnUTzfqb46W1WW5bxcEBBs/L1wklwQxJEzzhEgQIh7PSo3
+5ILU46LvQEeH5X7WiT6ftVD/OjQUSC6T+O5VoaHTanSBAygFW+T/ZGcmLCyayYt9lkQhVLQmb7ab
+2AMPHokQ71DKrnMeb07776K17hNdfCfj+HNyxTdKwqmcb/XBVV6/GZ5zusTkw/1kI7rDIkIZZ+8D
+AKBDDz4HZ/wzW7h/WmCUsOh9IuWfKKVAGQsfckHliJDXEPMBXfOsBGscJn74YLtHW9WOcprJ1cE7
+7y4u3X1aIYcjqJOasTXFO4/e+9/YGn43lrHYLoblf1sz/2SVtBP9ezHS/zdb8DjNJrs8F2TsvFwQ
+j/izNr5/OhfkpCWGEb/NecgFqRLxPj+vvlEUs+VunISGqsLts1h8ME1o6LQaXeCghFDnqVhmDoct
+dZ8IloVQ0eU5O66VAGNE8PcJZ9eo4Ndm/bdH59AW+RMu2B9Zll355RYRgTPywSz3FczPqrIfMf8e
+ekpeT58BAHr8Bko53BARv+HRe+8NoNOHqNxP1pIjZKIDnH9AueiFokdQBUopOI3PuIC1/BKKziOY
+0d5OB+O2taOc5p3HLCE/1zEW9iIhhyOoSz5SB2knnro1BQBAawtxIv/3ItbVBseTVf4j7ZL/M0+R
+Z9yqQv+1ra0qy3JeLggAe19Eb7ZU46nTIG/kggCAU3bgwQGlngH49HUuCPm9JSYUQS7mgbizT3Tn
+EHU5Xe6GM4hFaV4YS36OEvFx2ovmDu69SqMLHAAAQOE97/1SDgmjcwiAB1zUN0JuHVw0rpVxdgNk
+dqOKJ70pRgcUoC+T6K2A0YsXhgA87KjVAZ1D4dVLKsUN1Hjp5G0yPv8IlMEmCLYJAOARvUcFzpbP
+rMa+I9QCE+8QHl8nlAIToeARTIcyRq31Kqp7ITVwSvU7stzPtvhdykSrd2vRqL30D/Fnda/jtJDD
+EdTBGYeC0V+EZDMVbbWyT6JetNZFue5m8m9VTFZZh1aVZXmrJeZ0LshxSwweV0D8Bbkg6J0/GZV7
+NhcE1rklBv1bR22myd04GxoapcvbaGh8gYNwfg0dvqCMXbv6t+djiuJh1OlUPsd3nU0yrrXK+7PG
+oC+LByyWnzDOp3ohee+eAaFr1VvaBOg9+vxwl2XxzEfICR0nc1CAG0IeH21EB94PwWm/ZwsYOE8i
+KqI/EiFCa0swEQRR6ySvZbPGYeSHD7Y36CdcyNaPaHbGYacjSJ1jYS8ScjiCZVOFftLdTmcqUDjn
+UVDSyNfSslU1WSW0qizP1LkgMG6JOckFOWmJuSoXhMLqnAbxDhEoeWO6wCS5G84hloU9VAq+jVL+
+52QjrSQ0dFqNL3BQSsFrcwBSLLTAoYajXZmmrf9CV7dpx7VWeb+uLPYYpzusk852nBpRhUL68uHw
+1aMoiSotLBJCCDm+cGAcbgMAjFtbFKAtf3aIv4QA0+AqVMpbHhWs+rMCvUdQ43YUGYlzQ5jbiKB9
+FKVxrWNhLxJyOIJlKnLdT7vxR7NeaBhlDmUm/r3qdbURYYTGFUxWCa0qzXJuS8x5uSDwezDqmVwQ
+sMYN4NSo3DbngiAASA6vBy8Uhe0zyslFuRtvhoZGd7sJrbW1tfkFDsaowcIt8iinyYt9GUc312WX
+rkqzjmutki5Vn6L5QcRyrgLKOEwnPAWWyeSj/SgSN5cxinPc2sKAMnifH4/FDQGmwaUoBWfdc8rZ
+0id5LYtTqt/h+ffZlvys7e0opxml+1s9+X5Tj3+HHI5gWZzzyAn8MGtrCgCA1fa7JBXhhPMxJhhl
+FUxWibNo++i30S7bYrXscgfTeWtU7hW5IK9H5Z7KBTlpiSHgGaENzgVBAMqIBBifyjCF3U834rcO
+AhS57avC7rNIbEdpfLspIcSNL3AAAAClO4AIwFjlN61L3aeCZSSEil6pqnGtla3HOXT56AGP5Scs
+iis44oe4KjuXbWBV2ZfUZbTG196VAaZIB0h4F3j0AeW0RzkPpzzWCOUcTI4vBSx/VPmiHbejPNre
+oDe5aOYph3kI6r6VUdzYcNSQwxEsixqVM7emAAAY41BG4p3wPH3TyWSVeU9gpN34M1XYvSQVIf9v
+RcySC+I9gD7OBfHG5g6dPckFAQCQ3N9aZi4IAsLJFt/glXrU2fj9e8Lr0FBDfoxS8Ze0JxceGjqt
+VhQ4CBPXEf2AMaj0CBc6hzSEil6o6nGtla3Le7RF8YwxICJLKjlOjd4jpQuooAXnQueQ2/KAJRcc
+7/Tn/nThLg4wzcFZ/8zmIcB0nVBCqPGUevR+GaeMlgG9R9Dls+1E6ygRjftSUgWjyv7OVvRJ3eu4
+CoGQwxEslirma00BALCFeRZ3ZMgnO0fSiW+OXhX/QTmdebIKE4waZTdDq8p6OS8XhJ/kgsDsuSCU
+Qu91S8w8uSAIAGycu5Gk0U1CCDkODX3COI+WHRo6rVYUOCij4K39EQSvtBARQkXftKhxrVXSWvep
+Vt/JWH5OqvxWiAiU8bSy2wsuhfnhQ5ldkMJc+7PsTZcGmCq3Zws6cJ5EREb/K4ypXUFUXvMegTTt
+iTkDp1Q/ZcV33U3xOWWy/f9B5/DeYyLhey5440+lME5DDkewMM55BI/fC8nmei2g979d1HcfAGQV
+TFaJO9EHR6+GX3HBLg1wDNbLLLkggB4Qj1tiEMEZHPiLckHg4pYYBABw/pr39L+Ncf7w0H4VZ/zD
+pJvcaUPYMLn5//4/Ne2VTscM8y+jXqey46bjUNHkbhMu2uty0bhWSkkPKIUmvcmic2iL/AmX4iMm
+qm9pQGOQUvcPLuXCp/WsO3vU340SefeiHXFrDKbSEybas63pEf1xn+XPDvEXFwJMV4Y1BiOSH3HR
+3p21cTvK6FGvS27yBbx/Nokt1f7OO9GNNlyQOePQOff/pZ045HAElcsH5dPuVnx7nosRoywSgBcy
+nm4q3To6ejV80O2lM2+aOuPQGPtNaFUJFuFsLoj3AFa7PYCTXBD/Ri5IWdh/MaV6mPUSGafyM87b
+850coCUnOAAAPPWVjetbx1DRZY9rrZIpRgcUoC+TaHFTWDwAp/RPi7jt4Hcmz/ejiC8lVHSZCB3/
+B50XYGq133OFOwoBpu1EKQWn8RkX0MpRfqiK/e1E6ygWFxYVV4VzDrsdrttQ3AAYH01XhQo5HEHl
+VKH7SUduz7vTWir7pNuVoQA3gTRL7uYj/TjN5EyfFaFVJVik81pihGDjYto5o3L14Ojx9rvdL2Qk
+WvldtTUFDsr4LY8IZM48lXUJFa1rXGuVrNZ9r8pveRLdp4wtdPcA0RwCESv9nKjbOFTUkjpDRZfp
+JMBUcrgNwOF0gKnT7rl1VIUA0+ajjFFrvYrqXsiUnFL9mJTf9jb5/VVtRznLG7MXbbYrU4uQkMMR
+VMs7j+D8dzLi9+e5Hec8MkDXhuPoTcAEo9zhv84zWSW0qgR1OmmJGb7KH/a2k08Jta19DranwME5
+eIfPgc+eZo/WISWrGSrahHGtVUHn0JXFHuN0m3XSpaTgE8SfCCFrceFdB3QOGZY/sGi2nY1VcDrA
+lIvxuL6zAaaWUE+43CIsuk55OOXRFAiiiw49bcHJAHQOqR492emSP8pYNnaKSNWccbjZkzttuxgL
+ORxB1YqR2utsXZBxNQWjzGGcRZ9VsaZ1IWOxXQ7L0TynMNIsuVeGqSpBDbzzODoqvu72krtaOax7
+PfNoTYEDKAVb5i9ZJGcucJhyNUJFmzautUqmLA4Iul9ELJd7ysSDXtp9rSF3dLibbMRz7SatovMD
+TC14b8AVbs9iCDBtAirlLfCq7mVcyZblwVaq+nFX3Fn1dpSzqDe7Ikpa9/nOOAVj7HMR8dAGEMxN
+lbafdOT2rBM9TrPK7CepaHxYb9PEnfiD4WGxTzndmOXfIbSqBHXwzmNxXNw4+Rk6fAGCtTKbsDUF
+DkoIdUjlrDkc41DR9N4i1rZoTR3XWiU0Bl0x2mVJ/BcWxUvf5Sfg1So8jk1kh68exx3ZuguPOhBC
+CDk+qs74uDdyHGCqwJryhff4DxMCTJeOUA7O5s8pZzMX2BfJGd2PffHtzia/z7hcuzBAo1R/e1P+
+pU0nFU+c5HDUvY5gNXjr/i6783/eGuNQxnK7ja+pJuj0ko8Hv452O1vx3VlG9IZWlWCZToob2ani
+BgEA78lvABAKHAtH4T3v/dTD+toWKtqGca1VQe/R5aM9ymksOlktb+ToPcIKPaZNYvJ8P5Lso2mf
+sx78C2jpm2rVTgJMJYNrAHBtfMoDwfscXAgwXQrCKZgcXwqYvUVyEdA5pLZ4spP5tWpHOUsy/3ch
+eWuLqISwHYfoq9h1D9ZXcVQ+zTbjSjbyTKFfJJ2oUe93bbOxk92bZ7JKaFUJlsE5j+pMcQMAACgA
+mpoWVYFWFTgI59fQ4QvKJj8u04ZQ0YvGtTLOboDMbqxq9VZr3adafSeS6PNaizaIwBnr1nb/K2r2
+UFEK6OxvIEKB4zxvnvIIAabLQAmhxlPq0fumtH7YsjzopeqXpMvvULq+CZUmVwfvvFvNRV1dXudw
+yJDDEczGKIdRLOKqimTew0+M0bU7DVa1eSarnLSqWOMOuWDhvSGonHMeVa4eZb2k1Z+h52lVgYNS
+Cl6bA5BiogufJoaKtnlca1XQObRF/ohLcZNlSf25DIgA4dKvUugcMlv+wJL1DRVdphBgugRUXvMe
+gUx9hrBa1hhMfP5gu8c+4WK9X1/eeexk5Je2X4gxTsFofCZkO0cRB/WzWj9It7NKTnEZZTGKxQdV
+3Na6ez1ZpTDPomT6ySonrSrdXhJaVYJKvS5udKJzixsUANyS11Qljs5hW77oUsaowcJNMjMevUej
+yt0oy2q9gF6Fca1V0nm+z4jXMonuNuW/HT0A5/RW3etYJW50uJt0QqhonS4MMEVz6Ar3k0U6QCAR
+iBBgOgki5DXEfEBrmnaBziPo0d5O1+9Ea9yOcpozai/ZjFsfzjnO4cg1gKx7KUELFbnaz3rVbRaV
+yj7pdmXrX1dNMe9kldCqElTNGYeqNBcWN1YBt0o/AWcVUNoFxj7gjPWgyV90Kd0BRADGLv01Mxo9
+kulsfW/zWKVxrVWyWve9Kr+VSXSfsIYdp/YI4QhHdexo+DROQ6ho07xubWGwyQTbBHgzwBQt/mSA
+OkJ5NwSYvo1SClbjcy5g6V/8bVke9GL1S7Kz3u0opznjsNcVcdvGwl4k5HAEszDKYSQ4YRWNsHbO
+IwN0q/K6aop5JquEVpWgSs441Mo8zDrR5d/TKQXwS1rUAnCRxKeOM3tw6J6BMr9Z7xAo7VDOb1FK
+ARrSw02YuI7oB4zBhS9ykxf7MkkWfkJglce1VgWdQ1vmTzhnf2SdtJm7js79DQj9P3UvYxWYojyI
+hP+QhIuwVngjwDQ6P8DUeC4pl39c9wBTyhi11pfLvE9rHCZ++GC7R9e+HeUsguaRSJKVGWEZcjiC
+WVTZmgIAYJQ5jLPos6puL/hdp5d8POiPdju96SerhFaVoAonxY00u6K4cQJRL3hJC/M6g+P348zs
+BhwfZwbv4aTo4Yejf3rwlDC2Rbm4ThkFoMvf3aOMgrf2RxD83KNautR9Jvh7izglsA7jWqtkitEB
+8f4XGUeNbsXxgOHzogKoTF8SnVPOW90Pv84uDjDVbwWYUhndAkphrQJMmeiiQ08r2i29CDqPYEZ7
+Ox2MQzvK24xS/a1e9P4s4xebKuRwBNOqujUFAMAqs5+kYmUKh02zsTX7ZJU4tKoEczDGoZ2iuEEB
+wCIudVOnSheGjBJCCBACvxc95A3vvQdE8N6D03rPWXdECKGUkvcJF3+ibPG7e5QxaoriiCfxW3+G
+1iEDeMmEuFHFfa3TuNYqoTHoyuIBi+UnjPPGf1kj3h/B6nxPrgU6h6CH+yxb3X6+dTUOMGUhwBQA
+gMlb4NVC78Ip1e/Icj/b4ncpE+GN6Rwc8DsZsZXK+Ak5HME0rHEoK2xNARhfAIlIZGHHZ7HSbnZ3
+NMgfZhvTnUATglEXWlWCGRit+97Ay4lPbhxrcYfKdFNUCCEEGAMCAJTz2xzGX3TBe0D0h07pn6yz
+AwASEUb/SIRYyJFmT0nHI/rTBQb0Hp0qvxZZNnPleV3HtVYFvUeXj/Yop7FsajvKBcK/7XxwNNiN
+supyN9r8proO1jXAlFAOzubPKWdTp+FfxRqHkR8+2N6gn3AhQ6HwAiZXBzvvxH+pex2LEHI4gknp
+Uu/2tqsN0TeFfpF0ohC4vmCMESoieX2WySqhVSWYltG67y28jNLpNv8Ja/fJ3LnHxJ4UGRiDTRD8
+VHCdB+/wZ2v0L1WHmFLGb3lEIPT3mzCj0SM5RXEjjGutli5Vn1j9vUiiz9r02KFzyBh7+zhQMDE7
+Gj6NUlHZhy1t9VvqepouwDS5RSgFJtpX8CCcgsnxpQCorMCB3iOocTuKjMT98KX1Yt55zBLyMxds
+JY/QhxyOYBL5SB10uknlRT5E/19tH7ncFjIW22WuYJbJKqFVJZiULnUfEF5GSTWdDW0yd4HjPCfB
+dcDY+wzE+wC/h5giuhdemZ/mCTGlnIN3+Bz4+Evm61DRS74YhnGti4HOoctHD3gsP2FROwPfCKfh
+TPCMbFH2ZQgVDc5xcYDpEJz2e7ZwR65lAaaUEKqRSY/eEzp/IcIp1e/w/PtsS34W2lGuhkbtpX+I
+VzYAMeRwBFexxmEkWJ+JagsRRlmME/nnKm8zuFycRtv5YbFPCIFpWk5Cq0owiXUubgAsqMBxnpMj
+zQDsGsjxl90zIaZ9D95PFGJKKdgyf8kief2iUNEwrnXxdJ7vM+K1yJLW7joiInBGPqh7HW3kjEFB
+1EvK1/PNM5jOqgSYEibe894BgctHlV/muB3l0fYGvclF3MrC8LI547DTEWSVx1eGHI7gKrrUuxtb
+0wdUXqVUdq/bleFEwJKlM05WiTvRB0f94VfdzdCqErytquIGgXELchufY0srcJx1TogpTBpiSgmh
+zhPqtHEM4CXh/CM0BsO41uXQWveJLr6Tcfz5IqbVLBUiAA/HgaeF3iOUR1+zLFycBbM7L8AUHXrw
+OTjjn9nC/dMCo00KMCVCXkOXv6AMrk37d9F7BF0+2060jhJx6anD4AxnnkRpcqfuZSxayOEILnLS
+mlL1+4ZzHpnHYpWLh022sZXdG/w6+mpje7qJOHEntKoEb6v25EZ7v6PUVuA4zzQhptpqboviAY9i
+7lW5G8a1Lh46h7bIn3DB/siyasOt6uK9ewaEhhMIU8KjV4+iLArFjaByJyNYKYcbIuI3zg0wJbwL
+nH9QR4AppRSsxl+4nK7A4ZTqp6z4rrspPqdMhs+oKRjlcGsz+uMqjYW9SMjhCM7jjMNI0MpbUwAA
+jDKHcRp9XPXtBpPLNtN7005WCa0qwVlVt6V4wjoexic52qZRBY7znBdi6oxxUAy/EtvvfEEJIaGg
+sXimGB1QgL5MotXKK0FUa/CduVImH+6H3edgWSYNMAUm3iE8vr7oAFPKGHUOJ54VO25HGT3a3iA3
+uYhWojC8bILqBzLKWjWZa1YhhyM4j1pQawoAgFVmP05F2LCo0ayTVU5aVTa20vDZsuZ0qfvEw0tZ
+deaG9608yNH4AsdZWuu+yfPvkq13btd9VHkdoDHoyuIBi+UnjPOVS9cm3udtfOHWxaqyHzH/Hm17
+a1LQaucHmLq3A0xFtJBx5Z7KDjr0J6dNLoKq2N9OtI5icbeKUNJ1ZFTZ39mKPql7HcsScjiCs4pc
+99NOXHlrCsD4ZIiIeLYOp6OabtbJKnEnuVfk5m+hVWV9lbnqM0Jeyrji4kaL3xVaVeDQeb4PiEmc
+Zh9SPt7JCxYDnUNXFnuM0x3ZSVd45wwxnESYDDqHwquXVC4hVNT7hd9FsDouDjBVgLb82SH+Yh1V
+QHkXRAUBpkzeAn/xIQ6nVD8m5be9TX4/tKPMznuPkYDvuOBrtTsZcjiCE8445JT8ICRbyIkerfWL
+KJG3FnHbwfRmmawSWlXW28KKG3AcMlr1jS5JK05AoPeohke7jLOPCOP/zaRYuZMETaJL1ccyfyRi
+eZtJOXWQXlug90gpm30UwhpB79Hnh7tsGcWNIKgAoYRQxgiX/P0oln9NMv5FJPF2BDnh5ug5Hv1z
+Vw9+2zX5cN8qg+gcTn7bHIx1e2d/js4hFIPHO5kebW3LL6464RFcThf6RXcjXsix/CY7yeGoex1B
+/VShn8QdubBwXWf8f/FwIrNR0l7ycT7S36GffKcn7kQf5EP1zSLXFTTPIosbbdf4ExzoHLqi2JVp
++rnN8wei012rnZxlQufQ5aMHPJafsCi5V/d6Fg4RKONp3ctoAxy+ehQl0dpdaASr5a0AU/TeewuI
+5hCnCDAlnILLcXj6Z6YoD7Yz1Y+74k5oR5mfcw43N3ifsepDFZsu5HAEAMetKd34o0W1jxjlMErk
+/1zEbQfz2djK7g37oy87m8nEJ6hDq8p6WUZxg1LwbT3C0egCh9a6T9EdiE52X+f5U5Fm4QJrAdB7
+tEXxjDEgIkvur03LBiIAg+26l9F0Jh/tR5G4GS7aglUzHlNLgDLYhCkCTCkhVCMTHr1HZ17Fvvh2
+Z4vfZ1yu3cX4onhj9qLNeC2/qDPBaFmUKuRwrC/nPHICC2tNAQAwyuwlXbmWr7E2SDbSz6eZrCIE
+o6Yw0jr0PJweXGnFsNwXgmVC8oWe3CAA8SJvf5EaW+DQeb7PuMhYHN/WWveZiD5cqekdDaG17lOt
+vpOx/Jys2TFF9ACc0j/VvY4ms6rsS+oyynnIvAnWwqQBplY5Crx4srNB3pOxXOGcouVzxuFmT+7Q
+Nf7Mp4R0Qw7H+lKj8kl3K1lYa4p3HsFjEZ5fzXUyWaUszLN4wskq6Ub88fDV8Mvu5ipn5623Ylju
+S8ne42IJ38upuO7BLfxuFqGRGRxqNNzlUr7HJH8fnUOK/oAt4x9yjaBzqIdHjzng+NTGmhU3AAAQ
+zWGYoHIxdA65LQ+YXL3pOUEwKUIIoYwSxhmRMb8dpfJezMruO+lR1MugK+Pw+qgaQfNIRGyti8+M
+01seW3o2OJiLKo5bUxZYfNDaQpxGHy/q9oNqyFhsA8CO1vZg0r8TZcnnZWGeLXBZQU2WWtw40dLQ
+/0YVONA5VMOjr2SS3D2ZkmLL4iGP1/OY6qKYYnTgdfmNTKI761w4Iog/rUs3ziwwP3zIk3B8NQhO
+2EL1I3P49c4G3OhupZ9orf7ppwiCC65mlOr3NuXNtWmVvADjFIx6O8g2WG1ufLLieyEXOynQGP2I
+ChombrRAnEbbtnQja9zhJL8vBKPOeHQuVEhXSR3FjTaf72pMgcNq3Uetv4k6nfsnrSh6lD8WSbb6
+YZdLYo1BczT4kgt+jcfR7bVv+fGg615CU9mj/m6UROG1FwQAYJXqM/Xqy62OIZ2N6O5JWCkh9CZO
+PnwlmICg+K2Q61t4P8EEo1rZMEllzaiR2ku78WeLvI/x6FnOFxVeGlQv7SUfF7n9HnGyokW6EX+c
+H5VfLXpdwXIUw3I/ivhyT24AAJDWHuBoRoFD5/k+ARjx5PeTGqbID3gUf7T2F+EVQOfQjIZPKZoX
+spN+QdewHeU8BLwKz6+3mTzflxEPoaLB2rPGoS8Gu5uJHm30oi+4eHNXVQi5WRbmUV3rWzUmVwe9
+rSRMSjt2ksNR9zqC5VCF7icdub3o7Bmt9QuZ8oXlewSL0d1MPh0dqgeT/n5oVVkNJ8UNxhd7qmvV
+1F7g0MPh43Hehnjdx2y16RMmchr+MedmyuIAVfFExPI2kyHh/wR6jxCKG28Zh4paUu9rr/a3pWDN
+jUdm5097YvR8a5PfFRfk0BBGKFpkk+6qBRfzzmOWkJ9ZSP9/LeRwrA/vPILz38lo8Zk+Tvsfedjo
+aqW0l94bHRYPJ/nd0KrSfsWg3uIGoe39Pl7bytE51EfDL0Wa3Dl9MYXeI2rzPZdyoaNvVh0ag2bw
+6ivGSEck8V/DSYUzEIEz1q17GU2CziHD8ge24LFTQdBU6D2aMj/okNE325v+tozFjauyIChj/+6M
+e7GsNa4qNGov3ZALPZrfNiGHY32UudpLetHni74foxxGqfzzou8nWAzGCJVZ/OmkJzNCq0p7FYNy
+P0rCyY1Z1VLgsFr3nVVPZDf74uyFtxmNHok0CV9yZoTeoxkNn3o0z0Un+5yF8Z7nQwwHBc5wR4e7
+IpJ/rXsdQVCHkwDRd7r+WpSK25MeE+eSU53rHxe9vlXmjMNOR5B1Hgt7npDDsR5UaftxJreXMbLV
+KPOoxNFAAAAgAElEQVSMS7rWE4raTghGYYrJKlESWlXapinFDQIAzvpWFtmXfomn82IfwL8UUfLW
+hZTOi30RpzfDaYPZaK37OBruilje5lJeufO4ztADUEZv1b2OprDDV4/jjlz47lEQNI3V5twA0Wmg
+J+9jOAY8M4L2UZTy8H58jpDDsfq8dX9fRmuKH09oebWMQkqwWHEabTuDw0kmq4gotKq0ybAhxY22
+W2qBQ4+Gj7kU753XfmK17jMuspC7MT10DvXwaJcDEpEl90OBaAIeYVybDEye70vJQqBvsFZeB4jG
+5bkBotNggl0z2rRyl6NuRjnc6Mn3w0SH84UcjtVWHJVP095yJpZpbSFOo4+XcV/B4iWd+Oakk1VC
+q0o7DAflfpo2qLhBxwfe22gpBY7XeRvJm3kbp//cO//D6aDRYDKmGB14XX4jk+guW/b4oDZz7m+h
+vtGUUNEgWJ43AkR7FweIToMJTlXhRt63daBafQTVD2TEwmf/BUIOx+oyymEUi3hZJyqM0Y+ooL1l
+3FewHNNMVomS5HMVWlUa63Vxg4Xv41VYeIHDat13+vy8jROuKHZFEofe/ylYrfvmaPClEPwaj6Pb
+Yfd9Oh5w7Tt40DlkNoSKBuvh3ADRCkchEwo30LqQlzAFo8r+Ri/6pO51NFnI4VhdVusHUSqW8vnr
+jENOOQ8npVZPZ8LJKiJi1IZWlUYaHhYPmljcaHNU4ULXbor8AMC/FMnbeRsndF7s8zQLvf8TQudQ
+j44eU29HspN+QcKor5kQ749gzT/n3ehwVyQhVDRYfbMGiE5DCLlZFubvVd/uqvLeYyLhex5OHl4p
+5HCsniJX+1kvub+s+9Nav5Apv7Os+wuWh0wxWSW0qjTP8LB4kHXkvaYVNwAAgFKAln7yLKzAofPh
+UyZk57Jxr1rrPhPyvXD6YDKmGB2gKp7IOLrDpAxHeue0zkc47Gj4NE6bGyqKFo/qXkPQflUEiE6K
+MEKd9XEIG52MU/pZ1o3DxLQJhByO1WKUw0hwwhb4fnSW0/5HHjbEVtbJZBVVXl3kCK0qzXFS3AgT
+xKpXeYEDnUMzPPpKxMnty/r60Tmk6A9CbsTV0Bg0R4MvGWcdkcR/DQWh+aBzyBiL615HXUxRHkjh
+P2zs84gCIIYsg2B24wDRo0oCRKfBBbttrXuxjPtqM+ccdjtcL/MCr81CDsdqWWZrCsDrrI93lnV/
+QT3iNNpG591Vk1VCq0ozDF8Vu00vblAAsLZ9LZKDX9VupQUOq3XfluqR6HSunORh8+IBj+PbVd7/
+qkHv0YyGTz2a57KTfsF4KAZVhXAq615DHVCZviQ6D6GiwSp6M0CUVRIgOg0mOFUj/Z/LvM828sbs
+RQkLY2EnFHI4VseyW1MAAIwyz3jMri/zPoN6HE9W+c+rJquEVpV6DV8Vu9lGdLfJxY22Onqldjtb
+6d3KChymVAcA/qXMkivHXelR/lhk2VLf4NtGl6rvRsOvRSxvX9bmE0wPEYFS8kHd61g2dA5BD/dD
+qGiwahYdIDoVQj50NuyMXcQZh5s9uRO+2E0n5HC0nzUO5ZJbU7zzCOB/XdaklqB+3c3k34av1MOr
+pnqFVpV6vC5utKBNnjBC2/Shc/RK7WYb6V1KCKmkwKHz4VPK2aV5GydMkR+wKP6oscfjazYeqXu0
+y6knMkvuhsdpARAByPqNSsPRYFek8m7d6wiCKi0jQHQaTLJrRpv/W+camox6sysi9qe619E2IYej
+/XSpd+MltqYAAGhtIU7kX5Z5n0H9upvpZ/mgfHTZ74RWleUb/Ja3prhxwoNvxVqHh+pB1k1eP7Zz
+FTjGeRvDL0Wc3GYTHHlHY5AwkU/yu+tI5/m+1+U3MovvhmySxfHePYNWvFyrY0fDp1EqPl/nYNVg
+tSwzQHQajHGqlbM+5Mi8xSjV3+jJv4T3oemFHI52y0fqoNNNll5o0Mo+oZys3YbOujuZrFLk+m+X
+/V5oVVmewW/5bnczblVxAwCAAGn8d5nRQO/HWfy/T29wzVzgQGPQFsXXPEuvzNsAGB8htsp8Hdot
+3qa17pvh4VdSshs8jm6HL38LhqjW6SG2RdlvdKhoEEyhrgDRaVBKP0PnQmbCGYLit0KG4v0sQg5H
+e1njMBKszwRd6nPfGYeCElL3qbagHkIwyhi7dtVkldCqsniD3/LdjRYWNwAACABc1e5Up9FA70dp
+9B4/M2Z3pgKHLlUfPT6XnezupBfjJs8fiTQJI+FOQedQD48ec29HMsvukzDCaymI9zm07z1mJs4Y
+FES9DKGiQdvVHSA6DS45lIX5e93raBKTq4Pe1nLDFVdNyOFoJ13q3SgVSw/VNcodykz8+7LvN2gO
+GYsrJ6uIiFGtQ6vKohz+Onq4sRlPfL0cTC4f6v0oebu4ATBDgUPn+T7jjExzEkPnxb6IkpthB/l3
+phgdeF1+I5PoDpOysV/UVxPiOrzRoPcI5dHXTC635zcIqvRGgGiv5gDRCRFCKFq/ieELIwCMgw47
+GfkljIWdT8jhaJ+T1pQ6vnNYY79jrNJhiUELJZ34psrtf15WHO30QqvKIhz+OnrY20o+a/M1hye8
+28RPnXyo92UUvccv2MCd+J0PvUc1PNoVcXRjmgwNq3Wfck7CDvIYGoPmaPAl46zD4+h2KPosF3qP
+lDJW9zqWAY9ePZJp1LpTU7Si8OOg/d4KEG3RBTIT7LrT+LzudTQBGrWXdOSdutfRdiGHo12ccRgJ
+uvTWFAAAYxzKWLzT5guroDrZZvJvoysmq4RWlWod/jp6uLmdhpMbC3BVcQNgwgIHOod2NPpaZtlU
+Uz3QOfTO/xByN44DWUfDp4DmH7KTfsF46EOuBSJQxtO6l7FoJh/uy0SEN9aglZoaIDoNJjgtyvJl
+k3tXl8H9/+zd+XMcVbYv+j3nUKPk7kNfZDjv9MHDoXGfG0weiHj/PbZsaN/73AYjbCJug3ATlzZl
+1ZCZe1r7/SBLSHJJqjkzq9YnoqNBJVVtISkrc+Va3209tFsyxhyA+WEOR70UI/0oStXKR1MIIcTl
+9rmM+LUyXhtV02U7qxyPquAY3Nz6v43ud7fT9di18DCEo+xVHMuGbk+qi4sbhExQ4DDG9MC7qfI2
+jvg83xVxtPF3bUyhe1Bkj2SsbnGldspez0YDIIST7bKXsUxOF72Ih3fqeFGINptz1Q8QnQYl7CZ4
+KHsZpaLgHslE4IXWgmAORz3kmek1OsnNsm4yQAi/4UgYOolyyuJLdlZpduIbWR9HVeYxfJ097Gyl
+a5U3VZU3nCJzPc4FlROcG15Y4DBZtscpnSpv4/evzfdE2tjobSnBe7CD/peCByrT5A6Oo5QPAiGM
+sXfLXseygPcgg/6V1fzCEG2W4wBRUf0A0WlIpbq2cI/LXkdZrDa9dkddrWNyfFVhDkf1eetBUPKD
+VOW8D1vtIE7Uf5Xx2qja+AQ7q+CoymyCDzB8nT1sdZL16Nx4oypv3kXmepSKX6NYTFSTGFvggBBA
+j4a7Qql3uJx+lMIY0+NSvbOpF/QQApgs2wtOv5CN5B6Oo1QHgD1Y1x1UIAQI2cEuhoqiujgKEE3I
+6HFdAkSnQTll1voAG3rHXRD/TEV8LYpVVYE5HNWnc/M4bpXXvVxo95hL2inr9VG1He2sYo0bu7MK
+jqpML/gAo0H+1boVNwghhDESym7hMMV0xQ1CxhQ43mRF7KokuT1LMCh4D8yH/VkKI+vAGNOD0XBX
+KX5dKHV9kztYqogC/LSuPxIYvn6kkuhu2etAaBIu173I9Hf/0Ao7aUN+uq4jVYzzj731L8tex6od
+bgsbfVj2OtbNYQ6HHZS9DjRenple2oo/KKtryfsAnIDHzBt0kaQZ39SF/+W8IgaOqkwu+AD5mhY3
+qsAUrgcwXXGDkDMFDmNMD6z5Jmo2783afeGy/IFI4luzfG2dgfdghoOvBQEqG8k9yjm+uVRRIKbs
+JSyDzUZ7KpI31+nuN1pPzjo4DhDtqHvrWtg4IpRgJjM/lr2OVQo+QJKEn8WG3uhYNkZYE++uVo/3
+odTRFEIIsdoexI367Z6GVq/ZSW5ctLOKiqP/0tr+vOp11Yl/U9xorHFxg1L2XllvNkfFjTiZrrhB
+yIkCh8myPU7oSMSzFyfMKPtaNhprFawyCZuP9oMpvlFJ9Mmmdq7UBSVBr9volNNFTzHfYGL1W9Et
+SwiVGftDC3IcIBrlL9chQHQaEOhV8JtzQeqsed5oxXiRtSRMYg5HFelR8TgueTtkp+0e57jTOppM
++0rjzrCf7457TMVy2xbwLyymjud9AL3mxQ1CCCG0nHM1Y2YvbhDypsBxnLcxR7CbLYp9HsUfrNvF
+40WctWD7r+8LKXZEHN3apO+9jiAEIGv2MwLvQbhif56/3SqitOyJP7Qo4D34PHvSZqNv1ilAdBpc
+8h1n4EXZ61gFbz20m8LgDg7LIzCHo3J0/mY0pcRzDGs9qFht42g0mkbaSG5nI/P1uMcaneS/RwM9
+tgCyybwPoDP9aO2LG4QQVsI2sd56cJp+N2txgxBCmB4O7s+at3EErAXKeMbneI46eZNT8oSBfala
+zXsMx1HqAYAIzltlL2ORIDt4KBK1cSNhqPpOBYi2w60olbc2dYSKS8GK3Lw6rxV4rXj7OErFR2Uv
+Y51hDke1BB+A+PCszNEUQgixuXkpI45bMqOpcMmZEPzP5+2cEkXqhsFRlWPHxY1mdKfstawjbz3o
+gjxMm/NlCrJ58jYIOTyJddp+NctWsnVki3wfdP5YxuoWV2rj7kTWGsAlGyPXixv0dqMED7Coeo4C
+RK801ztAdBqUkevgfL/sdSyT1R463ehPuC3s8mEOR3XkI/007ZQf8B0C+Qk7p9AsVCy3A4R43M4q
+KpbbBkdVCCFvLr43rbhBV9fA4T2AzsmjeYsbhCzgcs9m2SOZJms/awvWgh30v+ScNmUSf4rjKPUD
+gRDG2VrcWbRZtqcigaGiqFLOBohygcfJI1KqblG478pexzJJZh7gtrCrgTkc1aAL10uaarvsXUus
+dhDF8r0y14DqLW7G7523swqOqhwWN4y2DzequLFCwQPkffgqbS3mv+9cBQ6T5XsySm6u88U+hAB2
+NHwSwL6QjeQeFxgiWlsBCFmD7MrDUFFH5xkrQ2iRNjlAdFKUU+YNxLCmd8GsLnrtTvSXstexKYRg
+xGEOR6mCD0Ccf6ai8nOFCu0eC8V2yl4HqrdmJ7kx6uuHMGaccpNHVY6KG2mj/E6tVaNs+a3vwQOM
++vBVsxsvLNNk5lU7Y3pMiLW+yDLG9GA03JWxuiWUuo7BTTXn/d/rXt8A74FD8QNXswfvILQo4MPG
+B4hOg0t+y1n/sux1LFoIASJJnuG2sKvDJWdau7Ueeaq6ItNPkwqMpngfgBPwZXeRoPXQ3mrcGY3Z
+WWVTR1WsMT2r7eNNLG4Qcnhb2Nuw1JD0Ud8vtLhByIwFDvAegg8/rGvuBngPZjjYFQSobCRzZZSg
+6ggEal+j8oODXRmpT8teB9psvweIDjY+QHQaQgmmR+b/lL2ORTO5edlqxxt58lcmRmhrXTuCqk4X
+rhc31DavwPmh1fYgbkRrPyqOVue8nVXSZnxrk0ZVrDG94MivSSPa7PNuSoplPfXrV8XDZnfxu9HM
+VODwebEr4qjUvb6Xxeaj/WCKb1QS3eZ4N2qt0BAGpMbXYG74+uu4qTbmImIjdpyoIQwQnROl73u3
+Phel3nvotkUPww1Xj0n2EdY3yhGc/64KoymEEOK03eN8jRLUUenO21mFcso2ZVTlqLgRJXItb+ZP
+jB3u0bAMr18VD7vbzaVstTv1EdFk+Z5I07u1vxV+hjOmZwf9L6UUOyKObmHXxnqq6++tzbI9pfgH
++HuJyoIBoovBFd9x1q5NdkKw9mmU8LUIb64bzOEoRz7Ue2mnGkGD1npQsdqu67kNqq7zdlbZhFEV
+U2BxY9n6r/RuZ6uxtM6zqQocxpgeF6qxThdZ4D3Y0fAJC26kmukXlPO1+d7Q78B74JzHZa9jFhgq
+isqEAaKLxblguvCjAPXvUPLWQ6cjY5z9LwfmcKye1R6iSNAqjKYQQojNzUsZ8WtlrwOtp+OdVfzp
+YkbajG9lQ/2grHUtkylMjwAWN44sozds8FrvNrfS28sszE68bvAemA/7fI1C5Gw+2gedP5axusWV
+WpvvC41HBVNlr2Fa4D1wh6GiaPUwQHR5GGOfg/e1vzClYB+pSODFVYkwh2O1nDEPorQ6Fz4hkJ9w
+PAwtU7OT3BgNTu+sQjllSqmb6zaqgsWNcyzwHWbwWu822ulttuSus4kLHC7LH4gkvrXMxawKWAt2
+0P+SC96USfzpOnWkoPEAgDBGa7dHvB8d7MoEQ0XR6kAI4DFAdKmEEqTI7Xdlr2MeVutep6tuYmt8
+uTCHY3XyTO81Osm9stdxxGoHUSxrd16D6qe91biTHRT3T35MxXJbr9GoChY3zrHAbWKHB/pBo5Us
+vbhByIQFDpNlT2SjUZmD+qwgBLCj4ZMA9oVqpl9wgSGiGwOAEMo6ZS9jGm40fBKnmxMqisrnct1T
++mB3CwNEl4pSysCFLvj6nhhKBt9Khe+hZcMcjtWw2kMkBa1St0Sh3VOh2E7Z60CbIWmnd0f9/OHJ
+jzXWZFTFFKZHAxY3xmGEEO/8YN7nGfXNXtyI/2tVI62XFjhsUexzFb9f9y4HU+ieHw2/krG6ta7b
+26LzheCfkxr9Btu82Fcy1P7vDtXDyQDRVjfCANEV4JJfc86/LHsds7CZ3u9sVedO9ibDHI7VqNpo
+ivcBOIEc82/QqnBOmYzUtZM7q6zDqMpRcUPF1fn7rppA5ssMG/XNXpRE7wi+ugy3CwscYC1QxjNe
+43BD8B7MYLArWKCqkdzGC8YNBaDr0kkN2vYUNRmGiqJlwwDR8nApWJHpf5S9jmkFH6CR0J+rdCd7
+02EOx3JVbTSFEEKstgdxEt0oex1os6hYbgdCrpzcWeVoVKWOx6Ai01jcuATllM3zg82Gb4obK76m
+ObfAASGAN2a3zt0OJsv2gim+UY34NpfYSrvJaAgZqUGBA7wHYoZ7GCpKFhpqhE7DANFqoITd9K5e
+J4Vg9dO0rZa2tRuaHuZwLI+zHpTgpmoFPaftHpP1GrtF6yFOo21b+F+c9cdFjkYzvjWq2ahKkeke
+pxSLG0uUDc2eilZf3CDkggKHzbJHIklrOf/vjOnZQf9Lpfh1EUe3MAQNEQJQh98DGPV3Zapul72O
+sgGwVtlrWFcYIFodXPGuLezjstcxKW89NJuSYlt8tWAOx/KYwuzGDVWpgH1rPchINFYR1IfQOGkn
+uZGNzLOjnVXqNqqCxY3ly4ZmT6pyihuEnFPgMFmxJ6PkZt3GOcB7MMPB1yy4kWqmX1DOa7V+tBwQ
+AjDGednruIwbDZ9Eqbxbh0IMqh+X654oXt/HANHq4FwwY3yoS2svBfcoSsVHZa8DnYY5HMuRjfR+
+s5V8WPY6zrK5eSlj/DtE5Tq7s0pdRlXykd7H4sb0Qpg8hyMbuj2pondkiWPPbxU4nDE9Jjit2/y/
+zUf7wRTfqCT6hCuF7dbodwCEcZGWvYyLuLzoYagoWobfA0QNBohWEBf84+Cg8henVntod9RVvGtc
+TZjDsVjOeogk73HJKncu7Fz4UeANPFQBZ3dWqfqoSj4s9pRkTSxuTGeag02RuR7ngpZZ3CDkTIED
+vAewsFen3A2wFuyg/yUXvCni6BZeIKK3ABDCyXbZyziPtxYk1b/WraiIqs05D5ANv/49QBRziKpI
+KMGKkf627HVcRjLzQEUcbx5UFOZwLJYpzG6Uysp1SVjtIWmofy97HQgR8vbOKpRTJrio5KhKPiz2
+lOLv4LnQDCjjk7y7FJnrUSp+jeLycwRPFTh8XuzKNK7F/D94D3Y0fELA/lM10y+4wF9YNB4EQhhj
+75a9jnEgBCDF4CuusJqMFuNkgOh2l32CAaLVB4FeBV/dq1Ori167E/2l7HWg82EOx+JkI72fNuMP
+qzguarV9KlQ1z2fQZjq7s0rciCo3qoLFjfkEwi7tgjdFdYobhJwocJgs3xNpWov5f1PoHhTZIxmr
+W1ypnbLXg6oNwB5UdQcVGLx+pNIIdyRAC+GLbD+Bg0cYIFovXPIdZ+BF2esYJ4QAiSLf44lhtWEO
+x2J46yGSrCdV9Toqgw9AAuQcO5VRxZzdWaVKoypY3FgASgi5IILDFK4HUJ3iBiFvChzGmB4XqlH1
+8Q7wHuyg/6Xggco0uVP19aJqoAA/VbFuZ7Phnkrk7ToUFVG1Oa17hzkbYSdtRXcwQLReuBSsyM2r
+aUK8VsXk5mWjFWMRtgYwh2N+xUg/Uqmq3GgKIYRobQ/iNLpR9joQGud4ZxWAcDSqYo3dL3NN+bDY
+iyKBxY0lOipuxEl1ihuEEMLAe2A+7PMKtzFDCGCybC+Y4hvZSO7hOAqaSiCm7CWc5XTRi3h4By9E
+0TycdUDzg/tbqaHtTvQFBojWF2XkOngoexmneO+h2xY9jsepWsAcjvnkmek1OsnNqgbpOmf3mGSd
+steB0HnaW407o4PDzo24EW0XObwqq+ia9w+LGxzz7eZGCSHjfojGVLO4QQghzI7yXZHEldrj+yRj
+TA9Gw12l+HURR7fwbjeaFiVBV6nbB7wHGfSvrOSE4erDE/XznAwQ7XTlXbw7UX9Sqm6R20dlr+Ok
+YO3TKOGVvJuN3oY5HLPz1oOg5IcqjqYQ8mZ9TIiqFl8QOpJ20jtHO6uUNaqS94u9KMHixjJ568Fp
++l0VixuEEMJUs3G37EWMA96DGQ6+FgSobCT3KG6JhWYAIQCpUnEjBAjZwS6Gil6MvrWBNSJkfIAo
+Fn3XA+WUeQNxVUYMvPXQ7agrrELHT3QxLjmz1g7LXkcd6dw8jlvRJ2Wv4zzGmJcqFZVdH0JHOKdM
+pfFnRW6flzGqgsWNxWOMhJP3HL31oHPyKG1GlawhEEIIq9Kd7SM2H+0HU3yjkugTjncm0TwAiOC8
+VfYyjsDw9SOVVPeAgKoLA0TXH5f8lrf+ZdnrIIQQFuyujDju1lAzIVBZlSJZXejc9NJW/EGVuyO8
+CT8KvNGHakJKzgghV4xx+6scVRlicWNJ2PbRD897OCxutKI7pS7pEpW6T+qsBdt/fV9IsSPi6FYV
+iy+oZgAq81tus9GeiuRNvDBF08AA0c0hlGDFyPyfstdhte61O6qS22Sii1FO/4z1jcl5H4CR6o6m
+EEKI1R6iVP172etAaBpxGm27wo+c9QdJM76VD/X/WubrDfvFXorFjaWgjO8QQkjwAHkfvqp6cYOQ
+ilz6gfdgR8MnDOxL1WreY1ilRgsCgRDGWekz5E4XPcV8gwmGB140EWcdsLz/JQaIbhr6vnflXqFK
+Bt9Khd2TdaSk6HpbzS2Hq0hn5nHcVJUe/bDaPheKYTcVqp20k9zIM/c9pYEyLv4fa9zBMl5n2C/2
+0hSLG8vCKCHBBRj1/VfNbny77PVMovQChyl0D3T+WMbqFleqsju5oJoKQA7zf8sD3oNwRaV3KkLV
+cRQg2pH5P9tdcQ8DRDcLj/iOs7a0oEib6f3OVnKvrNdH8+GSM6PNv8peRx3o3PTSpvqgyjkzwQcg
+AV7zCq8RoYu0uslnowP9IG5E20Xmvl/0qMrwtX6SpuIdzrG4sUjBB/DWg9UedGGh/9o8bnaTWhQ3
+CCFElPXCYC34In8gYvUXHsWflrUOtOa8/zuh7K9lLgGyg4eqEWPuBroQ+ADB5E/bkaOqKz7BUabN
+xLlgOtcjFYWw6t+B4AM0G/QXzhkWY2vsKIejyhfuZQs+APHhmVS80sU8YxyJ0+hG2etAaB7NTnpn
+dJA9TFrJZ/kwf9xoxwvpmhoe5A/SlrqDBcDpeR8AAEgAQoIH4kN4SRz5DUIwNDDNKaFciRajLPhB
+biXI3PXdro/o51HES2+QuMzKCxwQAvhs9JQJFstGcg9nfNEyBQKl/oq5QW83Sqo/q4bK5YtsP+Vm
+P27L24xLPCZuOErZdfC+z5norPJ1weqnSXcxJ56oPEc5HKzyp6DlyUf6aWur+jcerDWPoiStzV1T
+hMahnDLViD+zxv3AOP8Pa9yBVPO9vw0P8geNprqDhdy3hTfFCwBCjv6fhvB37wklQAaEUCIljygT
+kRBsiyq6QxnZoZTuUErJycBlnZne1T92QtD+hYyjdymDl72D7Een4L+iRG6V+X1eZKUFDmNMjxn9
+TCbRXQwQRatAQxiQkgocNsv2okhgqOiMQih7uGj5nNa9iOTftpvyHhcR3jVHhBBCZCS6RW6/akix
+sgsbbz00m5LiyWL9HeVwCMGvlb2WKtKF6yVNtV3133VvPQgmRJV3d0FoUlJy5q27wiTPisz8kwv2
+6ax/g5te3Jim+0JIdotSSiilf6WUkDf/PNF/N+8DJJ7+kLTiTwub22DdSDXU9Xe6nR3r/MHrg+xL
+y+2/80S+yzmtVEl9JQUO8B5cnj0SSt7kDZztRatVRgvHYaioo0xgfsJsKnWcXDhnPSg3erDVpH8R
+Mvqi7PWgaqGUMnChCx7CqnbNoeAeRWk9wsPQxbjkLB/m/4oSiQWOM4IPQJx/plqq8ueixpiXUVrt
+AFSEphGn0XY+LP6vjNUH+dDMNKoyfJ3vNlrrW9xYZPfFvNxAP95qp58QQkgIhHfb6fV//Ta639pK
+vlBSdP9tq/2F9z4MMv1wCMUWi9m1N1sEl27pBQ6bj/YZIT2VRLexawOtEngPnPO4lNeF4gceKcyW
+Qac454GZ/HEnDf9DNgWO6KFzccmvOedfKs52lv1aVpveVkddxTvF6wNzOMYrMv200a3+aAohhHgT
+fhRNjp19aK0kzfjm4HX+Fefsz9OOqgxf57uNdnS7zu9Vq+q+mJfOTG8rjX8PYeY0DSGQbju5O8iK
+v6dpfIsQQjjntNtK77QhDllhnh7kmaYR+1iWnNOxtAKHM6YXdPGtTKJ7lOMBGpWDCqZW/Zp+cNvb
+t0oAACAASURBVLCbtOPK3x1Cq3MyQFR2+SeM4VbY6GJcClZk+T9UJJde4JDMf6uiGDuJ1gjmcLxN
+F64XN9R2HQIJrfYQperfy14HQsvQ6iafDX4b3c+tlZOOqtShuFGl7ot5BB8gsvR7lZ4YkxX8I4BA
+pORMad51xh8IxY+LU4wx2kzjW2msgjb2Ze919hNE4UZZOR0LL3CA9+CL/CkXbJs3UzxhQqUBACI4
+fW+Vr+mGr7+Om6oWd4fQamCAKJoVJew97yBwsbwLMlvo/Svb0V+W9fyoHJjD8bbg/HeqVY/3Z6vt
+86Slrpe9DoSWpdlJ74x6w4eTjKr0f8t2W9249OJGXbov5mUG+ukf2+nnJz/GOSPGuhdC8GvNZvze
+v3qDrxsy+eTs98QYo0kc7cSRerfMnI6FFjhsPtqnIfwiY/UJjqOg0gEQItjKdiGwWbYXKf4B/u4j
+QjBAFM2PK75jjf0bF9FSxt1CCJBE4WexwjBTtBqYw3FaPtR7jU49djQLPgAh4VUdOk0QmhXllEWd
+9PboYPS1umBUpf9bttvuxreXXRxYl+6LeenM9LpJ/FYIMxeMuJHtk+Tw37fazY9/62ePWp3x2V2U
+Ujoup0PE7BpfQU7HQgocYC34In/AY/UXLgTmDqBKCME/J5St5A4IhoqiIxggihaFc8F0pkkUh7CM
+3Zi8Ns+7f4g/v/wzUR1hDschqz1EkaB1KRgY40icqA/LXgdCyyYlZ2kz+aD/avC/t/7U+n/PFgkW
+WdzYlO6LeQQfQLrwLErFW2P2nFNWgC9O/nsz4deMcT8rJS4cpT3K6Wj5OOTaPH2d54FF9KNl5nTM
+VeCAEMBno6dMsFjhOAqqGgC9iuMReA/cFT/wBENFN5lzHgQGiKIFY5x9DM73+RRBbJPw1kOrKQxf
+0S4taPUwh+OQM+ZBut2ozTmq0e5xlEy/uwRCdaRiua3S+I9ZXz9udn7/vT94NXrY2UomKm5g98Vi
+vBlNOXeMD0iIThbNkzjeLg5Ge56zMMm5BOfjcjrg8yhRC3+XmrnAYQrdo858L5Poc2zJR1VEQ8jI
+Co5ZfnSwmzQxVHRTYYAoWiahBClG+tuGEovNDvAWL6LWHOZwEJJneq/RSWrz/uytBykYXnChjdLs
+ph+++ufr/x0lh6MqB69GD7vb6fHoA3ZfLJ8p3NjRlFMYfSeE0x/a6jRu/Ppq+GVrK5m4iDwmp+Ob
+QpgP41h16IJyOqYucID34LLskYjkTd5IcG4XVRjAsg9qbjR8Eqf1CC2rFUrC5Z9UPgwQRctGKWVA
+6TZ4CGxB3RZWe9jqqP+x6aML627Tczis9hBJQevUpWS1P1CpwMIjWqjDXJe3jf0gIYcZduc9NOUD
+4ZzTuQCnP97sNv76y0+//U1KSra2GvHowDzB7ovVCD6AMP5ZdMkOkEyKHYBAOD/98bNbx07qZE6H
+cz4MR8WjQSh2ZMLfnTenY6oCh8myPU6DUY3lh70gNA8IARg7+ye4WDYv9iMZ3qd4x37jYIAoWiXO
++TVn4IVK2EIuVDk1uzI6vw0VrY9NzuGo22gKIYQ4654lTK7d3+aiLrCXdXF94gvGP/15nw7uZaDs
+1ZgvGPv35sc/DSH+3G/AMkaK8Q++DYBQxia/QRQopYKz1tgHzz1ijH+AEjr2dbliYy962ZjZOcUj
+/sd/a/1PITnF7ovVMQPz9I/t5NLjDheMaOueSslP/UzP2zp2GkJw2u00brd8spCcjokKHM6YXtDF
+tyqJ7lGOF3OoBgAI4yJd2tNr21PUZEwIvLjdIM564G70aKtJb2KAKFoVLgUrMv1KxvyDeU/2rC56
+293oQzxp3AybmsNRt9EUQggpMusA/B9M7gI5c6l93gU2BPj7OQ8s5AKbETI4/0J3zMtOeYHNOIsp
+pWrsgwu4wKacXWGcvPvWxxkl9LwXGPNhfu7L8h1K6PiAxcmf/s0D531f5336eh3Di5HeTxsyl5Gg
+2JWxOoejKdHFoylvMMaINSYjY66uLto6dhqLyum4sMAB3oPLs8dC8j9xDBFFdQJACCfbS3lq74GY
+4R5v1GPLOTQ/8B6C1k87qb8imwI72NDKUUaugwfCxeyNaSEEUJx8Jxed54EqaxNzOJz1oASvVYCu
+KVwvH+TfJ011lau3bySed2uREvHXcx44F15go6qx1gP35BVVUmBxY7W49t9FnXiicwLOKTMh+BBC
+GPf3f9nWsdM4mdNhrP354KD4h5HmQxVNltNxboHD5qN9RkhPJdEnGCKK6gYCIYKxt6r2C3nuUX83
+amDuxiYAHwBM/rwdOSO7/BZjAo+FqBRSqm6R20eNFp/5xMHk5uW//VuMhdkNsok5HKYwu+2t+oxg
+5VmxJ5ig3T80P9OFeywEv3DLRYTWjR2aB80kuus8vCh7LZsk7+u9d1rJdOcEjDRDCGRcHWqarWMn
+RSmlkVJX/02pq9a616NMfzVJTsdbBQ6wFnyRP+Cx+gvH9ntUUwD2gFDZXfTzutHwSZTKu3jnYv1h
+gCiqEsopAwN81jwF7z1026LHOcP39Q2zSTkc2UjvN1tJLUawgg8wGhWPGo34JpesSwghMCw0IVHZ
+S0NoZUb9fK/Tiu/p3L2WyeZ0mpXNag9dIenU7wuUXg1nt1I5IYnjbXtQ7HkOE20dOw0pRbfbEbdb
+PgmjvPhbP9fqvJyO4w+A92BHwycE7D9VM/2CC7Hwi0OEVoUC/LTo8xuXFz0lw/vY0bTenNY9rl9/
+udWEZtqK7ixq5wqE5sU4/9hb/3KWrw3WPo0S/tGi14Sq7yiHY9056yGSrHdULKgyU7heNtRfNTvJ
+7ZPrBcZasAk/LITI4d9BQ6kG54w6534YFzyKloPm9kGSquvTfh1TrGtduPA8pN2Jbwz75sHsq7sY
+54y2m+mn77Y7t7okeeH6blfr00FCjBBCTKF7UGSPZKxucaWwNQ7VXyBmkU/nrQVJ9a9M8MqfOK2D
+QGh8bpz5kjjrIeT93a3U0HYn+oLjzxpVjFCCFSPzf6b9Om89dDoy3oQ7+OhtRzkcZa9j2UxhdqNU
+Vb6Il4/yfUrIr62t5PbZvAHJ+FW44O4oQusi+ABEu2dRJK4GHyBQYjF/YzXyvt7baqUzhTAzxojz
+/rfLPm+7Hd/JsmJ8CPKCMMZomkTX/9Tp3v4jT1+Gg/ClznQv+ADMDvpfCh6oTJM7eGcarQtKgl7U
+7zOEAKQYfMWVnLrSiWZEF7Md5iTAe/BZ9qQjs39udcVtIbF7DVUZfR/8dHd4KdhHKhLY+ruhuOTM
+aPOvstexTNlI76fNuNKjKcEHGLzOv47juBml488nuKRd72CmLi2E6kT39eNGM7pLCCEOgCgprpS9
+pk1wNJoy6/iIlJxpbfuTfF7E+I4z/mCW15nGcU7HVvuLd6IuVRn/islGcg/HUdA6gRCALLBYB4PX
+j1Qafb6o50PVAD6AL7K9Jh19s90Nt1Qsdqp8cowQIYRwyXessU8n/Xyrda/TVTfxd3uzHeVwlL2O
+ZfBvRlOkqm7XndUeslGx29pKPrlohIZLQbzxv6xybQitWpGZXpqqD466Cp31B0Jh/sYqzDqaclJg
+hIeLgjjeaKTxtinM96t87znM6WjcZnjSg9YOABGctxbxVDYb7qlE4raga8YX2X7kD77aboXrUSpv
+Yes+qgsuBdO5H4UJ+9glg2+lwpsYm26dczh0bh6rCo+m5KN8n4TwotVN713Wgs85ZeB9saq1IbRq
+3nqQEPZPFiSdcT/hadjyzTOachrdmvT9pNNqfJINiqXlcZwH01zQ+gFYyG+200Uv4uEdDJlcHycD
+RJvt6Db+bFEdUcaug/eXtojaTO+3O/FfVrEmVG2Cr2cOR56ZXtqKP6jq7P5lIynjYNAoWmdmqHeT
+NDpVkPSEDPBG03JZ7aEjxMyjKacIfm3SQxTnlDUSebPIzfO5X3cKWOBAawcCIYyzue7mgPcgg/6V
+yeq2vKLJYYAoWicyEt0it99d9DnBB2gk9GeBxzBECBGCkXXL4fA+gKDkhyqOpljrYdTP77e68YUj
+KeMoya9ifQOto6Kf7zUbp7dxttaDUqJd5ro2Ac3tgzSNFpIlyDkj1rmJC+ZJHG8zR8FPmR82Dyxw
+oPUTgBAye4ESQoCQHexiqGj9YYAoWkeUUuZdiC8KGwWrn6ZthdlBiBBCCOWUwZrlcOhR8ThuRZ+U
+vY6z8lG+H/ybkZQZ7kpzzrveY9AoWi9We4i4pOJMwc9bIELiFubLdDiakixgNOUQF4w4A5d2kZ50
+tHXsJNkdi4AFDrR+vP/7HPUNAsPXj1RymOyM6gkCBoii9SYkv+WcH3sR5K2HZlNSbPlFJ7E1yuHQ
+eTVHUwb94usoiprxFCMpZzHBiCv8/iLXhVDZfG4ejvu7sMY/ZbxSf8ZrxVoPbc4N54v7j8w5ZRam
+zwrabsd38lxPHJI+DyxwoLUTCMx8LWuz0Z6K5E3KqnXStJFmPA/3RbYfWQwQReuNS8GKTP9j3GMU
+3KMoFXhHDJ2yLjkc3gdgpFqjKccjKe3oEzHnujinDMD7Vd3pRGjZRgf5k1YrvjPuMU9gwPE8bWnC
+0O42GvGtRT+vZ2HqrKBVbh2LBQ60dmggQzJDfcLpoqeYbzAx3bwsWoZZfn6HAaLdBgaIos1ACXvP
+u9MnGFZ7aHfU1ard2UblW5ccDp2Zx3FTVWY0pchMD5z/ZtaRlHEYF80JN0pCqNKKzPRacfT+uL8N
+bz0oxTB/Y0n0SO9vNeMPl/HclLGtWWqwq9o6FgscaA2FMG0LB3gPwhX7XImry1oVWo6zAaIYqog2
+BVd8xxr7t5Mfk8w8UBHH4xh6y3EOR407A3RueklD/qkqnXmDfvFEKUGTRrTQO6RCso/CmowToc3l
+fQDp4NxuK+eACCHfW/W6NoG1HpqE9+SSsucY5zvOhalyOI6sYutYLHCgtQLeA+c8nvrrsoOHIlEL
+b+FCy4MBomjTcS6Y0d6FN7d6rS567U6E28KiczFO/xwAyl7GTIIPQHx4pqLyb0RY6yE7yL5staNb
+846kjMM4I9762o8Toc2mX+ePkmZ8breVtf45E7SzyjVtjJHdTc9sx7tIXDBivf9xpq/llDWSeKlb
+x2KBA60dKpia5vPdoLcbJdHY2UBUPRggitDvGGOfg/f9EAIkinyPhT50EcFF15t65nDkI/007ZQf
+AH40ktLcanyxrE4SJhhxGn5bxnMjtArFSO+3WsnNi87PvPevMPJu8fRI73cb8YfLPDdmjBFt/WDW
+r09iudStY7HAgdYKABDG6MTtbjbL9lQkMFS0JjBAFKHThBKkGNlvTG5eNloxbguLLvQmh+PXstcx
+LV24XtJU22Uf87MljaScxTllEDBoFNWTtR4iwrKzW8Ke5H0AwVmEN6gWy1sPjSWOphzhnLIAgcxz
+jGp34hvZYDlbx4pFPyFCpQIgRLCJ2t0OQ0UdZQLveFad07oXQf6s1RQfChndLns9aL2FEMb38F/Q
+2Q/En/fADK9/3sfHP6CHeuudd9Rrzlnprfuo2iinzAeqIIRQlyDa4AMQ55+plrpX1hq89aAz/SDp
+JPdWtePDUdAor8ePCaFjdmgeNLvpFxd9jnOOiEj956rWtClgZHcbncZqOt0YaYYQyDxvJd1WfKef
+FX9rNOJPF7gyLHCg9RKCf0ko27ns88B74FD8wCO10D8otFjOeuBu9GirSW8KGZV2crssdbuQfvPo
+tK9/wDmMn9OE8dvlzPDqRDAYcDpdUyIEoIyyie8cUBqokrw11YsQcv6mQHT8t8M5fZ+ycXPJ458o
+p+QDzuj/Mpm+D0CucCmuyYhjhyYa6ziHg/OylzKRItNPG924tNGUIjM9SsN+c6tx4QXboh0HjeJf
+MqqRUT/f67TjS8/XrPbP4wa/voo1bQo90vvb6XJHU04R/COAQNgcxygpOUss/7M1/kAqvrA8Fixw
+oPUC8Bul9NIChx8c7CYTHIDR6kAIQAAIACFeG8iL7Fm3RbZUwj8LEKjV5vASuoYX0tOq6oX04dou
+et8c+1iX0PND+M59tukfOHd36HVvgVWp4oyzpNmJPwqEEGf8S53pfxwVO4RghC77lxbVxlEOB0/4
+tbLXchlduF7cUNur6po4K+sXT+JUvS8UX3kIOZOMOOtfCFH9nxNChBBiCtdrKNWY5O8VHPRwynhx
+jkdTVrgbJOeMWO9fCsEvve66SJrG273Xo/+PC/rXRY0hYoEDrRUaQnbuVc4bbvj667ipSg8q2zQn
+CxgkAKEABxTMTySAkcFqTikR3LcJI4FG4S/bTW862+k5B028kEbopKQhPtS5e5o01C0es50oljse
+IHgHPxcj82OAoCjnH0slsNix4YRgROfFryqRlb9wBmu/Va3Vdk4QcnixUAz1brqV3C2ruCIYI0bb
+30hSxqsjNB3vA4TCfR91kkvHiL0PwASjeM60OHZkHm93mufuWLMMlBHibPiNRGSuAgchhGx1G//9
+f3uDB+1OupDrMyxwoDUDcNEB02bZXqT4BxTLxgsHPgAhQADgsMsi2JcU/G8suEwE7wUDwRlJqaAR
+5/QapbRLKOlSQgll/M3Pg715LgAVB6Ez8yhtX/5midAmoyQ855JfL0YOIIFwdAeEM0a5YleVElfh
+sNhxkGdmL/jAKecfcyUIx2LHxqlLDkc+1HuNbrLyTssiMz1Cww+tK41SuzwPf04QQggBLwRR1el+
+8bjTSSYKunbOERmJuS+K0SGdmd6VNPlg1ccJKTkrRnmfNKKFPF8nTW/nuXkeJ2ru4jsWONDagBCA
+sfOHijFUdHaH3ReEnCxgUNDPSQhaBDtgAYiSEFFCIsbpFpdsh1CyQyjZ+b2AMfm8N+OMFSMy7P5B
+3M36+UMsciB0PkppQQghUcJvHXVxnP0cxhhlinWlErcBIHgPB0VuvjNZEEzwjwUWOzZK1XM4rPYQ
+RYKuunsiGxR7KpYNFYlK5HMxTrcAAuEc6xuouoqR3m+m0QeTFky9g5cyxgLHIngfIPH0B5mWc8wC
+EqJFFWGjiDNdUHDWHwg5Xx4HFjjQ+gAgjIt07EPeA3fFDzzBUNFxzo6PkBAI8/ppAE8UcQNOCBEC
+2oQeBp9RTgmh5DqllBBKCKXTFTAmUXiIKKVUJeIzLHIgdD4IhB7+bXKmc3Oqi2McxhhljHWlFHcg
+hAAOiMnt34ocHGXhhpCywyWGlK6zqudwOGMepNurG02pwkjKOFKJawHCot9eEVoYaz3IQHpS8Ymz
+H5z1+1GqsMCxAHZQrHw05STKWGuRRdh2J77x62+j+80OuztP0QQLHGh9ABDCydg+KT862E2amxsq
++vv4CDksYIB9ycD/dpR/wWigkofWifERQii5RQklhLI32RKrPcPygbVCCIRzxlQiPity/XWcRFig
+QuisExGyF3VxjMMopUxyIiT/NA4hgAdiCve3YlA4ygkWO9ZUlXM48kzvNTqrG00xheuBd6WPpIzD
+BCPWwFMhVx9yitAk7EDvbm1N/rcTfABCGa3yeFxd6Mz0tksYTTmJSn7tsMCxuOfstuI7/WHxuNGK
+Zy7cYIEDrQ0IhAjG3jpZc6Phkzhd71DRs/kXR+MjDFwmyO/5F0zQbcbpu5TSM+Mj1eM9P75zxTlj
+wcOfdW6fRxU8IUeobEd/xJN2cYzDKKVMcCKa/NOkoQIAEF24p8Uo6xPK/11K8S4WO9ZDVXM4rPag
+pKCcr6aLIh8UezKSjThNKlk8F4wRbfWAEFn2UhB6S9HP99rtZKrza+eASMm3lrWmTXE0mqJKGk05
+wgUj2rqncoFFWCk5SyT/j3m2jsUCB1obAPaAUHkqX8PmxX4kw/tVvYifxLjxEe7134EQqoIZkBCO
+8y+EYO9RTjvLHh9ZCUGIMf74zpVQYtsZR3Rhn0cxFjkQOhICObW1z7RdHONQSinnnKQNfitJD4sd
+1vjnxSD7F2H8fS7EuzLCYkedVTGHwxnzoL2C0RTvA+hh/iBpJ/dWVUyZBeWUBUJY1QpRCJnC9SIu
+py5GWusPZEVH4+rEDorHW+1GaaMpRxhjxBqTkbEBAbObd+tYAdYCYeeco7z5OKMYPIaqjwL8RCk9
+LnCAtj1FTcbE6vaEnsU026cKwQ7HRhT562EBgxJKWT0LGJdgjBFdmEHa+P1jQoltU2CRA6GTOA/m
+5L/P08UxzlGxgyf8epyo695DsMYdFjs4v8K5uIbFjvqpWg5HNtD7zc7yR0mPRlIa3fReHXYn4ZRu
+HXYzVn6paEMEH4Bo9yxuTz9K5pz7IWKy9AvzOjsaTVnE+/u8OKfMBnDLeO55to4VwbmngYTT/4EO
+d0voh0AICYF4Qgg5DDE7nPSllJDAWoSQo10dj1FCQmDkCmX83dMPsONPOPVl44orWFhBswjk+CQf
+vAdihnu8Ed0pc0mHa1nc9qmbhFHGchNY90w6s4oPixzWuO+lEtfLXCNCVUA512fPchbRxXEezhnl
+iToudjjrX+pM/wOAXOESix11UaUcDmc9RBHvcT55UOEsqj6SMg7HoFFUMbqvH7fa0dQXncEHCJRY
+7EaaXVVGU07yLLQAFnND5axZt44VIlZ/neYLQgjhzT+c9wmH/3f870f/AL9/ig/PQwjF+MIKISFA
+nxBC/NnXoJSEQAgl5xdXgJP3GT0zr0PZZIWVEx/H4kr9UBI0ffPHBaP+btRYfu7GqrdP3TQQaBog
+EHrmzpWKxbbJLXGUHQjJ5tpKCqHaC/DWh4TkrMgLHSViKScdRzhnlHO2E8VyxwMEZ04XO4RghOL2
+s5VUpRwOU5jd9tb0d+km5X2AvF88arTjm1yyWm0Vj0GjqEqKzPTSVM3UPeAAiJLiyjLWtSncQD/e
+aqeV6oBhlF8N59UF5hRFnGlL/bRbx06dwXF8J/WS98ILHxVkpruukxRX3i6sBHKyuAIO/n740THF
+FRp0gKAJOa+4EmJK+GHS04nTNXr0auLMm880XSsnPo7FlelB+P0M342GT6JUzrW90Knnrdj2qZtE
+O/bReX/uKpHbRW6+I0QRLHKgTTfueBdF8mNn7EsVRyvZjo8zRnn8e7HDO/i5yMzPwQdOOf+YK0E4
+FjsqpQo5HNlI7zdbyYfLGhcxhetZ6/Za28ntOoyknCUlZ8VQD0mKQaOoXN56kD78IBM+U/eAs/5A
+qGqMxNWRzkyvm8R/qsJoyklMsa5zoc85Wcq5eLsZ35x269hahYxOUly57LtmgkzVsXIkhBDm6loJ
+4SD48OPhw2OKKxCyQIN7ayTo6Hu9YCQIWIgZE6cPGJs2EgRAhJRtlxc9NUWoaB23T90kjDFinXvB
+xfjWtDiRN7HIgdB4MuJsNNA/iSi8u+o79JwxyhW7qpS4CgDBezjIR2bPYbGjUsrO4fDWQyRZj0u2
+lNGUfFDsiUjQVicpfVx1LoHKKnTaoM1mhnq3M0MewhFn3E8qFrXqoKqK4ANIF55FqajedtaMEev8
+jxERS+sy2+6kd14Ps4m3jq1VgaNMlFI6V9cKIV0iydR/1IsYCQIILwOEV8sYCXorb6WsrhUAAt5C
+JNyvTMjjDqHLtk+VPHBGQ6NO26duEsYY0bn9LY7P/5w4kTdHw3wvpgkRAoscCJ2klPjcaftSxWol
+XRzjMMYoY6wru+L2UbGjyM13JguCcfKfQsoObj9bjrJzOPSSRlPqPJIyDhf0HQwaRWUqRvleszFf
+p5UnZFC17oO6MAP99I/t5Y3xzUNKzopMD5sL3knlJM4pSyT/D2P8vlKXZzVhgaPiFjESxAjZIYf/
+m8qFxZUJCiuEEBI8PA+BjM9buWQkiATCCWHp0Tdx/NCbVzuZt6KLwihz4FlT5t4VTybfPhVVGeOM
+OUMuTWduNOMbo2G+l6QJ4VjkQBskhADkgvrw710ccuVdHOMcFzukuAMhBPBATGb/VgydoyzcwGLH
+apWZw5GN9H7ajBc+mmIK17Pafd/cTm5X4Xd+EbjkO95Bn3N8f0OrZ7WHiEgq5igWWutBKdFe5Lo2
+hSlcr5vE21UuDgUAGs5sCrBoh1vHZj+BoDuX/bfAAgc61yJGgmbJW5m2a8XqvBeZV8/akY7TJF37
+7VM3TW5DCyAExi4+aB4WOfSDtBndqfKbAEKLBECIkuyCHqdqdHGMwyilTHAi2vzT+KjYUbi/FYPC
+UU6w2LEijNN3Vp3DcTSaIie4EzeNPCv2BBO0tZXcXuTzlk0IRoxxP5IltoAjdB6bmQfNbvrFPM/h
+LRAh+UeLWtOmCD6AMP5Z1F7+Ftpz4TQNIZBl15S3uul///pq+GVrK7nw9xFPHFDl0COMjf8f55Ry
+TgkhwevB31JhWZpw3mgl/9Pk5hFlh19e9veBFsMGdjXAZOnMjaa6O+oXDwGWFOeMUAUxRtRFj8uI
+M124n2BZMecLwCilQnCaNqNPO1fS28123KU0fFOMsi+LTO9769/eKgYthOBix1t4ucrX1Ll5rFK1
+sIud4AMM+/luHEXvRKlcu+3DueTMG9cvex1o82QH+kl7ARfX1vinOPk9PTMwT7vNpJKjKacI/hFM
+eK4+r247uZvn+vlFn4MFDlRLtsh7VPceJ4p9QihvK+4oE4xHifzM5ObvZa8PLRBlXef8xCffzXZ0
+Z3SQY5EDbQggF42oHDnq4ljBguZGKaWcc5o2oludrea9Vjva4Zy8KAbZ/WKk963GYsciCcGI0W5/
+Va+XZ6aXtuIPFjU+YgrXy4b6q2Ynub0OeRvnCYFFVS5SovVTZKbXiMQ2X0BXrCcwWMTzbJLD0ZSo
+0qMpRzhnxFj3YhWvJSVnMrDYWX9w3udggQPVCngPNnv9dcwLquLoU8ooBfBEKbpDyGFmA2d0xxpz
+YWUP1QdjjFgb/jnN1zQ7h0WOgCeDaN1NeMekDl0c4xwVO+JEXe/+oXWv1Yl3lCQvikF+v8j0HhY7
+5kc5ZQFIWMXvhvcBBCU/SMUXUojIR/k+JeTX1tb65G2cRyr6DgD+uqPV8D6AdPCDisTcj1K37AAA
+IABJREFUY2TeelCKYf7GlLj230UL+O+/Clww4gysrMus2Yzf05l9dt55PhY4UG2c7Npg/Pdtppgz
+Lzlnx7PlIhLbLNAr1lgscqwBxhnTGehpv67Zie4MD/IHy1gTQlUy6VVdnbo4zsM5o1Girnf/0LzX
+asfXlaL/NJm+XwwPix3BB7wCnAUnO2EFF896VDyOW9FE2/xdJPgAg9f513EcN9dxJGUcJvgOuIBj
+KmglTD9/FDcn25LzMs4BEUK+t4jn2hT6tX6y1arP9tacU2bBF6t8zW47/Twb6sfjHsMCB6q8cV0b
+Jx8XofiRnuneEpHYpgAxeDi3fQnVR+EhmmXkpNmO7g37+cNlrAmhKgBCJq5w1LWL4zycMxrFcqe9
+ld5rbcXXo5i9tNrsYrFjeqvI4dD5YkZTrPaQjYrd1lbyyTqPpJzFOSPe+x/LXgdaf8VI7zcbyc1F
+dUVZ658zQXEHoAlpbaETySt1GE05CUiIYFVBHOTk1rHu57OPYYEDVdph18brt7o2joAPEMkQjQsV
+lbF6zxj9CxY56s969s6kQaNnpQ3xWYZFDrTGGKHRpJ+7Dl0c43DGqFLi6lGxI45Z3xrzlR4WX5vc
+gsdix4WWncPhfQBG5h9NyUf5PgnhRaub3lv3kZSzuOTMFm5Q9jrQerPWgwysN8+WsGd5719dshEe
+OoHn/kGcVGvXs4kw+s6qb5+kabztC/+vs4UVLHCgSjrdtaHe6to4/jzwRCr2n+c9T5LEN4zRv6yy
+oogWLwS+AzBbay6ljKkEixxoTQEhVLJrk376unVxjMMZo1KJbrub3m5tJZ8kDdEHZx5hseN8y87h
+0Jl5HDfVXO3umzaSMg7jXOH5DFomOzQP0oZa2HbE3gcQnI29EYnelvf13lYrrfaWsOdgUuyUcXja
+6qb/PTooTo2kY4EDVc5lXRsnca+fU3Zx21uSxDfMSD8MuKtGfQlCrJ29NZfzN0WOYbG7yGUhVL7p
+D2vr2sUxDmOMSim6rXZ652SxoxjqXZ0VPdx+9oQl5XDo3PSShvzTrO3W1noY9fP7rW68USMp43DO
+/oynMmhZRv18bxFbwp7knCMiUufeiES/s9pDV0jKeb1GU45wwYi27mkZr91tp3dObh2LBQ5UGeA9
++P6rLy/r2jiJg351Nn9jnKQV39GjAnfVqCnGGClyP5znOThnTEn6uR7hNsJovUx7X0xGnOmR/WnT
+jocnix3t7eR2oxV3KQmPi0GBxQ6ynByO4AMQH57NuhNDPsr3g38zklKzefRl4JJ2wS03KwVtJlO4
+XkOpxqK3crXaP+eYvzERmtsHSapq26HGGCPW+KyM1z67dSwWOFAlWJ3vM/36myiV9y7r2jhyUf7G
+OIdFDo138GuIUcYKG+gsQaMncSkY42FH57jDDloPs7aDqkR+7sxmdHGMwyilQnCaNqNP21dSLHaQ
+5eRw5CP9NO1Ed2f52kG/+DqKoma8wSMpZ3EpiDP+l7LXgdZL8AGIds+WsSUpOOhhbfJydR5NOcI5
+ZT4EX9bNk5Nbx2KBA5XquGuDFU0Zq1uTdG0cfy24C/M3xoka8nYxLDCLoYYcsK1FHDOFEtuMwhVd
+YJEDbS4ZcVYMN6+LY5yTxY7OlfR2sx13OScvikF2v8j0/qYUOxadw6EL10uaanvazovjkZR29ImY
+M5R03XBOGfjVbsWI1l/eLx43mrMVIi/ifQAmGMX8jYvVfTTlFEaaZZ5WHG0diwUOVJrjro3G5F0b
+J3FvnlM+Xdsbo4xFifysyDGLoW6859dm3UnlLKHENgEscqD1MOu546Z3cYxDKaWccxon6nrnSvNu
+qx3tHBc7Rnrf6jUvdiwohyP4AMT5qUdTisz0wPlvcCTlfMBYC4NG0aIUmek10+iDZfy9OeeIjET9
+dgNZsbqPppxC6dUyCxycU5ZG/D+wwIFW7q2ujRnPzjnoV7MckBlnTAp+3RqDF7d1Ighx3r9Y1NOp
++LDIYY37flHPidCqURJmPo5hF8fFThY7un9o3Wt14h0lyYtiWHxZZHpvHYsdi8rhKDL9NJlyNGXQ
+L54oJWjSiBa2g8M6koxfxaBRtAjeepAQ9ufdvvnc53fwkgmKBY4LrMNoyklMsa51odQbJ0kcb2OB
+A62UzbO5ujaOgPcQRUTN+vVCim0W6BVr8A5+XTDGiM7gt0U+p4rFtrM+cRYOFvm8CK0KpXSudnXs
+4pgc54xGibrevdL4otWOrytF/2kyfb8YHhY7whpsP7uIHA5duF7cUNuThhVa6yE7yL5staNbOJJy
+OaF412PQKFoAPdC7SRp9tKznd9bvM4aXmuex1kNHiPUYTXmDMUac9ws9V59pHWUvAG2G464Noefq
+2jh+PgAiBf1gnucQkdhmgVxxzuHFbQ0wypi2sPDwojgR71lj/olFDlRHEAglcxxNsYtjNpwzGsVy
+p72V3mttxdejmL202uzmA/2kzsWOReRwgLXfTjqacjSS0txqfIEjKZNhghGPQaNoTkU/32u3k7vL
+yscIPgChjDLM3zgXHdkHaRqtx2jKG1JyprXtl70OUfYC0PqzebYvQ94TDXlvUQfSN/kbcx8URCS2
+TWG/AwqEcYbbWFWc8bQZIBDKF/t+GSfyZpGb7whRREj8PUCb5aiLQ0YKW4lnwBmjXLGrSomrHiCA
+g4M8M3vBB045/5grQTin9bmhdJTDwfnUX5oP9V6jk0zUbp31iydxqt4XiuNIyhQwaBTNy2oPEV9u
+qKVzQKTkW8t6/rrTI72/3Yj/UvY6liEwwkMIocxw2fq84aLa+b1rwy6ka+MkEYp/Lepuj4rlTWP0
+L+DxDn7Vacc+WtZ95sMiR/6Lc/h7gGokkHkaOAgh2MWxSJwxKpXotrvp7dZW8knSEH1w5lE+KL42
+uQVfg86OWXM4rPYQRZe3W/s3IykJjqTMDBhreQwaRTMIPoDPzcNlb79srT8QEbu2zNeoK2s9NAnv
+STn7qH610a2yD09Y4EBLcTprgy30Dxi8h0iR9iKfM0niG6Yw3wZM7qo0xhhxzi9t9rjRjG8UWf6L
+xyIHqokQCCELqB1jFsfiMcaolKLbaqd3OtuHxQ7q3ONiqHd1VvSquv3srDkcxpjd6JKLpiIzPefc
+N82txheTZnSgt0VSfLSoXcXQZsmGxdNWK76z7Ndxzv2A+RvnGNnddInZJ6UT/BoWONBaWWbXxvFr
+ABAh2cIPDEkjuqtHxUO8i1ldjDFiNSx19rjRjG/kmf4Wt+FDdcB5MIt4HuziWK6jYkfajj9tbye3
+G624S0l4XAyKyhU7ZsnhyDO91+okF+6akh3vkhLjSMqcGGfE28XtKoY2Q5GZXiuO3l923k3wAQIl
+FvM33qZHer/biD8sc3xj2ThnxDpX6vEJCxxoYQ67Ng6W0rVxErPFU7qkY3PSiu8Uw+LBUp4czY1x
+xnQRlj573Giqu6N+8RCwowdVHOVcL+poKCJ23RlfejjYumOUUiE4TZvRp50r6aliR5Hp/UoUO45y
+OCZgtQclzx9N8dbDqJfdx5GUxWGCEWcWu6sYWm/eB5AOfljWlrAnOQCipLiy7NepG2s9NNZ6NOUQ
+Pzw+lXougQUONLfTXRtyKV0bJ0lqBsusPsdNdacYFg+X9fxoPrkNrVUUHprt6M7oIMeOHlRtC4x0
+iBK1nWX66cKeEF2Knil2tNrRDufkRTHI7hej8ood0+RwOGMenDfPX2SmZ5173LrSuIcjKYvDOWUA
+fuG7iqH1Zfr5btKMP1nFaznrD4TimL9x1sjuNtZ5NOUNzimzUG4QMhY40FxW1bVxZBn5G2cxyliU
+yM+wyFFNLtCtVc0eNzvRncFrLHKgaltkUVlJ9l/W4NbZZaCUUs45jRN1vfuH1r1W53Sxw+rVFTsm
+zeHIRnq/0YnH7pqSDYo9IfkobcSfLn6FiHHRxCZDNIlipPebjWRlYxHOuJ+wnnmaHun9brreoykn
+eRZaZY56Y4EDzeRN18b9VXVtHL+uW07+xlmMMyYT/pk15vmyXwtNJ1C+AxBW1vrW6kR3hv3i/qpe
+D6EyRYnazkbYxVEFp4sd8Y6S5IXJ9P1iqPeWXeyYJIfDWQ+R5D3OT+/bfTyS0oquq0hcXeY6N5mQ
+DING0aWs9RARlgm5/JuQRzwhS+20rht/NJqi1ns05STK2FaZ9waxwIGmdqJr4+4qujZOYr54uqpU
+ZsEFY4FewSJHtTDGiLX+x1W+ZrOlvhj2c+zoQRsBuziqh3NGo0Rdb2+l91rd+LpS9J8nix1hGdvP
+XpLDYQqzG6Xyo9Mfcz1rLI6krAAGjaJJ2KF5EKdqqVvCnno960EpsdRO67qBDRlNOYlxvuPc6m5G
+vvX6Zb0wqp+yujZOktQMKFvd64pIbLNAr3jrvl/Va6KLMc5YPlx9eFHaEJ9lWORAFRJCAEIX/zaO
+XRzVxjmjUSx32lvpvdZWfD2K2UurzW4+0E8WWey4KIcjG+n9Zut0y3s+KPYYo6O0leBIygoIwYjT
+GDSKzpcd6Cft9vgRsmXxFoiQfKMu5i+iM9PbpNGUI1wwYv1qb0aehAUONJGjro34/2fvXpvjOI58
+4VdlVXV191wADLyrXYFan2OLBOxD2RFHhgjSn18iKCsYYZu7NkQxwitxKT67hwSBuXTXLet5AUIC
+SZC4zKVv+Xu1KxmYpAjMdP87M6ufrGTXxnkwBNTpcvdvnEdqOUJExID0RLMmyoB61SeccA6QZBRy
+kPpAZEwKJpfxvamLoxkEAE8SeWO4kd9bG6WfpSkcO2v/ZCblN7ZwGOYIO963hyO4gFrBoXjd8h5C
+xNnR7Mu0r28lKY2krAoXHDDSolFyPlv6w1zL0ao7qZwNj0B06l7+vYILmCF/0qXRlFMAwIwL48pe
+v6oXJs3wdtdGpbV4ZEpUkwonWu1Ya55TyFEPIcKgims6IV6HHJNyf+UvTsg5pIR8Gd+XujiaBwC4
+SuT6cD2/M9jIPs968hi9/boYl9+Ya4QdJ3s44jt7OExp93We3Gbs9UhKaR721vN77zsmliwPLRol
+5wkhIrf+QFewAycwHNN42gk3tQ8HvdWcXFM34uTzg1UVwFLAQd7Lz6YHwr36rsqujbNEmD3kFb5n
+Zlm6bQvzjyq3ApMTIYibVS1XEwIgUfwLUzjazUIqhmwZIyqnqIujuQCAKyXXB8N8b20z/7zXU5x7
+/7CcmH0zKw8vffws8Df2cMym5mneP2m3PjuS0rX267qQCm7HQJck5E3muHyY99M7q37d4AImCdD+
+DXYymrKZZ592+r0RWL+qBjMKOMg7MATE4xdfauVuyWR1i4kuokRwq9y/cZ6sn/7eTs2DSI9MqiUZ
+szZU9nRZKAnAcZNCDtJm1MXRDsA5l0rwfJj+YTjK7vQG6Tpn8WE5Li8MO6T8eQ9HcAGVgOcgYDg5
+LPbTXH9EIynVAgXMOaTfUfKTcmqe9nP9KVRwY+09MinVJ6t+3boJIWIWujma8gYpblf1TJgCDvKG
+064N3U/+CKI+Q3QYAqY6blZdB2OMZYN0z0zLBzT3Wh0AYKasbraPMcZkIkfAcdOUFHKQimBky36T
+pi6OdgHOuZSC5339h7XN/OewYzr7spyZp2+HHXBmD4cp7EOQ8KtyZr4ejLI7YoXHTpLzSQAWnKv0
+s5DUh3MBVYRDlYhKfjedC49B8rUqXrtO3Lh8OOh3czTlLCGAuRDOXVS9bBRwEMYYY+j8664NX6uu
+jVPR+yMB4mbVdZw6CTnM11XX0VXAAZyvbrbvlEzkiCGFHKQayBhbdsJBXRztxc+GHRv9e4Oh3hKC
+fVeOZ1+V05Ow4/UcdSwm5iXnLBGC/7/BWrbX6bbrGuGCAyKDqj8LST24ib2f95LK9uWFEF5U3Ghd
+OTOzh6Ouj6a8xoEx72MlJz1RwEFOujbC0euujXouBoJQPqly/8Z5dKZ2y0lJJ2pUxAber2oPx1lJ
+ehJyOEtHCZN2UpJTF0fLcc65EIKnWXJr/ReDe4O19OewY1LqclI+Gqzl/6ZTVbsHIF0nBd+g1WCk
+PC4OhoPVHgl7VggRpQDd5Rv709GUpOujKa8pJcBad1zFa1PA0WF179o4qw77N94GAkBnatcU5puq
+a+ki4+F2XZ5ZJakceefROzplh6wQMibU8k+WSnM9mk7Lf1/265D6EAJ+Cjv6a3me9XRKIyn1JBJZ
+2dJtUg+29IepVLzKk4y890zq5NdVvX4d+LF52O/pzo+mnIUs6io6zCjg6KgmdG2c8q4++zfeBgJA
+AvzKWUsjCisGAMx5/13VdZxKM7XjrP2RQg7SRomEHeri6J4YIgrBXg7W0j9MXxXUsVhDIGnRaJfF
+EJEZ/zedVdtd5Ux4LDq8f8PM7OFGnn4KdETuGzjAoIoOMwo4OqZJXRunePBHQtRn/8bbpJYjiHzT
+WdrDsEoAwLyJlbS+vU+aqZ2yKJ57TyEHWYXIVtXXluaadnF0kLWepZn6DRccdC/ZpZCjfiQA89ZN
+qq6DVMMcm4e9vr5bdR3o8bCr9/YxRNSOf0ujKe/iStykgIMsVZO6Ns7iWD6p+0if1HLEEVMMdGO7
+KiAATBnLqut4W6+fbpczCjnI8q36ooF2cXSPM/YhKFhjjDEhOOhM7s6Oy/2q6yI/44ID44wjLRrt
+nHJmD/M8qbxrIISIIIF3df+GHZtHw4H+ouo66khIYMb5lT8coYCjA9B5DMcvvmpS18YpjBETEWzd
+9m+cR6XJJ8H5HynkWJ3CxQFi/S7qTkMODDQYTdqDuji6JbiAUgI/e/MklACVwK2yoLHMOhGcb9Ae
+jm4JLqAK8UlVR8Ke5b1nSsutquuogpnZw/UsHVUdMtUVADBnw2zlr7vqFySrddq1kfaTe03q2jiF
+Hlmq4y+qruOyklTtWGueI600XwkX4UZdL+p6/XR7NjX79LNAlmnVD8yoi6M7nPNHSZ7837f/uUzk
+iEe2aSjkqA1aNNo9dmL2s5ostAwen4HknQs4YoiofPyb1vJG1bXUlRAcMKJf9etSwNFSTdy1cR7w
+5lmd92+cJ8vSbVvY/VjDzoLW4bDufXhWdRnv0+snd6fH5YM6dpmQ5ouMrfxnn7o4uiPY8Dchzr9M
+TFI5YpFtmpJCjjqQEpiroA2cVKM8Lg76vey3dRkJ8S48BejeLaUdm0fr/azy/Sd1FyAOVv2wr3s/
+jR3Q1F0b5wHuntbk/ftKsp6+a6blgyqORuoSAGAhxJdV1/Eh/aHemx4V9LNAFk5w9qKK16UujvZz
+LqBK5S8+dAOVpHKEDjetc09XWRt5l1ACgvW1WrpNlsOZgFooLmtybHMMERkHDk28WJ+DLT2NplwS
+cHFj1ZfAFHC0SFu6Nk5hjJhwz5uwf+M82SDdK8fl/arraDMQAMUEa39R11/Te2M6fYAsGEbGWQXv
+jtTF0X7euMdKywu7J9NeMvKln1DgVb0YQdOi0fYLhX2Q5tUeCXuW98iUEhtV17FKMUSUNtBoyiVB
+Auver/bUQwo4WsLPJq3p2jiFHlmieaPfPNJBsldOSrqxXaIyoG7CCMhgTe+NDydfVV0HIYtAXRzt
+FjG+FJe8lsh6escZ96N3gX4eKiQk/4j2cLTb9Kj4S3+Q7lVdx1nOhSOpoVGj5POyY0ujKVcAAMyF
+8P1KX3OVL0YW7+eujdCKro2zTvZvwMdV1zEP4AA6U7tlQcfqLYsL8FFTHlr117J7k2Pq5CALElkV
+DRyMMeriaDNnPKaZ+s1Vvibr6R0zNc8p5KiOTMRW8PXvaCTXU87sYV8nI1GzkQjv/ZMu7d84GU3R
+NJpyBUoJMDZMVvma3fmJbKE2dm2c1dT9G28DAaCkuOUsLWNbhhjFVpOeWuU9uTujkIMsQNW5nhL8
+N96H5vzykUsxpX0ICtau+nX5MN0up+Z5oJOjKiEEsLDip6RkNUKIqDw+SWo2EhFDxMiZ69L+DWHC
+32k05eoiIl/lLjoKOBrIO4d4/OLLNGlf18YpDM3ev/E2qeQIIt901lHIsWiSMWtDY54kcw6QZBRy
+kAWp8C1Sp8m6mdivKyuALFwIEaXg/LpPJ3vDdHt2VNLx2BWgRaPtZV4VX6f9tBZHwp7lEVmi5GbV
+daxKcWwONgZZrUaEGkPwfJXd1hRwNIydHf9FhePvdD/5I29xexRiYIlu15naUssRRLbpraeN8wsE
+AMyUYVx1HVchxOuQY0KjS+T6ZALjKj8EuOAQIX4cAnVxtIUz9ijJk/87z/for6V3J69mD2jh5erF
+CJrCpXYpp+bpYJDt1LFLwrtwJBPRif0bzgRcl+ra4W/nSXF7lW9NFHA0RLDFIY5ffJUn8bO2dm2c
+Bd4+EwJaFXAwdhJyRMQJBqQ55QUBDlDYCE07hlUIgETxL0xBXT2kubI02SrH1MXRFsGGvwkx/6Xh
+YD3fm7yc0vHYK6YS/lEDdm6TS3IuoGYwq8uRsG/z1v/Qlft9Xrj7Wd7++69lEQKYdf67Vb0eBRwN
+YGfHf1GxnOpecq/NXRtnAXNPeUv/qEmqdqw1zynkWBwfYKNJezhOCSUBOG6akkIOcg0RGa/4qR51
+cbSHcwFVKn+xqJ+pwUa+N345paPSVwik2MIVH8dIlsdN7P20xjfVgbFxFzoaTkZT8ntV19FkQgLz
+dnVLkCngqLGzXRtCdWehDYaIifC86gv3ZcqydNuW5beRHrUshEN+s6n/JWUiRwwp5CDNRV0c7eCN
+e6y0XGi7+WAjvzd5RfuGVkUIYN4F+ixpgelxcTAcprW9qXYuYJLIYdV1LNvpaMplj80m5xOCg8NQ
+rur1KOCoIYwRu9i1cQoxsCRp1/6N82S9bNdMywcUcswPAJjzq2t9W7QkpZCDNBd1cbRDxPhyGRfx
+eS/ZnVLIsRJCCUDvTdV1kPnY0h/2kqRXtyNhzwoOmVTidtV1LBuNpiwOsriyHUEUcNRMsMUhm7zc
+71rXxlkimMdt3L9xnmyQ7pXTklp45wQAzMzwZdV1zOM05KAltOQyYozIeH0+wqmLo9mc8Zhm6jfL
++N5ccNAUcqwMAgxo0WhzxRAxlv7buh9F6mx4BKK2+ctC0GjKggH/aFWPdOtzddRxXe/aOEugedHW
+/RvnSfvJXjkp6cJvDiAAjMXQ9IV2SSpHzvmJd7SfhXwYImNSMFl1Haeoi6PZTGkfgoK1ZX1/ITjo
+TO7OxuabZb0GOaFA3KDG0OYqjsuH/WH6RdV1XCQwHNe5w2RezgRck5JGUxYIlNxaVfZKAUcNUNfG
+zzBE1CrqNu/feBtwAJ2pXQo55mM97zdx0ejb0kztOGt/pJCDXERKyKuu4Szq4mimECKC4GHZywKF
+EqAU/1VZWBrFWyKh+Dp6fFZ1HeTqypk97Of60zoeCXtWcAGTBFq9f4MX7n6eaxpNWSAhgRnnH63i
+tSjgqBB1bbwLMTCVwK+rrmPVQACoTOzawv616lqaykW40ZaHVmmmdsqieO49hRzkfZDVaUSFMeri
+aCpn7FGaJyt5YiwTOeKRbRoKOZZGKMm8Dc+rroNcTXABFcanKhG1PBL2LO+RSak+qbqOZTkZTclo
+NGXBAIA5G2Yrea1VvAh5F3VtnE8E85gDX1qbbJ1JIUEA33KWLvyuhcO696E1T616/XS7nBXPA4Uc
+pEGoi6N5ggkHQqzucjBJ5YhFtmlK+qxbBiE4YFjdaQVkMczY7Oe99LOq67gM58JjkO28Vncu4FAI
+K0TLF4xUQAgOIcaVjJNTwLFi1LXxYV3bv/E2qeUIIt8Mzn9bdS1NAwDMGWzVU6vXIcc/MLRg9oYs
+FkZWx3dK6uJoFucCqkyOVj0WmqRyhA43nfUU4C4BLRptlvK4OBgOs7tV13FZIYQXUO8pmmuLE7ff
+a0jQ1EjA+qtYl0cBxwpR18aHYQid279xHqnlCBERAz25vwoQAKaMrXtqlffT38+mZp8uVslZWHUB
+H6Cpi6MxfOGeKS1vVvHaaS8ZOeN+pJBj8RSIG/SR0Qy29IdaqMYsswwhohTQymt1MzVPN/rpb6uu
+o9U4v0EBR0tQ18blIGIn92+cJ9Fqx1rznEKOqykDamzh+vheP7k7PS4ftPHPRuZQ008SIThEHj8O
+1HlUe5HFH6q8scp6escZ96N3gT7rFkgmYj0EWjRadzFEZMb/Lc1VY5ZZeu+Z1EnrrtWdC9hn4lAp
+WfsdKE0GCaw7H5f+3kQBx5JR18bliWAfc9HOmb7ryLJ02xbmH/Tk/vJcgI/acJLKefpDvTc9Kh40
+/ShcsiDImFDidtVlvI/Okq1yaqiLo8ac8Zhk1S8KzHp6x0zNcwo5FgcksECLRmtvNikf9fq6MaMp
+jDHmTHgs2rh/Y+r281zX9jO1LQCA+RBeLv11lv0CXUVdG1cn0LxY9jF1TZP109/bqXkQ6cn9pUQu
+thDjcdV1LEt/Te+NXxV0nDCpPSE4xEhdHHVmSvtQKtiqug7GGMuH6XY5Nf8IFOgvhBAcgg+m6jrI
++5UzezhI9b817boXPR42rOQLmal5ut5Lf9vGsZu6UUqAMW7p1+kUcCyBo66NK8MQUGuWVF1HHWWD
+dM9MS3pyfwkAwJwL31ddxzIN1vTe9Ki4X3UdpGqR1f1SjLo46iuEiCB4qNPNVW+Y/n52VNK+oQUB
+IfsUGNVTcAFViE+acCTsWSFEBAm8TUFAcAF7NJqyUhGYWPY9DQUcC3TataEZdW1cFSIyJfmnVddR
+Vychh9mvuo66AwFQTLC1HRynsr68MzmmTo4ua8J9C3Vx1Jcz9ijNky+qruNt/bX07uTV7AFSoD83
+qeB2W0c2m85OzH7W059XXcdVee+Z0rIWXV+LglO336PRlBXjG8u+hqGAY0He6NqQ1LVxVeDKR7R/
+48N0T90pJyXd1F7AIIq2L+PkHCDvyd0ZhRyk5qiLo56CCQdC1PMScLCe701eTqlrcU4ggAUXvqu6
+DvKmcmqe9ntZI8chgsdnIHlrAg4zNU/XcxpNWTkpblLAUXMYAnVtLIDidlynVtmq01kGAAAgAElE
+QVQ6Ag6gM7VrCvNN1bXUmUfY6MJ1MecASUYhR5c14ZqMujjqx7mAKpOjOl/UDzbyvaOXUxrFmwNI
+YN7g0pf5kctzJqBmMJMKGjkO4V14CtCOW8efRlMSGk1ZNSGAOe+XGr6246e0Is4Wh3x2+Cfq2pgP
+hoA6YcOq62gCEAAS4FfO2sdV11JXIYibXWnLFeJ1yDEpaXypYyJjjTkCkro46sUX7pnS8mbVdVxk
+OMz2JrRU+dqE4IAxBOqEqQ83s/fTPGnMkbBnxRCRceBQ42D0KtzUPqTRlGoICczb5Y6TU8BxDRgC
+utmrb1JW8qSn71DXxnwQkUkF9CZzSVLLEUS+6ayjkOM8kjFrw6Oqy1gVIQCU5LdMQT8PXSI4e1F1
+DZdFXRz1Eln8QYj6X7dwwSHtJbtTCjmuDYTst3xiszFmR+Yvw2F6r+o6rst7ZEqJjarrWAQzs4eb
+efZpnbvY2kwIDg5DuczXoIDjipwtDrk5fJgl/HOQ1Na0CODKR7z+11q1IrUccYybGPCo6lrqBgCY
+Mziruo5VkokcAcdNU1LI0RUYGWcNetukLo56cMZjkqlPqq7jsoTgoDNJIcc10aLReihn9jDXciQa
+/EDUuXAkNdS+8+siIUTMAn9CoynVChAHyzwxiwKOS3qjayPVf6CujcVRrJzQ/o2rU6kaBed/pJDj
+TcABjMPOteXKRI4YUshB6om6OOrBlPahVNCoJYFCCVCZ3C2m5q9V19I0oIB5WjRaqRAiKo9PtG72
+KLv3/kkb9m+4cflw0E8bd4JN23BY7r685v+krgB1bSwPhoA6g0HVdTRVkqoda81zRAo5zrKB97v4
+1CpJKeTojMia1MDBGGNMa7llCteZ8bG6CSEiCB6a+EBBKQHA+VZZ0P6pq5AALNCi0UqZ4/Jh2vAb
+6hgiRs5c0/dvmJk9HNFoSi2AEFvex6Xt4aCA4wOoa2P50CNTQtD+jTlkWbptC/sfkQZtf2I83O7q
+f43TkMNb/7TqWsjyNPHnWygBMSCGZZ8PR87ljD1K8+SLquu4riSVIx7ZpqGQ49K44BAixq51NNZF
+OTVP+7n+tOnBgEdkiZKbVdcxj9PRlIRGU2pBSGAuhO+X9f0p4HgP6tpYDQi0f2MRsp6+a6blA7qI
+OQGw/COo6ixJ5cg5P/GOOntarYHXzIkWn1EXRzWCCQdCNPuyL0nlCD1umpJCjssCwTfo+cfqORdQ
+RThUiWj8PYR34UgmotH7N9y4fNjv6UZ30rQJADDjwnhp339Z37ipqGtjtRS3Yw4NvEqvoWyQ7tlx
++VXVddQBADBvltf61gRppnactT9SyNFOMoFxE984hRIQPXVxrJpzAVUmR21ozU57yQgdbjrr6b3t
+ElQib8ZAv26r5ib2ft5LPqu6jkXw1v/Q5Nuh09GUJo7ntZUQHCJGtqwHsxRwnPFz1wZQ18YKYAiY
+Zeyfqq6jTZJBcreclJ3fNg8CwJRxqUdQNUGaqZ2yKJ57TyEHqQ/q4lg9X7hnSstGP4E9K+0lI2fc
+j94Fem+7AEhgziH9vq1QeVwcDAfNPRL2bYGxcVPDARpNqTFg/WU1nlPAwc7r2mj+E44miN4fCWh2
+y1vdAAfQmdqlkIOxwsUBUl8u6/XT7XJWPA8UcrRLRNbUp/HUxbF6kcUfhGjmDcr7ZD29Y6bmOYUc
+HyYBWHBuaa3g5E229IdpkvTa8vvmXMAkkcOq67guPzY0mlJXUtxe1mVA5wMOV1LXRlUglE9o/8bi
+gQBQmdh1ttszyi7CjS6epHKeXj/dLqflt8s8c5ysVsTGHaLyBuriWB1nPCaZ+qTqOpYhH6bb5dQ8
+955CjvfhggMiA6QdXUsXQ0Rm/N+afiTsWcEhk6qZhwGYmT1cz9J/aWr3SdsJAcyF8GwZ37uzAcdP
+XRuCujaqokRw9N99OaSQAJFvdjrk4LCO2O09HGflA707PS4fUMjRDhxYo/8eqYtjdUxpH0oFW1XX
+sSy9Ybo9GxsKcD9ACr5Bgf/ymWPzsNfXd6uuY5GcDY9ANO9SPYaIysdWhU1tw4Ex7+NSjrHuZMDx
+RteGoK6NKmAImOrY6COn6k5qOYLIO3tcKAAw55Z3BFUT9Yd67yTkoCd5TRZjRMab//FNXRzLF0JE
+EDy0/QnmYC3dnbyaPaAuhfOJRN6kgGO5ypk9zPOkdYssA8OxaOCfyY7No/V+1qqwqW2UEmCtW8qD
+yOZfIV0BdW3UB+3fWA2p5SgiTjB0b/8CCIBigtTB8Zb+UO9Njwo6UrjhBDR7RIUx6uJYBWfsUZon
+X1RdxyoM1vO9ycspvbedgxaNLldwARXGp204Evas4AImCTRu/4Yt/eF6lo7aFja1EbKol/Ge3ZmA
+g7o26oXT/o2VSVK1Y6153sWQowyoqVvhXf01vTd+VXR+EW1TITKmFAyqrmMRqItjuYIJB0J05lKP
+DTbyvfHLKb23vUUpAd66SdV1tJWdmP0s143cU/Eh3iOTsln7e2KIKG2g0ZSG4ACDZTzjaP2nHnVt
+1A/GiAnt31ipLEu3bVl+Gzt2sx8iDOhh3vkGa3pvckwhRzMha8OICmPUxbFMzgVUmRw19bSd6xps
+5HvjV7P7VddRO5xxGuFZvPK4OOj3st+28ffMufAYJF+ruo6rsGNLoykNwpW4SQHHFZ10bbyiro2a
+QY+M9m+sXtbLds20fNClkCMEQXPHH5D35O6MQg5SMUVdHEvhC/dMadnJUdBeT9+ZUpfaGwTAFn0e
+LpYzAbVQXCpo5T1GCOFFk55FnoymaBpNaRAhgRnnF/7538qA482ujYS6NmqGB38kBO3fqEI2SPfM
+tOzORZ9kzNpAN07vwTlAklHI0TgYm7+A4wypBARLXRyLFln8QYhuXuhzwUH3kl0KOX4mlNgKnvZS
+LVIo7IM0V7eqrmMZQogoBegmdaYIE/5OoynNAgDM2TBb+Pdd9DesGnVt1B/H8kmD3i9bJxuke+Wk
+GyEHADBThnHVddSZEBRykOrpTHxmi8U/xekqZzwmWbNm5xdNCA46k7uz43K/6lrqQEpgIdDJYosy
+PSr+Mhike1XXsSzeeyZ18uuq67gs88r8ZWOQtfbvo62E4IAR/aK/b2sCDgwB/fHLferaqLfX+zcs
+/f1US2dqtwshB3CAwkagrfofdhpylIX5pupayMWQMdaqFg520sXhbUCkLo6FMKV9KBVsVV1H1YQS
+ILX4oizs46prqZpQAoL11MGxAOXMHg5S/W9tHoVwJjwWDdm/YYzDNa022/z30WYB4mDRn/2tCDic
+KZ6CefXvaS7vUNdGvZ3s32C/rLqOrgMBoDO1awv716prWTaMPKe544sJASA4+5UpXOdvBGoPGRMC
+Wvd0XmfiM0NdHHMLISIIHuhi/4RSAnhkm4ZCDhYjaFo0Op8QIiqPT9p2JOzb0ONhU95CRBHup1nS
++UC3qYCLG4t+W2p0wIEhYDh+8WUKZV+lyWfUFVB/4M0zIeDjqusgJyGHAL7lbLsv+oyH23Q5dzky
+kSPguGlKCjlqD5rxZO0qqItjMZyxR2mefFF1HXWSpHLEIts0Zbs/7y4iJP8IEasuo9HMq+LrrJ9+
+XnUdyxRCRJDAm7B/ozg2BxuD/F7VdZDrgwTWvY8L7S5rbMBx2rWhe+oedW00B3D3tAHvl50htRxB
+5JvOtveGFgCY8/67qutoCpnIEUMKOeotsra+jVIXx/yCCQdCNPbybmmSVI7Q4aYx7tuqa6mKTMQW
+LvhGokvKqXk6GGQ7Tbjxn4f3nglV/2WdzgRcl4p3dZlyWwAAcwveD9S4T8B3ujZa/ibTJhgjJtxz
+6rSpF6nliCOmGPCo6lqWAQCYKfBl1XU0SZKehBzO+s7eCNRZmxscqItjPs4FlKns0bXR+dJeMgrG
+Z876Vn7eXUQIWjR6Xc4F1AxmbT0S9qzg8ZlMeO27rXnh7md50spTbLpEKQHGhskiv2ejAg5XzKhr
+o8HQI0s0r30i3EUqTT6x1jxvY8gBAsBbtvANzW138rTT/8LZ0LqfCVJv1MVxfb5wz5JU3q66jjrL
++voTZ9yP3nXvvY0WjV6fOzb7aUdupr0LTwHqfYtIoyntEhH5Ig8EqPdP72s/dW1IQ10bDUb7N+ot
+y9Jta83zNj45LVwcINImjqtKMjXyzv3oXfuCr6Zr88cgdXFcX2DhP6ld+2JZT++YqXnexZCDcaHp
+d+tqpsfFwXA9u1t1HasQQ0TGgUONP2RoNKWFBM8XuWi09gEHdW20BzDav1F3WZZu26l5EFsWBrgI
+N+gkletJM7XjrKWQo0YiY63/u6AujqtzxmOaaTql7JLyYbpdTs1z77sVckjJPmrZR/xS2dIf9pKk
+J5pypMicvEemlNiouo4PodGUFpLi9iJz19oGHD93bTjq2mgBDBETQfs3miAbpHtmWj5YZKtY5Tis
+ex+eVV1GU6WZ2imL4rn3FHLUgeCs9TP01MVxdWXpH0kFdFTiFfSG6XYxNv/RpZ8zkGILPdLn4SWE
+EDGW/lut679wc1GcC0dSw82q63gfGk1pJyGAWbe4AwFqGXC82bXR/mU+XYAYWJJwuvBqiJOQw+xX
+XceiAABzLv5YdR1N1uun2+WseB4o5KgcRtaJoDjR4jNbBjoB6RJCiChELKAjT5kXqb+W3p28mj3A
+NoX6HyAEMG/D86rraAJzXD7sD9NOHbnsvX9S1/0bzgVck5JGU1pISGDe4sL2A9XqJ5i6NtoLvH0m
+BD1ZahLdU3fKSfmg6joWAQSAmaGpuo6m6/XT7XJaftulp5211YFPR6UFOOte0M/bxZyxR2mqtquu
+o6kG6/ne5OW0XZ2L7yGUAAyhrLqOuiun5mk/15/WeRfFosUQMXLm6vpn5lN3P881jaa0kBAcHC7u
+fak2AcdJ18YRdW20FDD3lFPg2ijAAXSmdsuibEUnRxlQ06LR+eUDvTs9Lh/Qf8sKxU7kG4wxxpJE
+fuGtp3b6CwQTDoQSa1XX0WSDjXxv/HLailD/IggwoODw/ZwLqCI7VIno1P2IR2SJkptV13EeMzVP
+13rp/6m6DrI8yOLCFiBXHnC82bWhqGujhX7av0F/t40DAkBJcctZ+7jqWublAnxEi0YXoz/Ue9Oj
+gkIOsnRKCzCl/6Er4wPX4VxAmcoefcbOb7CR701eFa0PORSIG/T2/X5ubPbzXvpZ1XWsmnfhSCai
+dvs3nAvYZ+JQKTpsotWAf7Sot6VKAw7q2ugGxMBSDdQ621BSyRFEvumsa3TIEaPYQowLm+/ruv7a
+ScjRhZbuuomRMdahe9kkkV9446iL4z184Z4lqbxddR1tkfeS3WnLQw6ZiPVAi0bPVR4XB8NhN46E
+fZu3/odarvGZuv081/Qe13Kg5NaiGssqCThed218RV0b3SCCecyBU+tsg0ktRxDZpve+uQsmJWPO
+hdafPrFK/TW9Nzkq7lddR9cIwSZd+tCkLo4PCyz8Jy3dWxwuOOiWhxwggQVaNPoOW/pDLVRnl1gG
+xsZ1W1Rspubpei/9Ld0rtp+QwIxbzPHwKw84znRt3KWujW4QaF7Q/o3mk1qOoscfMTTzFA0AYGUR
+JlXX0Tb9ob43OW7vjUAdcQGdu9GnLo7zOeMxzfQvq66jbYTgoDO5Oztuxw6qtwnBadHoW2KIyIz/
+W5qrTi6xdC5gkshh1XWcFVzAHo2mdAYAMGfDbCHfaxHf5DKoa6ObMETUKmr6+26HJFU71prnTQw5
+gAOULnLaG7F4eU/uzijkWJ2IrGvvqdTFcb6y9I+kohPKlkEoASqBW2XR/B1U56FFo28yx+Zhr687
+OZrCGGPBIZNK1GoMBKduv0ejKZ0hBIcQY1jE6PNKAo7Tro20n9CujY5BDEwl8Ouq6yCLk2Xpti3t
+f8QGBgUeYYPujxaPc4Ako5BjVSJ25hCVN1AXx5tCiChELOrWUt4mMpEjHtmmaWHIkShxg/KNE+XM
+HuZ58mmXf5ecDY9A1OePb6bm6XpOoyldg4D9RVynLzXgeLtrY5mvReqJ9m+0U9bTd820bNyCyRDE
+TTpJZTmEeB1yTNrZ0l0nHFgnf4ipi+NNztijNFW0wHvJklSOWGSbpmxXyCGEWA8ufFd1HVULLqAK
+8UnXjoR9W2A4FjUJeH4aTUloNKVrgIsbtQ44/Gx6QF0bhPZvtFc2SPfKSdmsBZOSMR/ogm5ZhABI
+tPjCTO1fq66lrWKMyHjlJ7xXhro4fhZMOAAl6AHCCiSpHKHDTWPct1XXsigggXmLL6uuo2p2Yvaz
+nv686jqqFFzAJIHa7N+g0ZTuggTWnY9zf8Yv/CoJQ0A8fvGlVu4WdW10G4aAWrOE2svaK+0ne+Wk
+bMxYAgAwM6MLumUSAgBE3DJFs48VrjMB3RxRYYy6OE45F1Cmogf0+boyaS8ZBevR2QafJnaGEBwQ
+w0Lm3ZuqnBYH/V7W+TEI75FJqT6pug7GGDMze0ijKd0FAMyHMPd1+kIDDj+bHgj36jvdT/4IokaD
+XKQSiMiU5J9WXQdZHuAAOlO7TQk5gAMYh52+oFsFmcgRcNw0JYUci4bImFIwqLqOKlEXB2O+cM+S
+VNITzhXLenrHGfejd6EVIQcI2W/gOq2FcCagZopLRV3mzoXHIKsfJw8uYIb8CY2mdJdSAoxxx/N+
+n4UEHOj8664Nf0smSSePVyLvEsE+5qL6N0yyXCAAVCZ2nW3GfLINvE97OJZPJnLEkEKOxcOqC6ic
+0gLM1HW6i8Oh/17Qg6RKZD29Y6bmeRtCDqngdlc/D93M3u/qkbBvCyG8gBo0TLipfTjopZ0eFyKM
+RWBi3geRcwccfjY9EOHoddcGLVsgPxNoXnR5I3WXSCEBIt9sQshhPNzu7m3RaiXpScjhrG/N3Hot
+dHgHx6kkU18E280uDmc8Zpn+ZdV1dFk+TLfLqXnufbNDDhDAurhodHZk/jIcpveqrqMOQogoBeiq
+R0LMzB5u5tmnVddB6oBvzHvC07Wvkqhrg3wIhoCpjp1uo+4aqeUIIt8Mrt43swDAvA+dvDGqQpLK
+kXch8w4bfSNQGxi7u4DjDKUFlBP3QxfHzcrSP5JafFx1HV3XG6bbxdj8Bzb4rFUpgXnTrb1U5cwe
+9rQc1eXEkKp575nUya+rrCGEiFmg0RTymhQ3Kwk4qGuDXAQRmVRA88EdI7UcISJiqO/NLAAwZ/B5
+1XV0SZrJT5y1P1LIQRYpydQXvmNdHCFEFBALujmrh/5aenfyavagqeNSXHDA2J1FoyFEVB6fJFre
+qLqWunAmPBYV799w4/LhoE+jKeSEEMCc93N1ll0p4KCuDXJZ4MpHdDxsNyVa7Vhrntc15AABYMpY
+Vl1H16SZ2qGQY37IGKMWjhNd7OJwxh6lmdquug7ys8F6vjd5OX3Q1J/DLi0atcfF1yndSL8BPR5W
+mZeamT0c0WgKOUOcHGE916LRSwcc1LVBrkJxO6b9G92VZem2Lcw/6tq6W7g4wK5c0dVImqmdsiie
+e08hx7UhY0JALY7zq4OudXEEFw5ACVreXTODjXxv/HJ6v+o6rkMquB1D+z8Oy6l52u9lO3S08s9C
+iAgSeFXhwuloSkKjKeQMITg4DHM9iLww4EDnMRy/+Iq6NshlYQioEzasug5Srayf/t5OzYNYwyDB
+R77R1c3xVev10+1yVjwPFHJcH9DpVKe61MURXECZiB7doNXTYCO/N3lVNOLI9LNAAfO+3YtGnQuo
+IhzSkbBv8t4zoaob1/Fj87Df09RRQ94RIA7meUj6wYDjtGsj7Sf3qGuDXBbt3yCnskG6Z6Zl7Vp3
+IxdbiHHuc7bJ9fT66XYxa/ZyvupERre3b+pKF4cz7lmSSvpsrbG8l+xOGxZySADmrf+fqutYJjex
+9/Ne8lnVddRN8PhMJryShcVmZg838vRT6vYm5+EAG/PcOpwbcNCuDTIP2r9BzjoJOczXVddxFgAw
+58L3VdfRZb1+cnd6XD6gUSEyr650cXgM/ymEoA/XGuOCg25YyMEFB0QGbf39mR4XB3Qk7Pm8C08B
+Vn/seAwRtePf0mgKeR8QYsv76z+IfOenmnZtkHnR/g3yNp2p3XJS1uaCDwRAMZlvgRGZX3+o96ZH
+Re06fOqMml7O1/YuDmcCap38r6rrIBcTgoPO5O5sbL6pupbLAsE32vjeYkt/2EuSHp069K4YIjIO
+vIqRNzs2j4YD/cWqX5c0h5DAXLj+g8ifAg7q2iCLgCGgTmn/BnkTCACdqV1T1OeCrwyoqXugev01
+vTd+RSHHVdAKhne1vYvDlu6R1KKSVnJydUIJUIr/qizs46pruQyVyJtt20sVQ0Rm/N80HQl7Lu+R
+KSU2Vv26ZmYP17N0RA9CyYcAADMujK/99Ywx5mcT6togC4EemRKCZoTJO0AASIBfOVuPC74QYdDS
+e6HGGazpvclR0cgTCFYtMkbLWd+jrV0cMUTkEAt6Ct0sMpEjHtmmaUDIARKYc/io6joWqTguH/b6
++m7VddSVc+FIari5yteMIaLykUInciEhOESM7LoPLeCkayNQ1wZZCAi0f4O8n9RyBJFvOusqv+AL
+QbTuiVWT9Yf63uS4OXPrVRGc0e6Y91BawGzm/tG2Lg5r7FGaqe2q6yBXl6RyxCLbNGW9Qw4JwIJz
+135aWjflzB72c00LLD/Ae/9k1fs37Ng8Wu9nFDqRywHWv+7HOVDXBlmkRLgpB+qfJu8ntRxxxBRD
+xceESsasDa16YtV0eU/uzijk+CCMjN5fPyBR8BvvQqv263gXDkAJOhq4oZJUjtDhpnXuadW1vA8X
+HCJjgC0IB4MLqDA+VYmgBZYfEDlzq9y/YUtPoynkaqS4fd3dQKtfnUtaC0PAVMfNqusg9afS5JPg
+/I9VhhwAwEx5/fk+snicAyQZhRwXosvD99JZMppNTWuCy+ACykT0qlgESBYn7SUjX/qJs762I2aC
+8402dDWasdnPck2j0h/gXMBEyZVdr8cQUdpAoynkSoQA5kK41tgpBRxkYaL3RwLESuf5SHMlqdqx
+1jzHila3Awdw/vrzfWQ5hHgdckzK/aprqaVI+cZFEgW/qfON5FU4454lqaSbtRbIenrHGfejd6GW
+P5uiBYtGy+PiYDjM7nIKBD/Iu3Akk9Vdr9uxpdEUcmUcGPM+vrzO11LAQRYGQvmE9m+Qq8iydNsW
+dj9WdJqJDbzf9Au6NhICIFH8C1PYv1ZdC2meNnVxeAz/KYSgD9aWyHp6x0zN8zqGHCeLRn1jf2+c
+CaiF4oLG7i/krf9hVZMiJ6MpmkZTyJUpJcBad62RUwo4yMIoERzt3yBXlfX0XTMtKzkm1Hi4Tf0b
+9SSUBOBxyxTVL6StkxgZY/Q2e6E2dHE4E1Dr5H9VXQdZrHyYbpdT8zxU1L34PkoJCNY3cn9NDBFD
+YR+kuaIDEy4hMDZeVeAgTPg7jaaQ60IW9XXuDyjgIAtB+zfIPLJBuleOy5UfEwoAzHn/3apfl1yO
+TOQIOG6akkKOU0KwSdU1NEEbujiscY+lFh9XXQdZvN4w3Z4dlftVjWi+T4ygm7hodDYpHw0G6V7V
+dTSBcwGTRA5X8VrFsTnYGGT090KujQMMrvM2SQEHWYjoaP8GmU86SPbKSbnS5ZIAwLyJjXxi1RUy
+kSOGFHKc4gIi9W9cTpO7OGKIyHl8Jaitu7X6a+ndyavZgzoFCkLyj5o2tlnO7OEg1f9GIxCXExwy
+qcTS9/o4E3BdKk5/L2QeXImbFHCQynCk/RtkPsABdKZ2y2J1yyVBAJgylqt6PXI9SXoScjjrv626
+lspFZLRA73Ka3MVhrWdpprarroMs12A935u8nFYyonkemYit4LExoX8IEZXHJ3Qk7OU5Gx7BCtb6
+8MLdz/KERobIXIQEZq6xG4gCDjI3jBETESzt3yDzAgGgpLjlrF3Z0/rCxQFWtOSUXF6SypF3Hr2r
+7mhh0jxN7eLw1n0NSqxVXQdZvsFGvjd+Nf2q6joYOzmWMYTwfdV1XJY9Lvazfvp51XU0SWA4XnZn
+2MloSn5vma9BugEAmLNhduWvW0YxpFvQI0t1/EXVdZB2kEqOIPJNZ1czkuAi3GhaS25XpZnacdb+
+SCEHuawmdnEEF1AoIYE6dTpjsJb/cfKqWOmI5nlEgxaNllPztN/LfksdbZcXXMAkgaXu3zgdTaHT
+bMgiCMEBI/qrfh0FHGRuPPgjIWj/BlkcqeUIItv01j9d+otxWPc+PFv665CFSDO1UxbF8y6GHDFG
+ZJw+tq+qaV0czrhnOpP0VLpj8l6yO61ByNGERaPOBdQMZlIBjaZcgffIpFSfLPM1aDSFLFqAOLjq
+Qma6UiJz41g+oQCdLJrUchQRJxiWeyMLACyE+HKZr0EWq9dPt8uieO5990IOcnU6S0bTafnvVddx
+WcHj90KsYEie1AoXHHQNQg6V8I8QscoSLuQm9n5KN9FX5lx4DJIvbfSNRlPIMnjPPrbWX+lNiQIO
+MheMEVPhA+3fIMuQpGrHWvN8mSEHCIBi0pylauREr59ul7PiOYbuzBchMpbq5bYXt1UiYacJXRzO
+BEwy9cuq6yDVEIKDzuRuMTV/raoGkGILfX1PF5sdmb8MhyndRF9DCOHFsi7XnQu4JiWNppC5hRCx
+LByW4/IvbOy/GkYxK/6/yZfm2Owb4y4VdFDAQeaCHlmi+Y2q6yDtlWXpti3Lb+MSF4GWATUtGm2e
+Xj/dnk3N/lVbF0n3pLluxC4Oa9xjqcXHVddBqiOUACn4Vlmsbtn2G69f40WjtvSHuZYjOj756kKI
+KAXoZe0s4VN3P881ddWQa3EuYDmzh+5V8Y0uwtcfKX28NRx89s/rvXv9TBYff7T+fzbSdLQpk2f2
+yHw1nZjDEOJ7ww4KOMhcwJtnQgBdjJGlynrZrpmWD5YVcrgAH9V85Ji8R6+f3J0elw+6EVAhox0c
+16ckr/Uujhgich5f0c0bkYkc8cg2TQUhh1ACXOnHq37di4QQkVt/oLWkh/LD/5UAACAASURBVGrX
+4L1nUie/Xsb3PhlNyairhlyJNQHLmX3qjsyXPc8ffpzl6x+Php+P1np7Wqv108/CGMHkuR6hc1FJ
+sfXx5vDeVr+3rkr8ejYuD5wL7wQddKVE5gLcPaX9G2QVskG6V07L+8v43jGKLTpJpbn6Q703PSoe
+xLanVBgZvdteX927OKz1LM3UdtV1kHpIUjlikW2asoJODgn9unXGmePyYd5P71RdR1M5Ex6LJezf
+cC7gUAhLe4PIRUKIaIzDYlwesLH/aoOL7z7O8q2PNwb31vvZH6QUnPNzAn5EC5yx4Vpv++i4uB9j
+jFIKPlrL97bWBreGUXxnjs1+Ufw8vkIBB7k2jBET7jnt3yCrkvaTvXJSLn4Bm2TM2lDbGx9ysf6a
+3hvX4AQCUm917uLw1n0NSixtASBpniSVI3S4ueqfWQXiRp2a4sqpedrP9ad0dPL1ocfDZTSHxYnb
+z3N9e+HfmLSCcwHLwqE7Lr9JpuFP/wTJsxvDwa1/Xu/d62X61kmo8eHfa86ZOQ0+NobZ3mRsHp7+
+OwHAe7m+9fFG/84/J/rYjc2X5cw8pYCDXArGiBgiYgiIIaB3Hv2sRODhYx88Yqz5ym3SCsABdKZ2
+Fx1yAAAzZahdSy65msGa3hsfTr6quo5lQcYYtXDMp65dHMEFFEpIuoEjb0t7ycgZ9+MqQw6h+Dp6
+rMXx6c4FVBEOVSLoSNhrCiEiSLjwRvKqzNQ83einv13WXg/STK/3aTy1r+x+z/OH/6pT/q9rg883
+N3p30jS5Mc8YphAClIL/XZb2v87+c86Ba63W/3Vj+Md/yXtbcv4/BmkajBFPrpRPMomTLsR48v9G
+POLB/XDybyODGMcsRs44jyCj5oxrzhgDHtfSePzf/7SuP40R/90FNwuBe+fjIEQ+4lx+zODkxhEE
+UJBGFgYEgMrEri3sX5Ms+Wwh35MDFDbCeoyRPqibrb+W3ZscFw/6w6x9rczIGOd8VHUZTXfaxaES
+WZtuCWfcM91Tn1ddB6mnrKd3ZsflAeecyRV0+QglmZma54lWW8t+rYu4ib2/sZ7/seo6msx7z4Ra
+7O4S5wL2mThUC/6+pHlCiOi9Z8zGx+Dji/We/oXO9E3Rh615r6lDCKiFSs/+szxLRq+OpgdKiXje
+aJSUglPA0XAXhhXov2cx8p/CChYZY5ydDSsk8BEA/5hJxhjj60zx9ZMfR2CMM/b2DyeGiD0+/lM6
+yHZZZP+e9dRnGVOnrx9ZjCxiZBjCYxfCsbHReBd1BJb4KG4DAAMAxuDkxnJV/61Ie0ghgYHfctY+
+VklycxHf0wfYiBgZpzHSxst7cnd2XDzIWxhygKSlzvNKcz0aH5dfriWyNjdNweP3Qgi6USDvlQ/T
+7elxeZD29NJDDiE4YAjlMl/jMsrj4mA4oCNh5xU8PlOpXGxYNXX7+Vrv7kK/J2mMECI665lw4aHi
+0q6nyS+Tgbi16F0sARlTkiVv//P1td72/7wcf7U5Gpz7/kABR428G1a8/r8/GFYwBpK9P6xgbP0k
+nzg/rLhyjSFgH2Zf5329FwPiaa2nADhnjDMmGBNK3FKMsbzHWMQY40n2wRDDf3mHh8aGMSKPHuMg
+RPiEc7HGJGPAqOuDXExqOfLGs+D8t0LJuY8mc8hv1mjkmMyBc4Aka2PIERn1Fy1Gnbo4nAmYZOqX
+VddB6q83TLfHx+Wfe8P0d8s+bQcBBogYoaJTfWzpD1OpuBB0qtC8vAtPdZ4sLOAwU/N01KPRlK5x
+LmBw4Uh4dpABsFGW7qgcPl/me0REZIKBPu/frQ/yvcmk/KbfT//w9r+jgGOJMEQ8N6xgjPFg/1p1
+WHFVIXgciOJB3kvuMsYYFwC2dMdpT134tRw456+HxwWDGyphN7KeYvEk92ARI2MxMmvxkQt+GgIL
+zsUBCq4R4eZp1wcFH+QsqeXIGvffPOARCJjrRgUAmPP+OyEX0xFCqiXE65BjUu7n/XSv6npIvdSp
+i8Ma9zgfJnOHtKQbBsP09+NXs/3+en5nmTcWCsQNxMiquOqKISIz/m96SEePziuGiIwDX9R+n+AC
+9mg0pTOsCYjOPROOfz9I1SDP8ttC8DvnnnayBIiMyQTOvS5XSoBz4VfGuSOt1Bv3ABRwXNJlwwoe
+cXz6Nw6CCc557ySsYBoAbr4OKxiT7HeMc8YrCiuuyjl3uJmZ/0l08kY7GjLG4xx7C/jpyqPXvyeZ
+Ep9lp9/7rXEXH9CUFo9DQIGM56fjLj/t+qBxl05KtNopivIgSTSbJ+QAAGZm7mWaXvy/Jc0gBECi
+8AtTuMc6U40Prmp2amPj1aGLI4aInMdXy34aT9plsJ7vjQ9n+/1R786yFtPKRKyHgM+kFCvfw2GO
+zcPBUNP4wwJ4j0wpsbGo74dTt9+j0ZTWOt2ngTY8zph8sZmqXyZ9vVXVCCXGyD7UuprnyejoePZn
+KcQbXW2dDDgWEVZwgJv83LBC1D6suCrn3OFmbv4nSdQ7T5g4xv4FP3vXdt64S/bOuEs88g5/MNaN
+I+PxjSWnNO7SGVmWbheT8s9Jrn933SdaIACMxTBPYEfqRygJ0fpNU7rHOm1+yEEWR+tkvZy5P6lE
+VjbGZK1naaa2q3p90lyDjXxv/HK6Pxj17izjMwskMDd1z9mKF42WM3uY58mnVY3GtI1z4UhlYiGf
+fWZqno5yGk1pm59GT2x4koIKo1xvy6G4VYvgPfjHwD/c4bg2zH//4nD65cZG76eOzMYHHCd7K86G
+FZGx10+53htWcCa54HkXw4qrOgk37LnhBmOMoeCaxZPFpavy5rgLW1eJWH/fuEtkwZwuOQ2CD2jc
+pb2yfvr7Ylzu6156h8P1fm+t531aNNo+MpEjbz1rQ8jR8Y+kheKCQ4T4sfchSlnNL7237mudt2lP
+DFmlwUa+N341/XK40V/4qFUVi0aDC6hCfKIy8c5MPbke7/0TDfOf0PTTaEpCoyltYE1ADOGZcPE/
+e4nS/Sz/XPT556saPbmsGMFc5rqn30/vTibmr/2+/oyxmgUcHworIrrHgGiuF1ZwCiuuwRlzuNn3
+/5Mk71/gyBnUZjHjeeMujL275NT78AwDviwtHkdkzMc4CAifcCHWaNyl2bJBuleMy33dT6/1RMtF
+uFGXn2eyWDKRI1s2O+QAzv7KGPtd1XW0SZYmW+XEfi3XVx8yBBdQKCGXNWJAuqHfz+5OXxUPekv4
+GeYgBwExrupJrp2Y/bW1nMYfFihy5hbxHuOm9uForU9HWTfU2dETHcX/20jVPy3qKNdlihhml6lO
+KwHO+S3r/FGi5NrSAo7LhBUn/y7OgGM4+SrOhWQDzhiTnEUu4DMu2On8wy0KK1YnOnPwTwP8SF5w
+OgUAZxHxmLH5Fjwu2xtdHxK2GGNbWY+ddH3gm+MuLrhZCNy/Me5yGnxQ10ftZYN0r5iY+2k/vfpF
+Eod178Oz1z8jpGWS9CTkcNZ/qz4Q3JLuOO3iCCHERR9vdxFn3DPdm//JKuk2LjjoXrK7jJBDKrgd
+MTK2giuf8rg46PcyGn9YIOcCJkpuzvt9zMwebubZp/R30yzOBQwemXDhYcpk2MiSLTWUtwRAY8Yi
+gfNw2a6Sfq5HL49nf5YCfnepgOPcsIJFxvCCsEKwAecfCisYYxwY55J+YWok2vJgox8/kgrWL/O/
+9y5+LxP22bLrWgbOOT8dR/hp3IWdnArz9pJTF8KxsdFgQBHOLDn9adEpdX3Uhu6pO+WkfJD20ytd
+7AEAc8Y/1ymjgKOlklSOysL9N+dwJFW9g9m3YWR8hdOAnZGlyVY5tl8v4wn4hwSP31e1uI20ixAc
+dCZ3Z8flfj5c3KlRIIAFF76TcjE7HN7HmYBaKH7Z605yOd6FI5nM93cXQsQs8CcqlzQ21ADOBQzG
+H4HnBz0lZT9LPxdLPsp1WUKIeNWvGZ3s47gvvfN4rbCCMcYkhRVtE21xMBqwj4S83IcMALDIgl12
+XVU4b8np2+MuiOG/vMNDY8MYkUePcRAifMK5WKMlp9UBDqAztWsK843O9KU/lEEAmDKW/Ubd9pKr
+SjO1Uxb274wlrFEhR1zltqPuqKKLw5mASaZ+uYrXIt0glADJ2BdlYR+n2WKOOwcJzBbupc4u/t/O
+IxT2QZ9GUxbOW/9Dksq5QiM3Lmk0pcZCiBg8smjDY/DxxXpP/0L39E0hYCnLh1cLWarU8Kpf1e+n
+d6TmJT83rGDAOFBY0SVoi4PNK4QbjDHGBYArXZn1lllZvby55BRuqITdeN+SUxf8NAQWaMnp6oEA
+kAC/ctY+VsnlL/bKgBoxRrjmolLSDGmmdqaT4iDlGZOyQSEHWYpVd3FY4x7nww9vhifkqpQSYEu/
+aQr7WC8g5BCCA2JY6uli06PiL2uDxXWdkJ8FxsbzPLk3M3s4otGU2gkhorOeCRceKi7teqp+mQz0
+rVWPWS5bQMbUNe6UtBIgRUWbw0m9gJvcHw3FHoirvxHGGAUdrXn+ktPThx5vdH14/9gHNKXF4xBQ
+IOM5LTldDqnlyBvPnHWPVXK5xZIuwEcnM8ed/nHuhF4/3Z5OioM0b0bIcXJgFf1cLsMquzhiiMh5
+fFWLI/hI65zuGjKlfazT+UMOELKPMTKxhPeecmYP+zoZ0e/C4jkXMEnklZ9+nzodTUloNKUWfjrK
+1bODDICNsnRHNXT05LIiIgOA0XW+tlanqJBqgJnsr6/LvWs/sY4sj5Guuz/kzSWnyS3FGHvfklNj
+3TgyHmnJ6WJILUeudAwDHoG4+CY2crGFGI8FY7W/4SXz6/XT7dmk+DP0st9dJ+BdJS7YrOoa2mxV
+XRzWepZmqjFL3kjzJKkclVPLDHffaq3m6hRa1qLRECIqj0+SweXHSMnlBYdMKnH7ul/vxuXDjWGP
+RlMqZE1AdO6ZcPz7QaoGeZbfFoLfqdtRrsuCyJhK4OPrfC0FHB0HZrK/sS7v8Dna8SNnG68fLS6w
+sm44d8npe8ZdIgvGlNH6EJMILKElp5enUjWypfs7Y5JdFHIAAHMufK8S0cjFueTq8n76++nE3M/7
+eq/OT0OEgFDb4lpgVV0c3rqvdb76Y2lJt6S9ZFRMzNRxfqQSee3AHgQwv4RFo/a4+Hq4ltPvwZI4
+Gx5l6fWuY05HU+r8edhGZ49yzZh8sZmqXyZ9vdXVZdQB8dpPzyng6DAwkwcbG3L+JTQgtiJGxsSC
+CiPnjrsw9u6SU+/DMwz4srR4HJGxn5ac0rjLO5JU7RRFeZBozQDeH3KAACgm7jjv0F4Zwlivn9yd
+HJf7vWF2p7b7VyLSEelLtuwujuACCiUk0N8jWYGsrz8ppubvnHMmlbhWyCElMDtzL9kCF42WU/O0
+38t26PdgeQLD8XVGf2g0ZbV+Gj2x4UkKKoxyvS2H4haNbTHGY/wrcPa763wtBRwdhDFiHsd/6o/0
+Qi7gADjziM8EE3S05gq8Oe4CW4yxrfeNu7jgZiFw73wcIHDNUN7s8rhLlqXbxdTc15ne+1DXkkEU
+tGi0e/pDvTc5Kvb761kLto+T61h2F4cz7pnuKWr7JiuT9fTO7Lg8YD19rZCDCw4YF7do1LmAmsFM
+KujkU+lVCC5gksC19m/4sXm4MczpPWqJXocaz8Cyp30tZT/LPxd9/nlXRk8ua55nOhRwdAyGiD0+
+/lNvsJhwgzHGGACLHl8yzSjgqNC54y5MMcYYQzxp+YgYGYbw2IVwbGw0GFAExvMujbtkPX23GJf7
+up++9ybWI2xEGrvqpP6a3hu/KvaHGzlt9e8ovcQujuDx+662G5Pq5MN0e3pcHqR9zaS8TsgBm4ta
+NOom9n5/Pf/j3N+IvJf3yKRUn1z168zMHq5n6b/QaMpinR09UYG/WM/1L3Smb4o+bNHDlPeLGGbX
+/a9DAUeHYAjYh9nXeV8v9MIdgDEMYcZe30yT+jnpROCMCcaEErcUe3fcBTH8l3d4aGwYI/L4etxl
+xLn4mEnGgLWn6yMbpHvlcfmlHmbnXmSFIG7S2FV3Ddb03vSouN9by+5WXcupGCNWXUNXCMEh8sV3
+cTgTMMnULxf1/Qi5it4w3R4flX/qr6V/uOoNrErkzRjmXzQ6PS4O1obpvfm+C7mIc+FxqsWVlsvG
+EFH5+DedS/r7WYCzR7mmTIaNLNlSQ0mjJ1cAnIfrdrVQwNERIXgciOJB3ksWfsHOOcD/z969drdx
+XHmj37WrqqsvAAiC8igR5eQ54+gyE2vmWbEl0c6780XOOt/kfLgzFill/KxJFMc0nWcd24qSiSJR
+IAH0pW7nBQiKonhnA33B/q2sFYsXoCiBje5/197bGDBlPy6Zv/fKXQBvywBun9bkVFszthas0V5Z
+zrrO4Z3Zro8mBh9BN/giG2VbYSf88C6tACgK+1xIajS6rKKOeDzaS7c6vRo1g2SN+zVrLBUF69m4
+eJqU+O9f5Hon7gXXmmhByHV0V8KH+28nm53V5PFl+l+gQNCFu9Z7YpGZ3SQIErrAmz9r7evLVtgW
++/nzj3pxbUL9JtLaOpubIRq2nUghBmH4q7aPcp0Xa71j10hUKeBYAlrr3bUofxWo8sONGQdOeef9
+daaxkPo4qcnprL/YaU1OrXXcAYuta0aTU2SIKpIPTwo5EBF0ridAjUaXFmOIcSIeTvbSrbgGIYdz
+AKG6Wk01uTzOGXrvb1nrPC9hfLC33jHm39LFHalatx9v7L8Zb3YHyYV7DQlEyHW+f9Wdut565zPz
+nVqp/ljadtZ6Jziqy5Q+FJnZ7UfhgC7EL8da76xx4Au7g8a/7ifqhkrUnWUa5To/DpTkVz7noYCj
+5bTWu2tx/ioIrjcH/TwMWOC9B0Y9C1rvMk1O80Lve2BeG9+1ng0YE7fq1OQUOaKM+ENdFDsyCA5H
+4CFDzLUrrakaaSbGEIOoPiEHWazpLo68lF0cRWEgjOS9MtZFyHV1V6chR2+tc6GSZcYZOgd41ffE
+dC/7emUlenT5lZLLMsaAUMEnF/16b70Thf2TotKhC5mVnnhjnkcgR/1Q/jLoqrvzHC2+jKwDkNe4
+SqCAo8Wm4UYx93ADAMAB3vZ+3s9C6uzEJqfJ2U1OjfbKIwRVNjkVXKAxZu14yFFY1vHOA6P3rKXG
++UHIMco2405YYeNRB8CoKcwilbmLwxT6qYopJCP10V2NN/bfTp50+xcrSxCcrTrn4bLXcdmk2O3E
+6lc0EnYxdG53wuTi/TeK/eL5R7369Juqo8NRrga2I0QYROF9GeMD2vEyP9Y6UIiDq34/BRwtpfN8
+d61jXgWBWEi9L2PYB0o4yCku0uT0aLmLdwAHTU4/ZoyvzLvJqVBiYHIDpjAvRCBuAwDkBj+llzQB
+mIYcUri7eap3VCTvnP8dc+A87Y+rQBm7OKy2jksu6AKP1E2SqMfjt+nWRSYG8UBcuvm21dZJ51/I
+iPpZLYozbvei193T0hRFpSknKHLrnNYvuWY/dkPZjaP4Uyo9WSAPIDneuuq3U8DRQl7n2x913U0h
+FxNuAEwnqVhjv+eSV3PyTxrpIuUu3nvQhXuurZ5Yy4zWvus4U2U3ORVKDIpM/91ZN0SOK4gI2pjv
+uQjoNU1ABGJgCgN5pndUWFHIQRaujF0cujBDFYvPyl4bIdfFOEOVBA8vEnJcpdFovp9vrq4mVPqw
+INZ6hwLZRcuIeG6/VSsh7d6A90e5RiBerylxI+ioO4g0yrUK1jm4zl87BRwt44tse7XjbwqJ/YU+
+MSI457KFPidpraPlLgAAQvIHEZxd7uKs4xZYfJ1ylyCU99M02w4CBYjYNbnZg7D8n480kwjEoMiq
+CTkcANAWjmpcdxeH1fZPnCu6yCO1xDlDFYmHk71sM+6dXoYnECEr8hHEF2s0mu2l2z0qfVgoYwxw
+Od2Fep78bf77j3pRhWWX1TssPSnsn0OUdhCre6LHaZRrDTDv/8AY/NtVv58CjhbxRbo96MJNLhYc
+bsB0B4cx9sodtgm5qIuUu0ybnJqf8sLuO8f8QbnLgDF+67xylygK76Xj9JmKos/zzGedlQX/gKTW
+grC6kIMxduV6VHJ119nFoXPrglDcmNfaCCkDlxyl93eztNgJo5N3LTLOEBgw570/r9yqyMyu4pKV
+MYGIXJw17qUMxfp5X5fn2q0oubaMpSkHocZLLOBFRwnRieLPMGE0yrVmvINrbZyhgKMlXJFur1UU
+bgBMpw1YC9SxgFTmvXKXI01O/TT3AO88gPdQFO65B5vPmpxazrrHy12iJHqY7mebGELHOe+Rxh+T
+I2Yhx9GeLXPnAFBcvR6VXM9Vd3EUud6Je8HCykUJuSoRiIHLDORpsaNOCTk4Y6vTPhynvyV66x3k
+5k9hL6JdSwtmtH2h4uDcgIOn9knYj367iDVV7WjpibTsdT9WN1Sk7vAOlZ7UmXd2cp1/HQo4WgD1
+6Mmgxzew4qTcOd/1zntGF4OkRtisGvXg1yM6qB8+q8mptY4rxeLd1+O9G6vSyYAxFAhsgdNdSL0F
+oRhkqf47MBwKiQvY5+OBjqzVucouDm+9Y+Bf03Zn0hTvdqgVOyr8MOTggbjjrNvj/PRj3mSUPe93
+qK/DonnrHTBk5+2uSffy7X/qxq0On2ajXLm2X4cg7GoUrMueoNKTBkHG7HUaulLA0XCYjzb7fbFR
+hzvMDKcNIRkVipOGOK/JaSz0/xtFuOccvNCp2QfvvQPoAmMfc44riNPGaxR8LKcwkveztPgWIIDF
+hBykSpfdxVEUBsJY/uu810VImYJQDLJxATnT3ykl39t9JARCUZgfZSBObDSaTYrdbqh+Qdv9F88Y
+B1Ly1bO+RufW9UU7S4e0ts7mZoiGbSdSiEEY/krGSKUnDWStdwyud1pNAUeDYT7aXO2Lx3XZMeGB
+xmqStvDeG7O1OugEKgpWAWD1MPjwHrwDcM4NjXY/UfCx3MJI3h+P0u2QRSDE/EIO5+jgWjXOGYKH
+8KK7OHRefK3imKankMYJk2CQjvO/a8aGMhCHxzUuOdpRtgex+uB7rLZOGvdnGfHPF7pYAgAAWtuh
+jM6eZMhS/STqd1pTmnJ0lGs/UTdUou7QKNc2cKAk713nESjgaCjMR1urq+JxrerHGIKnhIM0nPfO
+gXPPVCTuq0i819OGzepdEIAD9mUAfQo+SNIJ741H6XYUR8DnGHKQ6gWKP8gz/TxO1JmjMq22TgQC
+ztsuTkhdRYm6n47zbxljICQ/PK55j+qkRqPFKN9cWYmpNKUixpg/K5SnBqptKE2ZlZ54Y55HIEdr
+ofxl0FHrnPPF9MIiC2EdgLzmWTIFHA3jvHex33/WGagrjaubJ0QAc8kZ6YTUySzc6K6Ejyfj/D+E
+5Be600HBB0k64b3JKP2vKIn+bV79kOhauXpccizywlnn/Fn13LowQxUL2r1BGi1K1P3JXrYNiToM
+ObhgN51zgJwffl02zl90kuhfa3XTbcl4Bvq0QLXJpSmHo1wNbEeIMIjC+yLGB9RPo72sdRBxPLPc
+6jwUcDSIs94lbP9Z0q1fuAEAgIgA4KpeBiFX4q1zANNwQ+fGhaH45XUfk4KP5RJ3wn8fj/IncUdt
+lF33iwz+AHD1mfCkPIHiD/L07F0cVts/ca4afbeUEACAuBfeG+9l22FHgRB8RQR83Rm/BxxWAKYX
+zwpwIiTSXfSKaG1dIMXaaZ9vWmnKYemJZT8kgVSdKP6MSk+WiAfgiOdOAzoLBRwN4ax1HZw8jTtq
+o+q1nIZxxCLTe2Eiq14KIZfirXOMuaedXrgBAGBy81TFlxsHeRkUfLRX0gm+GO1lm0kvelyH5s+k
+fOft4tC5dUEoblSxNkLmIemF90bD7EmyEm5wPm00CjBtNKonxZNOP27MxXMbGW2HIji5/0YTSlOO
+jnKNQLxeU+JG0FF3EGmU6zKyzl17xyoFHA1grXFdnm7FSVD72kYHwLz3ng5IpCmsdY4fCTesNk6G
+Iqmidp6Cj3bo9NTGaJhudvpRaX2SHA2oqpWzdnEUud6Je8Hdk76PkKbqrIRf7L+dbHZWk8d2ZPYg
+VjAZ5r/v9cJaXzwvA1OYn4Lw/Z5hANOdHStC1LI0RWvrjHYgCvN1iNIOYnVP9DiNciXAvP8DY9fb
+sUoBR81prXfXovxVoOofbgAAMOc73gNQvEGa4Hi4AQBQaLsTx+rTKtd1HAUfzdNZURv7b9PN3mpc
+zq476t9cK6ft4vDWOwb+NZ2kkzbq9uON/TfjTcZ5MNnP3sRKDui1Xj0LsH9SWaQf6c14tVObAOqg
+n8ZLLOBFRwnRiaLPMGE0ypW8xzu49r0hCjhqTGu9uxbnr4JANuZOkONMgfcAdKuR1Jy1zgnut5JO
+eBgeeu8cA3zLRTPebCn4qLfuitoYD9MnyUpUSkDdiBflEjlpF0dRGAhj+a9VrouQ83jrDxumvfuP
+dz3UPvzku4Q1COWj//5xd7O/Ev1vXAt+Y613nDN6D6mI1tYFgfhgpGY+zl8MOmGlx6KjpSfK83/0
+Q/mRitQd3qHSE3I67+yEAo6WmoYbRaPCDQAABniHJsWSujPa7ErJvk066r0LzyI1wzCSj6paV1ko
++KiPqCMeT/bSrbh3vZ4u09yYzgfr5KRdHDovvlZRRNNTyKFZmPBeC/aDMOHDIAFgFiY454/+cfqx
+g/9mzvwBAMDZd7nn4ZcdnIQxBxMAsMce4tDsGwXnvfc+cOQPiMxP/x9+ATgdgS0Yg5+tdW+Emd+L
+UvscmCty63PjLQfOYuBsAIi3EBEQpw3oGQUgc2O1AyH5e7tOtbauA3xXSrHwxq+zUa5c268lE8Vq
+GPxCdvldzvm9Ra+FNBMyZq8bgFHAUUM6z3fXOuZVEIhGhRsAAIgMvHN7ALhy/lcTsnhGm90o4q9U
+KD+4q269/+aio2GbiIKPxWMMMYjEw+uGHJz7osx1kXIc3cVhtXVCIKPt1tU4a1fC++HC4XccfMmR
+y/+D/zzMFqx9icy/BngXJhwPEgAAmIP99z53xOzFgMhCZBi898EjH0fwnAAAIABJREFUqcI0TPAh
+immzSDE7vz/6ajr8kPq3Dz82+zM7/qnr7/c+RjD5+p/Wky+Ge5PtJAx+2Qv4yuH7yMF7idZ2xxqX
+51rvWwBv0HU9MAUC7zA+DT4QEWj3x/Xowj6PQv5+L6Cx3oxXkoWVtmttnc3NkDu2HXMhBmH4Kxkj
+lZ6QS7PWOwR+7dcNBRw143W+/VHX3RSyeeHGjNH+RxHAqePzCKnKkXDjg9+vskbDNhEFH/PF+fVD
+DsZ5TmeK9XN0F4cuzDCIg99UvaZF+GBXwgXLG47vSjiaLVxsV4Lfn122nxYmMMYYR+wefuC9zx7Z
+lSDwAQAAB/YuEzj+/wLXGbD1ox97/yHZ+9+2BNvudW7dIJa/AABY6cX3JpP8jbFmJ4rUncMfnwMI
+ye8CAHQOvs85570H8N6Ds35YFOYn48xYW28tWO4RY4fsY+RsBREBBYUfF2HB7R/tg5KP8xeDJPzX
+eb8WD0e5avZjP1E3VKLu0ChXcl3OOQjkwfH7GijgqBFfZNurHX9TSPygE3JTICJ4sHSnkdTOWeEG
+AIAu7NcqDmlr+REUfJRnFnJkaf67MFKfX/oByui6ReZitovDa7vPO+U2BJ9HeYO3dgeZzwDO3JVQ
+MAf50c8d9A/3ACeUNxz94LEgARisIcdbABfclcA++NQHQcL0Q/T7UAVvzE6QhIfvo3GsBlrb/t4w
+3er2wken/bu8dzdfQD9Q76Z+HN/9kWv7B19Yllq358GBReg6YAMm8BbnVPoyY7V1QYC9o39O5lSa
+Mis98cY8j0CO1kL5y6Cj1jnnCy+DIe3lAaCMM0YKOGrCF+n2oAs3uWhuuAEAwDiiznQWJVWvhJB3
+zgs3rHVOBlxVMRq2iSj4uBrOEb11/5ynekdF8k7V6yHX4613zjlwDmDv1ciHHblWpMY7fxACeDcE
+734EOCFIADjaK+H88gYAgZzH733wg/KGd7sSzgwSBL/7wcfee9Ll25VALk45/ub42FEpOSKGD4e7
+6VavHz6+bGnC4XsKwGz3x78BTHd/vAs/prs/tLYvrXFvZqUvGqxiiIEX+Omylb4Y40AI+fHsz26s
+N5MSS1MOpp4MuYHtCBEGUXhfxPiAJueQebHWQcT5x+d/5dko4KgBV6Tbay0IN2a899x77+mkiNSB
+1mY3PiPcAADIM/0ySeo1GraJKPg4nwjEwBQG8kzvqJBCjjo7GmA456avX2ueO+fBW7cPACAE9hhj
+kHTUr4uRfiYTBuwwXcA+AzZ9X6ddCaQFdG7dIJyWpxzHOcOV1XhjuDfZTiL1MxnwUnqxvRd+AIAQ
+fB0A1melL7P3F+felb44Z/J3jU8xBg6tbHyqtd0J1TSwzMf5i0F8/dKUw9ITy35IAqk6UfwZlZ6Q
+hfEAHNm1jx0UcFQM9ejJoMc3kLfowOEh9p4a/pPqXSTc8N45ZPgXLpC2Wc4JBR/vE4EYFBmFHFU7
+HmBYZ4dg/U/W+AK8y4ExEAJ7iOBR8AdMMAApHjDGDns9zB7LausCZMlknD9NuuG/CFnOxR0hdXK8
+POUkx/tyzHtNs/cXRDi39GXW+DTVeg8A4KTGp6JB4Ye19jUy9q40Jbh8acrRUa4RiNdrStyQibrD
+OY1yJYtnrBkyJq99w58CjgphPtrs98UGYrsOIJ7B6sFMw6qXQpbYRcINgMPRsDS+rALLHHwE4TTk
+0IX5Tp4zMct776AZ59u1coEAgwmBXURUKNgdLngfJPQZY3DZcjVEhMKYUXcl+mK0n21HHQUyEBRy
+kFY5qTzlJBftyzFvJ5S+HDY+PV76Yq3/iy7MrtFmosGbWenLYeNTUa/SF2u9ExwVY4y5sX5ymdIU
+ra0z2oEw9usQhF2NgnXZE3ep9IRUDR37iTGggKOpMB9trvbFY9aycAMAAJCve+cBeNULIctK52Y3
+Ts4PNwAAjPF/SiT/chHrIhezLMFHEIpBkWrQwIZnbed2DiCQGC5ybU2wyADjPIwztN4x773vdNW9
+dJx/65z/O+3QIW1xVnnKSa7bl2PePix9gdtKvdsBcXz3R1bo57PSl6ONT1FWU/pijAGhgk/ySbF7
+kdKUg34aL7GAFx0lRBKGn3FOo1xJvXgAKOPtmQKOCmA+2lpdFY/buvULkYFx7iUHvl71Wsjy0bnZ
+TTriVaDOH7Wsc+OimC/laNgmamPwEURykKX6W8YYCImnhhyIECxyXXXwQYBh7Utw/k0VAcZFMI6x
+8x44YxAl6n6WFW8yDzshNZQlLeC02Qk6Z5enHDevvhyLcHz3R0fyB7PPvbf7w3nQ5njjU9PlknvL
+8MG8Gp/q3O7IAH4VOfa/ZCA+mMw1Kz2Bwu+g8a/7ibqhInWHd6j0hNSY8yMKOBrGee9iv/+sM1CP
+q17LXCGCN+4NKKCAgyyUzvR20pXsIuEGAIA29msVKRoN23BNDz7CSN7P0uJbgOCUkMMBsPZtibPW
+Oz9r3nk0wLB+As5ZxpjgAmPkOEDObnHJ14HBelUBxnlQsE+98wAHr6IwDAZFoWE81FvJStzu933S
+eqG/WHnKSRbdl2PeTih9+aDxqXPT3R+zxqfGmbG23lqw3CPGh6UvB7s/uOSXev9xxu066/5Xt989
+PIeZjXLl2n4tmShWw+AXssvvcs5rd7wk5CSMlTOkggKOBXHWu4TtP0u6LQ83YDq/2Fk7AZBVL4Us
+EZ3p7V5fXXgakbXOScEVbc9sryYFH2Ek749H6XbIIhDiWMjhThogWn8fBBjavnTOv/HeT7x1DpHx
+JgUY50HkYI17eTDlAQAAgkAOLLMP999OtjorUWW9CAi5jsuWp5ykLn05FoExxg4zhYs2Ph0Xe7PS
+l6ONT8XB7o+jpS/WelfkxvxsrXffGOdtbt5yx7ZjLsQgDH8lYyo9Ic1jrXcI5YRxFHAsgLPWdXDy
+NO6ojarXsgiMIRoDpup1kOVx2XADgEbDLrO6Bh9JJ7w3HqXbURwBPxZy1PFM9awAA5yzyDnnCAkK
+XEVk61w1O8A4DyKALdzfAN7fvcglxxjx4fDNeKu3GteuFwEh53Ha7Kju5cpTTlL3vhyLUEbj03Gh
+74vcMhjbb3qR7EZJ8imNciVN55yDUGK3jMeigGPOrDWuy9OtOAku3N24DRw45Z33rWyiSmrlKuEG
+jYYlJ6lD8JF0wnuT/exZ1A0/n538O4BKEo7jAYZxdsdrnzvn9pn3gJwrjqBQ4MeIbIUrvs4OAow2
+3509DZcc03GRAagPPsc4w14v3Nh/m27SGFnSNKHnb8oKI5rcl2PeLtr4NC+kc7l2HSmCSAWfco5L
+ecwl7eIBDks8r4sCjjnSWu+uRfmrQC1XuAEAwIAF3ntgtbzvSNriKuEGwHQ0rAoFjYYlF7Lo4CPu
+qoejvWwz6b27w4nAPrxqvqbLBhhK8LtMTjuc08n0yRyict7703aodLtqg8bIkiYpozzlJG3ry7EI
+s/eiKAy46TnZTdTneWF293LzbRIHv5SS31rGXTGkHax1EHH+cRmPRQHHnGitd9fi/FUQnD+mso0c
+4G3fzLJx0hA6zbd7q9Glww0AAGvctpC89f1wyHzNM/jo9NTGNOSIHoMDYBIvfQFAAcbicfTd6Zj0
+0//6aIwsaZKyylNOskx9OcpmA/7IWPfXJFbrSay+zHPtRqP09+BZGifqsRDUWJQ0jAfgyEoJ/ing
+mINpuFEsbbgBAMAY9oESDjInOs23e4PoJueXDze0Ni6Mxcd0IkXmpazgo9NTG6Nhuqki+RBOKFI5
+HmA4a/9gjWfeuX3wHoTAHmMMKMBYHMbxjr/Aex+NkSVNUWZ5ykmoL8fVKCXx9dvsh3Ul12d/Vkr+
+u7XWjbPiRT40P3U64S+DgN+i3hykCYw1Q8bkpc/rT8I+/7/+T7oKLZHO8921jnkVBBcbU9lWVhsX
+Sv/nIAroxI2U6jrhBgDAZJT9vtMLH9BJFKmLE4OPwh4GH6/+tj/+H5989Iih/6NzHrzz7wcYkn/K
+2Cy4oACjSjq3jjv480VDi6LQb6zxOzRGltRRkRu3hvKvURisn//V10d9OS4nHedvboYxV6eUu6WZ
+dum4+FoqrsJIfkrjYkmdjfey36/1oge8hPNz2sFRIq/z7Y+67qaQyx1uAAAAIjjnsqqXQdolT/Pt
+/jXCjYPRsAWFG6ROTtrxIaRxOtc7Vrt//PxnHVWk+dfdQfw5BRj1hgLBjIs3EF1sTDqNkSV15rXd
+Ud1oYee01JfjcqJEDYZ72ZN/Cjon9vqLQolRKD/X2rp0kr/Q1v8Ux+rXgcQe7eogdeOhvH7qpY64
+W2a+yLZXE3dTyKtdeLUNIoCxdr/qdZD2yNN8e/Ua4QbAdDRsEMrPylwXIWXRhXHpKNseD7OvmIe/
+BqH6VaCE6H/U+bzTjz7LxsVTRGR0EVxfnDO0zl1qTDqXHONQPhy+GW8552hXLamNeZennCSO1YBz
+8cneMN3yF6n3WnIF97eNsWf+PUnJsdeNP17rJ1+C9d23bydb40m+Y+l4Q+rE+VFZpzcUcJTAF+n2
+oOsp3DiCMURngQ6cpBQ6y3+3Oohu4jXCDQAABuwnLuiuBamP46FGmKi73dXoSx6In9tC/y7phY8B
+phfOSuHDdFz8oeo1k7N5ht3LBhVHxshuGW2H81obIRdV5Mb1YlXKRIPLkpJjnEz7clDodzYRyvW9
+cfb0ol8fRRLXVjsbSopP0nH23XA42SoKM6QwiVTO+9J2p1KJyjW5It1e68KVJjm0nXO+6533DOlu
+I7k6UxRPVgbxBl7zdVRkZjeMxL+UtS5CrkoXxpnC7DgLr1Uofhkm6i7n74I3q40rMvM06YUbR7+P
+S4HG6/U81ztKUWPKukIBq85f7Q4SjZEldeG13ZEhVlZyzTnDldV4g/pynI1zhhNnwxXn/GV6FwSS
+YyDje9Z6l+XF29E4f0KjZklVrPWOIy/t8WgHxzWgHj250YO7FG6cjCEABcLkOkxRPOn1o2uHG9PH
+MttC0gkSqcZpOzWCSK4fDTd0rndNbraOhxszKpADb91anuudxa2eXAZDtu6c27vq93e66l4xyf+a
+Z/RvTKpTRXnKSVZ68b1CG5umOf0+nAIj8WCSFs+v8r2cM0xiNbixmnyJAD8fjdLf7w0nm+eVvRBS
+JucchBK7ZT0e7eC4IsxHm/2+KOXCq6084KeUb5Cr0kWxuVJSuEGjYUkVztupcVye613m4VXUDU9s
+GDejQjlIx/lYcxxKQaFd3XDBwRT2x0CKB1d9DBojS6pU5MZ9VFF5ykniWA20tv29YbrV7YXUjPcY
+KTmOsmzc8YG/TvPQ46Nm9b77MY6D/0G7Osi8eYBSt13QDo4rwHy0udoXjyncOAdD2sFBruQg3Cjt
+d0zn5rkIxK0yHouQsxzfqRF1Tt6pcVye610EeBVG8kJbwqNEfVykxV+NoX4NdcMRwTp37SbbYRgM
+wJm18XCyVca6CLkor+2OFLiQ0bAXRX05zmYD/igv7MsyHotzjr0k+nhtNfktePj53m76n+NR9gdr
+aVcHmQ9rHQjOSwtVKeC4JMxHW6ur4jH1lTgfIoAp3JW2zJHlVaTlhhvWOicE13T3gcyLzk8PNS7y
+usvTabihwouFGzNxou5no+Jv1Am/XhhnaD1AGU37gkAOAskf7r+d0EQJshDeeleX8pTjZn059vaz
+73RB4e5RSkl8Pcp+KPtxo1DiYC35PFTy1+kkf7H7dvxVXpih9/S+Q8rjnAeOrLQdqRRwXJDz3oVu
+b2swkI9pa9zFINLLi1xOkRabqzfKCzcApqNhVSh/U9bjEQJwLNSAy4caM3mqdxEvH27MJD11bzLM
+6I5mzTAGHVdSHkFjZMkiaWOhqukpF0V9OU5mpb+fF2YuwQ+NmiXz5Jwdlnl5TVegF+Csd4nff9bp
+qsdVr6VJGEcsCnvlRmtkuczCjTkEiD/QaFhShrJCjZl0nL9Azq4cbsx0VsKN8TCjO/w1wri/XeYN
+ThojSxaljuUpJ4ljNeBcfLI3TOnYdyBK1GA4zr6Z+/PQqFlSMnTsp2u0j/nw8Up7pJZy1roOjp4m
+FG5ciQNgdMAj58nTYmse4YbOjYsi+esyH5Msl/dCDYSX1w01ZtJxtq2U6CglShnD2FkJN0a74ydl
+PBa5Ps5l31lXSj38Ud2u2pjsZ3/Tc7pLS5abt95Fnr+uY3nKSagvx4cK7m8vagJKMN3Vca/XiR5a
+Y+3bt+lXea7/Qrs6yGV5ACjzoEMBxxmsNa7DJ1txJzhxXB85H3O+Q/EGOUueFltrH8VzKf3SuXlK
+o2HJZXjr3amhhpK3yzjxn4Yb8qaQvNQR40k32hjvZdSQsgYQAYxxb+bx2DRGlsyLNha6sfpF1eu4
+DOrL8T4RyvW9cfZ0kc85GzW7thr/FgF+PqZRs+SynB+VeRlAY2JPobXeXYvyV4EKzhzXR87mOFPg
+y87lSFtYbb5a+yj+ck6P7cJIDqhnDjmPt94ZY8Hog5GusfhF1FF353EXc17hBsC0jEEpfDjey7aS
+Xki7DivEJcd0XOwBqLk8Po2RJfPgtd2RIZayq2zRVnrxvckkf2Os2YkitbS/E5wznDgbrjjneQU7
+cWjULLkKxrwv83yddnCcQGu9uxbnrwJ1vbpoAsAA79AODnISb83Wymo4l3ADACAvzHOh+NKe5JCz
+Hd2pMRnlm/PYqXFcupdtq3A+4cYMlwJlwO5kKd3dr5oH4G6OJZo0RpaUqWnlKSehvhxTGIkHk7So
+dIrh8VGzo2H6Oxo1S05irXcIvNTjDu3gOGYabhSvgoDCjTIgMvDO7QEglQkQAADw3jlw7ll3ZX53
+mK11jjOeNvlEjZTvvZ0aHl6rcH47NY4bD7PfxR35Ky7mF27MyEAO8kxDnusdpejuflWQs1XvPJR8
+3vaeIJADy+zD/beTrc5K9Ih2rJGr0sZCv2HlKSeRkiPitC9Hrx8+XsbzACk5jrJs3PGBZ2V2bryi
+KJQYhfKh1talk/yFtv6nOFa/DiT26rA+Ui3nHIQSu2U+Ju3gOELn+UG4UU7TNzJltP+x6jWQelhE
+uAEwHQ0bxvLRPJ+DNMN7OzUmR3ZqrMxvp8Zxk/3sSdILPltEuDGjQjnw1q3pXL9Y1HOS9zGBdxZx
+E5nGyJIyYG6/bsL0lIugvhwANuCP8sKW3uj4Oj4YNTucbKVj2tWx7JxzpScSFHAc8Drf/qjrGIUb
+5UJE8OCLqtdBquftYsKNAzQadonNQo3JXvq7qkKNmfEw24w7wUYVdxFVKAdFYUbGLOcJftUQOVjr
+vl/Ec9EYWXId3noXIbdt2+2w0ovvFdrYNM2XrmRPKYmvR9kPVa/jNFEkca3f2ZCB/HU6yWnU7BJz
+HiCQ4tMyH5MCDgDwRba9mribQuLC7q4tC8YRdeGyqtdBquWtc4y5p4sIN2g07HI6GmqkWfEMOduL
+e+FnVYQaM+NhtpmsqEq3SMeJup+lxd+MpYveRUOBYI3bW+Rz0hhZchXaWEgida/qdczDMvflsNLf
+z2t+LPhw1Ox4i0bNLhfnPJRdXbn0AYcv0u1B11O4MUfee75sbyrknVm40emFCxm3bHLzlNNo2KVw
+WqjR6YaPZSD6VQYLozeTrc6Keow16ImQJOpeNsq/o/KFxeKcodZm4QE/jZEll4W5/VqI9vZKk5Jj
+nEz7cizTcTBK1GA4zr6peh0X8W7UbGcDAX4+oVGzy8O7l2WfKC11k1FXpNtrXbjJBYUbc+Uh9h6g
++tN8smjTZp+LCzesNk5FclCHi0oyH7NGoTrXXwNHq5S4F/fCz+q0tXo0nHzVW5vP+OOrSrrhw9Ew
+20z6US1Cl2XhEJVzzi/69UljZMlFtbU85bhZX47h3mQ7idTPZLAcN0IK7m8bY70Qc+x2XLKjo2bT
+tNjd1+5PNGq2xSy8YchK7f+ztDs4UI+e3OjBXQo35s8zWAXawLF0rHVOcL+1qHADAKDQdodGw7aP
+t94Vma7lTo2jvPUu3Zts9fr1CjdmOivhxvgNjRRdJI5ws6q3PxojSy6izeUpJ1m2vhwilOt74+xp
+1eu4Cs45djrR4Oio2f1x+jva1dEu1gGUfRK3lAEH5qPNfk9sIK/HSXHrIV/3y7MjkMB0J4Xgfivp
+qC8W9pzWOQR8W5eLXXI9x0MNLrCWocaMtd5lk/xZshIvoonulXVWo43xMKUL3gVhnK1XWaEZBHIQ
+SP5w/+1k6foPkItpe3nKSZapLwfnDCfOhk3vaRGFEvurycM4CH6TpfmL3bfjr/LCDD1dYDSeYLBP
+PTiuCfPR5mpfPEakLbqLgsjAOFerUVVkfow2uyrk3y8y3AAA0LkZqkjQaNgGa1qoMWO1ccUkf5r0
+FjIh6NpUHDwc72UUciwAFxyK3DyvdA00RpacYlnKU06yTH05MBIPJmlR6XGoLDRqtn08OGAlJxxL
+FXBgPtpaXRWPGYUbi4UI3sCbqpdB5s9osxtF/FUYyYWPW3befyNkc2pMyVRTQ40Zq40zudlKFliK
+dV2cM1QKH6bj4g9Vr6XtOCI4aydVr4PGyJKTFIVZqvKU42Z9Ofb2s+900d7fCyk5jnQ+bttuBxo1
+23zWeieQl94TdCkCDue9C93e1mAgH5edEJHzIQI4V/0JHpmvWbihwsWHGzo3LgzFLxf9vORqbMND
+jRmd612j/R+jbrjQ3Upl4FIg4349z2nSxjwxztA4sHU54aYxsuQort3SlaecZBn6ctiAP8oL28rd
+1DRqtrmccxBwjMt+3NYHHM56l/j9Z52uasTW4TZiDNEYMFWvg8xPleEGwHQ0rAhEqR2YSbmOhhp5
+g0ONmTzXu97DqyiRD6pey1WpQA68dWsUcswZY52a5BsAQGNkydQyl6ecpO19OZSS+HqU/VD1OuaJ
+Rs02j3MO2BwOQa0eE+usdR2cPI07qjFbh9vKgVPeeU/lQe2jtdmNKww3rDZOhiKh0Zf1Y613Vhsw
+hfmacTSBEveDsF4jXa8iT/UuIrxSFZRilU2FcpCO87HmOJRiOcYmLhpKf9v5et1RojGypCgMrMbh
+0pannERKjojTvhy9fvi46e9Vx1np7+eFGapAtP5YT6Nmm8F5ACn5p2U/bp3eb0tlrXEdPtmKOwGF
+GzXAgAUtDMSXXtXhBsB0NKwMROkHR3I1R3dqFFnxdLZTI+mGG03cqXHcYbhR4Wu+bFGiPi7S4q/G
+tLcGvUqcy75zbq/qdRxHY2SXG9fua8GpPOW4NvfliBI1GI6zb6pexyLRqNl6c87DPO5PtjLg0Frv
+rqrs+zgJGlcX3VYO8DblG+1Sh3DDe+cY4Fsumn3R3HSzUGPc0lBjpo3hxkycqPvZqPgb1SyXDxHA
+FPbHqtdxEhoju5yoPOV8be3LUXB/e1kv7t8bNZsXNGq2Drx7OY+DUOsCDq317lqcvwpU+05Am4wx
+7AOdO7WGzqsPNwAAitQMQxoNW4mTQo2khaHGTJYW20LAuOrX/DwlPXVvMsxaPzJx0RARrHGjqtdx
+Ghoju3yKwkASL+/0lItqY18OEcr1vXH2tOp1VElKjr0kolGzdWDhzTx6cLQq4JiGG8WrIGjvCWhT
+IQJYY7+veh3k+nRudpOOqDzcAACwNBp2oZYt1JhJx9l2IPlNGcjbVa9l3jor4cZ4mLXmZL4OGGdo
+vWN1/julMbLLhcpTLk5KjnEy7cvRhgCQc4YTZ0ParTd10qjZnEbNLox1APM4c2xNwKHz/CDcEJVf
+dJETIIJzLKt6GeR6dK5fJB3xKlDV/57RaNjFODHUWIlaH2rMpONsWyl5U0jer3oti9JZCTdGu+Mn
+Va+jTRjH2DXgfJnGyLafpfKUS2tbXw6MxINJWjyveh11cnTUrKNRswsjGOwD0A6OE3mdb3/UdYzC
+jfpCBDDW7le9DnJ1OtPb3V7QqUO4AQCgC/s1jYadD2u9y9Pi9FBjSSbWpONsW4XLFW7MJN1oY7yX
+UfPJkqBgnzalzJvGyLabofKUK2tLXw4pOY50PqbeEx+iUbOL5cEBm8M5ZeMDDl9k26uJuykkLt0J
+aJMwhugs0MGhoXSmt3t9VZsLPWudkwFXy3KhvQjWepdNit3xXrZpcv21kHwpQ42ZdO8g3BD1eM0v
+GuMMlcKHFHKUA5GDNe5l1eu4qChR963Wa1lKIUfbUHnK9bSlL4cN+KO8sI05JlVBKYkrveTfux31
+SBdm983u+Ks8139pQ6lSHVhrnUAu5vHYjQ44fJFuD7qewo2GcM53fRP26JL3zMINLurze5Zn+mWg
+aDTsdR0PNYJQ9JOV8HHUUZ8vY6gxM9nPnoTd4O6yhhszXAqUAbtDF7nXhwhgrftb1eu4DBoj2z7W
+ehdxKk+5rjb05VBK4utR9kPV62gCzjkmsRrcWE2+pFGz5XEOIOAYz+OxGxtwuCLdHnShVhdd5GwM
+ARocdi+lOoYb3juHDP9Co2Gv5qxQQwjOljXUmBkPs824E2xwugAAAAAZyAF4t5bnFHJcB5cctTaN
+60NFY2TbxRQGkojKU8rQhr4cVvr7OfXbuZQPRs3ujv8jzzWNmr0C5xzMY4IKQEMDDtSjJzd6cLdO
+F13kfB7wUzo9ag6d5rULNwAOR8PSCdolWGMp1LiA8TDbTFbUY7q7+T4VyoG3bk3n+kXVa2kyh6hc
+A0MCGiPbHlSeUr4m9+WIEjUYjrNvql5HEx2Oml1NfgsOaNTsFTgPICWfy27sudS9zBPmo81+X2wg
+0gl54zCkHRwNodN8u7ca1S7cAAAwxv8pkfzLqtdRd9ZYpws7tMZtC4EiCMVnyPExhRknOww36O/n
+RCqUg8k4/zvjOBSC0wXSFXD0Xe88QAMnWx8ZI7uZdMN/EZJeA01D5SnzE8dqoLXt7w3TrW4vfDSP
+ponzUnB/2xjrhWjggakmokhiFMmNQluXTvIX1sHLMAruB5L3mvRaWDTnPMzrr4ff+p//x/8zl0ee
+A8xHm6t98ZjCjYbyzjPv/ygCfrPqpZDT6TTf7g3qGW7o3Li8++/WAAAgAElEQVRAIeeC96peSx1Z
+Y12Rmbd5qv8LPPx3EIp/VpG8HSixjoiM3mhPNnoz2equhhRunEMG4kY6KX5AgRIRw6rX0zTWuoFA
+ZE2+wFRK3B7v5z8gR8k5vQaaROfGr4Zhl/7d5oNzZEKIW/vD9Gmg+HpT3m8Zx66Z6GdRGNyuei1N
+xzkypeRKIMUto006Gme/996nyHFA5xcf0nnxl1jK3jzeExtTooL5aGt1VTxmFG40FmJjXm5LK5+F
+G7x+4QYAgDb2axGIW1Wvo06Olp/YwlL5ySV46126N9nqrcWPm3IyWrUkUfeyUf4dlSpcHiIHo933
+Va/jumiMbDNxbak8Zc6a2JeDc4YTZ0NLx/TScM4wPhg1Kzl+QqNmT+HYm6XtweG8d6Hb2xoMJJ2A
+NhzjiEVh96peBzlZnubbqzUON6x1Tgqumnz3syynhRohhRoXNm22mj9LVuLHVa+laZJu+HA8zLaa
+2E+iSigQjDZvql5HGWiMbLNMy1MElacsSNP6cmAkHkzS4nnV62gjGjV7OusA5nVEqnXA4ax3id9/
+1ukqOgFtCQfAqBN7/RRp8fvVQXQTaxpuANBo2FmoMaJQ49qs9a6Y5M+SXkjvLVfUWQk3xm9ofOhl
+cM7QOmeqXkdZaIxsc9D0lMWLYzXgXHyyN0xrP4FISo4jnY9pEsj80KjZDwkG+wBLtoPDWes6OHqa
+ULjRKsz5Tr0P88vHFMWT/iB8UOdwY1lHw54UanQo1LgWq40rJvlTCjeur7MabYyHKV3cXoJn2G3T
+nTsaI9sMXNuvJTUHXjgpOcZJ+HC4m9Z+ApEN+KO8sC+rXscyoFGzUx4czKs6o5YBh7XGdfhkK+4E
+G1WvhZTLcaaAzoFqwxTFk14/2kBe7+CgSM1QhXwp7j5RqDE/Ote7JjdbSS+k95aSqDh4ON7LKOS4
+IBSw2rZTWBojW2+z8hQq865GU/pyKCXx9Sj7oep1LJP3Rs366ajZ8Wg5Rs1aa51EPrdprrWboqK1
+3h2E+YswCv5n1Wsh5XPWD4IAGU3CqZ4uis2VftSIkctFqv8rSoJP2nqCNpt+kqX6v9DDf8tQ/HMY
+yduSpp+UJs/1Lnh4FSWK3ltKhMgYMn8rz+1zSROyzmWt63LG9ts2yYIhY0qJ2/t72ZYQvIst+/ma
+jKan1EOo5I0s1xNr7QspxVrV6zlJYU0SMl4Ieq0snBScxWFwmzH2UZbmf0kz/S1D1uXIVBvPAa31
+Xnp4GwRiLucNtdrBobXeXYvzV4GSd6teC5kPRAbeOWo0WrGDcKMRI5e1Ni6MxcdtO8CftFOje2Sn
+Rtt+3irlud5FgFdhRO8t88ClQMb9ep5Tw8nzcMHBFPbHqtcxL92u2pjsZ3/ThantneplQ+Up9VH3
+vhxRogbDcfZN1etYZoHk2OvGH/c60UNvrH37drw1nuQ7bZty45yDeU1QAahRwDENN4pXQUAnoG1n
+tG/tyV0TFGlzwg0AAJ2b520ZDUuhxuLl6TTcUCG9t8yTCuTAW7dGIcfZOCJY5/arXsc80RjZ+qDy
+lPqpe1+Ogvvby9z4si6OjpoNWjhq1nkAKfncBgfUIuDQeX4Qbgg6AW05RAQPvqh6HcuqSIvN/lpz
+wo2D0bBFk0fbHQ81VCQp1FiQPNW7iBRuLIoK5cAWJtSmvnXmVWOcofUAdbx7WyYaI1sPJtdDmp5S
+P3XuyyFCub43zp5WvQ7yThtHzTrnYZ6nv5UHHF7n2x91HaNwYzkwjqgLl1W9jmVUpMXm6o3mhBsA
+B6NhQ/lZ1eu4rLNCDc6pp8YipOP8BXJG4caCRYn6uEiLvxoKOU7FGHRcu/MNAKAxsnUgDGxTeUp9
+rfTie4U2Nk3z2gSBnDOcOBu2rSSiDY6OmkU4GDU7auioWWt25nnrstKAwxfZ9mribgpZ3/GUpHze
+e972u1d1k6fF1uqN6HHTLqwZsJ+aMhrWakOhRk2k42xbKdFRioLzKsSJup+Nir/RCfLJGPe3l2Ua
+II2RrY613iVcSHrvqbc69uXASDyYpMXzqtdBTqfUwahZ1dBRsx5zaOMODl+k24Oup3BjGXmI63EI
+Xw55WmytfRQ3LtwoMrMbRuJfql7HWaw2LhtnL8Z7+X84D99TqFG9abghbwrJ6b2lQklP3ZsMs1rW
+mFeNc9l31r2seh2LQmNkq2FyPYzj4DdVr4Ocr259OaTkONL5uDEXy0usqaNmvXNF63ZwuCLdHnTh
+JhcUbiwjz2AVKOFYCJMVX619FD+ueh1XYQqzLWT9ttYeDTW8h+9VrNY7K+pLFcq7FGpUi8KNeums
+hBvjYVabu5J1gQhgjHtT9ToWiXGGvV64sf823TKaypcWQRjY5rzySnRyQXXry2ED/igv7NIEsW0Q
+hRLX+p0NpeSv00n+Yvh28lVemGEd34MZgxygRTs4UI+e3OjBXQo3lhjydQqF589bs9W/EX9Z9Tqu
+om6jYU8LNQIKNWoj3cu2VUjhRt10VsKN0e74SdXrqBMuOWptlnJcOo2RXQwqT2muuvTlUEri61H2
+Q5VrIFdzOGq2G23UedTsPI9PCw04MB9t9ntiA3kzaurJfCAyMG55tucumvfOeWu2uithI3duANRj
+NCyFGs0xHma/CxN5UwgKN+oo6UYb472MGk0e4QG4q+FdtUWgMbLzR+UpzVaXvhxW+vs5hZGNdXTU
+rJLik3ScfTccTraqbkpqrXWKy3Cez7GwgAPz0eZqXzRqggOZE0TwBpZqe+6ieO8cOPesyeGGtc4J
+wXUVo2EPQ41h9hWFGs0w2c+eJL3gM07hRm0xzlApfEghxzuMY7zMOxlpjOx8UXlK89WhL0eUqMFw
+nH1TxXOTch3s6rjX66iHVY+adQ6AIwTzfI6FHP0wH22trorHjMINAtP6Y+fspOp1tI23zQ83AKaj
+YVUoF3bn6cRQox9+QaFG/Y2H2WbcCTaqCMPI5XApUAbsDl3QTqFgny7pBo5DNEZ2Pqy2VJ7SEnXo
+y1Fwf7vqO/6kPB+Mmh2lv1/0qFnnHHBENc/nQDvHZk/Oexe6va3BQDZuggOZH8YQjQFT9TraxFvn
+AJofbhz4Yd6jYU8KNbqrEe3UaJDxMNtMVtRjCjeaQwZyAN6t5TmFHIgcrHXfV72OqtEY2fIZbak8
+pWWq7MshQrm+N86eLvp5yfwpJbHfS/792KjZv8x7eo5zAFzinXk+B7o8fz6PNxVnvUv8/rNOV7Xh
+gouUzIFT3tHJTBm8dY4x97QN4YbOjYsi+et5PPZ5ocY8npPMx+jNZKuzoh4jBVGNo0I58Nat6Vy/
+qHotVUKBYI1bykajx9EY2XJReUo7VdWXg3OGE2fDujWoJOU5Nmr25/MeNeu8h3mfvmEU+y+sLncM
+kLPWdXD0NKFwg5yCAQvoZs312YNwo9MLN6peSxl0bp6WORqWQo32GQ0nX/XWYtoV2GAqlIOiMCNj
+qh+FWBXOGWptsqrXURc0RrYcVlvXkULQ8bGdqurLgZF4MEmL54t6PlKd2ajZ8GDU7O7bcfmjZq3Z
+mfcZuBBSoJ/kP3nJb5VxQLTWuC5Pt+Ik+KKMBZJ2coC3Kd+4HmudE9xvJZ2wFb9rVhsXRnJw3eOQ
+1cbpwry0Bn5UkbihYnWHc7xd1jpJNbz1Lhunz3r9Zo4+Ju+LE3V/PM63wzgAwcsLNZvEISrnnKcy
+q3e6XbUx2s+2o44CGYilfF1ch9F2GEXxZ1Wvg8zPrC/HcG+ynUTqZzKY//FTSo6jLBt3fOAZo+PV
+MpCSo5Txx9b69Twv3r4dZ1uBkmthKH/Fr/ue5TGHee/gAACIYnhUxi4OrfXuqsq+p3CDnIcx7AMl
+HFdmtTkIN1RrftfywjwXil+pJo92arSbtd5lk/xZshLTrsAWSRJ1Lxvl3y1rWQJHuElvgx+iMbJX
+R+Upy2PRfTlswB/lRbk7/kn9zWPUrHeumPeZOQIACCnQF/lP19l+orXeXYvzV4GSd8tbHmkrRABr
+7NI3WLsKo81uIPGPbQo3rHWOM55e5k6mLijUWAZWG1dM8qdJr/k9ZsiHkm74cDzMttwS1iwyztaX
+8Me+EBoje3lUnrJ8FtmXQymJr0fZD/N8DlJvZY2aZQzyee8EOox5r7OLYxpuFK+CgMINckGI4Byj
++uNLMtrsRhF/FXWCB1WvpUx5pl+GsXx03tcdDTUYUKjRdlYbZ3KzlbSkxww5WWcl3Bi/Wb5RoVxw
+KHJDde2noDGyl2O0HUZhQOUpS2aRfTms9PfzwlCPnCVXh1Gz5zkMOIQU6E3+02UnW+g8Pwg3BIUb
+5MIQAYy1+1Wvo0lm4YYKWxkknjoalkKN5aRzvWu0/2PUbUePGXK2zmq0MR6mS3UhyxHBWTupeh11
+RmNkL47nVJ6yrGZ9Ofb2s+90Mb8mvVGiBsNx9s28Hp80z2zUbCeajpp9/Xr/q7NGzVprneIynPe6
+3jsSRiE8subiuzh8kW1/1HWMwg1yWYwhOgt0snJBbQ43ThoN+16owSjUWDZ5rne9h1dRIlu1U4mc
+TcXBw/FetjQhB+MMrfOGLtzPRmNkz2e1dd2QylOW3SL6chTc367TnXpSD5xPR81+tNb98qxRs9YB
+cIRg3ut5L+C4zC4OX2Tbqx1/U0jsz295pM2c893L7hhaRrrF4QYAgMnNUy75yqmhhqJQY5nkqd5F
+gFdh1M7XOzkd5wyVwofpuPhD1WtZFM+wS/nG+WiM7NmoPIXMzLsvhwjl+t44e1r245L2OGvUrHcO
+OKKa9xo+2Mt2kV0cvki3B10KN8j1MASgE7uzaW124xaHG3mmTZbmbvjfo02r7XciCH7e6YUbFGos
+pzzVu4jQ2tc7OR+XAhn363m+HM0lUfrbtCfh4rpdtTHZz/6mqQ/Ae6g8hRw1z74cnDOcOBta2k1F
+ziGnTUk/7nfjDW+sff16tPn6zeh/W+c+sda7eT63+OADUiAW6T+8S26xEyYauCLdXuvCTS4o3CDX
+4wE/pXzjdG0ON6x1Ls+K5954FigVJStB4i3k1rpvdKH3wAE4AGAAXc4BAPwAOb8FjAEyBogAgBwQ
+pnf2Kv1hSCko3CAzKpCDPNOQ53pHKXml0dFNwbnsO+f2gONK1Wtpik5X3UvH+bfO+b+rsN2vj4ug
+8hRykllfjuHeZDuJ1M9kwEs7xmAkHkzS4nk3CamMlJzIWuuMcaC1GTrrfwLn91cCpf6/V/uv0jAK
+R+n4R8khiCL1GykQpCw3of0g4AAACEJ8kGfmOQ/fn9SAevRk0OMbSHdWSRkY0g6OU+jc7MZJ+8IN
+a53Lc/0yEHy32wsf5JPiOxkG/6pz87ukqw7GgEoAAPBTB//9brePNW7HaMgdGHDWHoYhCNBFCkMa
+KUuLbSlYImkSFzmgQjlIx/lYcxxKUd6Jed0gApjC/hhIQRcKlxAl6n6WFW8yDzthtNwhh9F2GEUx
+laeQE6304nuTSf7GWLMTRaqU3xUpOY6ybNzxgZ/3uE9Sf7Mww1gPVpvn4Py+4lKJAH8eh+EtRNZH
+RDZ8O9leW13ZSxK1zjm/7Zzz1jrYGxX/6ZwzoWS3AyVvKSWvfa5+YsAhuMACcued8LNdHJiPNvt9
+sYFICTEpx/TEzj0XktOJ3RE6N7tJR7wKVHua93rvXJrql5zhi05HPeYcbwMAOMZyIRhyxh9mo3wz
+7KjDcaBs6oPHEoIf+Xs5IwzxANaeE4YgfowMVhCnx1IKQxYvHWfbSsmbQnLaFUjeEyXq48k4/5ZF
+AYiWhhyICIUxo6rX0URhGAyKQsN4qLeSlfhx1eupCs9hm3dwaX9+cr44VgOtbX9vmG51e+GjMnb7
+2IA/ygv7MlS4XsYaSTNY6511DrS24LR5Dhb2OUceBmIQBeIOhsEDfkIFyCTLdy0TDDmo2csPERki
+gpTic++9t85Bmtmd3b3RP4RknVgFn6oAgV+h/u7EgAPg/V0cmI82V/viMaNwg5RoelE51xKsxmlb
+uHEYbAD+pdNRj2bBxuHnLQAwBlwKdM7fzVO9o65wN+7UMERePAwx2v3BWGAMitxqnwMATJs9Q3xW
+GMIpCLkyCjfIeeJE3R/v5dtRT/VOOmlqOsYZWu+Y995TicHlBYEcWGYf7r+dbHVWolIu3JqEylPI
+RUnJEXHal6PXDx/jNY+nSkl8/Tb7YV1JCjhaahZmWOPAGr3jjN9FRBYFcjUM5B0MgwfIGJx3/LHW
+uv2x3e50wo2iKP7jpC9njDHBOYiY343i4K51zlvjhm+HxffOOxMqfi9QckVdsJTl1IBDcIGZSa3f
+n2yt3gwf08GTlI1xxCLTe2Eiq15KLehMb3d7QSIC3opwI58UuwDsu5OCjRkE2J8dWKSSgzzXUGR6
+J5hjXfUZYci/Hf/YRcKQjMKQK0nH2bYK5U0hKNwgZ0t66t5omG0mK9c/Ka8jxjF23gOn06wr4ZJj
+jPhw+Ga81VuNW/kaOY0u7DCKqTyFXEzZfTms9PfzwgxVIFq5w27ZaD0tNbFG7zjrdzmgC6ToJgH/
+FANxFxHPDTNO8o836WbSjb4AAPDgL/QYHJHxAPtB8G53x2Ridt7qyatAihuhEncCefrujhMDDqON
+U8w8jfx4sjIIQ7DFE23ZL1CIW5wjnaCT0jgAunMF03Cj11etaN6bT4pd79k3USJ/LSQ/c9us8+69
+A51ScpCnGorCfBcE1e9iuUwY4rz3MP0fAJwXhniFwALk4BHxAbDZjqblCEPSvWxbJRRukIvrrIQb
+o2G22elHrbvhgoJ96p0/Ya4duagjY2Q3k274L0K2s6TpOFHANu9SeQq5nLL6ckSJGgz3sif/FHS+
+KHN9ZP60ts5YB86Yl8b4vzHv80gGvSjgH4tA3EVkUEZ/leHbyXaUqC8YY8xa6wIhw8s+xtHdHTFM
+d3cYbYejSf4tgIcw+HB3x3sBh9V6VzK7faPHPwbHOE86CZd8RSXyHniAPNP/ORkbUzi8JwWuMAo7
+yDUx5zveA7TrdPVy2hJuFJnZddbPgo3fnvf13np3UtmbiuQgS/XfrXFDLpozWQAZYye9kC8ahnjn
+h1b7n4wF8DYfewcW4IQwBI80TwVoXBgy2c+eRN1go43lBmS+Oivhxmh3/FV30Pmy6rWUCZGDNe6l
+EJy2el9Tt6s2RvvZdtRRIFt+V5nKU8h1lNWXo+D+tjHWC8HpdVhT1lpXaAfWmKG1/s/MHYQZEj/m
+YbjOOVufR7PYSZbvWo6J4tPXhnMAXEBw3cfliIwr7AdKbnjvvLUeJhOzs5tP/qGUWAuVuMO+/L+/
+sLYww0S6b7q94NdcsBWdFt9FcfCR0XYnTIKH+Th/FvXCx9PFee+tH04mxbdp6oRn/DdcisacXJN6
+KfJ8e6Ub3F3WyTxtCDdmwUYY81/LQFz457DaOm3dH+M4OLHJbDrKvg3C4OdNCjnm4awwxAGAt3bi
+HRiA88MQRF5p89TxMNtMesFSbSEn5fLWuzTVz5KDc5I2sNo6X9g/xjRysTTpOP9WhAFv8xjZbFzs
+ridxn3O6sCRXZ613o7306VX7cljrXZDaZ4OVpDXH5CY7aTyr4lIFAf5MCL6OyGAR52BaW7e7V3yd
+dNTns4+luXaRwL1Aybld80x3d5i/iASLZ8mN4BEX+FsAgCI3u1GibnrvezLgtzlHBGS3rHGeC2SI
+jAGyfncl3Ei63htt/jIZ/f/svdl2HEeWprtt2+RDTACoiQCZ1aeSILNSrFxHJESIuU69xLnr1+i7
+vqqXEwVQw1ktMdVCgrk6JVGQSiIBxOiDmW07FyAoEARJDBHhHgH7biRhCN9CeLib/7b3/5c/5IVf
+YpzfCGJH4CwwwBuXNSl21sUNU1gypX0Yp3JFafXWjo1X8W/syI4b0a1RN9+KGgqQX16R4zWdIR2p
+4Pl5c8Q89eBfXhFD7HMxxNm8zzzzgACeoMkAAAVoZHhj0mLIsJtvpG19D8NuY+ACMM5Qa1wb9vLN
+eRE5uOSYDcte1XXME5chRlaUsIVhPCVwQS7qy8E5wxG5qE3kQ2fmdDkaz0rGPiLrB5GUSij8II6i
+q/x5PGsVtT3bH200W+lL3ZZEfuLr+YPuDrXC/t//8dcXj5fG2D0p2G86UqvZoHgSJ2qZi4M/zKCb
+f5q29WsfYsiRt8bt9Hrm++DXETgtzlhKItYXc95KehyTFVuthXgmxQ1jLNncPoxSuSKVWD5vW6Mp
+LCFnvbd1fYx6+edRQ90Nu/7j47gY8sJIlegnZ2DvQAyxL4khnAMAA42IN4CdTQwJ4kZg3JjS7JLH
+Z/Py8DrsFV+0m9Gd8BkZL2Vpdp312/MWI+uMo4ZlXzUb8d23/3QgcDpGo2IXEZ6d1ZfDGEdNh39r
+hi60iXFSPCvjTCRKLgjJbyAyqIvAtLs/2pJarR5ftw+Go612I16dRtfZCw8O54iQwT90pA4ulkRP
+GLIX86BKiz+Z0nZfN9OIHJniuHwlksvOkjeFfTQYlMPg1xF4G9b4H4SCS3NRNFmx1VqM3+N8tsQN
+ZyyVuX0YJeJatBBf+GHVew8M367kJq1orbefbTTaUXhAHhMvrFNf+XPyFangeeLNyZ0hh2IIWdqx
+BnZP6gw5KoYMdrPNK8ut9TAnHhgnUsnFIjdQFGZb69kXOTj6picPEKYNxsq8xsia0nWTNKSnBMbL
+eX05pOQ4yPNhwys/CS+Hy8ZJ8aycIUVaXomkOHU8axWMRsUe4zw9aVOSHBbTKvl3gaN0m81O9AnA
+gdjB8Pk4ynNUJBYH3fxTqcRbW9G5QMaFuq0T78l5GA3LzSwzwjP+EQoExoLYETgAEcGDK6uuY1oU
+WbHVmTFxwxlLRWEf6UiwxhiEjUM8eTjtS7U68XrvWbbRXAyR1dPmtWLIgSHicxH8ZDHEFpZMYYrB
+s+yBUPyK0PyG1GGMMTAedHQgcpjCPJFanhhFPSswjjf8ZZ3XnDDzGCMbxlMCk0JKjojRWncv2zyL
+L4dT/OOidDuRxmCWfEYO41nJ2R1n6QkAo1jKC8ezThtjHA1y9yR9TSePd240VYGjGJYbzYVo/fCL
+ZAmk4q8sFnQkPilz85OK5KlOXsYY44LBoV+Hs9Qd9stv8zz4dQQOYBzR5CaP06ormTxFVmwtLMbv
+4YyIG84RFXn5SGvBmu3o9rgXhdb7bxTAKwkjr6O1FK8P9rLPGgtxiCOrKcfFEJ4o3rrSiDh4lFq8
+58n/PNrPvmeIS0LzG0JUa3oamH10JBdHw+JXxrErxOxGgyJysIYeC8FnvhuljsxTjKwxjlohPSUw
+Qc7jy6G1xGf7+ffL+nTPiJeVF/Gszu1YQ8fjWZcRJ5NoMg1+2x991m6lr22EYBzctK5bIhvmX7c6
+yUu7ota4nThRr5ygUgscdLMfhRJX8YR4xzeByBgq3uksxfd/9+soDvw6EK8GsePy4r3n3ns/zzfr
+WRI3DoUNJQVrtsYvbPx+oFM3cLwgbUX3hv1iM23qsHM1I6Bkq0oqbgvzi9Dq/UYk7zsi76z7KRuW
+PwF5zjX/SCgxU3G3gfqQpPrWcFhsRYkCwWfzwRUFgh2WuxDLqkuZa+YhRtYXbidphPGUwORpt5Kb
+o1Gxa53dPo0vh5P+VlHarp7Rz9a4ORrPSs7/6K0fJFo1Y4nXuBbLPJldMeM4z/YGXzcb8Wsj3J1z
+JLgQr/v+uBGNZnz9FbHimP/GUeJEfmxK+/gi0Vuv+HWU9tGgH/w6Li0eEu9PsAOYE2xZfrawGK/X
+PQrXOaKiMDsC8ZdmK7oz+TZeX571TWecYRTxtSByzA5Kq04xLD9vNPW9bFTskuXbOpI3uMIVpeQK
+EXlnqVsOy++IvBBB7AicgzTVN4f9/POkGc2kITHnDEsiW3Udl4FGU9/MhsV3RP7XWYyRFQ5+QAxj
+AIHpcBZfjjjVi91e/tm7qnHpOm2PJJp0nbEv4lkjhe+LKFrGChNNJs1oVOyhVNff9P9HBCAkS6ZV
+kxDy5R3lk/w3jsKlwLzIRkTCn7WL48TXO/TriF/263CefyRU8Ou4DHgGCwe5lvP3ubdl+VmrE6+P
+47MyKbwnyjKzwxk+aTT0Pc5xKrPs3vviPH4eXAqMANaKzGzrOUlQmGc4Z+gBIkfk40QvFrmBbFR+
+EyfqNgAAIjJU2JFKrB+KHSYrH2fWW5R4Uytshw6/wGlIm9HaoJtvpJ3xeQVNE8+wSUR+XhfBdWJW
+Y2SNcdSJ1ZV57ngN1I+z+HKU3K9Y67wQ8+uY7Jwna+1L8axScNRaXIuVuMojNbdixnGKt/huHEJE
+IBAXp1UX++//8z9ecrUyhSVk8PObfDacIzKF+Zt+vkAdN0QHfh350GwNM+oEv475xhSGmilnXM7X
+xdCU5Ua7E9+rs7gxGhVPOOBPcUN+zKfcYTLoZp+2FpK3mha/jqIwu8zDMzWDO3CXDVNY4s7/LOOD
++4ozlvLcfZ42o9d24ZD3nhxBWZgvbRA7AmdgsJdtNJfS9bf/ZL3Ih8WPSaRXRM27/eaJWYuRLQfl
+kw8ayfI0YhYDgZN4my+Hc55U5j5fbKcz8Zl6G0cTTWxpToxnrWuiyTTY+a3/6Zt8Nw7JMkNJxJmU
+YjoeHMe/8Dr/jaNwjliQ7zhHfhIPRYd+HVLxe2nrwK9jOCj/mRv6A6IIfh1zBiIDS7TDgc9Ny2Xd
+xY1iVO55z75tNPX9aXVsHMU5T1zw6CKvobVcLDIDZW62g8hRb6QWONwdfX8ocHApMEG+1t8bPUjb
+0Scn7XQgYwwFByH4Xe+9d8/FjmxoCxT+D0rLqyLcCwIn0FiI14fdbDNtxzO1wGbIlg+iYquu5PIw
+azGyYTwlUDVv8+XgnOGIXNQm8nwGuxhK4+h4PKuS4iDRRMvaxrNWwW9v8d04iiPbZSim5kPIb/8/
+f/jPo1+wuflWRXLlbW+ekNjMB+XnUouJPhwxZIwL3ooTeT1JRFMJ/7jM7HZpfYoMNKvpA2Tg9HgA
+z73/QSj+XtW1jIM6ixtlbvdM4b6KU/lunMrVqmr0jhaEo9kAACAASURBVDwB7Ep5sfdcSB6bwo4Y
+IiCyCwkmgcniPKXIWHQoZjBkTMfyWr+Xb3LJm296/xhjDBGZVOKq0uKa4KJF1j/O+sWWtZYBsAYX
+s7eQCkwOFPxqNiwfqgmvUcaMp9L9TSoxF/fCWQE5Msnxaq+XPVSRWK7rw4sxjtpC5kqKK1XXErjc
+SCli79nCcFA8VPrVz4xH9i6W9Ddd82uZMY7K0vmyKH/KRubvZW7+KQG7seTvxUoupbFaSWJ9XSnx
+HufIkDFW1+vDtOkN8ieMi3eE4PFpfr4o3HYcyfemNT76UgfH2/w3jsIYIkN21RrqColTccvlHBmP
+1aqKDvw6isx82R8aoODXMdMgApBzI4DZd48vs3Kjs1Q/caPM7R45/22U8D9LJc49FjIuyHsY1+No
+lOpr2SD/TkUKuJjOtShwdpRWnXxYPmw0+Uu76q12vJ4Niy2vFchTvH+MMcY5A85xVUdy1Tnyzrrt
+wW72lGtcEoLfkDp0dlx2OGeoNa5lw/KbOJ3MOO244YhQku1XXcdlZBZiZH3hdqLG25MsAoFp8CZf
+Dik5DvJ82PDK1yUl5LXxrBKvCRXNdDzrtCmMo9LCKI5Pv4FA3pXT/Ou+JHCQJZCKn7rYpBFdG3Tz
+T0VbT/WBiTHGuGCQNPXdKD3q12GCX8cMwhiitTDz7vFlVm4sXInv1UndNYWlsrQbaUP9Wx2EjRd4
+ACH4h+N6ubgR3RoN8i0dK+A8iBx1hHOG4D0/yUQxTvXN0aj4kSw/c6oB58g4x1WlD8QOa9zOaD/7
+niEuCc1vCMGBhUSWSwmXAq03y0VhtrWu/xgb4wydB5j32PQ6U+cY2TCeEqgbnDNsLyTrJ/lyOMU/
+Lkq3E+npn7PH41mBfF9LqWPJ/zhv8axV8Gwv22y3kzMl5TCAYpp/85dGVMrc/KS0XD7j7nODiErO
+sZL28IPdPIx0LFaShC9pCT/bwnxTlgbBQ6Pu0ZyBA5w1v2otPpjVRV2RlZuLNRI3TGGpyMpNHXGW
+NPS/8VO2kE0La6znAtk4XaalElfyQfENl3i1Lu9D4BgM3gdLP3PBW8e/JaVoO+uYLd1jcc7RJUTG
+hOAtFclrXOKSJ79TjOzfytLtMYB3kDEfxhovF4Lz2BrHHPknQvClqut5G7Z0e1LyqbXxBl5FaXGl
+GBX/9MD26nLOhPGUQJ2JtLySF2bknHsipVgCABCCs0GveNRK9LVJHts5R8Y4X5RuPx8V20VWPkbL
+fpMcIVXqnTRS7zWS6LpW4qoQPELEMGZyAX57Nvgibbw5Lvg4znki536KIzXRc+EoL5uMEj1hyM6k
+tKlILPa7owdC8k+qPmGQI1Mcl1Ukl50jb0u73e+VuyXhTS6wzXkYYakrDJjy3gObwajYIis3l96p
+hwO7MZZsbh9GibgWp/URXI7jPXQZY2M3G0pa0VpvP9totKOZjImcd6QWONwb/VO+JqVLR3LRGtsZ
+9vPNNyWsnAaOyLjCFaXkiiPyZKmbDcstIM+55h8JJQ66SgJzj47kYjYshoZjV4r6jR4chXG/4skD
+hDOzUuoWIxvGUwJ1J0n0ojGu0+tmm83WwQOwk/5WUdquHlM31PF4VnDQ5xx5pMRirMSNyxTPWgXd
+QfZEaPXHs/6NiQik4s1J1XUSLwSOs/hvHCeK1Lop7M6bomWnzSt+Hbn5cjS01hB+HPw66gcBrnj/
+9p+rGyYrHiy9k57KQXiSOGOpyN1XccI/iBbi2j/cO+9/ZAwm4qbc6sTrvf1so9mOaivwXGa4wutv
+SuASUiA/TFjpxJ+M41x+LnZ0pBL3iMg7S91yWH5H5IXQ+JFQMogdc06c6mujYfEdixWIGoscnMsO
+OdoBMT+pYrNKFKnFsjQw7JrNqmNkhYMfOD/9CHkgUAXHfTniVC92e/ln76rGmcYZAF6OZ3XWbHsD
+TxlnIlZyIVbiBkYqJJpMkaIwZCw7k+/GIUQEgqGeRF2vg/33//kfHuCgpR0Z/HxekWLQzTbipq6d
+ueJRiH7368hzFxOKD4NfRz0whaVmiozL2cl2985uNtsX22W+KM5YKgr7SEeCKS0+nBXletgrvk5b
+6vYk6x3sjT5tLCT18R0JAMDBOWsL91WS6rtv+9leN9tIm9G9SUXNkfeensfPWustSrypFbbDfWF+
+GfaKrbilV+saX+iMI1/S35JUz4Qx6mXAGUd56T6vKkbWGEcdzx+nsV6d9rEDgfNy6MtBxvXeT5IV
+Id68vn8pntX5PQ4H8axa8Q+RIwQxozqc8/Tb7mij2TpdJOxxssxQEnEmpZja+/eig8MatxMn6tw7
+BnEiPzaFeaTj+rqVIzKGinek4vdSR95a99NoUP6QlXQdUVwNi9rqQARw1j3mkte+BdN7IiD6vEpx
+wzmiIi8fKSlYsx1NVCiYDDSY9H0qbcWfDPvFZtrUtRgfChzApcBiaOEks9HjtNrxetYrtkSi3j9N
+wspZQcYYCg5C8LtHxY5saC1KvKkUtkW4L8wVaUvfHHTzjbT9sut/XeCSYzYsewBT3ewKvAEuOSaI
+a93d4WZrIZn6eRPGUwKzSLuV3ByNil1PNOoN84eL7fTFWuxFoom1O9b6F4kmqeYfohKriAyCCWh9
+eLY//KrRjM7chXMIEQFD8fYfHCO/H+0c/htH4VJgXhgiR34WjD2f+3WsKC1Xms/9OgbD8rfCwL9x
+IYJfx7RBBCLKqy7jbVQtbjhHZAqzLQQvm61ZFDYO8B4mnhLAOMMoUWtB5KgfMhYfudLtYPR2d/W4
+pW/muf2OrDtzwspZOCp2eO89kQdr3Pagnz1FBdeVlleD2DEfNNrR+qCbbzQ69fQp8gCcvPd1HzW8
+TFQZIxvGUwKziHOepBSdsrCtH37tPhCIP3rn/+uleNY4xLPWnW632FKR+uNF3iMi/4gxNtUGCAFw
+Mf+No0Sxvm0K80gn9e3iOIkjfh03gl9HNSACWOv6ALLqUl5LleKGc0RFYXY4wydJQ997nX/BLOCd
+J5yS3QHnDKOIr41G5TfJjF2X5hmpBWZ72Q+vMxs9ThSJW0VudvPMTMXw7yCdi8FB/Ky48ZLYIeG6
+VPKq1EHsmGUa7Wh9sDd80FxsVO6hdBzGMfHkAWZnYvPSMO0YWWMcdWIVklMCtcE5T0QERAAABOQA
+wLod7mGXPIH2vA8AkEiuEZnmXOrOQuvDhlQdnfKVWd2Yu4zkudkz3rNYyAt55hHB1CMkBAAAWQKp
+Lq4Oc45YkO+8yUCuzjDGGBcMkoa+GyW/+3VkeRn74NcxURhDdA5qazPqHRHA9MUN74myzOxwwJ8a
+Df0x5zjzuzgEAKjwlZjQScGlQE5muczNtppgB0DgbDDJVs5yrxhnwspZOCp26EiuOkfeWbc92s+e
+MsQlofmNIHbMJmkzXh/28s20Va2X0nFQsA/9LLpuXxIaTX0zGxbfEfmJdpUBALjM7UStMJ4SmDzO
++QPJggheCBiOutz5Hz0QcOJ9Bp4JxiBSookAIKX6EDkD0LDMGFs+uJu/6pXhbPa1UnwhiBuzg3Oe
+9vvl35ut+ML3R8Zcf9oNiQLg4v4bR4lTtTzqFw+Tmi0YzspLfh3kvTU2+HVMGCLf9OQ9q5lRrXdE
+jNHDRitan+ZxR6PiyTwJGy8gN/UERK3lYpEZCCJHfZBaLJeFfRSfobNGSIEM+Vpvb/ig0UnGkrBy
+VjhHdtDZcSB2WON2RvvZ94dihxAcWEhkmQkYZ6g1rtVN5EDk4Bw9FqL+nlSXlWnFyCofxlMCF+do
+1wURHczBObftiQoEHAliDgEgkaKFCMCFXOCCLTPFOoyxDgMAdgGTTyI2qNnSPvAWnu4PHjaaFxc3
+Dpn2OOiBB8cF/TeOwhgiF+KqNdQVcvymcFWAyJjS8iW/jn6/eGocu45CXA1+HeOBIYD3HtjUG5le
+j3NEfMriRjEq97xn36ap+rOQvDaL7nFBHoAhm7qDno4PRA5rXHea89OBk+FSYD7Kh/qMXgOcM2wt
+JPcnnbByulqQcY7LOpLLjsg7637KBuUP4L3imn8klAjxszWHS4HSmxvTGn86DSgQXG57wWe03kw6
+RjaMpwTexpnHRRjTUqgbB2IFrD7/58QNPZH5ifuuBcZHd3+0pSN9axznhXOOIi2n1rV9iBiX/8ZR
+okReG3TzT0Vbz11E46Ffh47VqrPkD/06So83Jcc2C2LHufGAH9apK9c5IsH9Zto4v3PwWShzu2eN
+/d9pU/+bkHzuPjuHePIgVDU7kzqWi9kg/44xBnwCqRyBsyEU/9hZ6uE5BKfDhBWZqPdFDd5Ljsi4
+whWl5AoReWepWwzLLSDPg9hRb6SSi0VuoCjMttbVixycM8yMzUOSSv1RSi465tb6+6PNccfIHoyn
+RJWfj4Hpc5pxEQ4AggGLlGgiQy+FuH2acZFpY4yjSE3/ATdwPkZ5seeYYFqIC/luHEIEUMUZKMbl
+v3EcpcWfTGm70zBhqgoukL3k15GZh1lmhGf8ozDCcg4YQl3mjn8XN/TExY0yt3vk/LdRwv+cNpPa
+Gd6Nm6rf47gR3RoN8i0dK+C8+gfjy4xSAvJe/q3sxOf6nMWtw1l4/l9KydVx13deEJGhwo5U4t6h
+2FEOy+8ceUCJN7XCdrhH1AsdHYgcpjBPpJaVjwQQoj5NlHKgeiYVI3swnjJH46kBAHh1XMQTgfLw
+jXOOMcKRhJfHRYSQ11Cw9rjGRaYNkQchcLHqOgJvxzlH/aHbajTG17VuiSAW/Nq4Xu+0iHH6bxxF
+RWKx3x09EJJ/MisfwvNyxK9jPW3+7teRG7/EGL8RFrKnAxHAlvRISF5p2oU1dk8p/EeSTlbcMIUl
+U9qHcSpXlFZz27FxHHK0zRir9GE0aUQ3h/3if8Wp/PfwAFEdjDMEyRYvYkx9MAs/vYSVs3JE7Fgn
+7z05grIwX2ZDa4PYUS90JBdHw+JXxrErRLVjbBzhvZro/YFTMO4Y2TCeMnu8aVzEe18qjwXAa8dF
+/n1a4yLTxjqCWMurVdcReDtP90YP08Z4x+2IPGAFm4linP4bx4kitW4Ku6NOGQU4Dxz163DBr+NM
+ICIcZGxUhzV2L475bzqSdyd1DGMsmfxA2IjT+N68C4DHIcaKOvwfp039l95+ttFoR/eqMKsMHKC0
+uGFK95jHeG5xIorkoikMTDth5awgYwwFByH43VfEDuFXlJZXRRA7KiVJ9a3hsNiKEgWCVydyMM6W
+q+52C5ydccXIhvGU+nAoXAA8HxlxAECvjotIZEJLnhwdF2EaluH5uMi8CRenhQi+QQb/XnUdgTfT
+3R9txUk09mcST3absel32Ipx+28cRWqBw272s1Di6qSOUWde69dBeFOK4NdxHMYRy9z0olRWcvwj
+4sZEPojGWLK5fRgl4lq0EF/ah2rvoJqBvBNodeL13n620WyP/6IeOB3PzUaf6Uj88SLvgdRyEYVf
+G3RHD9JWXPvOwaNih/feE3mwxm0P+tlTlHBdRUHsqIo01TeH/fzzpBndrarDiwsOZWEfCVFtR2Pg
+7IwjRjaMp0yH046LNI6Oi0jWZjib4yJV4J0zoVG23ozyYs9xTDXnY3+jyGFRxcdDTMJ/4yhRIj8y
+hXmk49NHAc4jR/06vPPd0agMfh0nQADM++m7LU9S3HDGUlHYR3Eko8ssbByCAP06/QFanXi9vz96
+0OzMv/9JXRGKr1pLPXnBtm7OGTbacS0SVs4CY4xxzoBzXNXRi/jZF2KHVPKq1OE+MU3SZrQ26OYb
+aaeaazZHBOPMaNrHDYyHi8TImiKMp1yUk8ZFuHPbQFAcHxcRyDQ7HBdBBgzmd1ykCrynMvwd64tz
+jgZD+kfa0BPpXPfgB5UIHFzwic5FcSkwLwyRI4/nnLGeJxAZA2SdZjt62a+j8EuMB78ORr7h/XQ3
++CclbjhHVGTlIx0J1mxHt4PXwwHkqXa7HY1mvD7sF5tpU9d2vGGeUUp08mH5uRxTLHKrHa8P+8X/
+0rH6lzokrJyV5/GzR8WOndF+9j1DXBKa3xCCH/iXBCZKox2tD3ZHG82ldGox4YcwztCRt1UI/oHx
+cN4YWVeE8ZTX8aZxkaOxqCeOizBYBcbgMo+LTBvniCIlQxxUjfltd7TRaCYT8xxkQJXcw8Q0PuNR
+rG+XeflVlOo7Ez/YDHHUr4OeL2J7veL7y+zXQZxp8B4ApvNZMMbuJWMWN5wjKvLykZJB2DiOd55Y
+DcfVGGcYJWotiBzVwDhD8L7jiPy4ui7Spv5LNiy+847365CKcV6eix3LOpLLjsg7637K+vkPQeyY
+Do2FeH3YzTbTdjz164Jn2PTeQ9A3ZpfzxMhe1vGU04yLvIhFhTAuMgtYSyAkNquuI3Ayu/ujrbQx
+uZFe5xwpIaNJvPbbENPwxuAc0Xt49yJO+fMOcmSK4/KVSC47S94U9tFgUA4vm18HA7wxLV+1cYsb
+zhEVhdlRgu81W0HYOAkiAi55LW92nDOMIr6WDYsv4nQyrXqB1yMiccOW7jGPzm82epzDhBXKzfZ5
+Z+HrBEdkXOGKUnLFEXmy1M2G5RaQ51zzj4QSwIPYMXZ0otaGvXwzbU3XwBalXyEPEN7Q2eYsMbKm
+cLQY67kaTzkuXIA/GBfxRAV49sq4CEe+yIW4+vK4SBAuZhEiD1LN/r13HhmNij3GeTrJZxUiAC5A
+Ter134SY1oHiVC2P+sXDZMoLhFmEC2RcqNs68Z6ch9Gw3Dz060CBwNj8ih2IDDxRD2CybeWmsHtJ
+Oh5xw3uiLDM7nOGTRkPfu4w7L6fH13qxzqVAJP9/FZnZ1jWMHJ1npBY43B/9pvTFzEaPE0VysZiB
+hJWz8lzs6Egl7hGRd5a65bD8jsgLEcSOscI5Q61xLRuW38Tp9PzEOJcdIupBBRF7gfFy2hhZV7gd
+NSPjKeceF2FhXOSyQNbuMKYuTZLmrGCMo0E2Od+NQywRRAIXJnmM1zE1gYMxRCHFDWuoK2S4WZ8G
+xhjjgsGhX4ez1B32y2/zfL79OqzxPwgFE1tEjkvceCFsAP7UaOiPg7Dxdg7UXLxWdR1vQmu5WGQG
+ytxsqznY9Z8lUPFbzhEIwcf6ulrLRYF2ZhJWzgoiMjwQO9YPxQ6TlY8z6y1KvKkVtuf1fjEtuBRo
+vVkuCrOt9XSuC4gAtnQ/KCkutUn7PPG2GNk6jKc45w+sOYngsPPi6LjIYSzq8XERrrANDDqMsc6B
+ZBG6Li47DmAXkQWBo2b8tj/6rN1K/zrp4xB5QOSVvP9TEzgAAHQsF3vd0YNmOw5pBWcEkTFUvNNZ
+iu+/4teBeHVeFq+ICB5cOanXN4XdSxviN6XFhcSNYlTueQ//u9HUn1S9GJklvPfAsP4Cp44PRA5T
+mCez7N8wayitOvmwfNhojsds9ChcCmy0xf1eN9toNKM3tonPMkfEjrvkvSdHUBbmy2xoLUq8qRS2
+Q/zs+dBKLha5gWmJHIgIpbWDSR8nMF1eFyM7jfGU04yLIAAkz2NROcpFLlgYFwmcC+ahP6/32lnl
+2d7g62ZjOs/hZNwOS+T8CxwAAJFWt0xpuycp14HT8YpfR2kfDfrz4dfBOKLJTR6n439tk5uttCnZ
+RcSNA2GDfRun8s9C8iDUnRFPs2OYp2O5mA3yX5HzLp/BJI5ZhHOG5CEap9nocVrteH3Qyz+PEr06
+iwkrZwEZYyg4CMHveu89kYeycI/yYd5D4f+gtLwaxI6zoSO5mA2LoeHYleJiscZvg3GGzlMl0emB
+yXJSjOxFxlNOGhdh3u+gpd2j4yJKIleIKT+MRQ3jIoEJ4ZwnDOdTrRiNij2U6vrURCfGdhmrpoNn
+6gKHisTiYD/bEJLfCzfsi/PCryN+2a/Def6RULPp1+G95+Ne0JncbLU6+j0usHOe3y9zu0fOHwob
+E2/rmles998ogH+vuo7TEjeiW6NBvqVjBTzMwU8FFfHbVLgdHuPEboqNVrSWDYst7yXI18zCzxuM
+McY5gzjB25EXnsiDNW570M+eooTrUsmrUgex4zTEqb42GhbfsViBmLjIgQl5Dzwsl+aO4zGyJ42n
+vG5cRFj/yAMBJ95n4JlgDE4YF1lmjC2HcZFAFTgiUKqepvKXEWMcDXL3JE2jqY08knejqiSuqQsc
+AAA6lR+bwu6oqJq2lXnkJL+OfGi2hpnpzJxfh4fEe4Bx3YovIm6YwpKz/rMo4X+WSgRh46K4mWng
+eEHSiG6OuvlW1FSt0Go5eaQWONwdfS/jyd4f4lTfzHOzS47mImHlLByKHZzjqo7kqnPknXXbg93s
+Kde4JAS/EcSON5Ok+tawV2zFLd2aVLcRAAAK9qEPUSpzi1Jy0Xpz59cfdx9+0GxcKfv51inHRW6H
+cZFAnXFEEAtRa8+1y8Sv+4ONTqs51c5zBuCq6gqrROCQUuBwlP0slLg6jZjay8ahX4dU/F7aOvDr
+GA7Kf+aG/oAoau/X4RksgPcAcPFT47zihiksmdI+jFO5kjRUEDbGhi/HplxNkaQd3Rz0ss+Shl4P
+IsfkwYjfmkas+GHCymhYfpGk6tJGA3OOjHNcVfpA7LDG7Yz2s+8Z4pLQ/IYQHFhIZHmFtKVvDrr5
+RtqenKcLIgdnaUeIaozaApPBOU+2tMANfSUdKz+QeqljRP/dTvLR87GRMC4SmGmcsV2u1bm6pgPj
+5be9wdetRvrJNI/pnKdJiv9vg//lP/7lPys5MGfvG2P/JiR/r4rjXxYYMsYFb8WJvJ4koqmEf1xm
+dru0PkUGmtVQYCLyTSUZwws+3JxH3DDGUjkqN1XEWdLQf5p0+/Flo8zN/4lidb3qOs6D0vJav5tv
+Ki2Ww47ZZEHk2mTm/5NKXJ30sYTgMTL/fjYyD6Xil/69RWRMCN5SkbzGJS558jvFyP6tLN0eA3gH
+GfN1vG9UhYrEyrCbb6poQtcF7z1Z94NUIqyVZhxjHNnc/ORH9tvUsf9qCZk2IvXf0lhdZ8bvvNNK
+/n00Kj+PE71y2a9DgdmnKOx2HKv3MJzLlTIYFXuAoiMEj6d5XOfII4euktXcuyrp4AA4cLTPC0Pk
+yF/0QTZwOjhHxmO1qqIDv44iM1/2hwaoZn4diAws0Q6H8+9YmazYai3EpxY3nLFU5O6rOOEfRAvx
+vXBBDpxEqxOv9/dHD5qdJBjMThDOGZbkPRH5aXTMcCkwQb7W72Wb85ywclY4IuMKV5SSK4fxs9mw
+3ALynGv+kVACeOjsgEY7Wh/sDR80Fxtjvy5wyTEblr1xv25g8jjnyVkCKuy2tvC0Hcl3lI5u8Bhf
+EcO4ZwMhEBNUa/u94WanlY49SSoQmCaeYBS08GopjKMsd0+SKfpuHEJEIBjqaR/3kMoEDgCAKNa3
+y7z8Kkr1nSrruGwc+nUkTX03Smvo14EI3tIuaDiXwGGyYqu1GL/H+dvFDWcsFYV9pCPBmgvRnSBs
+TA7nPHHBo6rruCjNTnJ/2Ms301YUFqATRETiI1e6HYwmZzZ6FMYZvkhYSfWqCKayL3EkfvbeodhR
+DsvviLxgEv9VK2xXfu+okLQZr0/qukCImrz34f5Uf4xxRKXpMsv+ETPmUq1u8lSucsSbr/sdcp5i
+IfiBNw6wSIi1QX+00Wgm69OsPRAYJ4yBC51I1fJsL9tst5OpjqYcQgQgIqzM36xSgYNzRO/hXWfJ
+cxF2zKqgjn4diADk3AhAnvl3i6zY6pxC3HCOqMjLR1oL1mxHt8OO7RQgAsaZqrqMcRClem3YLzbT
+pg4ix4Q4MBsdfi+nbEb9ImFFK5BzHiN7Xo6IHevkvSdHUBbmy2xoLUq8eRnFDsYZao1rkxA5OPqm
+Jw/Aw22qbnjnyVoCb+w2GnrWVKqpVfyhiPHOaR/uHBEowZPD/5aSo/d+dZiV22msLpUBcmA+MMZR
+pGSr6jouM789G3zRbEaViaSObJehqMyDpVKBAwAgTtVy1i8+i1tRaPmuGOTIFMdlFcll58jb0m73
+e+VuSXiTC2xzPp0RFsYQrQV71t87jbhxKGwoKVizFYSNaULew7z8tTlnGEV8LR8UG1FDh122CcE1
+vzYNs9HjxKm+mY2KXbL80iWsnBVkjKHgIAS/e5LYoRS2xSURO7gUKL25kWdmO4rHd94wjje89+N6
+ucAFccaRtXRgEEqsXIjkH0QUr4r0fNcpZwl0HH149GtKicW8sDDKyu0kiByBGYPIgxC4WHUdl5Xe
+IH8itPpjlc84ntiPjLHLK3AwhsiluGUNdYUMu2V14RW/jtx8ORpaawg/noZfBwFpT/7UZnZFVmwt
+LMbv4WvEDeeIisLscIZPmq0wY18JHkAI/uHbf3A24FIgkV8tMrOtx/gwE/gdqcRykZsvk1RPPeEk
+TvRikRvIRuU3caKmPr86ixwVO7z3nsiDNW570M+eooLrSsur8y52SCUXi9xAUZhtrcdzXUDkYA09
+FoKH60xFmMIRWbuDxj9pcCmiSN1Bxe6MIyXAW7+DjL3SqRZpsZjnBYxytp0EoTUwQ1hHEGs5cZPw
+wKsUhaHSwiiOxUqVdRBBpZualQscAAA6louDbv6paOsQx1kzXvh1NPTdKPndryPPy5hQfDipNmQG
+THnvgZ0iKtaW5WcLi/GfThI3vCfKsgNho9HQ9zjHSj/wlxkignnzI5RaLhaZgTI32yosQMcOlwLz
+kbVV+Q/oSC46YzvDfr6ZNoPnylk48BNgcBA/K268JHZIuC6VvCr1fIodOjoQOUxhnkgtL3zPQYFg
+h+UuxGcf2wycj8MYV29oO3bsWScSV+RrDEIvCvf+F8ZO9hyLIr04ygrIAf4eRXJ1nMcNBCaFd7SN
+DML5OmWc87TXKzearbjyqQjGXL/KqOtaCBwAAEqLP5W5+UlNed46cHpe8utw5K11P40G5Q9ZSdfH
+7ddBgCun6ci1ZflZqxOv4wmdHqNR8YQD/tRo6I+DsFE93kO3yna1SaHj5yJHaf+ulAg39DGjIvGx
+s9RDWU1k84uElb3Rg7QdfRK6v87OUbFDR3LVcIMIWgAAIABJREFUOfLOuu3RfvaUIS4JzW/Mm9ih
+I7k4Gha/Mo7di8aNH6QK0ZnHNgNnwxhHrjRdYdhWxBksKHWLp7g6ji6NNyEZK950XUlivTgclUNE
+1lVKhE7nQO0h8v1wq5w+z/aHXzWaUSWmokdxztNpNqgnSX0EjkgsDvazDanF1eC6W3+e+3WsKC1X
+ms/9OgbD8rfCwL9xIS7s18EYduAtCocpy432CeJGMSr3vGffNpr6fhA26oPz/kfGYO4EDoADkSPP
+zK/OUpcHY8qxIrXAbC/7Vnbiym7ajDNsLsT3e91sI2lEfwoJKxeDc2QHnR1y1RF5W7qd0X72/aHY
+IQQHNgftXkmqbw2HxVaUKBD8YiKHZ9icVmzyZcE7T8YSwHOD0LbWV6SKb4gY701rHeqcp1jJt6aL
+pYm6NhwW3zEGIGUQOQL1hjEoqty9v4x0B9kTFak/1uHvTkSgtajUZLY2AgcAgE7lx6awO6GLY7Y4
+4tdxY1x+HYgAzrrHXJ48c/xc3Lh3VNwoc7tHzn8bp/LPQvIw7lQ3XNUFTJYolrdGg3xLRwqCyDFe
+mGQrVZiNHqfVjtdDwsp44YiMR7isI7nsiLyz7qdsWP4E5DnX/COhBPAZFjvSVN8c9vPPk2Z09yLi
+BApYIA8ws3+ImnDUIFQDc02tlkUkz20QeuF6LIFG1TzNz6apvtUbFluNlIGsqKMtEHgbzhEpwd8q
+2gXGR56bPWNZ5b4bhxBR5aECtRI4pBQ4LLKngsTVk0YOAvXmdX4dWV7G/qx+HYhARPlJ3zoubhwK
+G1HC/yyVCMJGbaHBvDdnJY3o5qibb0UNBRh2+ceG1GLZFPYRr4HZZ5zqm6NR8SNZ/mtIWBkvHJFx
+hStKyRUi8s5StxiWW7MudqTNaG3QzTfSTnzvvF4yDNnyQVTsuKubf0zhyBq7oxx9n6DS4zQIvSiO
+CJTGU19HWqm+2esNt5rtFC46+hQITAJHHpCjqrqOy4Jznvb75d+brbg2PmEEAFqKSkMFardQiLS8
+bXLzqOo6AhcDkTGpeKe5EN278l5ye6GDO8KXD0yRP3HG0tt/H8A61z/+9TL7XdwwhaVRP99QGlmz
+o/8qVXV5y4G34z34yzB+lrSjm6Nh8S0RhVzHMcGlwNLSkGqSlZkk+hqAX8pH5TdV1zKvICKTSnQa
+zehe0tR3BGKvHJYPB/v5xmhY7p3mPlInGu1ofbg72jzv73PBwZQ2rI1OgXOeisxQ3s2/Znvlgw6x
+xx9E0fK7zcb9ZkPflYKzOogbAACcaPust8VWK7nZ743+Hu4xgTriLIFW1T7cXiae7g8eNpr646rr
+OAqRh6r7FGrVwQHw3DW/MESOPFbcjhwYD4iMKS1f8uvo94unxrHrKMTVk/w6GEN0Dl66eZdZubFw
+Jb5nrfP50G7GqVyJ03hqs7KB8+OdJ5y9jddz02jFn/T2s41GOzr3jm3gZYTilZqNHkdHctGGhJWp
+gIgMFXakEuvkvSdHUBbmy2xoLUq8qRW2J5XoNU4aC/H6sJttpu2z77RxRCjJviL6Bw44ahCaci60
+kn/kDX27LkLG60Bie+cpsdWM1/b2BxuLC417dZi5DwQOIWt3GFPBamAKdLvFlo70rdpdA4i+YQz+
+vcoSarkgiGJ9uxiWD6uuIzB+OEemY7V65d3k/rvv6OVmTF+BKTfK0u55Ry/tyBH5pqeDHdsiKzcb
+bbWWD4pNgfBzayG+p7RcCeLGbEAAgAorNRyaNq1OvD7Yzc+9Yxt4GaUEFLn9ruo6jiKkwCRRa/29
+0YO6dJfMO8gYE4KzJI3uNlvRvUiJjincV4P9/NPRIHtia97ZoRO1Nuyd/brAOEPnAXw4zwDgQDQv
+C0d5r9jyu8WnbcMev6/jznut5F6zEd1VSnTqLm4AAHAAd951TKeZrO8+HWx6Hzo5AvXBAezOwEdv
+5hnlxZ7xnklRv+5156Dyx7PadXAAAHCOCMiuOkuei/ApmVe4QPaSX0dmHmaZEZ7xj7gUyBDAew/D
+Xr7ZbopIcvglXjj/DHOgQsjVU02dMK2leH3YyzfTVtjhvyiMMwTvO3UwGz3K0YSVtBndm4WHqnmB
+HYgdIAS/6733RB6scduDfvYUJVyXSl6tW/ws5wy1xrVsWH4Tp2fzlGEMGuQ98Et6C3TGkS1Nl1n2
+j5gdGITKVK5yxJtV13YerHHUUupCwn+nk6w/ezrYWLrSDN2sgVrAPPTDqThZnHPUH7qtRiNar7qW
+k/DgK/fcq6XAAQAQp2p52Cs20nb1eb6ByYLIGCrekYqvp03vrbE/jQblD1npl4a7g4fvXmslSosP
+Qzze7EIegCHTVddRBUmq14b9YjNt6iByXBCViBumdI95fHpTvmnRasfrWa/YEol6PySsTB/GGOOc
+Aee4qiO56hx5a9z2YDd7yjUuCcFv1EXs4FKg9Wa5KMy21qc3qmXcr/hLFKXinSdrCayxO9LQD6lQ
+KoriOyLGO/PwMO/Ig5Bi4aKvs9BJ1p/t9R5cWWzfH0ddgcB5cQfjyGwePp915une6GHaSGq7pmRA
+lXvu8b/8x7/8Z5UFvA7GGPMeUg9QImchbuiScJDEwltRIq9J4TIdq37aiv7vIG7MNs44LyRfuozv
+I0PGOMLVMjObQtUjwmtWQY4sH5ltpfhy1TfPk5BaXDGl+6eztCcEX6q6nssMImNC8CUdy2sccYmc
+/7kYFo9sSSMAWETGPKvQBU1wHlvjmCP/5LTniiem0fufueBzO+7nnCdTWA+Z/VLk9H1LCN5WarkZ
+62tai2WO8/PwZIzzC0q1xnFfVEIu9/r5wzhW4R4TqAzryAvGukqJ96quZV7p7o+2uNb/wjnGVddy
+Es45Yp491VpcrbKOWu8D6FguFqOQqHJZQeQ/LlxJPh72i83gFj7bXPaxcS4FSs0/LjKzXXUtsw5K
+tmqd71Vdx+uIInELwC/l4b2uDZwj05FcbrST+1GqVhnATtbPN7JesWUKS975Snw7dCQXXWkjY133
+ND+PCGAt7U66rmljjKNiWDwx+/lGMnJfvYOy904a31nqJPcjLZcFnx9R4yjo4NG4NH/OGaaxWtvf
+Gwbfp0BlOCKQkl+ruo55ZZQXe45jKgWvne/GIUQAXEDlMcG1FjgAAJQWfypz81PVdQSmi3NESnHN
+GGOtdrSejcoNcnSqRWCgfpA7exTevMGlQEBYKvPw4HsRIq06RWZqZTZ6HB3JRSHgX4f9YDJbNzgi
+U0quHIodCKyXDcvPR/v5F0VmyE1Z7IhTfa3Myp/tKUQOLjkaY2sr7p0Wd4JB6Hs6Wn6/lc6UQehF
+4X68c+qcM0xitbbfCyJHoBqcsV3Ow4jmJHDO0WBI/9Cq3l1alggkr17kqr/AEYlFk7sfiS75FvAl
+gyyB0vxfD/+70Yw+KUflL84GkWMWIcaKS65vAACA1nLRe1gqS/v3qmuZVV6Yjda8q0tIgVGi1np7
+w5CwUlM4IpNKdBrN6F7S1HcEYq8clg+H+/kXRVZOTexIUn0rH5S/nOac9gB8Fs+ngy6NfK/sFl+o
+ofn8CvDeB2m8+s5C+tckVquC87ns0ngd5DxJxsceNcA5w0iItf4o/2acrxsInAbv4ce6JZbOC093
+s40kVXeqruNtEHnAGohctRc4AAB0Kj+2pd2puo7A9HDWPeLHjPriVnTTluXPQeSYPbwDgMuzdn0j
+OpaLZFwczuPzIyJxgwpX+3sC5wxbC8n9QS/brLsgc9nB52JH2ozW01Z0RwrBTFZ+NdjPN0bDcs9N
+OH42bembo27+1nFMxjGZhVRQ7zyZwlE5KLbsXvagWcLf3lVx54Nmcmehmdy7LF0ar8MRQSx5cxKv
+LSVH4WF5mJWhWzAwVTzBqEJro7lld3+0Faf6k1kQgcm4nTpUORMCh5QCrXVPQxfH5QE59k8y3orS
+6JZz9mcTdsBnCgTo1+B6VxuiVF8r8yDWnRepBWa5+d7PyE52qx2vl4Py7za83zMBHsTPsiSN7jZa
+0b1IiY4p3Auxw05I7Gi0o/VhN99803mNgn1Y19PeGUdFZsj2ii+wbzYWPP78bhSvvt9p3m8k+rYU
+l6tL400QeVBicm3cSolFcLQ0CiJHYIowBi58xsfLaFTsMc5TzvlM/F09sN06nAIzIXAAAESxvm3y
+YDh6GXDGUqz5O6/7vo7ULe/9leBlMDuQp7G34s46cSO6VQzLX1zwljkXGPFbzlXiDXku4pa+aYry
+57I0QZydIY6KHc1WdC/WsuNK+NtgP/90NMiejFvsaLSj9cHe8LPX1oMcnKPH4zzmRTDFEYPQHL56
+Vyj2ThrfWWr/bhBadY11xDvqHu9SHTeRFovemqVRWCsFpoAxjiIl5zbhqQqMcTTI6B9KyVr7bhzF
+Ozeqw2p/ZgQOzhHJkXJuBnozAxfCGOpyLW686Wd0JBcBYakMSQW1xztPVcYx1pmkHd0shuXfQ0rQ
+2VFadfLMPqy6jrMQp/oWkb8SElZmE8YY4xxZnMjbzVZ0P46iZW/h8WA3ezDqZ09MMR6xI23G68Pe
+yQa1KBCcpcqMRp3zVGSG8l6xxfbKBx06ahCq70rB2WUePTktzPofp3FbjCK96MpyyRT2ycQPFrjU
+EHlAgYtV1zFPPNsfbaQNfbfqOs6C50CsBkYsMyNwAADoRN8oh+VMLWgDZ4d5v3Waz4bWclFI9q/Z
+oNiYQlmBc0JEwCc0azwPJK1obdArNmfROLBKOGdIHqJZE4eiSC5y9EshYWW2ORQ7dCRXWwvJ/TiO
+lpmHx4O9/NPD+NlzvzZnqDWuZf1X722cMzTG5her/mwY4ygf5nt2v9jQI/PwHZS9D9J4damT3I+j
+y2cQOg4UYyeO4U6CJNaLWV4MytKGbsHAxLCOQAp+teo65oVne4Ov00b8SdV1nAXnPCkueNV1AMyY
+wME5IiC76uxsLWgDp8d7Ii6Q4SkXS1wK1JH4eDAowsNCbfGzdaGpgFYnXh+8ZfY+8Coq4rfdDJiN
+HkdquRglam3QHT0I7/l8wDkypeVqqxP/NUrUKhD8PNrPHhyKHf6MiSxcCuQSVk/q9iFEPUlhzz+P
+cT00CG0b9vg9FXfeayX3Oo1k/bIbhF4U5zwpFGKax0wTfSsfFT8bE0SOwGTwjrbDVWE8jEbFHkp1
+fVoi6LggIhCSJVXXATBjAgcAQNKIruVD86DqOgKTwZYEOhbLZ/kdLjk2ErU22M/Dw0INIQLgAivP
+xK47rU68PtzPQzfSGZBaYFaYf1Zdx3ngnGGjHd/vh4SVueN5Z8dyo53cj1K1ygB2skG5MdrPvygy
+c2qxQyq5CJ6WiuJlkYMjvDfuO91Rg1AxNJ8vAt85NAhNYrUaDELHBxGBEjj1h4A01bcGw+IXY1wQ
+OQJjh8j3Z+x5vJYY42iQuydKik7VtZwVIgIOqKuuAwCA/+U//uU/qy7irHjvG+Sp5ByjqmsJjBdr
+zN+jRP03PONwKkPGdCyu9feKTRnx5bAQqw/OOs8FRrOmRFeBVGJ5NCwfKi1mxlCqaogc44its14z
+6oKO5Eo2KL9GjjEiC/e0OQMZY5zzltLimlD8A+ahl2fma5PZX8j79xmif9O5KwSPrXHMk3/GBW8B
+ADhHTYHILnpNNYWjMjc/YWa+SRz/ra3k1YaWV5NIrQg+u5+pumNK5xei6L0qumC0Elf6vdH3KpJL
+p+2UDQROQ1na/5Mm0fWq65h1/mt3+KDZTGbKd+MQY8hrzZd4DcylZ66DAwBAx3KxzFxIVJlDvGfP
+LvLBaC1G66N+sTlrc/nzjCcPYR11OhhnGCVqbdgPI1enRSqxXOTmy6rruAhpU//FFOXPpjDBCHCO
+QUQmleg0mtG9pKnvCMReOSwfDvfzL0bDcs+9JpFFR3KxLO3A2oOddy44lIU98xrohUFoN//60CD0
+gyhefrfZuB8MQqcHEm1XqR21WsnN3v5gI6yTAuPCOSIleBDoL8hve4Ovm434ftV1nBdHtlsDf1EA
+mFGBAwBAR+KTMjc/VV1HYHw4RxRpri76Os12tJ73iy9C/GY9sN5/U3UNswTnDKOIrxUhaeNUcCmQ
+nIdZX6zHqb7lvE+KEOl4KTgUO9JmtJ62ojuREh1TuK8G+/nGSWJHkupbeVb+Yp3rckQg50anOc5R
+g9Bk5L56B2Xvg0Zy+3eDUAyjJ9PGQeWt/K1m8sne/mDT+9m+bgbqgSMPyPHC6/fLzGBU7IkZ9N04
+iif2Y11uJzMrcEgt0BTuR6LguTAv2NKCjMSdcbxW2onXzKj8xdkgclSOCw0cZ4VLgYCwVIaH3VMh
+IvGRK2fPbPQ4USQXgYWElcsGMsaE4CxJo7uNVnTvJbFjkD2xz8WONNU380Hxd888c+TtSZ5Thwah
+ea/Y8rvFp23DHr+vDwxCm43objAIrR7OWFkHUanTTNZ3nw6CuXXgwjhLoJX4sOo6ZpXCOMpm1Hfj
+KORdWZe7y8wKHAAAOpEfm9I+rrqOwHjwnr4a57orbkU3bVn+HESOqvElVL+Wmzm0loveB5HjNEgt
+MMtn02z0OFrLxSjiIWHlknJU7Gi2ontxFC17C48Hu9mDUT97oiNxZ9jNNwlY4/D0cMZRMcz3yu7v
+BqEfpPHqOwvpX5M4xLjWCec8xUrWwoQPAKDTSdafPe0HQTVwIcjTTrjEnJ9n+6PPkjS6XXUdF4UB
+FKwmMypTjakaN1IKLItsRCTeaNIVmA0EcjPu1qwojW7lo/JHZ9mvKpI3xvnagdPhvS+Cmdn50LFc
+zEYFOEtdLrBddT11hku87hz5OphbXRQuBTba4n6vm200mtG9WW5ZDZwfxhjjnAHnuKojueoceWvc
+NjhPu/1uTzP2RBH8mAqloii+I2K8E4SMeuMsgUbVrLqOoyx0kvW9veHmwkJ6r+paArOJc7SLyM6U
+gBg44Ldngy9m2XfjEOc81ak7cKY7OAAAoljfNrkJhqMzjjGWdMKXJvHaUaKuAQs74YHZJE70YpmH
+TqS3IbVYPo/xYp1pteP10aD4wob3PgAv4mdXWwvJ/XfSRisx8Mt77cYnhwahQdyoP44IlMTabbak
+sVrb3xuGTo7AuUAP/XD5OTu9Qf5EaPXHedjEICKQitdGvJ15gYNzRHKknAtGSbOMK90OF2JiN30d
+yUVAWCqDceNUcc4TD87aFyZuRLeKvPwlGOe+Hi4FGktDmrOxjkYrWjNF+YsxLrz3AQA4iHd9t5HE
+aRLdKYswpjtLoINHdXyW4ZxhEqu1/V4QOQJnwzlPjAWz4rNSGEelhdGs+24cQkTAoD6nwMwLHAAA
+OtE3ymH5sOo6AufHAzyZ9NiW1nJRSPavg0GI4JwaRMA4C87aYyBpRDfzofnnrKeFTBKh+MfOUq/q
+OsZNnOqbzjkXElYCAAA8dw+VEjek5lhaExlrg/g1I3DvR3V9DuScYSTE2qA/2qi6lsDscNCVVJ+d
++1nh2V62Gcdqteo6xgURgJK8NkazcyFwcI4IyK46Gxb+s4hzRFIgm4ZPA5cCk0StBZFjOpD3UMPN
+qpklbem/DHrF5rx1KYwLHUsshuW3VdcxCQ4TVkbD8ouqawlUhykcdWK5cni/jJPo2nBg/umC8DkT
+cABX551uKTlyxNVhVgYxNXAqHBFIya9VXccs8euzwRetVrRedR3jhIhqFZk4FwIHAEDSiK7lQ/Og
+6joCZ4csQZTIm9M6HucMG4la63ezT0NKwYTxAELUR9GdB1qdeH3QzUO032tgkq3M68ii1nJRK/bR
+sB/e/8uKyOxnWqmVo19rtPRf+t0srH9qjjWOUqVaVdfxNpQSi+BoaRREjsApcMZ2kQcT9NPSHWRP
+VKT+WJe0kXFB5B/VSN+YH4EDAEBp8SdThlbNWYPIbU87IYJxhq1O/NdBP+yGTxIighqN5M0NrU68
+PtgbfVZ1HXVEarFsSje3vgSHXWj9XrYZxpUuF2Vm9haS6M8nfS9O1CeDYRG6e2qMIw9CioWq6zgN
+kRaL3pqlURiL+//Zu/PuNo5rUfQ1V3U3AEKgT3yiIbkrtkTm2LpZzzZlSlnvfbb35WINsX3XdRTb
+NO274qPBejElEEBP1VW16/0h0aZtDRwA9FS/PxOJ2InAHnbtIXgD79GDJs6VaSKtDRiLc866MXfj
+OO9RqOBYFaHYpCpcp6bo94H3+GldE4RHG2o3X+jworAi3qNZky54XTLYiHezRWi1+jXKGamMe9rl
+xCWmmPy0YSUMnu0NruFLLl7+YEw5JQijP4U5Lc3lHcw4bc8qTaXkxFXVZlmab+qOJWguDygP+Y03
+c87DdF79vUtzN47DCBq1SadTCQ6EEJKK3axK86juOIKTccaCilitw4mGG2q3SKsvwoaK5XPeP2jQ
+9a5TMMVExWInJDl+iwl6rYvDRn9tMFI7pqyemLBGtvOqVD+cDONbr/szSvFJaSxYFzbuNBEG/IC0
+7IYYR3JSaRNVoTo6eAWMketau8UqHBym9wZDeaPuOFbFI4+aNF+ocwkOLhkx2j0A6O7pXZdY62dc
+1D+jYbCh/mJ09cSFF4XlcnUH0G2UYqIU3cnz6h91x9IkQrCxLu3XdcexDlEit2xVhQ0rHeach8Tj
+R4y++SUiSeTWYqG/CjNamod6nzbo+f/EklhcKXP9gzEhyRH8kjEOlOCNnytTt9lM70klt7uaCHLO
+gWBc1R3HcZ1LcCCEUBTzG0ab0KrSAt6775rSuxclastW1Q+2CqdfywOtfKBrE8oZoRRfqsIL7k8w
+xQR5P+7LZokolhOE/GYREl2dBGW1P4yjE5/8DRJ5Y35YhlWfDQLOA8e0USecp5EkcjvN9BNjwvNR
+8DMAjyhFsu44mqwszdR4j7s4d+MIAEKUIVF3HMd1MsFBOSPOAYQqjmbzHoARWtU1f+NlVKK2wYML
+L4vL4T3ybX2gaxMp+cR7tBm+tz9jil01urvDRn9NKj4RHL+XLcrQstQhzjgYeVHRE1RvHMEUExGz
+j8siXA+awgGgmNNa23HPa5TIrXSePbE2JDmC56wDxDi/WnccTeWcg8NF9U1X524csQCI02atCu5k
+ggMhhFQkr5syVHE0mbWApKJ/rDuOX5OKTxAOL4vn5Z0Hgjt7iWkcGT1PchhtHtYdSxNw+XzYaJ9K
+9X/asDLNPwmDk7vB5fZ+HLNTt3FyTolxdrMKbQWN4CwgKU7/79g0o1G8tZjn34TrS4AQQt7BfnOO
+KJvnYJrfGwxVZ+duHAHwqGmrgjv79kEpIQB+7Fy4CDeVq9xjKtjFuuN4Gan4BBG0WWSh5PusACFE
+BAm9mWskIz6xxqVhlsxzhONrzkHdYawVppgML0S30kV5N2xYaTdrHIy5wGetcoxiOSky86QvrVpN
+5sE/7kr7/WgY7UwP07veh+9V3wH4RYOKsBtldpjvyUht96GK2YPdb9r/ys4mOBBCKErEJZ1V9+qO
+I3g5j9DDJl8YpeQTKel7aRq2VJwJuG5fYBoqGqhtXVZPwlYghIQU47KwvbwHjDai3bBhpd1I7u5F
+ET/XqX8yklvzWXm7T5VMTUScf9a2DSqvMx7Gu88OQpKj7zBGuquDM88jL/XUYYY5o52du3EcOKKb
+lsfp9PsHxoRggi9aEx7wmsY5ACkZb3pmk3JK4ljshCTH6YFHCBMchk/VIB6oLZ1WT/peRkwpJh4h
+1dcT7CiRW6aq5mHDSvsY7WAc8ctkCffIeCB3F4uyl4m+phAYL5o0b2wZxuN49+lBejckz/rJOQBG
+Gas7jqZxzkGawXdSsU7P3TjOo+ZtiOp0ggMhhOKBuqLzMIujacACEpK+U3ccJ0EpJoNY7Cxmxd/C
+jfzkPHhEGQnDp2oSb6itdK7v9j3JwSW9Dto9rjuOusSxvIKQ3yzDhpVWIbm9Izi/tIyfRSkmnJOr
+IdFVD+c8iI6+CF4Yx7tPp/PbdccRrJ8DjxjDcd1xNM3Bs+JOnIgP645jnTCCxi0U6HyCAyGEhGR/
+NlUYtNUkzrr7lDVrIM3rYIrJaBz9NV2EF8aTCrmg+o3G0W46170+YeOSkaI039cdR52k4hMWNqy0
+RlWY6Wai/muZD4xc8ok21pmwAWPtnAWkGL1QdxyrMorj3ek0C9eWnunK4Nxlmh3me1EibzbtZX+V
+nHPAWPMSuP1IcCg20YX5Z58f8puGUNLKcs3RhtrN0yokOU4AHOz36BrfWKNxtJvOil6fsBFFt611
+vf6dZcc3rIR7YaNxDV9ywZbeux0ncjtPq2/62rJVFwBAXLDOVjNSikkSiZ3DkOToFfDwODzj/Swv
+9dRRklBKe/V/CgBqZCVPLxIcCCGklNg12va2TLlJnLEQSfofdcdxVsMNtVtl1TdhiOPrAcY63Pua
+YTCMdrN5f0/v+zxs9LifNqzMi7vhJbeZqlQ/nCTRe6v6+clI7ixmxSer+vnBbxGA/S4NGH0ZSjGJ
+I7FzOA9Jjr5wDp618JxyJYx5MXdDiMt1x7JuFgBRTCZ1x/FrvUlwcMmI0e4BQDi5qpsxMCOCtvo0
+IxqpLaOrJ2Ed56t5hxDq+ENdW2CKiUrkTrbo57BcSjFB3tNQefXcaCPardLqm7BhpVm885B4/Ijx
+1U7ej2JxM890mMmyLg71YpUmpZgoxnYWeRm+Wz3gATdusGRdnh7md5KB/KjuOGoBCDFGLtYdxq/1
+JsGBEEJRzG8YHQaO1s7Dd4S2/6sXJWrLVtUPVWUf1h1LExGEFuHW1xyUYqIU3Sky/WndsdSBKfaB
+q/o7bPTXopHcctb9EAZPNocpqsfDOLqx6s+hnBLA/lKlTbh3rQHHWPelJ59zSphHl7KiCteVDnPO
+AyMY9eV7/TrPDvO9ZBDdrDuOuljnHjdxU3D73zJPgXJGnAMAF07x6uI9AGPULWP1XROoRG0j7+Mq
+vCT8BngIN7+GoZwRxsifdNG/7+uLYaP/qjuOJlGKbSPkN8sefh+axhkHG0hMKV3Pk6JSYlJUNrPh
+eWilrHEgBVd1x7FOQrAJcrCZhyRHZwFATwevAAAgAElEQVQAEpwO646jbnmup5jSpI0zBZfGo2dN
+fNTvVYIDIYRUJK8bbUMVR01sBUhGbCmr75pCKj5BGG1W4SXhJ955wF1vOm4pLvkEIbTZx6QcFeQP
+LrzQ/YJUfMIYeidsWKmXy+39KF7vRoIkkVuLRdHrLUurBoCQpPQ/645j3ZRkE2/NZt7D+0wfWADE
+Ob1Sdxx1MsZBWrqHQvDezd04Dryrmpje6V2Cg1JCAPw4POTWA8DtU0Y7leBA6PlLAqFos8z7Wf7/
+awCAaMjuN5aM+MR7tGl6VqLOBbukS/NZ3XE0DeOMqFjszKdZ2LBSA2scjLnAtIZTwEGibiwWZe8H
+8K6KA0CC0cb1p6+DUnLiqmrT6NDG2zXgPCKUbNQdR51+PMxvJ4m6XnccdcMIadzAHpXeJTgQQihK
+xCWdVeGGXgPv8dOuVnJxySdCsA/StJ+DHH/J9/Pi0iIy4hMHKO3ToFzKGXHWo/AS/1uUYjK6EIcN
+KzUgubsXRXyt1RtHMMWEc7YTZrGsBnHoflefeU4ijuSkKHVaVbY395k+AOd6/b1+Ok2/GA6iW3XH
+UTfnPNSRmD+JXr6DYEwI4+yqNf15sG8C5wCUpKLLcxkopySOxU66KHqd5ABAiDLS6/LFNlAR39Zl
+9aRPK495xD5wFuZ1x9FURxtWbI8SX3Uy2sE44pfrnEvFJSWVNcrY8BK6bNj7vMOPPCeSxHK7zPUP
+xoTvV1d4QHkzX2tXL831lHDxh17P3XgBABAXzazW7mWCA6Hnp5c6DxtV1gksIK7Yh3XHsWqUYjIc
+RR+nh8Unfe1t9t4jTHCvyxfbIh6oLZ1WT6AnSQ4uGdFZ9WXdcTRZNJJbRldhw8oasNLdEZzX3rYZ
+xepKlpp/heqd5eIIuS4f6pxUksjtNNNPjHG9uM90HcbINbEtYdW0cVCU7qHgbKWrvNsCABBFRNYd
+x8v0NsGBEEJCsj+bUDa3Ns72q6RteCG6lS70XejhA6MHj8IzXXvEG2orz/SXffmuYo4vhzlMrxcl
+ctuHDSsrVRVmeiGS/9WUF+DBSP5lMSs+qTuOrrDGQSLEqO44mmKUyK10nj0JSbR2M8YBF7yX3+un
+h/ntOMzd+AkAQoyTq3XH8TL9TnAoNqly+1VfT9nXjVGS9a2ka7Shdou8utOX0/Ej1vt/1B1DcDqD
+UXQzneu7fZhPwSW7VIVtWm+kFJ9Q4jfDhpXV4Bq+5KJZJ4FRLG6mWRiWvQwOPBKs35smfm00irfm
+h+mdviTTuwjAI0FRI0/tV+nHMHfjNwAANbWQp9cJDoQQkgm/YbR9XHccXWeMBRnTzbrjqMNgqG5W
+efWkT8MckQsFHG00Gke76bPuv8xSzoixkPUhmXNeXPKJisVOOst723K3ClWmH04S9V7dcfwa5ZQg
+jP4U2pPOzzuYUdbvTRMvMxrGN6eH6V3vQ5KjjawDxBhr5Kn9qszT8iELczd+A8Dfb+rDfu8THJwz
+YrX7ASA8uK2Sq9xj2rML4nHRSG2Zqk9JDl+hhl70gtcbbUa72bz7SQ4m6I0wbPRkKMVksBHdWoQN
+K0vhnYcE8CPW0D5upfikNBasC/MSzgNb/4CE++BLjYfx7rOD9G5ImraPd7Dfp/d8bRxUFuVh7sZv
+ASDU1K9C7xMcCCGkYv6B0WHg6CphhB42tYxpXaJEbTlnfzCV/abuWFbNe6/r3AoQnI9K5E626Pa6
+YyEY0kX1z7rjaJPRRrRbZtUXYcPK+ZiiejyMoxt1x/E6SSK3FgsdWnjPgWKchtvgq43H8e7Tg0Wn
+7zNdBOAXfUpwPJ0Wd6NIXKs7jibC2C0QauZ3ISQ40PNyZecAIAydWwnnACgjOLzwIiSV2Pbev1WF
+8t+gwSjFRCm6U6b6Tt2xrAqmmCCKN8Ow0dNJhvIvRlc/GG0e1h1LGznjYIjpE0qb/4YwSOSN+WHZ
+2WvAKoHzEBFGmzJAtqkujOPd6TQLSY4WwRjpvmxQ+fFp+ulwqHbrjqOJnPOAEEJNvcaFBMcLKpLX
+q9J8XnccXQQWkIr5Vt1xNIVUfIIw2qw6up3AOQ+UUVV3HMH5UM4I5eSa7uj3FCGEhGRXTeW+rTuO
+tokSue28j8OchtNzpb2fRLIV69IxxUTE7OOwSef0HAASjMR1x9EGSSR2DkOSoxWcA2CUsbrjWIdZ
+WjxkUrwb5m68CiAlm7tNJyQ4XqCUEO/R78Jp3vIBuP0waOuXpOITQtFm0cUTcgCEKRZ1hxGcH5d8
+ggja7GrFEeWMVMY9DWX4p6cUnyAcNqychjUOxlRg2qIHZs4pMc5uVsaGtqRTcBaQlPz9uuNoA0ox
+iSOxczgPSY6mc+ARY7jziTutDRiLw9yN1wBAjR61FxIcx0SJuKSz6l7dcXSN9/hpyID+Fpd8IhW7
+kabdmnUA3jd26FBwelLyifdos+ro7BjC8TUbho2eiZR8ohQNG1ZOyOfweRS176U3iuWkyMyTMGD2
+5Lz1j5v88N80lGKiGNtJF3n3Dn06xFlAUrDWXcNOwzkP03l1J8zdeD0LgDhv7nchJDiOwZgQxtlV
+a8IAtWVxxoKK2LDuOJqKckoGsdhJF0V3khweIcZoYy96wenJiE/AeejiFiAlxViX9uu642grytlP
+G1YgvAC/ktEONiX7fVtnUSUjuTWflbdDIutkiPfPwgaV0+GcEkrItayoOlkx2AXg4XFLL2EndnCY
+3hsM5c2642g6AI+afI0LCY5fkRGf6DxsVFkWa/2Mi/Cy+zqYYjIcRR8vpuUd6MDDIwA0dahycA4q
+4ttVWf3QtSQHppgg78fhdPp8RhvRbp7qT8OGlZejpbsnJL9YdxznEQ/k7mJRhirXExAYL0Ll6ukJ
+wSbIwWYekhyN5Bw86/LXejbTe1LJ7b4MUT0PD3a/wfmNkOB4GSHZn00V+k2XwXv3XZcvhss0mqjd
+fKFbfwrqPZp1PcPfV9FAbeusegKuWy+xTLGroN3juuNou8FI7RhdPTHGder7cV5VYaaTSG43ddr8
+SVGKCefkahgu+3rOeZCCh0HbZ6Qkm3hrNvPwPWscD91dfVyWZmq8x5yFuRsnAY7oJn8XQoLjJYRi
+kyq3Yf/7OXkPwAitwinGyQ031G6RV3fa/ALpvH/Q4GtecE7xhtoqs+qbtifijuOSkaIy34dr/vlF
+idxyzrnwEvwzXsJXXHTjoZlLPtHGOmNDEutVnAUkSWjNPQ+l5MRV1WZZmk7Ofmoj5zwwghu7FvQ8
+nPNwuKi+CXM3Ts4j3+hkV0hwvIJM+A2jbTjROwdrAUlF/1h3HG0zGKqbVV49aW0rgKs7gGDV4pHa
+Sef6bhdaqo4QQbedg7rD6ISjDSt5Vn1adyx107meTgbqv+qOY5niRG7nafVNaOt6OQeAOCdX646j
+7eJITiptoipUVDcCACDBaScTdwfT9N5gKG/UHUebYAS+ycmukOB4Bc4ZscY9BujOA/y6uco9poK1
+uue4LtFIbdmqrfMOoNFZ3WA5RuNoN33WnRWhQopxWdgwX2BJpOQTKfAH2aK829fKGO88DBz+hnVw
+1WAykjuLWfFJ3XE0EQXYb/LwvTZJYnGlzPUPJqwprt3zrRn0St1xLNvsMN+TkQpzN07BOQeCNbsN
+LyQ4XkMp/qHRYeDoWXmEHobulLNTidq2xs6rlpV6e48andUNlme0Ge2m0+J23XEsA6WYgEeqS603
+daOckTgWO33dsGKK6vEwjjp7KhjF4mae6X/UHUfjOLQIzz7LkyRyO810mO1TM3AeEUo26o5jmfJS
+Tx1mmDPauST0KgEgRBkSdcfxOiHB8RqUM+IcALj+PZidl3MAUjIeXnTPR8XiCsJosy1JDu88EBwu
+K32SjNTH2UJ3opJDKHrdhWGjS4UpJj9tWGnxbKHTcs7DENMnlHb3TZdySgD7S5U2D+uOpUk4xjo8
++yzXKJFb6Tx7YsPsl9qAc/e7lLhzzsEic3tSsTB345QsAGKUXKg7jtcJbyJvoCJ5XWdVKFs+JbCA
+hKTv1B1HF0jFJ4igzapofpIDEEJEkFHdcQTrgykmStGdLiQ5uGSkKM33dcfRRYOR2jFl9cS0su3u
+9Fxe3U8i+WHdcayaUmJSVDaz4SAIIYSQNQ4SIcI9cAVGo3hrMc87NeC6TTxCeYfyG+jgWXEnSeTH
+dcfRRgAeUUov1R3H64QExxtQSggi+KKz4YJ6GgBun7JulbLVSUo+YRy/k6YNf4kEFy4qPUQ5I0rR
+Hd2CJNybUEmuuPCythJRIrdsVXV+w4o1DsZUYNql487XSBK5tVgUvZ21cpwDjyglk7rj6KrRMNqZ
+HqZ3vQ/X6HXDHrmuzKmYHeZ7USJvhkqrswHjHqOG/z8X3kVOIErEpSqvOtFnvi7e+6dhPexyHfWz
+NznJAR4hTLCsO45g/ShnBJH2tFO9Chfski7M53XH0VVRLCcI+c0irzo7u8Hn8Hmk2Pt1x7FOg0Td
+WCzK3le7AngkGA3D1VdoPIx3nx2kIaG2Rs4BcME7UZmUl3rqKEkopeEd5Yw8ws+anhsKCY4TwJgQ
+ytm2Nf0orT0vZywkkXir7ji6iFJMBrHYSQ/LT5p4c/fgEWVhPV5fSckn3rc7yUE5IwDehzLo1ZGK
+TwTH72WL7mzhOWK0g03Jft+3BD+mmHDOdrpenfMmxKFOzSloqvE43n16sAhJjjWxFpCgqPWHV845
+SDP4Tgpxue5Y2swj1/h2pZDgOCEZ8YnOw0aVk7DWz4ig4SV3RTDFZHhB3UoX+i407ObesHCCGsiI
+T8CBaueK4+eYYh+4KgwbXaWfNqxM80+6lEyipbsnJO/lCT6XlFTWKGP7u9ITe583/WSzKy6M492n
+03morl4D6wAxxlr/XP/js/xOnIjOz0ZaNYya364UEhynICT7c1WaR3XH0XQe3HeEhq/Wqo021G6+
+0I1avwgO9sPDXaASeaUqqx/amuR4MWz0X3XH0XXPk7XRrXRR3u3ChpWqMNNJJLf73NcdxepKlpp/
+uQbdl9YFnAeJKfT533/dRnG8O51mnasEaxrvYL/tlUnPDvO9ZBCFuRvn5JyHNsyXCm+hpyAUm5jS
+PQglca/mPQBj1JFwAVmL4YbaLRf6U9eQlwPAWId/+QAhhKKB2tZl9aQp383TooL8IQwbXY/RRrTb
+hQ0rXMOXXLBx3XHUbTCSf1nMik/qjmPdAABFnA7rjqNPKMUkicTOYUhyrBSAX7T5sT7P9RRTmvSt
+dXAVAABx0fzrXEhwnJJM+A2jbShdfgVbAZIRa/TqoK5JxtGO0dWTJpyWe4cQavFNMFiueKC2dFa1
+cq0fF+ySLs1ndcfRF1Eit0xVzds6w0HnejpJ1Ht1x9EUUSxuppn+tO441sk9HzB6pe44+oZSTOJI
+7BzOQ5JjVTBGuq3JAWMcpAV8JwQPczeWAAAQRaTx81hCguOUOGfEWncAEKo4XsZZ95iyZu9G7qIo
+UVu2qr8lgCC0aOUdMFiZeKR20nnz5sW8CeWMWOdt2+JusziWVxDym2XLNqx45yGy5CvGQ/XGEcop
+QRj9qa0Jq7PwDmaUkY264+gjSjFRjO0s8rJV1442cA6AUMbqjuOsfjzMbycD+VHdcXQFAEKMN3+Z
+QEhwnIGS/Lopw8DRl8L4v1ua5G09lahta4yrc4MFeEChvzH4tdE42k1nZesm3jNBbzgL87rj6BOp
++IS1bMOKKarHG4m6WXccTaMUn5TGgnWu9urCdcDWPyDh9lcbzilhHl3Kiqo3SbV1eF6ZhOO64ziL
+p9P0i+EgulV3HF3iwM4aPl8UIRQSHGdCOSMOACD0Z/+CcwBKUhFecOujYjlBuJ41nd55wOHpLniF
+0TjazQ7b1ZcvI050Vn1Zdxx9w45vWGl4Usw5D4mnjxhtwRNfDZJEbi0W+qu2JTfPQmC8aGsZf1cI
+wSbIwWYekhxL4ywgKdj7dcdxWnmup4SLP4TfyeXygB+04TUvJDjOSEXyus6qe3XH0SRgAXHFwvql
+mknFJ4igzSJbb5k3ACAaBqwFr5GMopvZQrfmZB4hhDDHl8Ow0fX7acPKvLjb5I0cLq/uDxN5o+44
+mmyQyBvzw/JO3XGsEjgPgrS3jL9LlGQTb81m3qP2qFVyzs7a8EJ7nDYO0tI9FKFtcOnAu6oNKaOQ
+4DgjSglBBF90trkPXuvmrLsfEqXNICWfSEneS9N1vkz6cEEJXgtTTFQsdtqU5OCSXTLahpbEmow2
+ot0qrb5p4oYVaxxsYIHbsDKvTphiImL2cVl094XTASDBSCvL+LtIKTlxVbVptH1YdyxtBx49aNsl
+7ulhfjtJ1PW64+gijJDGLehRCe8j5xAl4lKZVZ0+lTgNRkkWSsGag74o815XkgMAIcpImCAfvBal
+mChFd/KWDJKknJHKQtb0Vokui0Zyy1n3Q9MGVkJu78dx+0q368A5JcbZzcrYxiWqlsFZQFLy8F1o
+kDiSk6LUaVV18zu3Lh5w2qYKjh/D3I2Vcc4DRu34LoQExzlgTAgXbMua5p0srZsxFqSkm3XHEfwS
+pZgMYrGzmBV/W3UPtPceYYLDBPngjShnhFJ8qc6BuKfBBL0Who3WSym2jZDfbEoVgNEO3pJiMyT1
+Ty6K5aTIzJMmtxydlbf+cRhB1TxJLLfLXP9gOppYWzXnPDCCWzM8Ps31lIW5GysDAEgqNqo7jpMI
+CY5zkhGf6DxsVHEGZlSyxq8N6iNMMRmNo7+mi9Wu6vTgUUvugUEDSMkn3tczEPe0hGBjXdqv646j
+76TiE8bQO03YsEJLd09IfrHuONomGcmt+ay83bWho9T7J+H210xJIrfTTD8xph/bfJYJAJBoyWw1
+bRyUlf8xzN1YHQBoSf1GSHAshZDsz1VpHtUdR52w93staMnqtdGG2s0X+i6s6PTMet+KloOgOWTE
+Jw5g0zb8wRNTTJD34y6ePLcN44yoWOzMp1ltG1ZMYabjiF9uy6lm08QDubtYlJ0a0s4x1uHUuLlG
+idxK51knq4dWyQIgxsiFuuM4iafT4m4UiWt1x9FlAAhx3o62zJDgWAKh2MSU7gFAt04kTso5AMoI
+JuFhr/GGG2q3yKsvnFtBW5ULBRzB6UWxnBhtfnANHCJ5nIjZVaPdt3XHETxvvRtdiGvbsMI0fCmF
+uLzuz+0KSjHhnFxt2kyVs3LOgxRc1R1H8HqjUbw1P0zvrOqQp4vAeUQZvVR3HG/y49P00+FQ7dYd
+R9cB8qgtrXghwbEkMuE3jLG9fPgFC0jFfKvuOIKTGQzVX4yuniz/hdJXqCUXvqBZooHa1mX1ZCWJ
+tyWhnJHKuKddK61vs6MNK3aNyTGd6+kkUe+t6/O6iks+0cY6Y5tdvXUSzgKShLWijL/vRsP45vQw
+vet9SHKcBLjmb0ecp+VDJsW7oYJqDQD+0ZbH/JDgWBLOGXHG5X2s4gBw+4SSMFyyRaJEbdmq+sFW
+y3u49N7rUMUTnFU8UFtlbv7V5NM1wvE163wYNtog0UhuGV2tZcOKdx6iinzNQo/3UsSJ3M7T6pu2
+tw04ACQ4CTPIWmI8jHefHaR3Q7L6zTxCeZPTBlobqCzKw9yN9XCuNfNmQ4JjmVQkr5uyfwNHvcdP
+KW3yJTB4GZWobfDg2jDkMeiHZCj/ks5XOwz3PIQUY12YMGy0YaJEbvs1bFgxRfV4I5RBL1UykjuL
+WfFJ3XGcB3Gw35aH/uC58TjefXqwqH1YcdNhjxxu6IA95zxM59WdMHdjfTzyrVkZHBIcS0QpIeBA
+ONfu04jTcA5ARaE0s62k4hOE0WZ1zhcD5zxQRkMPcnBuo3G0m87KRp6uUYqJR0i1/cS5i5TiE0r8
+5qo2rDjnIfH0EQvJ/KWLYnEzz3Rrh1RTj6ehOr59Lozj3ek0C0mOV3AOQDT4ue7pYfb5YChv1h1H
+n2AEvi0lHCHBsWQyllerrOrUdPDXsZVFXNBWTNQNXk4qPkEUbZa5/vTMPwQAYYrFEsMKemw0jnaz
+w2ae6nJJr4N2j+uOI/gtLvlExWInneWfLDtB5vLq/jCRN5b5M4PnKKcEsL9UafOw7ljOgiLk2vLQ
+H/xSEomdw5DkeClrAXFOGnmAOZvpPaHEu02tLuki5xwI1p5hyiHBsWSUEoIIvuhsP074vIfPw8lF
++0nJJ0KwD9JUn+lGD96j8DUIlikZRTezxdm+j6vEJSNFab6vO47g5SjFZLAR3VosccOKMw42sMA0
+3OxWRikxKSqb2ZZVwFrjIBFiVHccwdlQikkciZ3DeUhy/BqAR4yxxs2WKUszNd5jzsLcjXUCQIgy
+1JqDzJDgWIF4oK6UmWnk6eMyeQ/ACK3C5OJuoJySOBY76aI4/Y3eI8RYqOQJlgdTTFQsdpqY5CCK
+blvrWvUi1jejjWi3zKovlrFhxeX2fhyzcH1bsSSRW4tF0cj2tFdx4BHj7ELdcQRnRykmirGddJHf
+qTuWJnHW7Tft8d45D4eL6pswd2P9LADilF6pO46TCgmOFeGC/tlUtvXrz17HWkBS0T/WHUewPJRi
+MkjUTnpYnKrEGwAQatZ9MOgASjFRiu4U2Tnap1ZASDEuC9ubVsS2SobyL0ZXP5hztD4Y7eAtKTZD
+In89Bom6sViUrfnd8g5mnOBLdccRnA/nlFBCrmVFFYauvwDI66Z1Xh0cpvcGw9AqWAcAj9q0MTMk
+OFZERnxSFa7TG1Vc5R5TwS7WHUewXJhiMrwQ3UoX+u5JV3Z6j2ZNuxEG3UA5I4SRP+kVb8g4DUox
+AY9Uk1faBs9Fidx23sdnXSNLS3ePSx7uc2uCKSacs511rP1dBgz4Qch9dYMQbIIcbOYhyYEQQgh7
+tGhSYnd2mO9JJbfD3I16eLD7bXrMDwmOFZKK3axK86juOFbFI/SwQde+YMlGG2q3yKs7J3mJc94/
+aNOFL2gXKfkEIbTZpJXGQtHrLgwbbQWl+ATh029YMdrBOOKXScjerhWXlFTWKGObXwVLfXvWJgZv
+piSbeGs28wbda+rgHAChjNUdx5G81FOHWZi7USNwpHEVPa8TEhwrxCUjRrsHAO3pJz0p5wCkZDxM
+Du+2wVDdrLLqG+fe0Mfu1hRQ0Fsy4hPv0eZ52g2WiUtGCm3+VXccwclIySdK0VNtWGGFvS2FuLzq
+2ILfimJ1JUvNv5q8khmcB44pCs9B3aKUnLiq2ixL803dsdTFgUeC4bjuOBB6vr1jkbk9qViYu1Ej
+71zepktdSHCsmIz5DVPZb+uOY9nAAhKSvlN3HMHqRSO1ZXT1xL12WB+EU6xg5WTEJ9a49PXfxfWh
+gvzBtWzrQ59Rzn7asPKmyjSd6+kkUe+tK7bgtwYj+ZfFrJnrohFCyAGgmNNGrtEMzieO5KTSJqo6
+PkvvVZwFJEQzBisfTPN7SSI/rjuOvvMUQZuSuSHBsWKcM+Ksy7tWxQHg9ilrz7CZ4HyiRG05Z3+o
+KvvS03PvkW/ThS9or2igtnVZPXljVdEacMEu6dJ8VnccwemMNqLdPNWfvm7DiqjQl4yHcui6RbG4
+mTZsyPARAI84a89WgeB0klhcKXP9gzH9S3I4Z2ekAY90s8N8T0ZqOzxf1ss5B4IyWnccpxESHGug
+InndlKZTA0e990+bNHwoWD2pxDbyPv71HATvPBAcLiXB+sQDtaXT6kndQz4pZwScR3XHEZzeYKR2
+jK6eGON+8/JSpfrhZBjfqiOu4JcopwRh9KcmDh0FC4/DQU+3JYncTjP90utEl4FHD+qe5ZmXeuoo
+STijIdFcMwCEGG9Gy9JJhbeSNaCUEHAgulLK7IyFJBJv1R1HsH5S8QnCaLM6ttECEEJEkFGNYQU9
+FG+orTzVJxqCu0pMsQ9cFYaNtlGUyC3nnDv+8uych8TTR4yGBH5TKMUnpbFgXbNeMonzz5pwyh2s
+1iiRW+k8e2Jts75/q+QBp3V+t51zkGbwXZiB1AwAgCgmk7rjOI2Q4FgTGcurOqtas9v9daz1MyLo
+1brjCOohFZ8QijaLVN9BCCEELlxIgloMRtHNdK7vnnRo5CpwyYgu7X/X9fnB+RxtWMmz6lOEEIKy
+2h/G8kbdcQW/lCRya7HQX9X5u/5rAuNGrdEMVmc0ircW8/ybuhPq6+CcB0ZwrcNzD54Vd+JEfFjX
+5we/BIAQY6RV69LDe8maUEoIJviis+2/OHpw3xEavjp9xiWfSMVupKm+Cx4hTLCsO6agn0bjaDed
+FbfrjAFzfLkrFXp9JCWfSIE/mD7NPpElrgjC4d+ygQaJvDE/LO/UHQdCz18CRYPWaAarNxpGO9PD
+9K733b7WAwASNQ7PfXaY70WJvBnmbjSHAzuru2XptMJb6hrFA3WlzExjJ4KfhPcAjFFHwoWn9yin
+JI7FzrOn+afg/Dveeag7pqCfhuP4VjYv79b1+VyyS5W2nZqz1DfW+plc2Op3TCBSuL/reflpkeup
+MS5c1xoCU0xEzD4ui/rncQAAEpS0qic9OL/xMN59dpDWWjW4ahYAMUYu1PHZea6nmNKEUhreMRrE
+A37Qtte+kOBYMyHZn02L107ZCpCUNPTE9Zx3Hoq8muapvpckYgzG/p88Le+kh8WnRVZNnbHhpSBY
+K5XInWyha0lyUM6IsZBBhx96u8o5D/pQf6pSePDupbf+b0/wYnMUf3xxY/jh71U83gD6Lcz038q0
++kKXBlxIeNSKc0qMs5tVzZstnAUkJW/EGs1gvcbjePfpwaKzSQ5wHlFGL637c41xkBbwnRA8vGM0
+DHhXtayAIyQ41k0oNikL88+2XhiddY+pYK3qwwqWx2gLxbzcK/Lq70IwPNxQHycJf5cyOhuMolvJ
+UH4oBB3byv9z8az4JJ+Xe0ZbcKG6I1gxSjFRiu6UR7Nh1owJesNZmNfx2cHZ6MJMaW7+15DzP709
+GkwEpxTACwDwGGPMGMVxJK797sLwrxcH8fX/YGoeGfS5Xei/FWn1UGsHoXJt/aJYTorMPHE1zkMg
+APthwGh/XRjHu0+n81pbI1cFnHk6BuUAACAASURBVLtfx2iZp4f5nWQgP1r7BwdvhBHSuGU9KqF/
+sAaRErtG28dC8bVnSM8N4/8mBLcv7uDMnPNQaTOzxn8pFf0PNZTXjg9Wo5zhIq00QggRQjAhCDFG
+r6uYIwfgwcJMZ/prAIQo85cZ5xe5ZCG5Giwd5YwA+Gu6MPsy4msdhCwEQ+W8/JKPo5vr/Nzg9Lzz
+UKbm/ljyCZXk/4oq/E8l2XWEECKCfuDAI/KrKxQhBAuBxkJEHw299wAeGQePsqJ6pJ31juMtxtkG
+52FA1TokI7k1n5WfjMdRPb36Di3CfNF+G8Xx7nSa3b1wIfm47liWySOUr/ur/XSafpEMwr2ziZzz
+QFt4sQsJjhpwyUg6Kx4wwS6SFh0BOAegJBVh8E8/GG2hMu4+9iiXMf84ismtV/7bYzoEAP/rifKU
+EEwFGXPBdsF778Eja91+dlgceIIHnNP3GcOI8pDwCJaDSz7RhUFVafaFWl+SA1NMjoaN0rBitLGq
+wkxp6b96a6huEkKwn+u/DceDvx7994wRVOrqM86iV54kYowxpRhRSi4rwS577z0AIF25/XxmDwoE
+AyLx+4wSREPCY2XigdxdLMp7o1G09hdMinEVnoX6jVJMkkjsHE6zu+MOJTmwR26dp/V5rqeEiz+E
+jUTNBACIi/qGzp5VSHDUJIr5DaPNfRmJ63XHclJgAcmYvVt3HMHq/FStoeErFbM/xom4fpKbDhXo
+8puargjGGD1/KbgmJb8GAB7Ao0rbz+zCVFTiTc7YVcYowhSHl4LgzGT0IslR2W+EYNfW9blcskum
+ct/SiIQ12g3jnYcqN/eHnE/kBr+FEELVovr07VF86/if45ySrKiqgff+pC+wzxMeFMURvRZH4hoA
+eAceFWX1WZrrChjexIxeZYwgGq5tS0MpJpyTq7o0+3KNyUznPESCh81hAaIUkzgSO4fz7O541P4k
+h3MAglG1rs8zxkFauodJolrzLtQ3AIBadBb/k5DgqAnljJTaADjwpCWnfc66+5S1JyETnJzRFqrK
+3cfoebVGnNBbb/5bP2OUjp1xjyklJ25fOtbO8pGPn5d8g3OPikw/AvCUcvqOEGQjVHcEZyEjPikL
+829nYUYZ2VjHZ1LOSJmXT6Vi74bT3eaoCjMlJXx1YRjdPCq1NaneeyuO331ZAtdTcgXAo7MO8j+6
+tvFB9NEIIeQceOv8LC/114W1yFFymXF6kctQ3XFeXPJJnul/E0ZmnNG1/J47C0gS0boTzWA1KMVE
+MbazyMt/DON2v6hbC4hzsrbv9r8P0zvj0fBUz5vBegEgpBRt3UBl+pf/53/8v3UH0VeU0t8Zbf/J
+OH277lhOBPz/UbG4UncYwXI450GX5rBMzf9inFAZ8Xel4lfOVCbowdsKvuVnHECLMcaEYEwpHQnJ
+LnPJfk8IVtb6b4uF3nPG5QB+ggnxbWrrCurFOH2rzPX3hBBOCF7LqZT3PsYIGUrJ2k7Bglcr53pv
+yDgaJOq9o/XmtjLTDSZyKdhLE7Le4yFx/gfG6WgZMRCCMaNERZJfHihxacDZiAH+1qR2T1f2/zMA
+/0kQas1hR9Nwwd7KF9U/uKAX17HCvjLOX5BiM5TUB0coJdg74JWDh4LTzbrjOStjnFeCb66jzfLH
+afpFEscfhsOAZqsq66VkuE3XuwdPZndDBUeNKCVEgx+3oWfbGQtStveiHfzMaAu6NJ8zTpFU/MM4
+IefOnlPOSJFW5TLiQ+h5OwthFDFGrynFrx0NK62K6ltnvT0aVhraWYI3iQdqK5+Ve2ogEKGrr+QQ
+go3LrPo757T15cptZrQFVLjbk0F06/iANOc8CIP3oiHffdXfZYygPK++V9HyB4H/1M5C6bVY/dyq
+V2p7f57rBWC8iWVoZzmtZCR3FrPib+MLyV/f/KfPhzh0nxDc6pP6YPmEYJNSW5QX1X4ciVa2KTrr
+9gkRK2/rTHM9ZWHuRisA+PsYodZc7x79uLjD4/jjkOCoWZSIS/lC34tHqtEPw8bALEraecEOEHLG
+QaXNY3D4exnTPyYj9eHSbyyvGDS6DMeGlX7kX2wwcMY9ztPye+yRoJJ+wBgJw0qDl4o31FY6L27H
+A7m76gcqTDFB3o8dgG/j5PEu0JneS7DA0Uj95mXXp/rOeDx47bR+SjE5Whe76u/LUTvLgNHrg0Qi
+APDG+lmpq28zY+xROwtjJCRz3yCKxc080/+IE7nSh3HsfR4OnYOXUZJNylKjvMT78RrnwiwLIK9X
+/d3WxkFRuodxmLvRCgAIteV6d3CY7RGhPsaY4JDgqBnGhGCCL1oDM8bX0yd+Ftj7PUxwo5MwwW/9
+olojlh9SSi6v6rNOMmh0GY5tMLgkFL90dAJqKrifL4oFZXiTS3aVMBpOQIOfDEbRzflhcWewoT5e
+dRk7U+yq0WHY6LodVW1ciKNblP02MaFTvfefG8mJ1ooSQT+Al6yLXTVCCJYCjaWIPhp59Xw7i4XH
+eWa+1wgEMP9OWEf7cpRTYpy7VGnzUEi+snsdR8iFsvrgVZSSk7zQyGD8kEu2su/hKmCPFqtO6j6d
+Fnc3NuKwErYlCIZFGy53B7NsT3v+NnvRERESHA0QD9SVdFb+jW3IlZdWnoVzAJQRvI7e1uD81lKt
+8RJnGTS6DMeGlV6PYo6cAw/OPdKZfgiAEOVkKwwrDRBCaDSOdudPizujzeiV7QnLwCUj2WH+Yxg2
+uj4603sJennVBkII6VxP31LR2ye9FjJGUKGrz4avWRe7asfaWS7F8udkbqnd/SzXC4PxJhb4alhH
++zOlxCTL9I+EUc9W0PprjYOREEuZzRJ0VxzJSZbrf3uMZkKwxh5eHuecB0LZSt8Lf3yafjocqpXe
+f4Pl8sijpj/HzNLyYenY25zT8dF/FhIcDSEk+7Op7Iw38EIIFpCKXj6MLWgOoy2Upfmcr6Fa42UI
+o8jk1ROEUK3fFUoJppRc5oJfBu+9B4+McftlVhx4ggec0/cZw6GdpadGm9FuNi/vJituCySCbjsH
+iDG6yo/pPWss+OzVVRsIPV9FOGbyRyHoiXvLOacky6tqEJ98Xeyq/bKdRSAA8Nb6WVFV3xal1gbj
+PxJOL4qet7MkidxazIs7443442X/2znwSDAahq0Hb5TEcjvL9NcYI8R5857tf80BIMFwvKqfP0/L
+h0yKl26uCprJOQdK8kYndLNCT2clyuWvqqVCgqMhhGKTxSz/hHF6ovLZdQJw+5StfuhQcHpH1RrO
+of9WMfvDYCP6sK5KG0oxKaxb2qDRZSAYY/S8neUaOj6sVLtvXWY1pf6PTIRhpX0TJ3InW+i7yVCu
+LMkhpBiXWXVvMAzDRldFL/TDGItp/IqqDYQQ8s4DzeFufEGduiTas/Oti101QggWAo2FiD4avZhN
+pK17XBTmYQmWAsO9bWcZJOrGYlHeG42ipf7+eQczqsj4zX8yCBBKErk9z/TeIMGI8/WsMT4rB4Bi
+wVeyDlQbB5VFeRS1q2Wn757P36g7ilfLCzN9msGPUv72HTUkOBpEKbFrtH0s1PInt5+H9/hp07e8
+9I0uDVTa3WOcJjKW76+7WuOVVjhodBleN6zUeyQop++EdpbuwxQTpehOmeo7aiBXUi5LKSYeIRWG
+jS6fNRYgg9sbkXqPc/raa1+VVfd+P07O9G/MGbtkKveYRuttuzuLo9lEMSWXYskvee+9c4Aq4/bT
+mf5RIzwkEr/fl3YWTDHhnO3o0uzLJQ57xNY/IBiHBEdwYqNEbs3n2d7owmDU5HuBM3ZGpFj6d9s5
+D2HuRjtZABQ1tGLNGAf/nlffRbF6aRtpSHA0CJeMpLPiARPsIiHNyJk5B6AiNqw7juD5qt5K2xfV
+Gvy/Bht85cMST2tdg0aX4VXDSm0F94u0nBOK3grDSruLckYA/DVdmH0ZrWbaPZf0Ouh2vCC3hV7o
+hzES02gob72p2lGneu8/knj7rFWRq1wXu2oYY8xerNqOI3ENALwDj4qy+izNdQUMb2LW7XW0XFJS
+5KUiFs84W06LAMU4bdhtN2iB0Sjemh+mtzfGg5Vv8jor8OgBJstP3j09zD4fjcLcjTYC8IjQ5i3A
+cM7Dg4Py78ng1a3GIcHRMFHMbxht7stINGJ9kq0sUiO5kpK14M2881AZiyrt7ommVWu8BKN07Fpy
+4vlrx4eVqpijo3YWnemvARCizF9mnF/kMlR3dAWXfKK1QVVp9sUKVvpxyUj2LP+et/AFuWmcseBO
+WLWBEEKmNNMLUmLOz95OsM51sat2dH3jg+ij4YvqNePgUVZUj7Sz3nG8xSjb4LJb1R1RrK6kc/2/
+hyPyP897eg7OA8e08QP3gmYaDeOb08P0zuTC4GOMm3c98YDTZZ+tztLioVDi3Sb+7w3ezIPdx5g3
+bkTBg3+nt5NB/NrFHCHB0TCUM1JqA+DAkwa0hXgPnxOCP6w7jr5pQ7XGyxBGkanqHzS6DMfaWXaP
+hpVa6/azwzCstEuk5BNdGFRV9hsh2NJv5ETRbefAhza/s9Np9TD2/ERVGwgh5KyDGMh3UczPvQGl
+rnWxq3Sseu2yEuzy83Y9QLpy+/nMHhQIBkjg9wXrRjvLYCT/spgVfxtfSM61qc4BoCGnoaI1OLPx
+MN59dpDembw1XPoA3PNwzgPBCC8zJq0NGIvD3I0WA0d0g76mCCGEHvx7cUcl0a03/bmQ4GggFcnr
+VVl9rhJZa2LBewBGqGn7yVVbeOehqtysquyelGwiY3m1ydUaL9PEQaPLcHxYqZT82lE7S6XtZ3Zh
+KirxJmfsahhW2k4y4pMy05kjZEbZcssxhRRjnVefx4N6r+dt5JwHu6g+34jku5yf/CGZ5Pb2aDxY
+ytr1JqyLXbWf1tFGv2xn0dren+d6ARhvYtnudpYoFjfTTH86SOSZ/x2dBSQjFSpag3MZj+PdpweL
+O2/9x6gxbRsAgJRgg2X9POc8TOfV34dLHvIbrJdHvlEteY8OsttMqt2TJOJCgqOBKCXEe/S7uk/9
+rAWkYrpZ1+f3hTMWqsLue4wPhWJbg0i1olrjlRo+aHQZjrWzfIQShJwDD849KjL9CMDTMKy0fVQi
+rxRp+bVQAi0zyUEpJhV43/XfiWUr8mqaAPluNIxPtRmqnFdf/H4Uv/F056SO1sUOk2X9xOb7qZ2F
+0euDRCLnwFvnZ3mpvy6sRY6Sy4zTi6xF62gpp8Q4+NN5ho568I8xbn91YlC/C+N4dzrN7l64kDQi
+AWABkGB0sqyfd3CY3hsMQ3Kj7TCCxqxJPzjM9hDlfz7pc1RIcDRUlIhL+ULfi0evHqCyaq5yj2ki
+VjJ8r++881BqM7MGnldrDOS1rpSwU4Eud62k+00oJZhScpkLfhm89+AAWQv7RVr+SDgaUkrfZ4K1
+9vSzL6KB2s5n5Z4cCESXOFiLKfaBq9xjoto3m2bdjqo2LkTyXa7YqU7bda4f/i6J/rDsRJJn5Erd
+Bw51en59Q2Mp4t3xUTuLgf08NQcagwCOP2CMoKavo1WKT7JM/0g5mTF6+pWdxPlnBOPwOxwsRRKJ
+ncNpdnfcgCQHOI+4pBeX8bNmM70nldwOczfazTkHjLFG5Amezcu9EtjbnNMTz9RqRODBb2FMCOPs
+qjUwY7yeCbYeoYeEhJv5MhltweqfqzWiWDSqD3MZGKVjMPAYMdrL7w7BGJMX2wuU4teOhpVWRfWt
+s95S6i8zwS+GdpZmijfUVj4v/64G4qNlvSg/Hzaafc8btgK8aXRhppHDp67aQAghUzm4wGV+kgGk
+p8UZbc262FX7qZ2F0mux+rldr9T2fp7reYXxW1jgq4w3M6GbJHJrMS/vjDeiU997BcaLUIUVLAul
+mMSR2DmcZ3fHo3qTHODcfULwuZcblKWZGu9xxHhYpdxyAAhxhuO640gzPc0MflsIdqrvVEhwNJiM
++GQ+yz8Zbrx5mMqyOQcgJeNde/mug3MeqmPVGmoor3X5IalLg0aX4diw0o/8i+0FzrjHeVp+jz0S
+VNIPGCNhWGmDxCO1Mz8s7gw2ltcuRiXtdRXA63jnoVpUn28o+S6PT1e1cfT3pYG/R8PVVDwyRlu7
+LnbVjtpZBi/aWQDAG+tnpa6+zYyxTWxnGSTyxvywvLNxIbp50r/jnAdFm3GaGXQHpZgoxnbSRX5n
+MIxrm8nhAVXnvTM55+BwUX0T5m50gwVAgpCltS2dRVbo6bPC/yjl6Te5hIt1wykptk1lZ1wsZ4f7
+SYEFFMXsnXV+ZtcYbaEy7j72qJAxvxHFpHPVGi/T1UGjy3Bse8Elofilo9NPU8H9fFEsKMObXLKr
+hNFGnn72yWgc7c6fFneGE7WU31su2CVdms/icww57CJdmCkr/VeTYXTzrInfKtP3fr8xWNlDdZfW
+xa4aIQRLgcZSRB+NvHrezmLhcZ6Z7zWyAhh+h3G2UWc7C6aYiJh9XBZmX0Unm8fhLCDFxYVVxxb0
+D+eUeO+vZUW1n0T1tIVjjPR5W0oOpvm9wTAOyY2OAPCIieW0LZ1Fqc30YAE/qkicabtdSHA0nFBs
+kh4Wdxina305BnD7lJ3tS9VnP1VraPhKxeyPcSKu9/KBuAeDRpfh2LDS61HMXwwrhZnO9NcACFFO
+tsKw0vqMNqPddFrcHpzipPdVKGdEZxaB977VQ4SXxDsPZWrub0g+kRv8zFWKOtV7bw+Tld8fu7gu
+dtWOtbNciuXPCd3KuP3FTB8YigeY4fcZXf86Ws4pKXK9SQyeCf7mAyQAQFySMJMsWAkh2KTUFuVF
+tR+vOcnhHIBgVJ3nZ8wO8z0Zqe0+HOL1BTh4jGsaU2CMgyeHZi+K5ZmrmkKCowVkwm8YbR+LNfZv
+Y0wOCCFb6/q8tjPaQlW5+xihXMb84ygmN/t8oe/joNFleDGsdMwF2wXvvQePjHH7ZVYceIIHnNP3
+GcOhnWWNkpH6OFvou8lQnvtkikfsA2dhTvjpBxx2SVWYKS39V28N1ZmrNhBCSJfVdCJVso62H8YI
+0treZ4yeu0+9r44ldH9aR2utn5VV9W1eam0w/iPh9KJYUztLFMtJNtd7dERG9A3fQwKwTzAOhz7B
+yijJJmWpUV7i/fiMm37OwlpAnJPhWf9+XuqpwwxLdvIBkEELePQM1zBU2TkPDw7KvycDda6WrZDg
+aAHOGcny4gcm2EVCVv/S7IwFJelo1Z/Tdr+p1hj0tFrjJfo+aHQZCMYYPW9nuYZeDPNzFmaVdt+6
+zGpK/R/DsNLVwxQTFYudZSQ5uGSkmBZf8vH5K0LaSi+qL4b8fFUbCCHkrIMhsIcqZmtJODxfF1ss
+kkSu4+N6gRCChUBjIaKPhi/mExkHj7KielSCpetoZ0lGcms+Kz8Zj6PXH0o4tAi392DVlJKTvNCo
+ROgbpU4/d+AsnrcinC2h4pyDNIPvkkFovewa8O7cc1nO4uG/0zvJ4Pyr3kOCoyVUzD8w2tyXkVj5
+w5y1fqZi+v6qP6etfl2tESd07UNgm44wikpdPRRh0OjSEEIwecmw0iLTDwE8pZy+E9pZVoNSTJSi
+O7ow+/KEPfuvgjm+3Mdho1VhpqSEry4Mo5tvOi0/CZLb28Px4K/LiO3EGN7s47/dOhybT3RZCXbZ
+H62jrdx+PrMHBYIBkatpZ4kHcnexKO+NXjMckWOs+1yVGaxPHMlJllcZIXgm1jB/D6x9TIg407Pa
+wbPiTjLsb8K+yzA6/1yW03rw78UdmailfJ9CgqMlKGek1AbAgScrfrjy4L4jlHy4ys9oG2ccVNo8
+Boe/F4r+j1Ct8XqUYgLWubrj6KrfDCv13oMDZCu4X6TlnFD0FuX0KhPNXNXYRpQzYsFsVqXZF+co
+H+aSXaq0vR/Fq09WN0U513sDJnB0zqqNI9Wi+vTt0flPeE6LMXY1rItdj5/md0Q/t7M48Kgoq8/S
+XFfA8CZm9Cpj5NzXOEox4Zxc1aXZly/53bbGwYiJUNUarE0SiytZpr/GGCF+ghkx5+HQ2VoRZof5
+XpTIXrdjd5VzHpZxEHEaP/y4+JRJ9fGykiohwdEiKpLXq7L6XCVyZckH7wEYoy4MwXvOaAu6NJ8z
+TpGM5YeUkst1x9QWmNCBA/Drvkj2EcEYE0YRY/S6ijlyAB7ssWGlzF9mnF/kMlR3nIeUfKILg86T
+5KCckTIvM9mDYaNGW0CFuz0ZRLeWdR0wqd57K47frSPBzBhFRVE9DOti1+9ofgcfRB+NEELOgTcO
+HhVl9bCwFjmOtxhlG1yerbqDSz7JM/1vwsiMs1/OyHkx8LnWdYlB/ySJ3J5nem+QYMRXOLcJe7Q4
+7fU0z/XUUZJISjt9D+srAEBc0DPPZTmtg1m2B0y+y5Z4Xw8JjhahlBDv0e9WWSJrLSAlaa9f4o+q
+NZzz/61i/odkpD4M1RqnxyV+34NHKLxSrx0lBNPn7Sy7R+0s1rr97LA4wAgJKukHjJEwrPQMZMQn
+Ra6RszCjjJzpoZMJeqPrw0Z1pvcSLHA0UktrI7GVmW5IiTkntQyzoxST0gENG6Lq92Ig82Ul2OXx
+UTuLgf18Zg40BgEcfyDY6dpZ4kRuZ3P998FIfnQ8IecAkJD1rUsM+muUyK35PNsbbiSIseXfL5zz
+QCg71bugMQ7SIszd6DIAQAyTtQycejYv90rH3uZ8uUNqQ4KjZaJEXMoX+l48UivZNe0q95gmZ+vF
+azujLZSl+ZyHao2lIIQgsPAtYjSs1qvRsXaWa1I+H1YK4FGl7Wd2YSoq8SZn7GoYVnpyUSwnRVp+
+LZRAZ0lyCMFQmVVfc05Xch2vkzUWfOZuX4ijW5QtLwngnAdh8F405OearH5emNM/hQ1RzXJsHe21
+WP18jSu1vT/P9QIw3sT/f3v3/h1FlfUB/9xPXfqW4MhIwHnWKJdRGdeoCOLfL4aIrPUi7zgxut5R
+AqNy6fStqs79/aFpCCGBTtLdVdW9P+tZzxovJEfodFft2vu75XTjLGlLXhv08m86a+mLwhxx6D4h
+eGVGykC1tFrJ5X4/+67dSb+YdWHVeY8Ew8lxfs3TvWyz2Uohe26JeY8Qi+a/Fns4Ut2RwakQbOYP
+LaDAUTMYE8I4u2iN7zF+sqeHb/kGv5GS9h6XYX+2hkzo3xrQrTEzhFFUjPQzcart6mDW9q1q/AKl
+41Zv79zDfKQeQljp9OJGdCUbFtsyFojS470XY4oJCqGzbIGVaqS2UzTbro2JMFSbnU6j9DA7zmkH
+1sVW2+Q9rsHo1UYqkfc+GBt6WaH+k1uLHCXnGafn2BHraONEfJWN1A9JKq8ihBAOIVvyaTJQca1m
+fK27N9xcX2vMLKMAoXGBI2bswrT//rO9bDttQKjosnPe9jCZfdFhvyw33We5fyylmMu2IChw1JCM
++fqwV3zD2nKmF5HOeR9JKlYhMEgVxmvlthinqUzkJ9CtMXuToNEQQliF11RdTVq9ueDnX4SVWr+T
+D4vHhKMmpfQTCCs9XNKILo/66v+JG/yfxy2MioRdNNr9TOP5PyWZN2ust0O3uZbGX7EZdm1MqKHa
+/ms7rUSYHayLrR9CCJYCdaRIbrwYZ7H+UTYyvyrkhWfhlXW0lFNinNvQyuwyxs6JQOEzDJSu00xu
+PHsy3Fx/p3l9Vq9HZ2yPSjHVjWyWqS5m7Cw8BFx+weMHGOO5FTiUcf7PgdmNYzm3BwVQ4KgpIdk/
+jLY9PsMVUt56JBP24ay+XtU4Y71W9pFz6Lco4R812vz6sof8lY1y2vAhIAq/zbWwL6z0UhTxS5Ow
+Up3rn50NltJwngl+DsZZXkpb8tP+Xr7ZaEfHej95Hjb6VEbswzrfPKmB2k2w6K61o7m0LKtCd9+J
+4mpdVMO62NraN86ykUi+8XKcxd3PMtXXGL+DBb7IOe/khX4cIRTWJG+UfW4AEEKo00luPH0y2Dwz
+oyJHCOgBJm+/kTXG+WHhdtM0gs61FeA9QvP6dHPO+f89U1txIuc6bgoFjpoSEVsf7uWbjNPZVXKt
+u0/Zcq0uDC54bSyCbo1yUAZBo3W2L6z0i0lYqTPuUTYsfsUBCQzjLAghhFqd+EZ/L99stqNjvR8T
+ji9ZF/qc4dqFjTpjvRv5b9tx9DHn8wmmNsb5JuK7QlRrHIQxdtFY94hSWBdbd6+OswjkvQ/Whl6u
+xkXdP7q9W6131j5WyvlJ7gohp19NC8BJrXWSG0+7/VvvrLdPXVT2Hg/JFB9Zj/eyb9utdOajh6Ca
+MHaDWY5C7ffrH9l3aTOZe5YWFDhqTKb8S6PsIxHNZmUdo2RUqadkpwDdGtUAQaPLY19Y6YaIXj75
+NNrfzwb5gDJ8hkt2kTC6khf/rU58Y/BsdKu5Pn34WiRFpxjp73hT1ipsVA3UboJEN27Km/PsPqGZ
+v91ciyo37/1iXayEdbHLhhCChUAdIeIvWiEKwuP/UIe61LvcWfTMeY+ccwMfcMAEoRBCEyGEKKUB
+E3yVEIIQQYg9r4ZAMQTMQytJbnS7o9tra+mpPjsIfvsI8dPu8F6zEUOo6IpwLvh5fe0Hv/dup83G
+Qq53oMBRY5wzMlL5E+bZOTJNCfYNnLFeSnpmVmcrQ3DBa+16WtttAd0alQBBo8trX1jp1TjhaDLO
+okbqP94jRDm5zBhpc7k63R2NdnJjNFC30ykLFi/CRr0PtAbF5ZddG/Jjztlc31tVX22+10lL3Zhy
+FFgXuxq8R6EpeRchRKTk1zF+NYA9hBAQQsiHgFBAKKCAQkDIO9+z2j0IyCPl/chZ5BBCKGBEMQoJ
+xgQRRi5gQtrjeghBhIyLIQghKIiAt6IUkzQW1/a6o9udExY5jHE+Erz1pn9nmKku4eJ9eJ9bHd57
+FMk3vy5O4uHjwSZPkoU9zIECR81Fkl81ytyX8elGS4zxvTgVtXzK7oz1Orc7AeM9EbHLjfh4s/Bg
+fijFxHsIGl0F+8ZZbvgQQvABGeN2Rnv5k0Bwg3P6CWMYLfM4C6aYRIm4dpwiB4vYRa/cIxpXe9wh
+z3Q39eSXdjOea9cGQgiZ2eUpEgAAIABJREFUodr+S5pcqfJ7BqyLXX5aW9SM5UfehZY2vi8FfWWU
+bPL6fC1jitGOROi1XIMwhsLzYggK4+KIsf4HZx02HinrvQoejcc6Q2hiTBAmaJ0wdo6gcREERmUA
+QuPrqyQW1/b6o9ud1vGLHNZ7JBhdP+qfK+N8XrjdBHI3Vs6sP3kfPx3eIyKa6Qagt4ECR81Rzkih
+jPfOB3KKwDMcwjYmuDZt0sEFXyjTs8ZvS8nWZUNegsC3aqIUgkZXDcEYo/E4yyUU8UuTcRat7Pdu
+ZBWl4W/LGlZKKSZRRK9lmf4hSd5eeOaSkdGz7FcWsXNVvKF3Lng70HfXYvkhj9gX8/5+pjDdtpSY
+czLXFXWnBetil5+3dkuk8joWGD/rZvelOF0GAR577e8Ljv6JEH/l770ohoz/9/MOEYSs9TveBnXY
+qAzGBGGGJEHkIozKrAZKMYkYuzbIih+ayfEKEd4FxCU9d9Q/fwq5GyvJeo9iwT6Z1dd70httayLe
+ZwvuAoICxxKIYnlVjdRW3IpOVKBwznvKCK5D18PBbo04ETMLWQXzAUGjYN84yythpflI7XofKF2y
+sFLKGaHebOjC7IiIv7UzjkT0inMeMUYXcbypqdx0Y4d/aTWTzxfx+eCs84knv8QJn3sh5bRgXexy
+M8b5iFM2ub7gnLxvnQuM0oVcbxxVDOGMXjr496YZlSmsz7xHdvzFg0QICUppQAS/D6My9cY5JUHb
+jVGud9J4+k5s79x9gtGhRZHHT4d3IHdjNXkf0ClTD17oDYvdwrGznNOFP7CAAscSoJQQRPA5Z32g
+7PgVMm89imJW2fbog90aUVNegnnA+oCgUbDfa2GlIQTvPLLa38+HRZ9Q9A7l9CITrNYX2FLydZUb
+NE2RQ4zDRrcaTVqJLrpJ10Y7kh/yZP5dGxNhZDZba836XFTDutilZbV91Enl55O/TmK5keX6brNB
+P3/TryvDPEZljPUKIfTWURkohlSDEGy9UBZlud5JpixyBI/0YZfS/WGxy6T4EK6zV1Pwdgdj/loh
+9bhGuer2CpRJOd+8rqNAgWNJxKnYyAfq27gVHfvi0Hu3Q5k49Yt51oyy3qpxt4aM+eU4IdCtUUMQ
+NArehGCMCaOIMXo12hdWqvPxmkbKwnnG6znOIuNxkcMa12OcHrkKllJMfEBRFUIrX3RtNOLPF3mW
+oq/vvddOK7cx5U1gXezy8sb/xujL9ceUYmK9Y1X4GT2tWY7KGG+Q9b7vfMCU4ACjMuWJJFsvCoWy
+Au8kU3QOhuD1wUwEZZzXFmVxXM5NKSifd0Sd9lYry0336cg/lrK8e0socCwJjAmhnF2xxvcYJ0de
+SB8mBPy0Kk+gnAteK9OzJvw7iuj/QbdG/UHQKDiOfWGlL8ZZrHU72aB4ghESVNLPGCO1CSuVMV/P
+h8V/MMaIsqPfm0VErzrlHpGSwkaDC74YmvtrUry/yK4NhBBSmdp9N41rl9QP62KXk1LOt1Lxt4N/
+P5Hyqtb2URSJlfnzPtWozPPCiHPhodOu+6ZRGUzwVTTpCtk3KgPFkOOJIrme5QoZjHf5G56cO+d9
+JPhr83VPu/ntdjupVaEZzFZAYXiaS3VjnP+zr3+Jk6jUUVMocCwRGfP1Ya/4hrXl1KFAznkfSSrm
+ea5pGGW9Nu4+DiiTCb8eJ2TuSf1gcSBoFJzEvnGWS1K+GlZqB0ZTic9wxi4SRit9IRw3oivZsNiW
+sUCUHl7kmISN8njxN8s6N11ahB/faUZfLbrIYLTzHSYzzmntnhhO1sVC8Xa5OGN3eDN67QZeSkq6
+e+qBlLySgcBlO2pUhjN0HiH02s/3wVGZ8LwoctioTECIYjxesYspXieUwqjMEZJYro8y9WfAqCcE
+O/TzxlqPOCfN/X/vz6fDO81mVMnV3GBxMPIn/jxzLvgHT4rv0sbJMiFnCQocS0ZI9g9dmIcimu4i
+2WqLopYsZab0RbeG8j9GCftbkoqrdXuCB6YDQaNgFvaHlaIUIed88M49VCP10HsUKCeXqxpWmjSi
+y1mv2I6aonXU+xyV5MIiMx0mXRttyddlmy88+yK44KXx3yXN8i+GTgpz+vcqBsSCk3EueBrwHj3i
+Z1RKeumwlbHg+E47KuNDQM5NMSpD2EWC0EqNyqSJvDIaqf9gjBDnrxc5vA+IiZdjLL1hvisiyN1Y
+dc45Lxg/8UD5r38ObqeNaoyaQoFjyYiIrQ/38k0up1s5GIK/SwheaIHDKOu1dvcxGndrJCmtT6gc
+OBFCCHLG/8wgaBTMEKUEU0rOc8HP+xBC8AEZ43byYfGYcNSklH7CGK7MOEvSji739/LNRju6fthW
+Ei7YhsrN3aQx/6LzpGvjTDP66qibubmfYaS23ms3alvcQAjWxS4brS1qJvzyUf9cCtEZDtR3UsS1
+ft3WzVHFEMTR9KMy1j1y1j0LyKPCjFfsjr/4q6Myk9yQuo/KpKm80h+p7UaKET+QAeWtfUTIeNRK
+KeONxZC7AZD3CFGGTtTV/+DPwWaSJpXpAIICxxKSKf/SKPtomi4ORqhZRMXWueB1rh5Zg36LEva3
+pAHdGquEMYoypZ/BQkUwLwRjjJ6Ps0QRv/QirFS5n93IWkrDeSbKDyttdeIb/b18s9mOXgtNppwR
+ndkw7yBDNdD3mrycro0XZxiq7Xcb6ZW6t/rDutjl4q3dEqk8snhBKSaEhnOwPae6jh6VoRsIoVeu
+iyfFkIOjMt75nvX+tzeNyhBGLmBC2lUelWml8nK/P9purTVa+wvZDqFnGOMN54Lv9vVmswUrYQFC
+1nsUMbJ23F/38MnoWyajG1X6PIcCxxLinJGRyp8wz86RNywzNsb6KKFn5nkWo6xXhbnLOEUykZ8n
+lECFeAVhCBoFC3ZYWKkz7lE2LH7FAQnM6QdljbO0OvGNwV52q9lJXruoZBH7zGn3iESzDxs1ynqc
+uc21Zlxa1wZCCKlCd9dllDJGXlthWUuwLnYpGON8JFj6ts+oKBIbhdb30ziCrp2am/xZv/ZH/mLF
+7slGZYJHr67YLXFUptVKLvf3ht+2O40bk8I5DmhACMF/PB3cbjTjSowUgPJ5HxCl7FjXHk/2RtuI
+8n9U7aE1U4X+JjgvEcJi/MOIL2CM2i9btBCaJBtjTCpRkQRvF8XyqinMfZmIIz+AnXaPaDrdvuzj
+cMZ5rcwj7/CvMqF/S1vRQtcNgmqCoFFQln1hpRsi4huTsFKj/f1skA8ow2e4XGxYaaMZ3xj1i9tp
+69X8CS4ZGXWz//Ipc5SmpUZqO8UCx+3jrxKfJWedb3q2GyVsaW4OYV3scrDaPuqk8pO3/XucUzIY
+KRXL+q+MBcdz3FGZSTHkbaMymCAUwvxGZVrN5Kvu3nBzfa1x3XscCGWs11PbMpJXDq6KBavLG/cI
+J9NfezzrF9uFZ2c5p5V7WMHaa8nXftKbhdCLFGOEEPLO7zgXVPAImcIOAn7+cwoFkcqjlJDCe++d
+D+SIp0oBoV1C8MwuyA52a1Do1gD7QNAoqIp9YaVX44SjyTiLGqn/jGdQw3nG+Tku59fdgSkmUSqv
+jQbqdtp8tSWecvL+rDoCjLIe5e7btSS+SVn5F7Iks982O42pN33VAayLXRLO/8rodNt84ph/po17
+FEkoaoHDvWHF7vFGZZx74JBHyvuRs8ghhFDAiGJ0YFTmQDEEoVdHZTrN5MazJ8PNRju55q3Gnkoc
+M165G1NQnoDwM4Snuy8cjFR3ZPBZIVglX0MMoeezy4dVJF/Zc/0yc+TQgohHyIfDCyLehibGCCGC
+EEb4E4Se//BBQWSuolheVSO1FbdeT6h3znvOyBGl6OlBtwaYFmMQNAqqad84y41JWKm1bme0lz8J
+BDc4n09YKaWYRBG9lo/UnTiVL3bGc8k2tLL34zd04E3jRddGK6pEQUEP9J2zrdfHcuoO1sXWn1LO
+N2Lxf9P++7Hk5Fk3+y8UtcAsvH1U5lVHjcrsW7F76KgMpfj8f/+/P76TSUr+cib60BjnyfO5mark
+hoDyBOeyae7gRrnqdvPwWEr+WudSVZwog+PIggh6vSASXpYlJzWRFwURa90PASEcPEJa2f7kV04K
+IpiggBC+ihAURE6CUkIQweec9eHgkztvPYrfkBT+NkZZXxR2i3PCoFsDTIMQigoLQaOg2vaHlUrJ
+L03GWbSy39uB0Yyj92cZVko5I8yHv6vc7Mh4vLaPckaKrBjJEMJh21bexhrrw6g6XRsIIVSM1O67
+SbK0awhhXWy9GWPu82Z8rIKilPQf1rrAGF3K1zSorpOu2EUBoV7E/9hTqFM80T+H4FQISFEcFEII
+URJoJFhCCA2pJC/GZNjz+y4ohCw3TJF728hSoUz3ycA/jmJR2eIGQgsIGcUvy5Kvf3NB//nyr6Ag
+Mg9JI7ow7OXfpu3olRAh790OZcd7cU66NZxDv0UJ/+ioVYcAHAZTTCaftPCUE9TFvnGWL0IyDiv1
+zj3MR+qh94HSGYSVcsnXVW6QLsyOiMZFDibol876Pjmw3u9t1EDtpkRkVenaQAghq013XciM8+Ut
+hI/XxTpYF1tDzgXPA8mPG7wbSdEZDtRWuwMrY0F17S+GZLnuNhvNs3lP/8YF/Qpj9urDTx9C4QMK
+DqGhdigEh7x3j1AIz3xAiOHQR+hlIQRhhBJJLlDK2oTghYangtlyLnhG2RvrAsY4//ue2Y4TWZl1
+sEep3BaVWRdEvEcYoXFBJLiAMcXh5chMkBiRiwjtK4i8+OFcnoIIF+yyNb7HOHlxoYwxeUIImaqD
+QxXGa+W2GKepTOQn0K0BTgojtAZBo6Cu9oWVnueCn/chBO88stbvZIPsCWXkDOX0IhPs2Bd3Mh4X
+OYwyu1zy8zLmJO/m/+ad6RLurbHeDt1mJ4k+4ny6HIFFcC54YfB23OSVvyA6jZfrYsXb/2VQKVqZ
+XvMEHa2UYoKJ7zjvQ5lbiQCYVn9o/t1oJV+vpS7p2dc7zsabFw++lA/PDCn8+L4rMwGFYFEIoRe8
+exAQQhiFAUEoUISQiGiTYIQko+tC0HOEYLR/tS6ldCnuterOe48Yx8lR/9y54B88Kb5LG1EtPssr
+V+A4rlkVRIIPPWf9b94jHFBQWjmFEBpni/jQxBQhhMYFkUkRpC4FERnz9WGv+Ia15dcIIeSM9ZGk
+rTf9Gmes18ru69bg0K0BTo0KchGCRsGyIBhjwihijF6KIn5pElaqc/2zs8FOwkqnHWeRMV8vcvMn
+sb5HGWljjs9PEzaqBmo3waLbacmvqtYdFYZqs9NprMQaQo9hXWwdWee2BX89q2waUSwvKqXvJ7Ay
+FlRcb5Dvxsl4i1YsRedxVmwxdrLuoyNGZDoIvRo4GUIIel8hBOV2fM/lwg8eeRx8yBhBFiGE4ueF
+EEaxjCW/SBB+EZgKhZD5894jhsmRU+S7fw4300Z9MrRqX+A4rjcURDpcHBHkM/4ftS6IyIh9pQvz
+UER8w9rQixL62iq04ILXxiKt3JaAbg0wB4wRZDW0cYPltC+s9IsQxuMs1rqdbFA8wQgJKulnjJE3
+hpVGMb+SDYttGQvEJdswyt6nR4SNOmO9G/lv23H0cZW6NibUUG3/tZ1WrugyL0LCuti6Mcb5hmDp
+SV+jglMyytQojmD0ElSXMc4ri7pJMr6mpxSTmAbq/XxXHb9hre4/9//luBDyvAPfItQv7HiJhQ87
+PjiF9uWExAxLwohgDMuYs4uTAgiBnJBT8R4hFpFDlwA8+HOwKdOoVg8qVq7AcVynLYhMVu4GH3rW
++gfBIzRtQYSQyf97Hhh6ClwyMuzlD5hg54J3vxCCP5/8M2es19ruOIeeRjF0a4D5IYQiZ82g7HMA
+MG/7xlleCSs12t/PBvmASnyGM3aRMPraxVjSiC5nvWI7agikrR2JQ8JG1VDvJoF346a8WcUbK1Xo
+7jtRfHZZQ0UPA+ti60cX9lGzGb32wOc4IsG/1Nr1pWTHyssBYFGe9tVWmr7apbSW8M/+zPwjUYFV
+xy/rIK99XFw6eKuqfQjIBxQUQv1iupyQZsQ/2R+YihDkhBzkvO1h8vrK1/89HtxhMrr+tvDRqoEC
+x4ydqCBycOUuOlAQ8W6kjHUIIeRcoAShBBGEkEfrmOBz0xZEZMK/1Fr/xCjVOOCgcruntd2Wkq3L
+WF6Ctlowb5hiEhAmEDQKVs2+sNKrccKRcz545x6qkXroPQqUk8v7w0qTdnR52M+/ZZxd2h82Ou7a
+cFvtWF7hnFWuawOh8dPCJuK7QqxWpxasi60fEsKD03aqxjEnz7rZfSlZZYJ9AZgYZborBL9y8D1J
+Sk58L/svkqz0AsdxnCgnZDAuhBzMCUHeI05IiCLaPBiYumo5IcHjBxjjV+5Tn/RG257JD1kNH1RA
+gaNkR7ZvHbMg4p1/6Fzovq0gMujlKkkZpxn5TkTscjOOrsOFGFgkjNCa9wFR2KwHVhilBO8PKw0+
+IGPcTj4sHhOOmpTST+KYXx8O1GZgjHJOr+eZ7qae/NJqJpXusqOZv91cq1c766zAutj6UMr4RiIv
+zOJrcU7et84FBh9soEKcC76fmx+bR2QntCL8frakq46PkxOyPzAVobfnhAhK1qVk55YpJ8QHp/eX
+MZ71i+3CsbOc09fuResAChw1c2RBhNHzCKHXnkIcLIjIhL832su/jVJxlVIC7ZRg4aigFyevSQDA
+OKwUPR9neSWsVLmfKaHhyR97OTXt79fS6AMesS/KPu+bqL7afK+T1iJlfR5gXWx9GG3vipb4/O3/
+5tslsdwYZmqr3YSVsaA6+lmxk0RHF5sbidjo9c1Kv1+dJCcktwiF4tVCyJE5IYcEplYxJwQjpCZj
+KMOR6o4MToV4fWSlDpxzHgocS+7gD24kOQ6twFWuf2eM/ikifmigDADzwhiGoFEA3mB/WKlV1tk4
+/ma9kfyLsWpu6powQ7X9lzR5rRV6lcC62HpwLnhOqJtVRgylmPjgI1gZC6pCG+eNxzoRR78eOaNE
+ODXyPoTx6Ac4ypE5IQcKIQiNc0KCCwi5VwNTQ3DqsJwQQmhIJblaVk6Ic8Hj5/9dWW66z3L/WEpx
+ad7f921nQsgj78d/7cdjC8iH8caXkXaPcu2f+YAQ8gg9Ldxg8uxUW8SgwLFiMMXEu0DTtrxkCtsd
+DdTtpCG+XOULUrBYEDQKwHRUbrrEoT/WmpGsfHGjMN22lJhzUssnPrME62KrTyvT6yTiy1l+zUTK
+q0bbRzQStco0AMvpaa/YbDTit44KrjX5l0+U7wtCoat7Rg7PCXk9MNX75+MxDqGhfpET8jB41/UB
+IYLDgCAUKELozTkhpyuEeO+RjFhLGef/HJjdOJYzewB5WKHC+0mxIqB+7na088oHhIz3ul8EFVzA
+mOKQaSQDxnJ8h0qCx/jq5PcVY7yBMN1ACCGMMEKYITwp0gkYUVlJjOO/e+eRjPk6c+HaaJDfitPo
+JlyMgUWAoFEA3i4fqe2I0tQTdDZh/K9ln+dNnAs+8eSXOOGVHp9ZFFgXW33WuW1KyUzHSaSkpLun
+HkjJz8FnGyjTcKi7MhIfTfM6FJwhOyz+IziMVy3aEYWQ8wi9GiB+WE6I968GphKEAkKH5IRMEZjq
+vUfeB/9koLbiRB46Yrq/ULG/m2JSqHg6dD8E5LEPCI20y3KDHELjnRsjg1uT/x0QlgGTiwjh5/+H
+L6HxKlGEERv/Pfa8V0a++rtznGQrKHCsIM5pxxn/M2P0IqWYNFrJ19mw2GaMNkQE6+3A/GEKQaMA
+HGW0V2w2E3GFMtop9opN1paVvvAMQ7XZWmseGmK3imBdbLUZ43xT8vV5FCGkpJe08X0p4Gk4KIdz
+wQ+V/anRmK5gQSkmTRE6GrrOKus4gamTnJDMBIQO5oT4MKJkXHiIGZaEE8EoltiHD/7cy03cTC4/
+/jP7f1zwGHmE9go3sGFyhlcLFR6RNYSfF/HHhYp/7i9U4H0jT2TfxOaiXmBQ4FhBlDOSjbI/Zfwy
+fyNpRJdVbp7lI/V9nMqZhG4BcBRKIWgUgIOcsV4PzWarFX9FMMbGOB9LMZcbsVkpBvree+10JTem
+HAXWxVabLuyjZjOaS/6YFKKzNyhuS5HAzwQoxd6wuJ8k8ljjV81IXvxjaH+mVEAuX41NmxMSQgg6
+IBRsQMgi9N9He/ef+Ogcy1AHI9xBmL4+9oFeLVRUfU9YpWd6wfwQRpve+1fuMGXM14Wg/xrsZbcO
+/jMAZmkSNFr2OQCoCpWbrlfubqud3JysgLXKPhKcVvaCU2Vq990ken9WQY3LZLIuFlQPCeHBvJ5U
+U4qJoOi8c3ANBRZPKec9ItFx35OloAQ5+zjAk6eVgDHGhGA8fh8MQTPpcQgPKKWYUIIJIRiTo9bL
+1AMUOFYUY+QT78YpvvtRzkizk9wsBvono8xuGWcDy28cNOogaBQANM7b4AE/TpLoRYZFcMFThx9Q
+Vs3igdHOd5jMOKcrHyp6mMm62LLPAV6llPHNRP5jnt8jisRGoTX82YOFe9YrNuPoZNsv1lN6BYqy
+q+dJX99nQv6T4BCWqcAFBY4VxShGRtudo/550o4ue4+SfKTuLPJcYDVMgkb9Er2ZAnAS2V5xJ2X8
+rIz4Kxel2hiUxnyuN2InFVzw0vjvkgNnBi9xTkmuNRRxK8Zoe5dzMtd8DM4pMdor6IQFi9QfFrsy
+ER+d9NfHUnS01luzPBOoNuec31MIE0qwYGQjLNFbFhnsZd8463tlHwQsFuWMWOv0m6p1z0dWPht2
+s2/ggxrMGqZobZneTAE4DueCz7r5rWZDfk4P6YIIhd+ivJpBhXqktjqNeKYrNpeRx/gMfHZWh3PB
+x4ziRYxUyYh9prV9NO/vAwBCzz9PTPhdcHbijjpKMYlpoPCetTqe9PV9wvknCCEkBN3w4fXO/roi
+rbXka2OMG/byWzAzuFoYJRfe9j5GOSONteTrfGTuWeOgEAZmBoJGwapSynTtUG+128nNw262jHE+
+4iIlFZx/VUO1/W4jvVLn2dxFEZJd1MbBTW5FaGV6SSQ+W8T3iiUnw8z8uojvBUB3kN1PInHqBQFr
+Cf/MGg/vWStgf/cGQghRwpA39ueyzzUrBCGE4kSuNzvxTav0bjZU30P1bjVQxjacnu7iK23KT531
+Lsv0D/M+F1gNEDQKVlE2VLvc4ceNZnTornmExuGiUtJPFnmuaahCd9dllDJGIHdjCoxRlEOWVWV4
+7X6kdHGT2XFEr1jr4HoazFWujMdUrM+iM0lKToLWv83iXKDa9ndvIIQQoZhgb9Wy5HC88k4fpdGF
+KBH/Kkbmnsr0DzAfv9wYo8hYP/XFl4z5uuTkYxhZAbNACEVWu2HZ5wBgUfK+2k44bxzM2zioiuGi
+zjrf9Gw3kux82WepC0oxcc/XxZZ9llWnlPNpwt9ZZOdRJEVnNIRMAzBfvb7+VorZvS83YwxbgJbc
+we6NCcnpmWUZHX+tlE0pJmlLfsoF+Tjrq+91bh7Ch/NywhQT7wI9TiHrxcjK0NyD7BZwGphiggjG
+UEgFyy644Ed7xWaaiEtv2zpilPNJFcNFR2az2ZBXyz5G3cC62Gpwxu5Eki905TKlmGDiO3CzCOal
+Nyx240TenOXXbMRiQxvYArTMDnZvTAhBLi5LDseRvXrjdaHRF4Ti94b9/BbkLywnxvHf/QkuvtKW
+/FRr4woYWQGnAEGjYNlZY70e6O/azeg6naKF2OVmi1UsXFQP9J132ulXZZ+jjmBdbPmcC56i8HSa
+n79Zi2J5UcHKWDAHxjivTOhSRmf6uuacEuH8yHt4+LSMxt0bPj/YvYEQQoSQpcnheOswIpeMtDrJ
+1955N9jLvoFK9HLhnHac8Sd6MceJXOecfDzYy2/ByAo4CQgaBctM5aaLNfq50YquT9Ma76zzkjFW
+pXDRYqR230niDxexeWIZwbrY8mltURrLE6/PPA3BKVHajaATGszas35xN47lXLKaWk16yTq/FE/y
+wasGI/MIc3noFjRKKcHeqkWfaR6mTluSMV9vrSVfW6V3RwO1CYWO5UA5I6owf57m1zc78c1iqO/A
+yAo4LggaBcsqH6ltgfEoit+ct7GfKewjGfFTJ+HPitWmuy5kxjmEip4GrIstl7d2S5TYFRVF/EsF
+K2PBDI0y3WVC/HVemTIxFx1r9H/m8bVBeZwL/o/MPaSHdG9McE6W4vPq2HHSURpdiFPxpcrMvTzT
+PyzDb8KqI5Q2T/vnmLSia0aZvsrNzqzOBZYf5YxA0ChYNqO9YjPl/KwQ/HjBbz78yioSLupc8MLg
+7VhOX6ABh4N1seUZr1ymrMy1xrHkJMv0f8v6/mD5DEbm37MMFj2IUkyaIkB+zJIZjNSR3RsTEaMX
+va9/DseJ9mVNgkilIB8XQ3MPgkjrjXHyiXenfzFHqbxACP5g0MtvQXAkmBoEjYIl4Yz1eTe/1WpG
+1yl7c5joQUY5n0rxt3md7bjsSG11GtH1ss+xDBijqIB1saWw2j5KIlF6VxTn5H3rYGUsOL3uIN+O
+k2imwaKHaUbyorNQmF0W03RvIIQQYQR5Y2u/KvhUC8EpZyRty0/HQaTFbQgirSdGMTLazqTzgktG
+Go3oRtZT38PICpgGpWgDgkZB3ancdL1yd1vt5OZJMjSscnc5pxvzONtxqaHa/msrnSo3BLwdpZg4
+7wM8CFo8b/xvjM42hPEkklhujDJYGQtORxvnjcd6EWvEpaAkWPPrvL8PWIxpujcQGudwIGdXs4Pj
+oHEQaXzDO+8G3dEtuLGtF8oZsdbpWV18YYpJoxN9YZTu6wJGVsCbYUo3lqEdDqyufKS2ecCPkyT6
+4iS/3lnnI0JQFYI8VaG770Tx2SqcZakwegnWxS6WUs630mp0RVGKSUA4cjDWDU7hWa/YiqWYS7Do
+YdZSesVa6Dyqu2m7NyY4J6eOLijbTAocEzLm66319KbVpj8cqNswu1UflJIzs34tR2l0IWB0ZjRQ
+t2EEARyFMYyscbXTyQqjAAAeHklEQVRvhwOrKdsr7qSMn5XRybMqqhIuaozzTcR3hTjeeA14O85p
+xxi3FOv36sIZu8MFO1f2OSZiwa4avRwrGMHijTLdFVJcWWRnXSRYxyhzd1HfD8zHtN0bEzGnn9S9
+s3qmBY6JKJUXGqm4Zgu9C0Gk9cAYu+jmEIImJV9PEnFt2CtuQ2cPOMw4aLT+7XBgtTgXfNbNbzUb
+8nPKT1kQqEi4KM387WYirpZ9jmXEOSWjU2wsA8fjXPA04D1aoU4kKSnJC/MURpXAcTkXfD83PwrB
+Flp85oySiPkA93H1ddzuDYTGORzO2FpvOJxLgQOh8ZhC1Igu7Asi3YGn+NXFGEXG+LmEoGGKSasT
+39CF/h+MrIBDYSLh/QHUhVKma4d6q91Obp52lKMq4aJqoO6804lvlH2OZeYxegduFBZDa4vShF8u
++xwHSUkvaeOhoA+OpT/MdtIk+qqM772W8M+s8RA2WlPj7g0xdfcGQuMcjuDsYF5nWoS5FTgm9gWR
+fjDqF7d1YR7O+3uC48MUE+dCmOdNZtyIroQwHlmBJxhgP8bQ2bq3w4HVkA3VLnf4caMZzaQYYJS9
+X3a4qBmq7b8kyYcQKjpfQrKLxsHN7SJ4a7cEp+2yz3FQEsv1Yab+XfY5QH0o5bwNFJeViyQlJ0Fr
+GCOuoRCC/z1zD+kJgpY5Q406F+TnXuCYmASRIoTiwV72DYwrVA/n+NK8bzJlzNejRFwb9IrbzsFr
+AIxB0Ciog7yvthPOG6fJ29jPueAlwXmZgZ6mMN22lJhzArkbc8YYRXmu/1P2OZadMc5HgqVVLdgJ
+is5DRh2Y1rNBsRlF4mKZZ2jGGF6zNdQf6kfkmN0bE7Hgtc7hWFiBY0LGfL21lnxtjHHDfn4LfmCq
+g3PasXr+IWj0+ciKyvXvMLICEIKgUVBtwQU/2is200Rc4qfN29jHKN2L5ckuPmbBueATT36J5WwK
+NuDNYF3sYlhtHyWSL2zTxHFFkdjICv192ecA1Tcc6q6MxEdlF+sasdgwRtc6k2HVhBD8/0b2RN0b
+CCE03hZb3xyOhRc4JuJErjca0Q1b6N1sqL6vcxvMsqCcEV3YJ4v6fkkjuhwCOpOP1PdwwbfaIGgU
+VJU11uuB/q7djK7PPLBQhx8ZP9nFxyyEodpsNU622hacEKyLnT/nf2UnvKhfBM4pcdYjuO4Fb+Jc
+8ENtfxJ8scGih+GcEub8CK7V6+M03RsIIUQZJcjW97q8tAIHQi+DSKNE/KsYmXsq0z9A0GC5MCXp
+Ij90ZczXRST+NRpAN8/Kg6BRUDEqN12s0c+NVnR91k/QjHY+jcoLFy0G+t5f2mkpoXWrDNbFzpdS
+zjdi8X9ln+Nt4kh8prWF4EZwpO4gu5/E06/2nLd2Si8ZCxlCdXDa7o0JxlCzroXYUgscE5Rikrbk
+p1yQjydBpFAlLAfj5JNFv5YpxaTRSr5Wuf4JQmhXFwSNgirJR2pbYDyK4vmMb5jC3meCnpvH134b
+lanuu0n0fpnZH6tqvC5WPy77HMvKKH2fC1bKz9VxSEnJMDO/ln0OUE1KOR8IO1Ol9+hYio41kCFU
+B6ft3piQjJ2v63V5JQocE5SPg0gJwe8Ne/ktaxyEUC4YoxgZZUuZDX0+shLnI3WnjO8PykU5g6BR
+UAmjvWIz5fysEPz8PL7+JFx05iMvUzDG+Q6Tj2eZJQKOx2N8pq5PxarMueA5pqX8XJ1EHNErWsN1
+Lnhdt198G0tR6natgyjFpMFwBN3W1Tar7g2Exh2H3tez47BSBY4JLhlprSVfe+fdYC/7Bn6YFody
+RqxxuqzvL2O+LgT9bLCX3YILwNVCCIKgUVAqZ6zPu/mtVjO6Ttn8CgBlhYsGF7zU/rtkRltgwMnA
+utj50Mr0mgm/XPY5phVJ0ckzeCIOXtUbFrsyFh+XfY7DtBJ+1VkHo1UVNqvuDYTGORzemIVlM85S
+JQscE5ONK1bp3dFAbcIN72JQRs6UWVSinJFmJ7lZDPRP0MWzOiBoFJRJ5abrlbvbaic3yZwT67FG
+P1K2+I9fPdJbnUZcmZnuVQXrYufDOrfNOG2XfY5pUYoJZqEDD/HAhDHO5yb8zisQLHoYKSgJFkar
+qiqE4P8Y2Qez6N6Y4DjwOt5/V7rAMRGl0YU4FV8WI3Mvz/QPdfyNrhPG2EVnyq/QJu3osrPeZZn+
+oeyzgAWBoFFQgnyktnnAj5Nk/htFjHY+ivg7i177p4Zq+91GcqXsdYMA1sXOgzHONwRL6/b6jqS4
+qDSs3wRjvVFxP4nE52Wf403aklyw1sF7VwUNM9MLVPxjll+TC/73On5U1aLAgdDLIFIpyMfFSN/R
+OQSRzgthFBnjd8s+B0LjLh7JycfDbvYNFLaWHwSNgkXL9oo7KeNn5YLGNqy2O0LQi4v4XhOmMN11
+GaWMkUo+FVxJjF7yHtbFzoou7KNYik/KPsdxCU6J0g7WbwKU5bqLqVivUrDoYZKEb1hjSsnqA2/2
+R1//m804X0sw2vHO1y6HozYFjgnKGUlb0TVC8XvDfnEbRhhmj1JMnAuhKk/SKWeksZZ8nY/MPfjz
+Xm4QNAoWxbngs25+q9mQn9MFBW4GFzxDaG+RIYjOOp94+ksk2VwCU8HJcE47WtczvK2KSAgPKK32
+jeFRooh/qWBl7MrrD82/paj++zRnlEhsETx0rJbBSHcdkzPPbqGMIG/qt/mrdgWOCS7HG1deBJFa
+Dze+M8Q5vlS1J+lpU35qjHUFjKwsLQgaBYuglOnaod5qt5Obi3xappTuJVIsNgRxZDZbDTn30Rtw
+PLAudnaUMr6RyAtln+OkYslJlun/ln0OUJ7eIN+NE3mz7HNMay2Vn1kLQclVMo/uDYQQwhgTjoMI
+vhoPvadV2wLHxIsgUq37w4G6DWFNs0Ep7ThTvadLcSLXOYysLC0IGgXzlg3VLnf4caMZ3Vj4N9dh
+m7HFhSDqgb7zTjv9alHfDxwPrIudDaPtXcFJpVZqHhfn5H3rINdgFRnjvLKoS9nsgiHnTUpOgtL/
+LvscYGxe3RsTXPC/+1CvkcraFzgmojS60EjFNV3onyCI9PS4ZETltpKrgV6MrAzNPejcWUIQNArm
+JO+r7YTzxqLyNvYzxvlYivVFhSAWI7X7ThJ9WPV57lUG62JPz7ngOaGu7q/zJJYbo0xvlX0OsHjP
++sXdOJa1y49pxvg8PFSuhnl1b0wIRjvB+VqN0S1NgQMhhDDFJGlEl6UgHxdDc08XZgdulE4OU5JW
+uVCUtuSnRpm+ys1O2WcBs8M4BI2C2Qou+NFesZkm4hJfUN7GQVbZHSEXEy5qtemuC5mV9d8KpgPr
+Yk9PK9NrJaL2q48pxSQgHLkKX3OB2RtlusuF+LBu238QQqgRiw1rTOU6vVfNvLs3EJrkcJhKLJ+Y
+1lIVOCYoZyRty08JwR+M+sVtXZiHZZ+pjhjDn1T9szZK5QXG8AeDvfxWlYsxYHqUQdAomB1rrNcD
+/V27GV1fZLjnfosMF3UueGHQT7FcfJcKOB5YF3t61rltSpfjUjYW7KpScMO4KpwLvjcy/xGC1bIQ
+zTkl1Lmn8P5Vrnl3byA0zuEgOIQ65XAsx6fCESZBpAihGIJIj48xgoyylV8FRTkjzU58sxjqO/Bn
+XH8QNApmReWmizX6udGKrpf5hEwZ20vEYsJF7UhtdRpx7Z9orwxYF3tixjjflHxhY1/zJiUlSlm4
+YVwR/azYSZMSsqBmqJ3SSxA2Wp5FdG9MCEY26pTDsdQFjolJEKkxxkEQ6fQoZ8Qap8s+x7SSVnTN
+KN3XBYys1BkEjYJZyEdqW2A8iuIKdDIUbpvy+YeLqqHa/msrLbWYA44H1sWenC7so0jwhYx9LUok
++ZfawA3jstPGeeOxpqze2TGxFB1jYMyuLP/b0z/Ou3tjQgi6UaccjpUocEzEiVxvpOKaLfQuBJFO
+h2Jypk4FoSiNLmCMPxj08luQv1JfhBAJP5/gpEZ7xWbK+Vkh+Pmyz2KM85EQKZlz0UEVuvtOFJ+t
+e9jiqhmvizV/ln2OOiIhPKB0uV7vcczJMFOwnWLJPesVW7EUtQsWPYhSTBoMR3W6T1gWw5HuBiE/
+WtT3o4TVKodjpQocCI2DSKNGdEEK8nExMvdUpn+AG+GjMckuhprlIXDJSKMR3ch66nsYWaknwtBZ
++KkEx+WM9Xk3v9VqRtcpq0bAplX2kRR0rheyxjjfRHxXiGr8N4Pj8Ri9AwXd41HK+GYi/1H2OeZB
+UHQeVsYur+FQd4UUV5al066V8KvOuto82V8Wvy8ge2M/Qp/ncNTknnnlChwTlDOStuSnXJCPIYj0
+aIRRpApbu/YzTDFpdKIvdKH/ByMr9UMZ23AGPjDB9FRuul65u612cnPe3RLTCi546vCDebch08zf
+bibi6jy/B5gfJiisiz0mo+1dzsncx77KEEViIy9M5fPPwPE5F/xQ2Z/qGix6GCkoCdb8WvY5Vslw
+gdkb+wlGNuqy5XBlCxwTlI+DSAnB70EQ6esoxcS5EOra5RI3oisBozOjgbpd1/+GVUQIQs75/5V9
+DlAP+Uht84AfJ0n0Rdln2U8bg9KYz/UpsxqoO++Mw7RBTQnOYF3sMTgXfMwoXtZxLM4psc5x6OpZ
+PnvD4n6SyKULgW5LcsFa6DpalEV3b0wIQTd8TXI4Vr7AMcElIy+CSHv5LZgne4kzVJuK3WGk5OtJ
+Iq4Ne8VtKGDVA+WMGG1rE3ALypPtFXdSxs/KqAJhogeEwm/NM1zUDNX2X5Lkw2VpdV5VsC72eApl
+ekkkPiv7HPOUSHlVa1uLGwkwHaWc94hEy1iYSxK+YQ10HS1CWd0bCD3P4XDu9zK+93FBgeOAOJHr
+zU580yq9OxqoTaigvxgXqHXKO6aYtDrxDVXo32FkpR4wYQ34+QNHcS74rJvfajbk57SEJxlv46zz
+EZ9fuKgpTLctJeacVO6/HZwArIudnnY/Urrcl69SUjLMzK9Q9Foez3rFZiSXa+vPBGeUSGyR9/B6
+nbeyujcQGudwYG9VHd6XlvsT4hSiNLoQp+JLCCIdd7eo3D4p+xyzkDSiyyGMR1bq8AO6yqhA5+FP
+CBxGKdO1Q73Vbic3q/o0TBf2kZTzCRd1LvjEk19iWb2uFXAysC52Oko530jFO6vQtRRH9IqBlbFL
+YTjUXZmIj5b5ddtO5GcWsoTmqszujQnJ6Zk6dPVDgeMNKMUvgkizvvpe5+bhqt4UY4yXZh5Uxnw9
+SsS1Qa+4DaNI1cUo7UDQKDgoG6pd7vDjRjOqdO7EPMNFw1BtthrVyhsBpwPrYqfjjN2Rgi3lU/CD
+Iik6eQbZLHXnXPBD434RfHmCRQ8jOEOhgBXH8/TnwPxYVvfGhBDkog/V364JBY4pUM5IsxN9QSh+
+b9jPb1njVi7HgQny2ZLUNxBC4+JVqxPfULn+CTboVBMEjYKD8r7aTjhvVDFvYz+jnE/mFC5aDPS9
+v7TTr+bxtUG5YF3smzkXPEXhKa1o19asUYoJoeEcPIipt+4gu59E4vOyzzFvlGKSxngdXq/zoZTx
+mvD3yz4HIQR5YyvfbQgFjmPgkpFWJ/naO+9WbeMKYwRp7e6XfY5Zez6yEucj9f2qdudUFeWMWONU
+2ecA5Qsu+NFesZkm4hKvYN7GQVa5u2wO4aIqU913k+j9qo7lgNNhgl6EFu+jaW1RGsuPyj7HIslI
+bBRaL92116rIlfGBsDOr8p7disVFa0zlb37r6Pe+2mKcbpR9Dkopwd5W/tocChwnIGO+3lpLvrZa
+90cDtbkK1UrKGXHaDso+xzzImK+LSPxrNIDtOZWDaROeaK42a6zXA/1duxldr8OTW2edjwhBsw4X
+Ncb5DpOP61DgAScjOEMZrIs9krd2S8xxK1EVCU6J1m4ED2DqqdfX38ZSlH5TuiicU0Kdewqv19lS
+yvg8iPNVyXDhnJyp+rU5FDhOYRJEqkf6pzzTP1T9D/u0KK7+C/qkKMWk0Uq+VkP9k1Fmt+zzgDEI
+Gl1tKjddrNHPjVZ0vSof7G9jCvtIRnym7cjBBS+1/y6p+GgOOB1KMdGwLvZQxjgfccrq8j4wS1HE
+v1SwMrZ2esNiV8ai1EDIMrRTesk52Ag1S1Xp3piIGL3ofbVzOKDAcUqUYpK0o8tSkI+Lobm3zEGk
+TLKL3lX7BX1aSTu67D1K8pG6U/ZZAASNrrJ8pLYFxqMortlNvQ+/shmHi+qR3uo04i9n+TVBNVFY
+F3soq+2jVcgxOEwsOcky/d+yzwGmZ4zzyoQuX/Jg0cPEUnS01ltln2NZVK17AyGECCMoOLtT9jne
+BAocM0I5I2lbfjoOIi1uL2MQKWEUqcIuffusjPm6EPSzwV52a1k7VuqCMIqc9b+XfQ6wWKO9YjPl
+/KwQ/HzZZzkOo5xPpfjbLL+mGqrtdxvJlSpd3ID5gXWxh/PG/8YoXdmfASHoP6x1cD1SE8/6xd0o
+EnNZE151lGKSUh/B9fNsVK17A6FxDkcw1c7hgALHjI2DSOMb3nk36I5uLVMQKaWYOBdWon12vDkn
+uZmPzL1lLFbVBaWYWOuKss8BFsMZ6/NufqvVjK5TVr+sCavcXT7DCxFTmO66jFLGSO1+L8DJwLrY
+1ynlfCudbeGwbuJIdEY5PBWvgyzXXSbEX1clWPQw7URctdB9e2pV7N6Y4JxUOiMPChxzImO+3lpP
+bxpj3HCgbi9LeCVnaKPCr+eZS5vyU2e9yzL9Q9lnWVkQNLoSVG66Xrm7rXZyc9YBnYvgrPOSEDyr
+i1pnnU88/SWSrFZdLOD0YF3sq5yxO1ywc2Wfo0yUYhIQjhy8LiqvPzT/lmK137el5MQb89+yz1F3
+VezemIg5/SRU+O0IChxzFidyvZGKa7bQu8sQREoZ23BmtdpnZczXJScfD7vZN3X/86sjCBpdfvlI
+bfOAHydJ9EXZZzkpU9hHUcQ/m9XXI5n9ttWQtf39ACcH62Jfci54GvBeHTYozVsSsatKwQrOKusN
+8t04iW6WfY4q6ETkfRirOrkqd28gNM7hcMZWdoU1FDgWAFNMokZ0YV8Q6Y6v6ZgHYxQpZR+XfY5F
+o5yRxlrydT4095Zp7KgOGKUdp6HVcVlle8WdlPGzsu4bQmz4bVbhokVf31tvJXCRvKJgXexLWluU
+Jvxy2eeoAsEpUcrCCs6K0sZ5ZVGXzjhkuq6ShG9YY74v+xx19XtfbVFWze4NhJ7ncDg7KPscR4EC
+xwLtCyL9YNQvbuvCPCz7TMeFKSY4YLGqnQxpS36qtXEFjKwsDGEUOQdBo8vGueCzbn6r2ZCfU16/
+vI39jHI+jWaTEaAytftuGr2/yvPbqw7Wxb7krd0SnLbLPkdVRJJ/qQ1091TRs77aimO5ksGih+GM
+Eu699R7ex47LGOdzzy8QUs3ujQnOUKOq94NQ4CjBJIiUEPzeYC/7pm4dAUyQzyr6el6IOJHrHEZW
+FgaCRpePUqZrh3qr3U5uLsONvFH2Phf01BkBVpvuGpcZr3nBB5werIsdX+RHgqVVbdEuQxxzMszU
+v8s+B3jVKNNdIThsuzpgrcm/hHG743u0l29RXv3coVjwyuZwQIGjRFwy0lpLvjbGuGE/v1WXIFLG
+CLLaVXbuahEmIyvFUN+pW4GqliBodGlkQ7XLHX7caEY3yj7LLDgXvCQ4P22hxrnghUE/xbLmozpg
+JmBdLEJW20eJ5PBE/ADB8HnrINugKpwLvp+bH4VgUJg+QHCGglL/b9nnqJO6dG8ghBClBDlbzRwO
+KHBUQJzI9UYjumELvZsN1fdVv5GjnBGjqzt3tUhJK7pmlOmr3OyUfZZlBkGjyyHvq+2E80bt8zb2
+MUr3Yim+PO3XsSO11WnEp/46YDnAuliEkPO/Mkorf5G/aJHkG3lu7pZ9DjDWH2Y7aRJ9VfY5qohS
+TJIInanLA9wqqEv3BkIIUUYJsraSHTpQ4KiISRBplIh/FSNzT2X6hyoHkVJMzlS9ELMoUSovMIY/
+GOzlt6r8Z1ZnEDRab8EFP9orNtNEXFq68QsdfmT8dDdhaqi2zzbT69DeDPZb5XWxShnfiMX/lX2O
+KuKcEusdW9XXRpVo47wNdGbrwZdRO5YXrYHtP9OoU/fGBGOokh3WUOCoGEoxSVvyUy7Ix1lffa8L
+87CKQWNE0IvehUpW7cpAOSONZnQj66nvYWRl9iBotL6ssV4P9HftZnR92VY9Gn36cFFV6O66jFJK
+l+v3BpzeKq+LHefa1OMpZhkSKa9qbaHoX7KnvWIzisTFss9RZZxTQp2D7T9TqFP3xkRVczigwFFR
+lDPS7ERfEILfG+7l31rjKnXTzDhDSluoyO6DKSaNTvSFUbqvCxhZmSUIGq0nlZsu1ujnRitayu4E
+q+x9dopwUWOcb3q2G0l2fpbnAsthVdfFOhc8pzRftoLoLElJSV6YB3DTWJ7hUHdlJD5axs+2WWun
+9JJzqx2a/DZ17N5AaJzD4X318qKgwFFxXDLSWk9ueufdYC/7pipzbJRi4kww8OH6uiiNLmCMPxgN
+1G0YWZkhCBqtlXyktgXGoyhenryN/ZwLXmB8qpswmvnbzYa8OstzgeWxqutitTK9ZsQvl32OqhOC
+XjKwMrYUzgU/1PYnwSFYdBqxFB2t9VbZ56iyOnZvIDTO4fDGPCn7HAdBgaMmZMzXW2vJ11bp3dFA
+bVbhRo8ztFGBY1QSl4wkibg27BW3YWRlNqhA5+H1Vg+jvWIz5fysEHxpOxNOGy6qBurOmfZybJIB
+87OK62Ktc9uM03bZ56i6SIpOnq1eh08V7A2L+0ksIRR6SpRiEtNAq3DvUkXGOF94ltate2OC48Cr
+9mcLBY6aidLoQpyKL4uRuZdn+ocyX1CUsQ0Ifjwappi0OvENXej/wcjK6TFKO976yrXBgZecsT7v
+5rdazeg6ZUsWJnqQDtuUnewj1AzV9l+S5EMIpgNvQ+lqrYs1xvmGYCm0/b8dpZgQGs5VpbN3VSjl
+vEckgvfv41lL+GfWeLhnOMSzYXGfcFbbldhc8L9XrdEQChw1NAkilYJ8XAzNPZ2XE0TKGEVK218X
+/X3rJm5EVwJGZ0YDdXvVWo1niTCKtPHPyj4HOJzKTdcrd7fVTm6SJb85Mdr5OBLrJ7kJM4XptqXE
+nJPlLgCBmXietVC59t950YV9FEtR2wv9RYsisVFofb/sc6ySbr/4No7EUo5ezpOUnDij4J7hAGOc
+39P13sQjGO14V60HkFDgqDHKGUnb8lNC8XvDfnF70UGkmGKCAhZVa0uqIin5epSIa4Necds5GFk5
+CUox8da5ss8BXpeP1DYP+HGSRF+UfZZFsNruCEGPnZzvXPDS4e1YLmcuCZiPQEm6Kp+zJIQHsFFo
+epxTopRT8PBkMXrDYlfG4uOyz1FXaxG9YK2D1+o+de/eQAghygjyRj8u+xz7QYFjCXDJSKsT33gR
+RLrAzAfG8d9X5Lrr1OjzkRWV699hZOVkMKENBy+4Ssn2ijsp42dltBo37cEFzxDaO0m4aBiqzbVm
+DLkb4Fgww5+swrpYpYxvJPJC2eeomzjmnylYGTt3zgWfm/A7h2DRE0sSvmGsgY6j55ahewMhhDDG
+hOMggq9OoRUKHEvkRRCp1v3hQN1exFwm57RjtYM3q2NIGtHlEGBk5SS4xJXct72KnAs+6+a3mg35
+OeVLnrexj1K6l0hx7A0PxUDf+0s7/WoeZwLLTXCGcm0q1f47D0bbu4KTjbLPUTex5CTL9H/LPsey
+6w6y+0kkPi/7HHXGGSXC+ZGv0I1wmZahe2OCC/53H6oTiA0FjiUUpdGFRiqu2ULvzjuIlHJGdGEG
+8/r6y0rG45GV0SC/BQFh0yOEIAgaLZ9SpmuHeqvdTm7W/cnDsemwzdjxNjyoTHXfTaL3V+73CswE
+pZgo45Z6LbtzwXNCHfyMnIyU9B/Q+j8/uTIeU7EOr8/TW2vyL1ehI+1tlqV7Y6JqORxQ4FhSmGIS
+NaILL4JIC7Pj53RxxCg9syrzwbNEKSaNVvK1yvVPujAPyz5PHUDQaPmyodrlDj9uNFdvxakxzsfy
+eOGixjjfYfIxX6EuFzB7hJKNZV4Xq5XptZKTr11edZEUnVGut8o+x7Lq9fW3UrClXXu+SIIzZA2s
+N16m7g2ExjkcwZjKXJ9DgWPJvQgiJfiDUb+4PY8baSLoRe/CyldjT+r5yEqcj9T3ZZ+l6iBotFx5
+X20nnDdWJW/jIKvsjuDTh4sGFzwv/Gayor9fYHYYYxvaVOfp2KxZ57YphUvSk6IUExx8BzKqZq83
+LHbjRN4s+xzLglJMmiJ0Vrl7edm6NxAa53AQHEJVcjj+f9rU8LajhRHrAAAAAElFTkSuQmCC
+"
+ height="1061.5347"
+ width="597.11322" />
+ <g
+ id="g3310"
+ transform="matrix(1.3814851,0,0,1.3814851,-594.7198,-687.84793)">
+ <g
+ id="g3333">
+ <rect
+ style="fill:#ececec;fill-opacity:1;stroke:none"
+ id="rect3887"
+ width="199.00003"
+ height="29.799492"
+ x="458.19833"
+ y="1199.1094"
+ ry="8.3438606" />
+ <g
+ id="g3672"
+ transform="matrix(0.1688388,0,0,0.1688388,406.15055,1151.9632)">
+ <g
+ id="Layer_9">
+ <path
+ id="path3639"
+ d="M 313.25,252 H 265.3 c 1.047,-0.933 2.105,-1.85 3.175,-2.75 H 313.25 V 252 z m 0,61 v 18.75 h -80.5 V 292.3 c 1.324,-2.403 2.724,-4.778 4.2,-7.125 V 313 h 76.3 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#94c061;fill-rule:evenodd" />
+ <path
+ id="path3641"
+ d="m 232.75,292.3 v 39.45 h 80.5 V 313 h 3.7 v -61 h -3.7 v -2.75 h -44.775 c 1.307,-1.109 2.632,-2.192 3.975,-3.25 2.202,-1.742 4.435,-3.408 6.7,-5 4.153,-2.919 8.412,-5.585 12.775,-8 9.974,-5.517 20.499,-9.717 31.575,-12.6 12.134,-3.167 24.934,-4.75 38.4,-4.75 9.199,0 18.083,0.75 26.649,2.25 3,0.5 6,1.117 9,1.85 24.967,6 47.217,18.583 66.75,37.75 0.334,0.333 0.667,0.667 1,1 21.334,21.367 34.717,45.983 40.15,73.85 0.2,1.167 0.416,2.351 0.649,3.551 1.4,8.3 2.101,16.85 2.101,25.649 0,0.134 0,0.283 0,0.45 0,22.934 -4.601,43.967 -13.8,63.1 -4.601,9.434 -10.284,18.417 -17.051,26.95 -2,2.4 -4.033,4.783 -6.1,7.15 -1.934,2.133 -3.917,4.217 -5.95,6.25 -3.5,3.5 -7.066,6.8 -10.7,9.899 -4.833,4.034 -9.833,7.717 -15,11.051 -5.333,3.399 -10.833,6.416 -16.5,9.05 -0.533,0.2 -1.033,0.416 -1.5,0.649 -17.466,7.867 -36.483,11.967 -57.05,12.301 -0.533,0 -1.05,0 -1.55,0 -0.366,0 -0.733,0 -1.1,0 -40.434,0 -74.934,-14.317 -103.5,-42.95 -0.467,-0.467 -0.917,-0.917 -1.35,-1.351 -27.7,-28.3 -41.55,-62.333 -41.55,-102.1 0,-0.167 0,-0.316 0,-0.45 0.042,-14.928 2.042,-29.053 6,-42.375 0.517,-1.738 1.067,-3.464 1.65,-5.175 2.562,-7.495 5.762,-14.728 9.602,-21.699 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#658d38;fill-rule:evenodd" />
+ </g>
+ <g
+ id="Layer_6">
+ <path
+ id="path3644"
+ d="m 304.3,301.2 c -0.614,-0.905 -1.206,-1.821 -1.775,-2.75 0.907,-1.061 1.598,-2.144 2.075,-3.25 1.167,-2.333 1.75,-4.9 1.75,-7.7 0,-1.033 -0.083,-2.033 -0.25,-3 -0.368,-2.332 -1.21,-4.482 -2.525,-6.45 0.112,0.118 0.204,0.209 0.275,0.275 L 304,278.5 c 2.9,3.256 4.35,7.09 4.35,11.5 0,1.759 -0.233,3.425 -0.7,5 -0.266,0.932 -0.616,1.833 -1.05,2.7 -0.515,1.195 -1.282,2.362 -2.3,3.5 z m -7.475,5.225 c -1.841,0.65 -3.816,0.975 -5.925,0.975 -2.68,0 -5.146,-0.533 -7.4,-1.6 -1.783,-0.85 -3.433,-2.033 -4.95,-3.55 -0.894,-0.895 -1.669,-1.836 -2.325,-2.825 0.106,0.106 0.214,0.214 0.325,0.325 3.434,3.433 7.55,5.15 12.35,5.15 2.171,0 4.205,-0.35 6.1,-1.05 0.588,0.867 1.197,1.725 1.825,2.575 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#bbd89c;fill-rule:evenodd" />
+ <path
+ id="path3646"
+ d="m 333.575,324.85 c 0.758,-1.002 1.6,-1.968 2.524,-2.899 4.9,-4.867 10.801,-7.3 17.7,-7.3 3.473,0 6.689,0.616 9.65,1.85 -0.393,-0.553 -0.81,-1.095 -1.25,-1.625 0.193,0.112 0.385,0.229 0.575,0.35 0.349,0.262 0.69,0.537 1.024,0.825 1.32,1.517 2.354,3.133 3.101,4.851 0.1,0.199 0.199,0.383 0.3,0.55 1.1,2.033 1.866,4.184 2.3,6.45 0.063,0.356 0.121,0.715 0.175,1.074 -3.332,0.468 -6.757,0.7 -10.274,0.7 -9.27,0.001 -17.879,-1.608 -25.825,-4.826 z m 102.55,-21.8 c -0.209,-0.221 -0.417,-0.438 -0.625,-0.65 -1.628,-1.637 -3.294,-3.195 -5,-4.675 2.639,-5.218 4.613,-10.71 5.925,-16.475 l 25.851,-25.775 c 0.342,0.343 0.684,0.685 1.024,1.025 21.334,21.367 34.717,45.983 40.15,73.85 0.2,1.167 0.416,2.351 0.649,3.551 1.4,8.3 2.101,16.85 2.101,25.649 0,0.134 0,0.283 0,0.45 0,22.934 -4.601,43.967 -13.8,63.1 -4.601,9.434 -10.284,18.417 -17.051,26.95 -0.075,0.091 -0.15,0.183 -0.225,0.275 l 5.975,-21.976 c 0.101,-0.399 0.051,-0.816 -0.149,-1.25 -0.167,-0.366 -0.417,-0.683 -0.75,-0.949 -0.134,-0.034 -8.167,-8.784 -24.101,-26.25 3.448,-7.858 5.157,-14.851 5.125,-20.976 -0.005,-1.372 -0.005,-2.605 0,-3.7 0.547,-2.661 0.964,-5.245 1.25,-7.75 0.469,-4.224 0.561,-8.232 0.275,-12.024 0.033,-0.367 0.033,-0.783 0,-1.25 -0.4,-2.634 -0.884,-5.25 -1.45,-7.851 -2.666,-11.433 -7.75,-22.116 -15.25,-32.05 -1.333,-1.7 -2.7,-3.383 -4.1,-5.05 -1.467,-1.7 -2.95,-3.317 -4.45,-4.85 -0.455,-0.458 -0.913,-0.908 -1.374,-1.349 z M 255.05,462.1 301.775,415.526 c 1.695,2.331 3.52,4.623 5.475,6.875 0.874,0.999 1.757,1.975 2.65,2.925 l 51.075,81.075 c -0.362,0 -0.721,0 -1.074,0 -40.434,0 -74.934,-14.317 -103.5,-42.95 -0.454,-0.453 -0.903,-0.903 -1.351,-1.351 z M 368.6,340.05 c -1.316,3.908 -3.649,7.324 -7,10.25 -0.066,0.033 -0.149,0.117 -0.25,0.25 -0.1,0.033 -0.149,0.084 -0.149,0.15 -0.101,0.033 -0.167,0.083 -0.2,0.149 -0.434,0.367 -0.866,0.733 -1.3,1.101 -0.101,0.033 -0.2,0.1 -0.3,0.2 -2.434,1.8 -4.9,3.017 -7.4,3.649 l -2.85,0.601 c -0.267,0 -0.517,0.033 -0.75,0.1 -1,0.1 -2.034,0.15 -3.101,0.15 -0.1,0 -0.2,0 -0.3,0 -0.1,0 -0.2,0 -0.3,0 -0.101,0 -0.2,0 -0.3,0 -0.134,-0.067 -0.284,-0.101 -0.45,-0.101 h -0.25 c -4.182,-0.275 -7.89,-1.476 -11.125,-3.6 -2.517,-3.904 -3.775,-8.338 -3.775,-13.3 0,-2.092 0.226,-4.092 0.675,-6 9.717,4.448 20.358,6.682 31.926,6.699 2.441,-0.001 4.841,-0.102 7.199,-0.298 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#7bad45;fill-rule:evenodd" />
+ <path
+ id="path3648"
+ d="M 301.775,415.525 255.05,462.1 C 227.35,433.796 213.5,399.763 213.5,360 c 0,-0.167 0,-0.316 0,-0.45 0.089,-36.006 11.589,-67.339 34.5,-94 1.905,-2.214 3.888,-4.397 5.95,-6.55 0.805,-0.837 1.622,-1.671 2.45,-2.5 4.5,-4.5 9.184,-8.667 14.05,-12.5 0.165,-0.13 0.332,-0.264 0.5,-0.4 0.336,-0.264 0.669,-0.522 1,-0.775 0.154,-0.119 0.304,-0.235 0.45,-0.35 l 13.15,-8.95 c 0.752,-0.458 1.511,-0.908 2.275,-1.35 v 0.025 c 0.41,-0.238 0.818,-0.479 1.225,-0.725 l 1.225,-0.675 c 0.469,-0.25 0.935,-0.5 1.4,-0.75 4.524,-2.416 9.158,-4.565 13.9,-6.45 4.045,-1.601 8.171,-3.009 12.375,-4.225 1.177,-0.34 2.36,-0.665 3.55,-0.975 12.141,-3.167 24.94,-4.75 38.4,-4.75 9.199,0 18.083,0.75 26.649,2.25 3,0.5 6,1.117 9,1.85 7.557,1.815 14.865,4.231 21.925,7.25 6.836,10.689 10.252,22.79 10.25,36.3 0.002,10.708 -2.14,20.524 -6.425,29.45 -8.328,-5.511 -17.444,-9.411 -27.35,-11.7 -0.233,-0.066 -0.45,-0.117 -0.65,-0.15 -1.434,-0.333 -2.916,-0.633 -4.45,-0.9 -0.199,-0.033 -0.35,-0.05 -0.449,-0.05 -5.301,-0.7 -8.25,-1.067 -8.851,-1.1 h -0.05 c -18.967,-1.267 -36.134,2.783 -51.5,12.15 -4.233,2.567 -8.316,5.55 -12.25,8.95 -0.1,0.066 -0.167,0.15 -0.2,0.25 -0.133,0.1 -0.283,0.233 -0.45,0.4 -0.53,0.462 -1.056,0.929 -1.574,1.4 -2.051,1.869 -3.984,3.803 -5.8,5.8 -1.214,-1.499 -2.355,-3.032 -3.425,-4.6 1.019,-1.139 1.785,-2.305 2.3,-3.5 0.434,-0.868 0.784,-1.768 1.05,-2.7 0.467,-1.575 0.7,-3.241 0.7,-5 0,-4.41 -1.45,-8.244 -4.35,-11.5 l -0.15,-0.175 c -0.071,-0.066 -0.163,-0.158 -0.275,-0.275 -0.069,-0.076 -0.144,-0.159 -0.225,-0.25 -0.051,-0.051 -0.102,-0.101 -0.15,-0.15 -0.633,-0.633 -1.317,-1.217 -2.05,-1.75 -2.26,-1.695 -4.768,-2.728 -7.525,-3.1 H 293.6 c -0.432,-0.1 -0.898,-0.149 -1.4,-0.15 -0.434,-0.066 -0.867,-0.1 -1.3,-0.1 -0.333,0 -0.65,0.034 -0.95,0.1 -0.667,0 -1.317,0.05 -1.95,0.15 h -0.05 c -0.256,0.041 -0.506,0.091 -0.75,0.15 l -2.2,0.6 c -0.44,0.165 -0.874,0.348 -1.3,0.55 -0.117,0.05 -0.233,0.1 -0.35,0.15 -1.731,0.798 -3.332,1.931 -4.8,3.4 -0.2,0.2 -0.383,0.417 -0.55,0.65 -0.062,0.066 -0.12,0.133 -0.175,0.2 -1.904,2.117 -3.179,4.5 -3.825,7.15 -0.333,1.4 -0.5,2.85 -0.5,4.35 0,3.525 0.908,6.667 2.725,9.425 0.656,0.989 1.431,1.931 2.325,2.825 1.517,1.517 3.167,2.7 4.95,3.55 2.253,1.067 4.72,1.6 7.4,1.6 2.109,0 4.084,-0.325 5.925,-0.975 1.599,2.163 3.333,4.271 5.2,6.325 0.039,-0.053 0.081,-0.103 0.125,-0.15 -0.357,0.478 -0.708,0.961 -1.05,1.45 -0.7,1 -1.35,2 -1.95,3 -1.6,2.434 -3.083,4.967 -4.45,7.601 -0.016,0.033 -0.033,0.066 -0.05,0.1 -1.014,2.101 -1.964,4.217 -2.85,6.35 -0.633,1.601 -1.216,3.233 -1.75,4.9 -2.267,6.967 -3.683,14.384 -4.25,22.25 -1.522,21.336 3.803,40.428 15.975,57.274 z m 160.5,-160.05 -25.851,25.775 c 1.307,-5.716 1.966,-11.699 1.976,-17.95 -0.018,-11.181 -2.109,-21.498 -6.275,-30.95 10.682,6.175 20.731,13.884 30.15,23.125 z m -100.075,59.4 c -0.057,-0.069 -0.115,-0.136 -0.175,-0.2 0.254,0.176 0.504,0.359 0.75,0.55 -0.19,-0.121 -0.381,-0.238 -0.575,-0.35 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#94c061;fill-rule:evenodd" />
+ <path
+ id="path3650"
+ d="m 433,487.2 c -3.879,2.285 -7.846,4.368 -11.9,6.25 -0.533,0.2 -1.033,0.416 -1.5,0.649 -17.453,7.864 -36.47,11.956 -57.05,12.275 -0.523,0.01 -1.049,0.019 -1.575,0.025 L 309.9,425.325 c 0.931,0.984 1.873,1.943 2.825,2.875 2.176,2.226 4.417,4.309 6.725,6.25 2.767,2.366 5.684,4.533 8.75,6.5 10.033,6.566 21.25,10.816 33.649,12.75 0.101,0 0.233,0 0.4,0 5.441,-0.049 10.25,-0.207 14.425,-0.476 1.525,-0.091 2.968,-0.199 4.325,-0.324 5.1,-0.467 10.3,-1.184 15.6,-2.15 l 1.4,1.4 v 0.699 c 0.2,-0.03 0.399,-0.063 0.6,-0.1 L 433,487.2 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#6c983d;fill-rule:evenodd" />
+ <path
+ id="path3652"
+ d="m 414.8,207.875 c -14.804,-14.35 -32.604,-21.525 -53.399,-21.525 -21.301,0 -39.467,7.5 -54.5,22.5 -3.536,3.543 -6.652,7.26 -9.35,11.15 -2.247,3.233 -4.206,6.583 -5.875,10.05 -0.465,0.25 -0.931,0.5 -1.4,0.75 l -1.225,0.675 c -0.406,0.246 -0.815,0.487 -1.225,0.725 v -0.025 c 3.759,-9.244 9.451,-17.686 17.075,-25.325 15.042,-15.012 33.208,-22.521 54.5,-22.525 21.259,0.003 39.392,7.512 54.399,22.525 0.337,0.337 0.67,0.678 1,1.025 z m -6.1,6.075 c 0.331,0.331 0.664,0.665 1,1 3.316,3.316 6.225,6.799 8.725,10.45 7.55,11.081 11.325,23.714 11.325,37.9 0,10.513 -2.066,20.171 -6.2,28.975 -0.072,0.155 -0.147,0.314 -0.225,0.475 -0.525,1.09 -1.084,2.165 -1.675,3.225 -3.098,5.593 -7.081,10.818 -11.95,15.675 -4.908,4.92 -10.191,8.937 -15.851,12.05 -5.304,2.91 -10.937,5.027 -16.899,6.35 -1.729,0.384 -3.486,0.7 -5.275,0.95 -0.607,0.085 -1.216,0.16 -1.825,0.225 -2.757,0.317 -5.573,0.476 -8.449,0.476 -10.305,0 -19.788,-1.983 -28.45,-5.95 -2.097,-0.97 -4.146,-2.053 -6.15,-3.25 l -0.325,0.55 c -0.111,0.182 -0.22,0.365 -0.324,0.55 0.322,-0.596 0.673,-1.18 1.05,-1.75 2.078,1.124 4.203,2.124 6.375,3 7.946,3.219 16.555,4.827 25.825,4.825 3.518,0 6.942,-0.232 10.274,-0.7 0.526,-0.073 1.052,-0.156 1.575,-0.25 1.565,-0.254 3.106,-0.562 4.625,-0.925 11.948,-2.813 22.557,-8.863 31.825,-18.15 5.637,-5.626 10.078,-11.743 13.325,-18.35 0.096,-0.186 0.188,-0.369 0.274,-0.55 4.285,-8.926 6.427,-18.742 6.425,-29.45 0.002,-13.51 -3.414,-25.61 -10.25,-36.3 -2.478,-3.868 -5.403,-7.551 -8.775,-11.051 z M 295,303.85 c -6.065,-8.954 -9.948,-18.82 -11.65,-29.6 0.117,-0.05 0.233,-0.1 0.35,-0.15 0.426,-0.203 0.859,-0.386 1.3,-0.55 1.337,10.945 4.862,20.97 10.575,30.075 0.549,0.882 1.115,1.757 1.7,2.625 0.852,1.233 1.744,2.45 2.675,3.65 0.707,0.909 1.44,1.809 2.2,2.7 -0.044,0.047 -0.086,0.097 -0.125,0.15 -1.867,-2.054 -3.601,-4.163 -5.2,-6.325 -0.628,-0.85 -1.237,-1.708 -1.825,-2.575 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#e2e2e2;fill-rule:evenodd" />
+ <path
+ id="path3654"
+ d="m 305.575,223.6 c -4.743,1.884 -9.376,4.034 -13.9,6.45 1.669,-3.466 3.628,-6.816 5.875,-10.05 2.698,-3.89 5.814,-7.606 9.35,-11.15 15.034,-15 33.2,-22.5 54.5,-22.5 20.796,0 38.596,7.175 53.399,21.525 0.335,0.318 0.668,0.643 1,0.975 7.129,7.129 12.571,14.962 16.325,23.5 4.166,9.452 6.258,19.769 6.275,30.95 -0.01,6.251 -0.669,12.234 -1.976,17.95 -1.312,5.765 -3.286,11.257 -5.925,16.475 -0.037,0.074 -0.07,0.148 -0.1,0.225 -3.637,7.117 -8.504,13.716 -14.601,19.8 -10.662,10.686 -22.903,17.577 -36.725,20.675 -0.104,0.029 -0.203,0.054 -0.3,0.075 -2.47,0.547 -4.986,0.972 -7.551,1.275 -0.869,0.103 -1.744,0.194 -2.625,0.274 -2.357,0.196 -4.758,0.297 -7.199,0.3 -11.567,-0.018 -22.209,-2.251 -31.926,-6.699 -1.929,-0.879 -3.821,-1.846 -5.675,-2.9 0.047,-0.277 0.098,-0.552 0.15,-0.825 0.015,-0.092 0.031,-0.184 0.05,-0.274 0.173,-0.857 0.39,-1.69 0.65,-2.5 0.388,-1.194 0.871,-2.336 1.449,-3.426 l 0.051,-0.125 c 0.104,-0.185 0.213,-0.368 0.324,-0.55 l 0.325,-0.55 c 2.004,1.197 4.054,2.28 6.15,3.25 8.662,3.967 18.146,5.95 28.45,5.95 2.876,0 5.692,-0.158 8.449,-0.476 0.609,-0.064 1.218,-0.14 1.825,-0.225 1.789,-0.25 3.547,-0.566 5.275,-0.95 5.963,-1.322 11.596,-3.439 16.899,-6.35 5.659,-3.113 10.942,-7.13 15.851,-12.05 4.869,-4.857 8.853,-10.082 11.95,-15.675 0.591,-1.061 1.149,-2.135 1.675,-3.225 0.077,-0.161 0.152,-0.32 0.225,-0.475 4.134,-8.804 6.2,-18.462 6.2,-28.975 0,-14.186 -3.775,-26.819 -11.325,-37.9 -2.5,-3.65 -5.408,-7.134 -8.725,-10.45 -0.336,-0.335 -0.669,-0.669 -1,-1 -13.142,-12.666 -28.908,-18.983 -47.3,-18.95 -18.9,-0.033 -35.034,6.617 -48.4,19.95 -2.754,2.768 -5.228,5.651 -7.419,8.651 z m 115.775,211.8 -3.1,2.449 c -0.2,0.134 -0.366,0.25 -0.5,0.351 -0.267,0.2 -0.517,0.366 -0.75,0.5 -1.134,0.733 -2.267,1.467 -3.4,2.2 -0.1,0.033 -0.183,0.083 -0.25,0.149 l 65.601,65.75 c 0.133,0.134 0.316,0.316 0.55,0.55 l 1.1,1.101 c 1.4,1.366 3.067,2.05 5,2.05 1.634,-0.066 3.051,-0.55 4.25,-1.45 0.301,-0.166 0.551,-0.383 0.75,-0.649 0.233,-0.167 1.25,0.399 3.051,1.699 1.767,1.334 5.116,4.817 10.05,10.45 4.866,5.533 11.833,9.533 20.899,12 -5.933,1 -14.783,1.7 -26.55,2.101 -11.121,0.349 -19.721,-2.201 -25.8,-7.65 -1.462,-1.316 -2.778,-2.8 -3.95,-4.45 l -20.1,-20.1 h 0.05 L 433,487.2 l -34.4,-34.45 -0.6,-0.6 -1.4,-1.4 c -5.3,0.967 -10.5,1.684 -15.6,2.15 -1.357,0.125 -2.8,0.233 -4.325,0.324 l 33.95,-33.925 c 0.542,0.528 1.075,1.045 1.6,1.55 4.902,4.798 8.96,8.848 12.176,12.15 -0.167,0.066 -0.284,0.167 -0.351,0.3 -0.899,0.733 -1.767,1.45 -2.6,2.15 l -0.1,-0.049 z M 302.15,312.6 c -0.759,-0.891 -1.493,-1.791 -2.2,-2.7 -0.932,-1.2 -1.823,-2.417 -2.675,-3.65 -0.584,-0.868 -1.151,-1.743 -1.7,-2.625 -5.713,-9.105 -9.238,-19.13 -10.575,-30.075 l 2.2,-0.6 c 0.244,-0.06 0.494,-0.109 0.75,-0.15 H 288 c 0.633,-0.1 1.283,-0.15 1.95,-0.15 0.3,-0.066 0.617,-0.1 0.95,-0.1 0.434,0 0.867,0.034 1.3,0.1 0.501,0 0.968,0.05 1.4,0.15 h 0.025 c 0.946,7.487 3.054,14.487 6.325,21 0.793,1.581 1.651,3.131 2.575,4.65 0.569,0.929 1.161,1.845 1.775,2.75 1.07,1.567 2.211,3.101 3.425,4.6 -0.236,0.257 -0.469,0.515 -0.7,0.775 l -4.875,6.025 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#d3d3d3;fill-rule:evenodd" />
+ <path
+ id="path3656"
+ d="m 309.9,425.325 c -0.893,-0.95 -1.776,-1.926 -2.65,-2.925 -1.955,-2.252 -3.78,-4.544 -5.475,-6.875 -12.172,-16.847 -17.497,-35.938 -15.975,-57.275 0.567,-7.866 1.983,-15.283 4.25,-22.25 0.534,-1.667 1.117,-3.3 1.75,-4.9 0.886,-2.133 1.836,-4.249 2.85,-6.35 0.017,-0.033 0.034,-0.066 0.05,-0.1 1.367,-2.634 2.85,-5.167 4.45,-7.601 0.6,-1 1.25,-2 1.95,-3 0.342,-0.488 0.692,-0.972 1.05,-1.45 l 4.875,-6.025 c 0.231,-0.26 0.464,-0.519 0.7,-0.775 1.816,-1.997 3.75,-3.931 5.8,-5.8 0.519,-0.471 1.044,-0.938 1.574,-1.4 0.167,-0.167 0.317,-0.3 0.45,-0.4 0.033,-0.1 0.101,-0.184 0.2,-0.25 3.934,-3.4 8.017,-6.383 12.25,-8.95 15.366,-9.367 32.533,-13.417 51.5,-12.15 h 0.05 c 0.601,0.033 3.55,0.4 8.851,1.1 0.1,0 0.25,0.017 0.449,0.05 1.534,0.267 3.017,0.567 4.45,0.9 0.2,0.033 0.417,0.083 0.65,0.15 9.905,2.289 19.021,6.189 27.35,11.7 -0.087,0.181 -0.179,0.364 -0.274,0.55 -7.707,-4.751 -16.065,-8.167 -25.075,-10.25 -0.233,-0.066 -0.45,-0.117 -0.65,-0.15 -1.434,-0.333 -2.916,-0.633 -4.45,-0.9 -0.199,-0.033 -0.35,-0.05 -0.449,-0.05 -5.301,-0.7 -8.25,-1.067 -8.851,-1.1 h -0.05 c -18.98,-1.281 -36.146,2.769 -51.5,12.15 -4.22,2.58 -8.303,5.563 -12.25,8.95 -0.1,0.066 -0.167,0.15 -0.2,0.25 -0.133,0.1 -0.283,0.233 -0.45,0.4 -5.433,4.733 -10.1,9.883 -14,15.45 -0.7,1 -1.35,2 -1.95,3 -1.6,2.434 -3.083,4.967 -4.45,7.601 -1.034,2.133 -2,4.283 -2.9,6.449 -0.634,1.608 -1.217,3.242 -1.75,4.9 -2.268,6.971 -3.685,14.388 -4.25,22.25 -1.451,20.351 3.324,38.659 14.325,54.925 2.144,3.148 4.519,6.224 7.125,9.226 0.08,0.091 0.163,0.183 0.25,0.274 1.057,1.209 2.132,2.384 3.225,3.525 -0.952,-0.93 -1.894,-1.889 -2.825,-2.874 z M 363.8,316.05 c 0.185,0.165 0.368,0.332 0.55,0.5 2.034,1.934 3.551,4.05 4.551,6.351 0.1,0.199 0.199,0.383 0.3,0.55 0.91,1.683 1.594,3.44 2.05,5.274 -0.523,0.094 -1.049,0.177 -1.575,0.25 -0.054,-0.359 -0.112,-0.718 -0.175,-1.074 -0.434,-2.267 -1.2,-4.417 -2.3,-6.45 -0.101,-0.167 -0.2,-0.351 -0.3,-0.55 -0.748,-1.718 -1.781,-3.335 -3.101,-4.851 z m -33.9,34.85 c 0.853,0.762 1.744,1.445 2.675,2.05 3.235,2.124 6.943,3.324 11.125,3.6 h 0.25 c 0.166,0 0.316,0.033 0.45,0.101 0.1,0 0.199,0 0.3,0 0.1,0 0.2,0 0.3,0 0.1,0 0.2,0 0.3,0 1.066,0 2.101,-0.051 3.101,-0.15 0.233,-0.066 0.483,-0.1 0.75,-0.1 L 352,355.8 c 2.5,-0.633 4.967,-1.85 7.4,-3.649 0.1,-0.101 0.199,-0.167 0.3,-0.2 0.434,-0.367 0.866,-0.733 1.3,-1.101 0.033,-0.066 0.1,-0.116 0.2,-0.149 0,-0.066 0.05,-0.117 0.149,-0.15 0.101,-0.133 0.184,-0.217 0.25,-0.25 3.351,-2.926 5.684,-6.342 7,-10.25 0.881,-0.08 1.756,-0.172 2.625,-0.274 -1.101,4.872 -3.643,9.047 -7.625,12.524 -0.066,0.033 -0.149,0.117 -0.25,0.25 -0.1,0.033 -0.149,0.084 -0.149,0.15 -0.101,0.033 -0.167,0.083 -0.2,0.149 -0.434,0.367 -0.866,0.733 -1.3,1.101 -0.101,0.033 -0.2,0.1 -0.3,0.2 -2.434,1.8 -4.9,3.017 -7.4,3.649 l -2.85,0.601 c -0.267,0 -0.517,0.033 -0.75,0.1 -1,0.1 -2.034,0.15 -3.101,0.15 -0.1,0 -0.2,0 -0.3,0 -0.1,0 -0.2,0 -0.3,0 -0.101,0 -0.2,0 -0.3,0 -0.134,-0.067 -0.284,-0.101 -0.45,-0.101 h -0.25 c -5.009,-0.33 -9.343,-1.98 -13,-4.95 -0.979,-0.805 -1.912,-1.705 -2.799,-2.7 z m 100.6,-53.175 c 1.706,1.48 3.372,3.038 5,4.675 0.208,0.212 0.416,0.429 0.625,0.65 -1.864,-1.801 -3.772,-3.501 -5.725,-5.1 0.03,-0.076 0.063,-0.151 0.1,-0.225 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#b6b6b6;fill-rule:evenodd" />
+ <path
+ id="path3658"
+ d="m 462.475,367.475 -51.85,51.825 -33.95,33.925 c -4.175,0.269 -8.983,0.427 -14.425,0.476 -0.167,0 -0.3,0 -0.4,0 -12.399,-1.934 -23.616,-6.184 -33.649,-12.75 -3.066,-1.967 -5.983,-4.134 -8.75,-6.5 -2.308,-1.941 -4.549,-4.024 -6.725,-6.25 -1.093,-1.142 -2.168,-2.316 -3.225,-3.525 -0.087,-0.092 -0.17,-0.184 -0.25,-0.274 -2.606,-3.002 -4.981,-6.077 -7.125,-9.226 -11.001,-16.266 -15.776,-34.574 -14.325,-54.925 0.565,-7.862 1.982,-15.279 4.25,-22.25 0.533,-1.658 1.116,-3.292 1.75,-4.9 0.9,-2.166 1.867,-4.316 2.9,-6.449 1.367,-2.634 2.85,-5.167 4.45,-7.601 0.6,-1 1.25,-2 1.95,-3 3.9,-5.566 8.566,-10.716 14,-15.45 0.167,-0.167 0.317,-0.3 0.45,-0.4 0.033,-0.1 0.101,-0.184 0.2,-0.25 3.947,-3.387 8.03,-6.37 12.25,-8.95 15.354,-9.381 32.52,-13.431 51.5,-12.15 h 0.05 c 0.601,0.033 3.55,0.4 8.851,1.1 0.1,0 0.25,0.017 0.449,0.05 1.534,0.267 3.017,0.567 4.45,0.9 0.2,0.033 0.417,0.083 0.65,0.15 9.01,2.083 17.368,5.499 25.075,10.25 -3.247,6.607 -7.688,12.724 -13.325,18.35 -9.269,9.287 -19.877,15.336 -31.825,18.15 -1.519,0.363 -3.06,0.671 -4.625,0.925 -0.456,-1.834 -1.14,-3.592 -2.05,-5.274 -0.101,-0.167 -0.2,-0.351 -0.3,-0.55 -1,-2.301 -2.517,-4.417 -4.551,-6.351 -0.182,-0.168 -0.365,-0.335 -0.55,-0.5 -0.334,-0.288 -0.676,-0.563 -1.024,-0.825 -0.246,-0.19 -0.496,-0.374 -0.75,-0.55 -3.474,-2.444 -7.615,-3.87 -12.426,-4.275 -2.301,-0.139 -4.501,0.011 -6.6,0.45 -3.92,0.822 -7.487,2.656 -10.7,5.5 -0.233,0.167 -0.45,0.351 -0.649,0.551 -1.766,1.505 -3.249,3.154 -4.45,4.949 -0.377,0.57 -0.728,1.154 -1.05,1.75 l -0.051,0.125 c -0.578,1.09 -1.062,2.231 -1.449,3.426 -0.261,0.81 -0.478,1.643 -0.65,2.5 -0.019,0.091 -0.035,0.183 -0.05,0.274 -0.053,0.273 -0.104,0.548 -0.15,0.825 -0.114,0.75 -0.198,1.517 -0.25,2.3 0,0.033 0,0.084 0,0.15 -0.09,1.646 -0.04,3.246 0.15,4.8 0.082,0.744 0.199,1.478 0.35,2.2 0.834,3.666 2.601,7.066 5.3,10.2 0.018,0.016 0.034,0.032 0.051,0.05 h 0.1 c 0.133,0.155 0.266,0.306 0.4,0.45 0.887,0.994 1.819,1.895 2.8,2.699 3.657,2.97 7.991,4.62 13,4.95 h 0.25 c 0.166,0 0.316,0.033 0.45,0.101 0.1,0 0.199,0 0.3,0 0.1,0 0.2,0 0.3,0 0.1,0 0.2,0 0.3,0 1.066,0 2.101,-0.051 3.101,-0.15 0.233,-0.066 0.483,-0.1 0.75,-0.1 L 354,357.8 c 2.5,-0.633 4.967,-1.85 7.4,-3.649 0.1,-0.101 0.199,-0.167 0.3,-0.2 0.434,-0.367 0.866,-0.733 1.3,-1.101 0.033,-0.066 0.1,-0.116 0.2,-0.149 0,-0.066 0.05,-0.117 0.149,-0.15 0.101,-0.133 0.184,-0.217 0.25,-0.25 3.982,-3.478 6.524,-7.652 7.625,-12.524 2.564,-0.304 5.081,-0.729 7.551,-1.275 0.097,-0.021 0.196,-0.046 0.3,-0.075 13.821,-3.098 26.063,-9.989 36.725,-20.675 6.097,-6.083 10.964,-12.683 14.601,-19.8 1.952,1.598 3.86,3.298 5.725,5.1 0.461,0.441 0.919,0.892 1.375,1.35 1.5,1.533 2.983,3.15 4.45,4.85 1.399,1.667 2.767,3.35 4.1,5.05 7.5,9.934 12.584,20.617 15.25,32.05 0.566,2.601 1.05,5.217 1.45,7.851 0.033,0.467 0.033,0.883 0,1.25 0.284,3.789 0.192,7.798 -0.276,12.022 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#a3a3a3;fill-rule:evenodd" />
+ <path
+ id="path3660"
+ d="m 474.175,453.9 h -0.024 v 0.05 c -0.367,0.066 -0.75,0.033 -1.15,-0.101 -0.192,-0.096 -0.359,-0.229 -0.5,-0.399 -0.115,-0.131 -0.216,-0.281 -0.3,-0.45 v -0.15 c -0.134,-0.333 -0.134,-0.683 0,-1.05 l -0.05,0.101 6.949,-25.551 c 0.101,-0.399 0.051,-0.816 -0.149,-1.25 -0.167,-0.366 -0.417,-0.683 -0.75,-0.949 -0.134,-0.034 -8.167,-8.784 -24.101,-26.25 1.967,-3.834 4.051,-10.117 6.25,-18.851 0.32,-1.295 0.612,-2.57 0.875,-3.825 -0.005,1.095 -0.005,2.328 0,3.7 0.032,6.125 -1.677,13.117 -5.125,20.976 15.934,17.466 23.967,26.216 24.101,26.25 0.333,0.267 0.583,0.583 0.75,0.949 0.2,0.434 0.25,0.851 0.149,1.25 l -5.975,21.976 -0.975,3.575 0.05,-0.101 c -0.012,0.032 -0.02,0.065 -0.025,0.1 z m 53.775,19.45 c 6.564,5.904 9.681,14.588 9.35,26.051 -0.467,13.733 -1.383,23.517 -2.75,29.35 -0.233,1.167 -0.767,2.25 -1.6,3.25 l -0.15,0.3 c -0.333,0.233 -0.649,0.45 -0.95,0.65 -0.8,0.533 -1.666,0.866 -2.6,1 -0.8,0.2 -1.684,0.399 -2.65,0.6 -5.933,1 -14.783,1.7 -26.55,2.101 -12.402,0.389 -21.669,-2.827 -27.8,-9.65 6.079,5.449 14.679,7.999 25.8,7.65 11.767,-0.4 20.617,-1.101 26.55,-2.101 0.967,-0.2 1.851,-0.399 2.65,-0.6 0.934,-0.134 1.8,-0.467 2.6,-1 0.301,-0.2 0.617,-0.417 0.95,-0.65 l 0.15,-0.3 c 0.833,-1 1.366,-2.083 1.6,-3.25 1.367,-5.833 2.283,-15.616 2.75,-29.35 0.296,-10.23 -2.154,-18.247 -7.35,-24.051 z m -31.125,3.225 c -0.357,0.039 -0.698,0.014 -1.025,-0.075 -0.333,-0.2 -0.6,-0.467 -0.8,-0.8 -0.066,-0.066 -0.1,-0.15 -0.1,-0.25 -0.134,-0.334 -0.15,-0.667 -0.051,-1 l 0.051,-0.05 6.75,-25.051 c 0.1,-0.433 0.083,-0.85 -0.051,-1.25 1.423,1.927 2.105,3.01 2.051,3.25 l -6.75,25.051 -0.051,0.05 c -0.011,0.039 -0.019,0.081 -0.024,0.125 z M 398.6,452.75 c -0.2,0.036 -0.399,0.069 -0.6,0.1 v -0.699 l 0.6,0.599 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#8f8f8f;fill-rule:evenodd" />
+ <path
+ id="path3662"
+ d="m 410.625,419.3 51.85,-51.825 c -0.286,2.505 -0.703,5.089 -1.25,7.75 -0.263,1.255 -0.555,2.53 -0.875,3.825 -2.199,8.733 -4.283,15.017 -6.25,18.851 15.934,17.466 23.967,26.216 24.101,26.25 0.333,0.267 0.583,0.583 0.75,0.949 0.2,0.434 0.25,0.851 0.149,1.25 l -6.95,25.55 0.05,-0.101 c -0.134,0.367 -0.134,0.717 0,1.05 V 453 c 0.084,0.169 0.185,0.319 0.3,0.45 0.141,0.17 0.308,0.304 0.5,0.399 0.4,0.134 0.783,0.167 1.15,0.101 v -0.05 h 0.024 l 25.325,-6.65 c 0.434,-0.233 0.833,-0.217 1.2,0.05 0.333,0.167 0.633,0.434 0.899,0.8 0.134,0.4 0.15,0.817 0.051,1.25 l -6.749,25.05 -0.051,0.05 c -0.1,0.333 -0.083,0.666 0.051,1 0,0.1 0.033,0.184 0.1,0.25 0.2,0.333 0.467,0.6 0.8,0.8 0.327,0.089 0.668,0.114 1.025,0.075 0.039,-0.01 0.081,-0.018 0.125,-0.025 v 0.101 l 0.1,-0.101 26.65,-7 c 1.576,1.142 2.992,2.408 4.25,3.8 5.195,5.805 7.646,13.821 7.35,24.051 -0.467,13.733 -1.383,23.517 -2.75,29.35 -0.233,1.167 -0.767,2.25 -1.6,3.25 l -0.15,0.3 c -0.333,0.233 -0.649,0.45 -0.95,0.65 -0.8,0.533 -1.666,0.866 -2.6,1 -0.8,0.2 -1.684,0.399 -2.65,0.6 -21.5,-21.6 -32.816,-32.934 -33.949,-34 L 430.55,438.2 c -0.2,-0.101 -0.366,-0.233 -0.5,-0.4 l -5.2,-5.25 -0.149,0.15 c -0.101,0.066 -0.2,0.166 -0.3,0.3 -3.216,-3.303 -7.273,-7.353 -12.176,-12.15 -0.525,-0.505 -1.058,-1.022 -1.6,-1.55 z m 10.725,16.1 0.101,0.05 h -0.101 v -0.05 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#dbdbdb;fill-rule:evenodd" />
+ <path
+ id="path3664"
+ d="m 421.35,435.4 v 0.05 h 0.101 c 0.833,-0.7 1.7,-1.417 2.6,-2.15 0.066,-0.133 0.184,-0.233 0.351,-0.3 0.1,-0.134 0.199,-0.233 0.3,-0.3 l 0.149,-0.15 5.2,5.25 c 0.134,0.167 0.3,0.3 0.5,0.4 l 60.101,60.35 c 1.133,1.066 12.449,12.4 33.949,34 -9.066,-2.467 -16.033,-6.467 -20.899,-12 -4.934,-5.633 -8.283,-9.116 -10.05,-10.45 -1.801,-1.3 -2.817,-1.866 -3.051,-1.699 -0.199,0.267 -0.449,0.483 -0.75,0.649 -1.199,0.9 -2.616,1.384 -4.25,1.45 -1.933,0 -3.6,-0.684 -5,-2.05 l -1.1,-1.101 c -0.233,-0.233 -0.417,-0.416 -0.55,-0.55 l -65.601,-65.75 c 0.067,-0.066 0.15,-0.116 0.25,-0.149 1.134,-0.733 2.267,-1.467 3.4,-2.2 0.233,-0.134 0.483,-0.3 0.75,-0.5 0.134,-0.101 0.3,-0.217 0.5,-0.351 l 3.1,-2.449 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-rule:evenodd" />
+ </g>
+ </g>
+ <text
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ xml:space="preserve"
+ style="font-size:12.16765976px;font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Dosis;-inkscape-font-specification:Dosis Ultra-Bold"
+ x="494.94437"
+ y="1221.5253"
+ id="text16247-9"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan16249-5"
+ x="494.94437"
+ y="1221.5253"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;font-family:Droid Sans;-inkscape-font-specification:Droid Sans">Open</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#666666;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
+ x="553.65778"
+ y="1221.5852"
+ id="text3883"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3885"
+ x="553.65778"
+ y="1221.5852">Keychain</tspan></text>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/Graphics/drawables/drawer_header2.svg b/Graphics/drawables/drawer_header2.svg
new file mode 100644
index 000000000..a431b5ac5
--- /dev/null
+++ b/Graphics/drawables/drawer_header2.svg
@@ -0,0 +1,1636 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="512"
+ height="288"
+ id="svg4270"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="drawer_header.svg"
+ inkscape:export-filename="/home/schuerm/Projekte/OpenKeychain/Graphics/drawables/drawer_header.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4272">
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6747-5"
+ is_visible="true" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6749-3"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4566-7-3"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6679-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4678-8"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4668-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4452-8"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4450-4"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4448-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4446-9"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4436-5"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4434-1"
+ is_visible="true" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4428-2"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4416-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4294-5"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4304-7"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4308-0"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4312-7"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4316-5"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4320-7"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4324-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4328-6"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4332-4"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4342-4"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4349"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4351"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4353"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4355"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4357"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4359"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect4361"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4380-4"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6355-7"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4658-8"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4566-97"
+ effect="spiro" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect4543-2"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6052"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6050"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6048"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6040"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6038"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6036"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6028"
+ is_visible="true" />
+ <inkscape:path-effect
+ is_visible="true"
+ id="path-effect6024"
+ effect="spiro" />
+ <inkscape:path-effect
+ effect="spiro"
+ id="path-effect6020"
+ is_visible="true" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6204">
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:0.28078841;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect6206"
+ width="74.565163"
+ height="170.26346"
+ x="425.43484"
+ y="1201.8348" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath6278">
+ <rect
+ style="color:#000000;fill:#b22222;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect6280"
+ width="57.606529"
+ height="95.568382"
+ x="0.98397124"
+ y="1276.5299" />
+ </clipPath>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="546.50452"
+ inkscape:cy="96.739494"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="2558"
+ inkscape:window-height="1419"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata4275">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-764.36218)">
+ <path
+ sodipodi:nodetypes="csssccccscccsssc"
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:none;stroke:#00000f;stroke-width:1.52761483;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.94117647;stroke-dasharray:12.22091815, 3.05522955, 1.52761478, 3.05522955;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 40.554746,989.85755 c 0,3.99463 0,7.98935 0,11.98405 0,1.7142 -0.07273,3.4279 -0.190812,5.1404 -0.118083,1.7125 -0.24392,3.4401 0.190812,5.1316 0.602399,2.3439 2.343864,4.5685 4.959243,6.2568 2.615381,1.6882 6.097694,2.8271 9.779073,3.1592 10.405177,0.1663 21.178634,0 30.816471,0 55.420497,0 108.675337,-0.6707 164.095827,-0.6707 55.93565,0 114.03694,0.6707 169.97259,0.6707 2.23552,0 4.47057,0.036 6.70423,0.094 2.23365,0.059 4.48422,0.1206 6.69422,-0.094 3.61013,-0.3514 7.01315,-1.4835 9.58014,-3.1428 2.56701,-1.6593 4.29285,-3.8337 4.93487,-6.1305 0.5177,-1.852 0.36804,-3.7505 0.22735,-5.6297 -0.14067,-1.8791 -0.22735,-3.7598 -0.22735,-5.6411 l 0,-10.27199"
+ id="path15548"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#00bcd4;fill-opacity:1;stroke:#213149;stroke-width:1.39133608;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14996"
+ width="544.41058"
+ height="236.06712"
+ x="-17.378559"
+ y="752.45825" />
+ <g
+ transform="matrix(1.1545885,0,0,1.1545885,-1.9290913,-595.99783)"
+ inkscape:groupmode="maskhelper"
+ id="g6275"
+ clip-path="url(#clipPath6278)">
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:0.27586209;fill-rule:nonzero;stroke:none;stroke-width:1.76498926;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -58.945242,1270.4982 c -4.83684,1.861 -8.96854,5.1238 -11.94377,9.271 -20.50515,2.77 -36.314528,20.2975 -36.295388,41.5584 0.0209,23.1709 18.806838,41.9331 41.977698,41.9122 6.83376,-0.01 13.27608,-1.6477 18.96999,-4.5543 11.28951,10.374 28.17457,12.1091 41.3523302,4.1676 6.51563,1.8162 13.80376,0.6134 19.4842198,-3.9402 0.95682,-0.767 1.80576,-1.6194 2.5974,-2.504 3.82071,0.8873 7.99622,0.094 11.29411,-2.5493 5.70967,-4.577 6.63029,-12.9349 2.05324,-18.6446 -0.4153,-0.518 -0.88519,-0.9719 -1.35765,-1.4106 1.69733,-0.7746 3.32049,-1.7756 4.84269,-2.9958 1.44477,-1.1582 2.72288,-2.4571 3.81039,-3.8584 2.96096,-0.2503 5.8726,-1.3426 8.36537,-3.3409 6.67925,-5.3543 7.76073,-15.1043 2.40645,-21.7835 -3.32091,-4.1427 -8.32714,-6.1064 -13.25002,-5.7402 -0.35877,-0.3362 -0.72756,-0.6607 -1.10325,-0.9701 2.76256,-3.3974 2.88929,-8.3847 0.0394,-11.9399 -3.28167,-4.0937 -9.24366,-4.7507 -13.33738,-1.469 -0.51964,0.4165 -0.96353,0.8828 -1.37076,1.3767 -3.34471,-3.1097 -7.80689,-5.0317 -12.7341498,-5.0273 -3.85721,0 -7.42727999,1.1939 -10.40375,3.1968 -2.08311,-0.497 -4.2606,-0.7642 -6.4961802,-0.7621 -2.35539,0 -4.64199,0.2905 -6.82537,0.8444 0.11313,-0.7701 0.16942,-1.5435 0.16869,-2.3452 -0.008,-8.8349 -7.15434,-15.9815 -15.98927,-15.9736 -5.10302,0 -9.63378,2.3848 -12.55952,6.1085 -1.41391,-0.2342 -2.85443,-0.3643 -4.33497,-0.363 -3.29614,0 -6.45843,0.6198 -9.36053,1.7364 z"
+ id="path6269"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1.1545885,0,0,1.1545885,-63.05983,-596.82255)"
+ inkscape:groupmode="maskhelper"
+ id="g6201"
+ clip-path="url(#clipPath6204)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6158-9"
+ d="m 511.49596,1239.0283 c -4.83684,1.861 -8.96854,5.1239 -11.94377,9.2711 -20.50515,2.77 -36.31453,20.2975 -36.29539,41.5584 0.0209,23.1709 18.80684,41.9331 41.9777,41.9122 6.83376,-0.01 13.27608,-1.6477 18.96999,-4.5543 11.28951,10.374 28.17457,12.1091 41.35233,4.1676 6.51563,1.8162 13.80376,0.6134 19.48422,-3.9402 0.95682,-0.767 1.80576,-1.6194 2.5974,-2.504 3.82071,0.8873 7.99622,0.094 11.29411,-2.5493 5.70967,-4.577 6.63029,-12.9349 2.05324,-18.6446 -0.4153,-0.518 -0.88519,-0.9719 -1.35765,-1.4106 1.69733,-0.7746 3.32049,-1.7756 4.84269,-2.9958 1.44477,-1.1582 2.72288,-2.4571 3.81039,-3.8584 2.96096,-0.2503 5.8726,-1.3426 8.36537,-3.3409 6.67925,-5.3543 7.76073,-15.1043 2.40645,-21.7835 -3.32091,-4.1427 -8.32714,-6.1064 -13.25002,-5.7402 -0.35877,-0.3362 -0.72756,-0.6607 -1.10325,-0.9701 2.76256,-3.3974 2.88929,-8.3847 0.0394,-11.9399 -3.28167,-4.0937 -9.24366,-4.7507 -13.33738,-1.469 -0.51964,0.4165 -0.96353,0.8828 -1.37076,1.3767 -3.34471,-3.1097 -7.80689,-5.0317 -12.73415,-5.0273 -3.85721,0 -7.42728,1.1939 -10.40375,3.1968 -2.08311,-0.497 -4.2606,-0.7642 -6.49618,-0.7621 -2.35539,0 -4.64199,0.2905 -6.82537,0.8444 0.11313,-0.7701 0.16942,-1.5435 0.16869,-2.3452 -0.008,-8.835 -7.15434,-15.9816 -15.98927,-15.9737 -5.10302,0 -9.63378,2.3848 -12.55952,6.1085 -1.41391,-0.2342 -2.85443,-0.3643 -4.33497,-0.363 -3.29614,0 -6.45843,0.6198 -9.36053,1.7364 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:0.27586209;fill-rule:nonzero;stroke:none;stroke-width:1.76498926;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:0.27586209;fill-rule:nonzero;stroke:none;stroke-width:1.76498926;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 222.56453,811.44724 c -5.58455,2.14869 -10.35496,5.91589 -13.79013,10.70419 -23.67501,3.19821 -41.92834,23.43527 -41.90623,47.98285 0.0242,26.75287 21.71415,48.41548 48.46696,48.39136 7.89019,-0.0115 15.32841,-1.90243 21.90253,-5.25834 13.03474,11.9777 32.53004,13.98102 47.74493,4.81186 7.52287,2.09696 15.93767,0.70822 22.49626,-4.54932 1.10473,-0.88557 2.08491,-1.86973 2.99892,-2.89109 4.41136,1.02448 9.23234,0.10854 13.04005,-2.94339 6.59233,-5.28455 7.65527,-14.93449 2.37065,-21.52684 -0.4795,-0.59808 -1.02203,-1.12214 -1.56753,-1.62867 1.95972,-0.89434 3.83381,-2.05008 5.59132,-3.45891 1.66812,-1.33725 3.14381,-2.83693 4.39943,-4.45486 3.41869,-0.289 6.78044,-1.55016 9.65856,-3.85737 7.71179,-6.18201 8.96045,-17.43925 2.77846,-25.15097 -3.83427,-4.78312 -9.61442,-7.05039 -15.29832,-6.6276 -0.41422,-0.38815 -0.84003,-0.76281 -1.27379,-1.12005 3.18962,-3.9226 3.33594,-9.68087 0.0454,-13.78567 -3.78898,-4.72653 -10.67263,-5.48509 -15.39919,-1.69608 -0.59996,0.48089 -1.11247,1.01927 -1.58267,1.58951 -3.86175,-3.59042 -9.01373,-5.80955 -14.70269,-5.80446 -4.45349,0 -8.57546,1.37847 -12.01206,3.69099 -2.40513,-0.57383 -4.91924,-0.88234 -7.50041,-0.87991 -2.71951,0 -5.35959,0.3354 -7.88049,0.97492 0.13062,-0.88914 0.19561,-1.78209 0.19477,-2.70773 -0.009,-10.20067 -8.26032,-18.45206 -18.46103,-18.44294 -5.8919,0 -11.12306,2.75346 -14.50109,7.05282 -1.63248,-0.27041 -3.29569,-0.42062 -5.0051,-0.41911 -3.80568,0 -7.45683,0.7156 -10.80756,2.00481 z"
+ id="path6158"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#a99381;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.44650555;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14992"
+ width="148.87991"
+ height="110.6807"
+ x="183.26987"
+ y="877.81458" />
+ <g
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#008000;stroke-width:2.18264699;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0.93365368,0,0,0.93365368,-132.76183,588.71385)"
+ id="g6335">
+ <path
+ transform="translate(451.84123,82.731493)"
+ d="m 129.11158,230.45037 -7.47529,-3.05812 -3.50894,7.27457 -6.1644,-5.21843 -5.58517,5.8342 -4.25011,-6.86793 -7.114679,3.82274 -1.919791,-7.84515 -7.947752,1.43709 0.598455,-8.05442 -8.002847,-1.08924 3.05812,-7.47528 -7.274567,-3.50894 5.218434,-6.16441 -5.834203,-5.58516 6.867933,-4.25012 -3.822746,-7.11467 7.84515,-1.9198 -1.437092,-7.94775 8.054428,0.59846 1.089235,-8.00285 7.475285,3.05812 3.508937,-7.27457 6.16441,5.21844 5.58516,-5.83421 4.25012,6.86794 7.11467,-3.82275 1.91979,7.84515 7.94776,-1.43709 -0.59846,8.05443 8.00285,1.08923 -3.05812,7.47529 7.27457,3.50894 -5.21844,6.1644 5.8342,5.58517 -6.86793,4.25011 3.82275,7.11468 -7.84515,1.91979 1.43709,7.94775 -8.05443,-0.59845 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="1.2042772"
+ sodipodi:arg1="1.0471976"
+ sodipodi:r2="31.608938"
+ sodipodi:r1="37.605831"
+ sodipodi:cy="197.88277"
+ sodipodi:cx="110.30866"
+ sodipodi:sides="20"
+ id="path6339"
+ style="color:#000000;fill:#f5deb4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.18264699;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="star" />
+ <path
+ transform="translate(451.84125,82.024401)"
+ d="m 137.17871,198.58986 c 0,14.83992 -12.03014,26.87006 -26.87006,26.87006 -14.839926,0 -26.870061,-12.03014 -26.870061,-26.87006 0,-14.83992 12.030135,-26.87006 26.870061,-26.87006 14.83992,0 26.87006,12.03014 26.87006,26.87006 z"
+ sodipodi:ry="26.870058"
+ sodipodi:rx="26.870058"
+ sodipodi:cy="198.58986"
+ sodipodi:cx="110.30865"
+ id="path6337"
+ style="color:#000000;fill:#fffacd;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.18264699;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#f4a460;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 67.147407,877.86895 -64.9095294,31.82333 15.0818124,0 0,78.51203 99.65544,0 0,-78.51203 15.0818,0 -64.909523,-31.82333 z"
+ id="path14990"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ y="885.24792"
+ x="190.8345"
+ height="103.13316"
+ width="133.98546"
+ id="rect15144"
+ style="color:#000000;fill:#d7d6c1;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03635883;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ id="g15146"
+ transform="matrix(1.1545885,0,0,1.1545885,-113.95677,507.58726)"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path15148"
+ d="m 269.2751,330.50947 c 0,0 -2.32031,0.0251 -2.32031,3.41406 1.71881,0 8.53041,0.0773 8.53041,0.0773 l -0.26645,-3.46957 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path15150"
+ d="m 269.28125,330.5 c 0,0 3.5,-0.005 3.5,3.5 l 0,43.65625 13.78125,0 0,-43.65625 c 0,-3.54345 -2.84375,-3.5 -2.84375,-3.5 l -14.4375,0 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15152"
+ width="22.514477"
+ height="13.566416"
+ x="198.07083"
+ y="941.71259" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204.42146,893.2197 8.68759,7.71184"
+ id="path15154"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path15156"
+ d="m 204.42146,896.35359 8.68759,14.95158"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path15158"
+ d="m 204.42146,931.12206 9.15975,-31.63445"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204.10668,899.15902 9.47453,3.46249"
+ id="path15160"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path15162"
+ d="m 204.42146,905.75553 8.84497,-9.60052"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204.26408,902.1218 9.31713,6.76763"
+ id="path15164"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204.42146,917.68935 9.15975,-5.66591"
+ id="path15166"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path15168"
+ d="m 204.42146,915.15734 8.68759,-21.71919"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204.42146,920.96689 9.15975,-2.67554"
+ id="path15170"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204.42146,934.3309 9.15975,-12.90552"
+ id="path15172"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path15174"
+ d="m 204.42146,924.55927 8.68759,-9.28578"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204.42146,927.69328 9.15975,0"
+ id="path15176"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204.73624,906.11772 8.84497,24.70946"
+ id="path15178"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path15180"
+ d="m 204.42146,937.4237 9.15975,-3.4625"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path15182"
+ d="m 204.42146,924.18957 9.15975,12.90554"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ inkscape:connector-curvature="0"
+ id="path15184"
+ d="m 218.34826,944.05715 0,0"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218.34826,944.05715 0,0"
+ id="path15186"
+ inkscape:connector-curvature="0" />
+ <use
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ x="0"
+ y="0"
+ xlink:href="#path3638"
+ id="use15188"
+ transform="translate(27.508011,546.95333)"
+ width="500"
+ height="2100"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <use
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ x="0"
+ y="0"
+ xlink:href="#path3640"
+ id="use15190"
+ transform="translate(27.508011,546.95333)"
+ width="500"
+ height="2100"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.75721121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 276.78879,877.6686 3.23568,-31.11228 6.96915,4.23127 3.85793,27.12991 z"
+ id="path15202"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:none;stroke:#008000;stroke-width:1.75721121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 276.78879,877.6686 13.51249,-3.62066 -12.77982,-3.42436 11.84167,-3.17295 -11.19957,-3.00091 10.37743,-2.7806 -9.81474,-2.62986 9.09425,-2.4368 -8.60114,-2.3047 7.96974,-2.13546"
+ id="path15204"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ inkscape:connector-curvature="0"
+ id="path15206"
+ d="m 276.78879,877.6686 13.51249,-3.62066 -12.77982,-3.42436 11.84167,-3.17295 -11.19957,-3.00091 10.37743,-2.7806 -9.81474,-2.62986 9.09425,-2.4368 -8.60114,-2.3047 7.96974,-2.13546"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.75721121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ id="g15208"
+ transform="matrix(0.83696608,0.53916004,-0.53916004,0.83696608,141.70548,424.74204)"
+ style="color:#000000;fill:#e1e1e1;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <path
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0"
+ id="path15210"
+ d="m 324.5792,269.34446 c 8.05457,13.95092 25.89353,18.73085 39.84445,10.67628 4.03717,-2.33086 7.45686,-5.59543 9.97251,-9.52012 z"
+ style="color:#000000;fill:#e1e1e1;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="color:#000000;fill:#e1e1e1;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 348.92619,269.90951 0.25,-28.68768"
+ id="path15212"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(114.85156,-150.88227)"
+ d="m 236.12911,392.2916 c 0,0.99658 -0.80789,1.80448 -1.80448,1.80448 -0.99659,0 -1.80448,-0.8079 -1.80448,-1.80448 0,-0.99659 0.80789,-1.80448 1.80448,-1.80448 0.99659,0 1.80448,0.80789 1.80448,1.80448 z"
+ sodipodi:ry="1.8044801"
+ sodipodi:rx="1.8044801"
+ sodipodi:cy="392.2916"
+ sodipodi:cx="234.32463"
+ id="path15214"
+ style="color:#000000;fill:#e1e1e1;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#f5fffa;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15216"
+ width="85.681778"
+ height="78.503403"
+ x="24.179277"
+ y="909.7077" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#f4a460;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 445.4246,877.54931 -64.87346,31.82334 15.08182,0 0,78.51202 99.61934,0 0,-78.51202 15.08181,0 -64.90951,-31.82334 z"
+ id="path15274"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path15276"
+ d="m 442.89181,959.76098 c 0,0 2.14873,-1.55893 4.7015,0.84965 0.2746,1.36219 -0.30614,1.91374 -0.30614,1.91374 l -4.42438,0.0404 z"
+ style="color:#000000;fill:none;stroke:#008000;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ y="909.388"
+ x="402.77783"
+ height="78.252388"
+ width="85.367004"
+ id="rect15278"
+ style="color:#000000;fill:#f5fffa;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ y="955.28381"
+ x="190.96666"
+ height="3.2656732"
+ width="32.615685"
+ id="rect15458"
+ style="color:#000000;fill:#e2cf96;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ececec;fill-opacity:1;stroke:none"
+ id="rect3887"
+ width="199.00003"
+ height="29.799492"
+ x="136.0555"
+ y="1006.2523"
+ ry="8.3438606" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ inkscape:connector-curvature="0"
+ id="path15550"
+ d="m 241.652,956.85905 -7.10795,4.11322 2.63392,24.21035 -5.55647,2.63384 10.0305,0 0,-1.76791 0,-1.87621 z"
+ style="color:#000000;fill:#ffe7d2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cccccccc"
+ style="color:#000000;fill:#ffe7d2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 246.05878,957.2162 -7.10795,4.11322 2.63392,24.21035 -5.55646,2.63384 10.03049,0 0,-1.76791 0,-1.87621 z"
+ id="path15552"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#375163;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15554"
+ width="15.87114"
+ height="29.212097"
+ x="233.12956"
+ y="942.79175" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cssccccc"
+ inkscape:connector-curvature="0"
+ id="path15556"
+ d="m 215.14043,929.173 c -0.75139,0 -1.86254,0.32375 -1.86254,1.63733 0,1.31346 1.19107,1.68824 1.86254,1.68824 0.90123,0 1.79035,0 1.79035,0 l 0,4.2774 3.98002,0 0,-7.60297 c -1.88062,0 -3.91511,0 -5.77037,0 z"
+ style="color:#000000;fill:#ffe7d2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#beadad;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 232.65233,920.9513 -4.76268,8.22644 -6.96361,0 0,7.82949 8.19036,0 3.17512,-3.35546 0,8.44293 -0.0361,0 -4.11322,10.35516 11.04076,0 1.98445,-2.30918 1.94836,2.30918 11.07684,0 -4.1493,-10.35516 -0.10819,0 0,-21.1434 -17.28274,0 z"
+ id="path15558"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#beadad;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 241.06514,949.69223 0,-27.37193"
+ id="path15560"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#beadad;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 236.86734,920.80755 4.44815,12.68535 4.15255,-12.68535 z"
+ id="path15562"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <g
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ id="g15564"
+ transform="matrix(1.1545885,0,0,1.1545885,-109.19124,598.89613)">
+ <path
+ style="color:#000000;fill:#d6a07e;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 298.42306,266.0069 0,0.90625 c 0,2.84739 2.30886,5.15625 5.15625,5.15625 2.66943,0 4.86091,-2.02516 5.125,-4.625 l 2.3125,9.3125 c 0,2.99605 -18.47503,3.75835 -15.0625,0 3.41253,-3.75835 2.1875,-10.75 2.1875,-10.75 z"
+ id="path15566"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscczcc" />
+ <path
+ style="color:#000000;fill:#ffe7d2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 303.40965,261.88607 c 2.59977,0.26402 4.625,2.48682 4.625,5.15625 l 0,7.34375 c 0,2.84739 -2.30886,5.15625 -5.15625,5.15625 -2.84739,0 -5.15625,-2.30886 -5.15625,-5.15625 l 0,-0.90625 -2.71875,-0.0625 c -0.0244,-2.15098 1.65479,-3.48205 2.71875,-4.125 l 0,-2.25 c 0,-2.84739 2.30886,-5.15625 5.15625,-5.15625 0.17796,0 0.35793,-0.0176 0.53125,0 z"
+ id="path15568"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#ffe7d2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 302.8925,266.84687 -4.77433,1.58618"
+ id="path15570"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#ffe7d2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path15572"
+ sodipodi:cx="275.71677"
+ sodipodi:cy="350.51285"
+ sodipodi:rx="1.4946961"
+ sodipodi:ry="1.4946961"
+ d="m 276.64803,351.68197 c -0.64569,0.51433 -1.58606,0.40784 -2.10039,-0.23785 -0.40452,-0.50784 -0.43493,-1.21875 -0.0753,-1.75928"
+ sodipodi:start="0.89816185"
+ sodipodi:end="3.7287121"
+ sodipodi:open="true"
+ transform="matrix(-1,0,0,1,576.01738,-81.440409)" />
+ <path
+ style="color:#000000;fill:#d6a07e;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 306.89208,259.95813 c 3.95907,1.06083 6.16631,4.22568 6.16631,8.6875 0,3.20529 1.08432,12.61557 4,15.53125 2.91568,2.91568 -17.66647,2.84493 -14.62876,-0.19278 2.41613,-2.41613 3.05971,-7.81538 3.41001,-11.55722 0.41605,-0.27379 0.75456,-0.73249 0.875,-1.34375 0.17531,-0.88976 -0.15466,-1.75124 -0.75,-2.125 -0.0892,-2.42425 0.87321,-5.41914 -2.28549,-4.57277 -3.1587,0.84637 -8.93326,1.47578 -8.93326,-1.83817 0,-3.31395 8.18712,-3.64989 12.14619,-2.58906 z"
+ id="path15574"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="zssscsczzz" />
+ </g>
+ <rect
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ transform="matrix(0.96592583,0.25881905,-0.25881905,0.96592583,0,0)"
+ y="812.11774"
+ x="473.1936"
+ height="11.202963"
+ width="4.7517385"
+ id="rect15576"
+ style="color:#000000;fill:#696969;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#beadad;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 244.70722,938.16817 c 0,0 4.5541,-5.52332 6.76728,-9.35666 2.21318,-3.83336 1.80224,-7.13109 -0.58329,-7.13109 -2.38552,0 -7.25996,-0.72912 -7.25996,-0.72912 z"
+ id="path15578"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="czzcc" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#ffe7d2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 251.60324,917.22648 c 0.19354,-0.72601 0.16693,-1.88313 -1.10226,-2.22144 -1.26903,-0.33886 -1.93811,0.71597 -2.11106,1.36485 -0.23215,0.87079 -0.46115,1.72992 -0.46115,1.72992 l -4.13308,-1.10148 -1.02566,3.84559 7.34623,1.95888 c 0.48451,-1.8172 1.00884,-3.7829 1.48678,-5.57552 z"
+ id="path15580"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssccccc" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#beadad;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 243.37171,920.97659 6.15042,1.64805 c 0.33184,0.089 0.54884,0.43412 0.43848,0.75949 l -4.82212,14.21495 c -0.11037,0.32536 -0.42958,0.53446 -0.75944,0.43851 l -4.60022,-1.33794 c -0.32996,-0.0958 -0.51396,-0.42442 -0.43846,-0.75948 l 3.27187,-14.52508 c 0.0755,-0.33505 0.42763,-0.52742 0.75946,-0.43839 z"
+ id="path15582"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssssss" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ style="color:#000000;fill:#beadad;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 234.51219,946.35075 2.76867,0"
+ id="path15584"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path15586"
+ d="m 245.19128,946.35075 2.76866,0"
+ style="color:#000000;fill:#beadad;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:#b22222;fill-opacity:1;fill-rule:nonzero;stroke:#b22222;stroke-width:2.12883234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224.60959,873.82411 0,14.15525 34.09674,0 c 0,0 3.04482,7.91817 -4.25612,12.19442 9.80412,-2.399 11.04678,-12.19442 11.04678,-12.19442 l 5.1169,0 0,-14.15525 -46.0043,0 z"
+ id="path16245" />
+ <text
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ xml:space="preserve"
+ style="font-size:12.16765976px;font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Dosis;-inkscape-font-specification:Dosis Ultra-Bold"
+ x="224.83459"
+ y="884.76703"
+ id="text16247"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan16249"
+ x="224.83459"
+ y="884.76703">%#&amp;$!</tspan></text>
+ <g
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ transform="matrix(1.1545885,0,0,1.1545885,-206.70914,431.76905)"
+ id="g16580">
+ <path
+ sodipodi:nodetypes="czzc"
+ inkscape:connector-curvature="0"
+ id="path5477"
+ d="m 582.02501,478.1979 c 0,0 0.1848,-3.72883 -1.78312,-4.033 -1.96792,-0.30417 -5.24362,1.4559 -5.22172,-1.6261 0.0219,-3.082 2.71637,-1.5138 2.71637,-1.5138"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#f0e68c;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5600"
+ width="16.721498"
+ height="15.198018"
+ x="580.9635"
+ y="465.04739"
+ ry="4.5931172"
+ rx="5.1732965" />
+ <path
+ style="color:#000000;fill:#f0e68c;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 586.53033,459.0876 c 0.0729,0.029 0.13302,0.098 0.18907,0.189 l 3.18717,5.1859 4.13253,0 3.21418,-5.1859 c 0.85531,0 1.53957,0.6843 1.53957,1.5396 l 0,18.1469 c 0,0.8553 -0.68426,1.5396 -1.53957,1.5396 l -10.5339,0 c -0.85532,0 -1.53957,-0.6843 -1.53957,-1.5396 l 0,-18.1469 c 0,-0.7484 0.8404,-1.9337 1.3505,-1.7286 z"
+ id="path5479"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccssccsscc" />
+ <path
+ style="color:#000000;fill:#213149;fill-opacity:1;stroke:#213149;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:transform-center-y="0.24214388"
+ d="m 592.06728,473.4687 0.62745,-1.0101 -1.25489,0 z"
+ id="path5485"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 594.3761,474.908 c -2.05526,0.2491 -2.24652,-1.1211 -2.24652,-1.1211 0,0 -0.62721,1.3079 -1.6237,1.2456"
+ id="path5487"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 596.59642,471.223 c 0,0.5383 -0.47097,0.9747 -1.2514,0.9747 -0.78043,0 -1.2514,-0.4364 -1.2514,-0.9747"
+ id="path5505"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="czc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path5567"
+ d="m 583.51179,477.5599 9.69477,2.5586 0,1.3269 -9.69477,0 z"
+ style="color:#000000;fill:#f0e68c;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="czc"
+ inkscape:connector-curvature="0"
+ id="path5571"
+ d="m 589.92436,471.223 c 0,0.5383 -0.47097,0.9747 -1.2514,0.9747 -0.78043,0 -1.2514,-0.4364 -1.2514,-0.9747"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="color:#000000;fill:#f0e68c;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 598.79285,477.5599 -9.69477,2.5586 0,1.3269 9.69477,0 z"
+ id="path5860"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path8448-07"
+ d="m 69.289514,958.20706 0,0.79378 -9.020223,0 -2.128773,0 c -0.590284,0 -1.182586,0.0323 -1.767963,0.10853 -0.290114,0.0381 -0.550392,0.0936 -0.82986,0.18046 -0.279457,0.0866 -0.557736,0.21937 -0.757699,0.43297 -0.190081,0.20298 -0.329012,0.45192 -0.39689,0.72162 -0.06789,0.26971 -0.06015,0.552 -0.07216,0.82981 -0.03152,0.72669 -0.01385,1.4737 0,2.20099 0.09618,5.02881 0.01248,10.05207 0,15.08181 -0.0023,0.88499 -0.0023,1.78499 0,2.66999 l 6.02551,0 -0.252566,-14.72101 12.051018,0 c 1.793479,0 3.597516,0.0866 5.376049,-0.14433 0.889261,-0.11557 1.796094,-0.31993 2.59782,-0.72161 0.801755,-0.40168 1.48842,-1.01385 1.912298,-1.80404 0.491815,-0.91698 0.554746,-1.99063 0.577294,-3.0308 0.01869,-0.86433 0.0052,-1.73339 0,-2.59782 l -13.313851,0 z"
+ style="color:#000000;fill:#497b7b;fill-opacity:1;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4537-1"
+ d="m 69.289514,958.20706 13.313856,0 c -0.0032,-0.49231 0.0032,-0.98707 0,-1.47925 -0.01837,-2.44208 -0.0073,-4.8823 0,-7.32449 0.0084,-2.52832 0.01155,-5.04856 0,-7.57699 -0.0021,-0.56344 0.02362,-1.13553 -0.03601,-1.69573 -0.159515,-1.49682 -0.758066,-2.94399 -1.659726,-4.14937 -0.901636,-1.2054 -2.109026,-2.16635 -3.499845,-2.74215 -1.390818,-0.57579 -2.948161,-0.7566 -4.43795,-0.54116 -1.489789,0.21533 -2.906342,0.82184 -4.077141,1.76792 l 0.39689,23.74122 z"
+ style="color:#000000;fill:#fa8072;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="color:#000000;fill:#fffbb9;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g4531-4"
+ transform="matrix(-1.0985315,0.35539148,0.35539148,1.0985315,621.52368,325.05801)">
+ <path
+ sodipodi:nodetypes="ssssscccsss"
+ id="path4533-6"
+ d="m 620.03942,344.29143 c -2.59977,0.26402 -4.625,2.48682 -4.625,5.15625 l 0,5.70857 c 0,2.84739 2.30886,5.15625 5.15625,5.15625 2.84739,0 5.15625,-2.30886 5.15625,-5.15625 l 0,-0.90625 2.71875,-0.0625 c 0.0244,-2.15098 -1.65479,-3.48205 -2.71875,-4.125 l 0,-0.61482 c 0,-2.84739 -2.30886,-5.15625 -5.15625,-5.15625 -0.17796,0 -0.35793,-0.0176 -0.53125,0 z"
+ style="color:#000000;fill:#fffbb9;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(348.41125,0.21364798)"
+ sodipodi:open="true"
+ sodipodi:end="4.0130333"
+ sodipodi:start="2.1549128"
+ d="m 274.8925,351.75972 c -0.68863,-0.45523 -0.87784,-1.38251 -0.42261,-2.07114 0.0791,-0.11963 0.17496,-0.22725 0.2847,-0.31956"
+ sodipodi:ry="1.4946961"
+ sodipodi:rx="1.4946961"
+ sodipodi:cy="350.51285"
+ sodipodi:cx="275.71677"
+ id="path4535-7"
+ style="color:#000000;fill:#fffbb9;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 70.763336,942.99778 -5.599017,5.6031 -13.116484,4.99117 0,2.72205 19.725766,-1.44322 5.089976,-5.72884"
+ inkscape:path-effect="#path-effect4543-2"
+ id="path4541-4"
+ d="m 70.763336,942.99778 -5.599017,5.6031 -13.116484,4.99117 0,2.72205 19.725766,-1.44322 5.089976,-5.72884"
+ style="color:#000000;fill:#fa8072;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#fffbb9;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 51.588471,953.63893 c 0,0 -2.148712,-1.55893 -4.701484,0.84967 -0.274608,1.36229 0.306138,1.91372 0.306138,1.91372 l 4.424384,0.0404 z"
+ id="path4545-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 51.025055,959.46025 -13.266778,0 -8.7315,-18.88883"
+ inkscape:path-effect="#path-effect4566-97"
+ id="path4564-5"
+ d="m 51.025055,959.46025 -13.266778,0 -8.7315,-18.88883"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="966.51929"
+ x="62.539154"
+ height="3.2656732"
+ width="20.126583"
+ id="rect4620-0"
+ style="color:#000000;fill:#a26b3c;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="969.78497"
+ x="64.622307"
+ height="18.419437"
+ width="15.960277"
+ id="rect4622-4"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="rect4626-2"
+ d="m 24.179273,961.10426 26.641685,0 0,2.82563 -26.641685,0 z"
+ style="color:#000000;fill:#d4c8a4;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g4628-3"
+ transform="matrix(-1.06884,0.43664155,0.43664155,1.06884,194.06278,429.17107)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4630-9"
+ d="m 295.05828,363.05901 -3.40274,0"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 295.00031,359.49936 -3.2868,-0.8807"
+ id="path4632-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 295.00031,366.61866 -3.2868,0.8807"
+ id="path4634-8"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cscccc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 56.978171,981.47756 c 0,0 -4.374101,-0.19686 -5.745175,1.46286 -1.371073,1.65972 -1.471003,1.7268 -1.471003,1.7268 l 10.450192,0 0,-3.18966 z"
+ inkscape:path-effect="#path-effect4658-8"
+ id="path4656-4"
+ d="m 56.978171,981.47756 c -1.004589,0.0264 -2.013545,0.0781 -2.997181,0.28393 -0.983635,0.20581 -1.946799,0.57231 -2.747994,1.17893 -0.607602,0.46004 -1.113401,1.05379 -1.471003,1.7268 l 10.450192,0 0,-3.18966 c -1.077756,-0.0284 -2.156258,-0.0284 -3.234014,0"
+ style="color:#000000;fill:#d0a480;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="color:#000000;fill:#a26b3c;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect6351-8"
+ width="10.964646"
+ height="3.2656732"
+ x="-954.03717"
+ y="85.744301" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 82.665745,967.97603 c 0,0 1.84033,0.33922 2.659281,0 0.915977,-0.37939 1.723748,-1.18715 2.103159,-2.10308 0.313815,-0.75763 0,-1.6401 0,-2.46021 0,-0.75348 0,-1.50707 0,-2.26067 0,-2.37164 0,-7.11492 0,-7.11492"
+ inkscape:path-effect="#path-effect6355-7"
+ id="path6353-4"
+ d="m 82.665745,967.97603 c 0.856933,0.27913 1.802348,0.27913 2.659281,0 0.493914,-0.16088 0.961802,-0.41502 1.338581,-0.77261 0.376779,-0.35759 0.659164,-0.82182 0.764578,-1.33047 0.08338,-0.40231 0.05935,-0.8182 0.03666,-1.22843 -0.02268,-0.41023 -0.03666,-0.82092 -0.03666,-1.23178 l 0,-2.26067 0,-7.11492"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#a37d20;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 70.582053,935.45554 c -0.09918,-5.36167 -1.600018,-4.34056 -3.813814,-6.55437 -2.213796,-2.21381 -0.797024,-4.78784 -7.286792,-3.04961 -2.089691,0.55998 -3.956683,1.03844 -4.510747,-1.02931 -0.554076,-2.06787 2.053401,-3.12639 2.053401,-3.12639 0,0 6.078296,-1.62867 9.260124,-2.48122 3.333873,-0.8933 5.450616,0.57636 6.936351,6.12116 1.485737,5.54481 2.106439,7.86137 2.106439,7.86137 -1.8027,3.67552 -0.974953,1.11672 -4.744962,2.25837 z"
+ id="path3376-4-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="czczcsscc" />
+ <path
+ transform="matrix(0.41343445,0,0,0.41343445,153.46003,773.70385)"
+ d="m 386.525,337.53635 -12.86732,31.06445 -31.06445,12.86731 -31.06445,-12.86731 -12.86732,-31.06445 12.86732,-31.06445 31.06445,-12.86732 31.06445,12.86732 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="true"
+ sodipodi:arg2="0.39269908"
+ sodipodi:arg1="0"
+ sodipodi:r2="40.587658"
+ sodipodi:r1="43.931767"
+ sodipodi:cy="337.53635"
+ sodipodi:cx="342.59323"
+ sodipodi:sides="8"
+ id="path4276-1"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#5b5b5b;stroke-width:4.92904329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="star" />
+ <rect
+ y="941.88019"
+ x="255.0197"
+ height="4.4903092"
+ width="69.803703"
+ id="rect4284-3"
+ style="color:#000000;fill:#e2cf96;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="rect4286-5"
+ d="m 259.51352,946.38827 0,41.48181 6.89146,0 0,-3.30297 52.82242,0 0,3.30297 5.59254,0 0,-41.48181 -65.30642,0 z"
+ style="color:#000000;fill:#e2cf96;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.02179956;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(1.1545885,0,0,1.1545885,-119.22335,509.0759)"
+ id="g4388-1">
+ <g
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g4374-0"
+ transform="matrix(0.92101549,0.38952595,-0.38952595,0.92101549,161.91311,-111.38853)">
+ <path
+ transform="translate(1.5,-2.375)"
+ d="m 358.625,345.125 c 0,0.62132 -0.50368,1.125 -1.125,1.125 -0.62132,0 -1.125,-0.50368 -1.125,-1.125 0,-0.62132 0.50368,-1.125 1.125,-1.125 0.62132,0 1.125,0.50368 1.125,1.125 z"
+ sodipodi:ry="1.125"
+ sodipodi:rx="1.125"
+ sodipodi:cy="345.125"
+ sodipodi:cx="357.5"
+ id="path4290-8"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 355.125,343 2.5,0"
+ inkscape:path-effect="#path-effect4294-5"
+ id="path4292-6"
+ d="m 355.125,343 2.5,0"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 359,345.59375 359,347.5"
+ id="path4302-5"
+ inkscape:path-effect="#path-effect4304-7"
+ inkscape:original-d="M 359,345.59375 359,347.5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 361.875,347.75 -5.75,0"
+ id="path4306-3"
+ inkscape:path-effect="#path-effect4308-0"
+ inkscape:original-d="m 361.875,347.75 -5.75,0"
+ inkscape:connector-curvature="0" />
+ <g
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g4346-3">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:original-d="M 356,347.875 348.75,343.5"
+ inkscape:path-effect="#path-effect4312-7"
+ id="path4310-3"
+ d="M 356,347.875 348.75,343.5"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 355.68435,348.5486 -6.1187,-1.9722"
+ inkscape:path-effect="#path-effect4316-5"
+ id="path4314-1"
+ d="m 355.68435,348.5486 -6.1187,-1.9722"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="M 355.21875,349.8125 350.5,349"
+ inkscape:path-effect="#path-effect4320-7"
+ id="path4318-3"
+ d="M 355.21875,349.8125 350.5,349"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="M 355.21875,351.0625 351.25,351.125"
+ inkscape:path-effect="#path-effect4324-8"
+ id="path4322-8"
+ d="M 355.21875,351.0625 351.25,351.125"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 355.84375,352.28125 -2.875,0.59375"
+ inkscape:path-effect="#path-effect4328-6"
+ id="path4326-2"
+ d="m 355.84375,352.28125 -2.875,0.59375"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="M 356.59375,353.5625 354.25,354.125"
+ inkscape:path-effect="#path-effect4332-4"
+ id="path4330-3"
+ d="M 356.59375,353.5625 354.25,354.125"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 356.9797,354.35653 -0.92815,2.22444"
+ id="path4340-5"
+ inkscape:path-effect="#path-effect4342-4"
+ inkscape:original-d="m 356.9797,354.35653 -0.92815,2.22444"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="6.5992993"
+ sodipodi:start="3.664871"
+ sodipodi:type="arc"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path4344-3"
+ sodipodi:cx="357.5"
+ sodipodi:cy="345.125"
+ sodipodi:rx="1.125"
+ sodipodi:ry="1.125"
+ d="m 356.52554,344.56281 c 0.31049,-0.53818 0.99847,-0.72276 1.53665,-0.41227 0.46093,0.26592 0.6725,0.81842 0.50707,1.32419"
+ transform="translate(-1.875,12.59375)" />
+ </g>
+ <g
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g4356-7"
+ transform="matrix(-1,0,0,1,717.69845,0)">
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 356,347.875 348.75,343.5"
+ id="path4358-4"
+ inkscape:path-effect="#path-effect4312-7"
+ inkscape:original-d="M 356,347.875 348.75,343.5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 355.68435,348.5486 -6.1187,-1.9722"
+ id="path4360-1"
+ inkscape:path-effect="#path-effect4316-5"
+ inkscape:original-d="m 355.68435,348.5486 -6.1187,-1.9722"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 355.21875,349.8125 350.5,349"
+ id="path4362-6"
+ inkscape:path-effect="#path-effect4320-7"
+ inkscape:original-d="M 355.21875,349.8125 350.5,349"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 355.21875,351.0625 351.25,351.125"
+ id="path4364-6"
+ inkscape:path-effect="#path-effect4324-8"
+ inkscape:original-d="M 355.21875,351.0625 351.25,351.125"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 355.84375,352.28125 -2.875,0.59375"
+ id="path4366-8"
+ inkscape:path-effect="#path-effect4328-6"
+ inkscape:original-d="m 355.84375,352.28125 -2.875,0.59375"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 356.59375,353.5625 354.25,354.125"
+ id="path4368-2"
+ inkscape:path-effect="#path-effect4332-4"
+ inkscape:original-d="M 356.59375,353.5625 354.25,354.125"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 356.9797,354.35653 -0.92815,2.22444"
+ inkscape:path-effect="#path-effect4342-4"
+ id="path4370-3"
+ d="m 356.9797,354.35653 -0.92815,2.22444"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="translate(-1.875,12.59375)"
+ d="m 356.52554,344.56281 c 0.31049,-0.53818 0.99847,-0.72276 1.53665,-0.41227 0.46093,0.26592 0.6725,0.81842 0.50707,1.32419"
+ sodipodi:ry="1.125"
+ sodipodi:rx="1.125"
+ sodipodi:cy="345.125"
+ sodipodi:cx="357.5"
+ id="path4372-8"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ sodipodi:start="3.664871"
+ sodipodi:end="6.5992993"
+ sodipodi:open="true" />
+ </g>
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 355.7631,347.78939 6.0988,0.0442 1.28163,2.47487 -2.43068,4.28683 -3.66812,0 -2.38648,-4.15425 1.10485,-2.65165"
+ id="path4378-0"
+ inkscape:path-effect="#path-effect4380-4"
+ inkscape:original-d="m 355.7631,347.78939 6.0988,0.0442 1.28163,2.47487 -2.43068,4.28683 -3.66812,0 -2.38648,-4.15425 z"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 295.09989,897.58958 0,0"
+ inkscape:path-effect="#path-effect4416-8"
+ id="path4414-0"
+ d="m 295.09989,897.58958 0,0"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 295.09989,929.08849 0,0"
+ id="path4426-3"
+ inkscape:path-effect="#path-effect4428-2"
+ inkscape:original-d="m 295.09989,929.08849 0,0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 279.35042,913.33898 0,0"
+ id="path4430-4"
+ inkscape:path-effect="#path-effect4434-1"
+ inkscape:original-d="m 279.35042,913.33898 0,0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 310.84934,913.33898 0,0"
+ inkscape:path-effect="#path-effect4436-5"
+ id="path4432-1"
+ d="m 310.84934,913.33898 0,0"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 283.96333,902.20251 0,0"
+ id="path4438-6"
+ inkscape:path-effect="#path-effect4446-9"
+ inkscape:original-d="m 283.96333,902.20251 0,0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 306.23644,924.47557 0,0"
+ inkscape:path-effect="#path-effect4448-8"
+ id="path4440-2"
+ d="m 306.23644,924.47557 0,0"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 283.96333,924.47557 0,0"
+ inkscape:path-effect="#path-effect4450-4"
+ id="path4442-2"
+ d="m 283.96333,924.47557 0,0"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 306.23644,902.2024 0,0"
+ id="path4444-8"
+ inkscape:path-effect="#path-effect4452-8"
+ inkscape:original-d="m 306.23644,902.2024 0,0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="csssssc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 291.70604,910.84427 c 0,0 0.2552,-0.0219 -0.18434,0.34325 -0.30777,0.25609 -0.42584,1.25943 -0.5219,1.64806 -0.13324,0.5392 0.0316,1.11602 0.14432,1.65972 0.0926,0.44695 0.58087,1.22501 0.79016,1.63063 0.35523,0.68836 0.21753,0.51655 0.68221,1.13634 0.23667,0.31566 0.72163,0.93811 0.72163,0.93811"
+ inkscape:path-effect="#path-effect4668-8"
+ id="path4666-0"
+ d="m 291.70604,910.84427 c -0.0647,0.1126 -0.12624,0.22708 -0.18434,0.34325 -0.25903,0.5179 -0.45143,1.0733 -0.5219,1.64806 -0.0681,0.5553 -0.0206,1.12512 0.14432,1.65972 0.17843,0.57845 0.48871,1.10568 0.79016,1.63063 0.22005,0.3832 0.43703,0.76871 0.68221,1.13634 0.21906,0.32847 0.46034,0.64212 0.72163,0.93811"
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#bcbcbc;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 298.49536,910.84427 c 0.0648,0.1126 0.12624,0.22708 0.18434,0.34325 0.25903,0.5179 0.45142,1.0733 0.52189,1.64806 0.0681,0.5553 0.0206,1.12512 -0.14432,1.65972 -0.17843,0.57845 -0.48871,1.10569 -0.79016,1.63063 -0.22005,0.3832 -0.43704,0.76871 -0.68222,1.13634 -0.21906,0.32847 -0.46033,0.64212 -0.72162,0.93811"
+ id="path4676-8"
+ inkscape:path-effect="#path-effect4678-8"
+ inkscape:original-d="m 298.49536,910.84427 c 0,0 -0.2552,-0.0219 0.18434,0.34325 0.30777,0.25609 0.42583,1.25943 0.52189,1.64806 0.13324,0.5392 -0.0316,1.11602 -0.14432,1.65972 -0.0926,0.44695 -0.58087,1.22501 -0.79016,1.63063 -0.35523,0.68836 -0.21753,0.51655 -0.68222,1.13634 -0.23667,0.31566 -0.72162,0.93811 -0.72162,0.93811"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssssc" />
+ <rect
+ y="950.8526"
+ x="266.54208"
+ height="25.103462"
+ width="24.405905"
+ id="rect4690-3"
+ style="color:#000000;fill:#e2cf96;fill-opacity:1;fill-rule:nonzero;stroke:#b19a58;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.37037036;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#e2cf96;fill-opacity:1;fill-rule:nonzero;stroke:#b19a58;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.37037036;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect4692-3"
+ width="24.405905"
+ height="25.103462"
+ x="294.30026"
+ y="950.8526" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path8776-8"
+ d="m 45.317184,794.59124 c -10.202593,0 -18.473418,8.27089 -18.473418,18.47341 0,0.0612 -5.89e-4,0.1195 0,0.18047 -0.709622,1.23413 -1.118508,2.6596 -1.118508,4.18539 0,3.77803 2.490031,6.98006 5.917267,8.04598 0.0058,0 0.0306,-0.0115 0.03603,0 3.378983,3.7128 8.222863,6.06158 13.638579,6.06158 2.280313,0 4.441933,-0.43505 6.45848,-1.19061 0.522648,0.11314 1.067278,0.18035 1.62364,0.18035 2.431853,0 4.587435,-1.11823 5.989428,-2.88647 1.083062,0.57406 2.333054,0.90208 3.64417,0.90208 1.128668,0 2.171517,-0.2524 3.139038,-0.6856 1.458281,0.45364 3.010821,0.6856 4.618354,0.6856 8.573494,0 15.514789,-6.94128 15.514789,-15.51479 0,-8.57351 -6.941295,-15.55092 -15.514789,-15.55092 -4.201883,0 -7.993228,1.6902 -10.788187,4.40188 -3.37507,-4.42393 -8.690899,-7.28835 -14.684923,-7.28835 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:0.28078841;fill-rule:nonzero;stroke:none;stroke-width:1.76498926;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:none;stroke:#008000;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 440.84709,960.07676 c 0,0 2.14873,-1.55882 4.7015,0.84978 0.2746,1.36218 -0.30614,1.91361 -0.30614,1.91361 l -4.42438,0.0404 z"
+ id="path4545-5-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="cscccc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 425.20871,950.64007 c 0,0 1.86439,7.83342 0.57234,15.96819 -1.29207,8.13467 -14.10225,-1.87367 -14.10225,-1.87367 l -0.73896,-15.84568 3.35245,-0.60697 z"
+ inkscape:path-effect="#path-effect6679-8"
+ id="path6677-3"
+ d="m 425.20871,950.64007 c 2.56178,1.74152 4.22044,4.74341 4.3314,7.8391 0.11095,3.0957 -1.32853,6.20863 -3.75906,8.12909 -2.07516,1.63967 -4.82592,2.39595 -7.44765,2.04761 -2.62173,-0.34833 -5.07958,-1.79664 -6.6546,-3.92128 l -0.73896,-15.84568 3.35245,-0.60697 10.91642,2.35813"
+ style="color:#000000;fill:#dcf2b0;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(1.1413935,0.17405607,-0.17405607,1.1413935,-23.799891,519.71886)"
+ id="g6698-9">
+ <g
+ style="color:#000000;fill:#dcaf60;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g4525-9"
+ transform="translate(-181.2137,-49.791143)"
+ inkscape:export-xdpi="134.28999"
+ inkscape:export-ydpi="134.28999">
+ <path
+ sodipodi:nodetypes="ssssscccsss"
+ id="path4527-1"
+ d="m 620.03942,344.29143 c -2.59977,0.26402 -4.625,2.48682 -4.625,5.15625 l 0,5.70857 c 0,2.84739 2.30886,5.15625 5.15625,5.15625 2.84739,0 5.15625,-2.30886 5.15625,-5.15625 l 0,-0.90625 2.71875,-0.0625 c 0.0244,-2.15098 -1.65479,-3.48205 -2.71875,-4.125 l 0,-0.61482 c 0,-2.84739 -2.30886,-5.15625 -5.15625,-5.15625 -0.17796,0 -0.35793,-0.0176 -0.53125,0 z"
+ style="color:#000000;fill:#dcaf60;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(348.41125,0.21364798)"
+ sodipodi:open="true"
+ sodipodi:end="4.0130333"
+ sodipodi:start="2.1549128"
+ d="m 274.8925,351.75972 c -0.68863,-0.45523 -0.87784,-1.38251 -0.42261,-2.07114 0.0791,-0.11963 0.17496,-0.22725 0.2847,-0.31956"
+ sodipodi:ry="1.4946961"
+ sodipodi:rx="1.4946961"
+ sodipodi:cy="350.51285"
+ sodipodi:cx="275.71677"
+ id="path4529-0"
+ style="color:#000000;fill:#dcaf60;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ id="g6663-2"
+ transform="translate(-243.08979,-87.905588)">
+ <path
+ style="color:#000000;fill:#eee8aa;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 675.27359,381.69204 c 0,0 -3.61906,-2.93343 -6.81651,-1.08738 -3.19745,1.84604 -5.13494,7.68161 -2.09252,12.95124 -0.82084,0.48215 -2.91788,0.16781 -2.91788,0.16781 1.26397,2.78835 5.40232,3.69932 7.22024,1.43927 1.81792,-2.26005 4.60505,-13.47152 4.60667,-13.47094 z"
+ id="path6665-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="czcczc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#ff7f50;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.74692678;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path6667-0"
+ sodipodi:cx="660.45526"
+ sodipodi:cy="377.89401"
+ sodipodi:rx="1.9102902"
+ sodipodi:ry="1.9115926"
+ d="m 662.36555,377.89401 c 0,1.05575 -0.85526,1.9116 -1.91029,1.9116 -1.05502,0 -1.91029,-0.85585 -1.91029,-1.9116 0,-1.05574 0.85527,-1.91159 1.91029,-1.91159 1.05503,0 1.91029,0.85585 1.91029,1.91159 z"
+ transform="matrix(0.92603044,0.01983755,-0.27468835,1.09644,165.84273,-46.640666)" />
+ <path
+ sodipodi:nodetypes="zczssscsssczz"
+ inkscape:connector-curvature="0"
+ id="path6669-8"
+ d="m 673.15276,387.85974 c 0,4.0455 2.90712,8.22999 4.82356,8.22999 0,0 2.70903,-0.58102 1.31422,-3.86008 -1.39481,-3.27905 1.55317,-2.73938 1.55317,-2.73938 0,-2.66943 0.59153,-5.9675 3.1913,-6.23152 0.17332,-0.0176 0.35329,0 0.53125,0 0.19972,0 0.40037,0.009 0.59375,0.0313 0.27718,1.03938 1.27138,1.8125 2.46875,1.8125 1.4113,0 2.5625,-1.08657 2.5625,-2.40625 0,-1.31968 -1.1512,-2.375 -2.5625,-2.375 -0.56029,0 -1.04756,0.18283 -1.46875,0.46875 -1.22824,-1.45445 -3.76164,-2.84864 -7.53366,-1.83793 -3.77202,1.01071 -5.47359,4.86212 -5.47359,8.90762 z"
+ style="color:#000000;fill:#eee8aa;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 441.4105,965.60943 13.2668,0 8.73149,-18.88872"
+ inkscape:path-effect="#path-effect4566-7-3"
+ id="path4564-2-4"
+ d="m 441.4105,965.60943 13.2668,0 8.73149,-18.88872"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g4628-2-9"
+ transform="matrix(1.06884,0.43664155,-0.43664155,1.06884,298.37281,435.60895)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4630-4-2"
+ d="m 295.05828,363.05901 -3.40274,0"
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 295.00031,359.49936 -3.2868,-0.8807"
+ id="path4632-1-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 295.00031,366.61866 -3.2868,0.8807"
+ id="path4634-4-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="matrix(0.98445818,-0.17561917,0.17561917,0.98445818,0,0)"
+ ry="3.5612204"
+ y="995.78815"
+ x="232.86958"
+ height="25.373697"
+ width="12.241695"
+ id="rect6671-0"
+ style="color:#000000;fill:#f2c1b0;fill-opacity:1;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="color:#000000;fill:#b0e1f2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(1.1545885,0,0,1.1545885,-96.234342,516.4607)"
+ id="g6751-6">
+ <path
+ sodipodi:nodetypes="ccccssssssscc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 458.9254,397.90026 10.42983,0 -0.18882,4.13356 5.21598,0 c 0,0 -0.1058,-0.91691 0,-2.29951 0.21669,-2.83164 0.92377,-1.61663 0,-4.4786 -0.2033,-0.62984 0.20329,-1.25968 0,-1.88951 -0.21289,-0.65957 0.1477,-0.94425 -0.41261,-1.35218 -0.24741,-0.18012 -0.91032,-0.41784 -1.3945,-0.52031 -0.63797,-0.13502 -1.12527,-0.10621 -1.52851,-0.10621 -0.61046,0 -1.22091,0 -1.83137,0 -2.60504,0 -7.81512,0 -7.81512,0 2.42596,-37.07148 -2.47488,6.51276 -2.47488,6.51276 z"
+ inkscape:path-effect="#path-effect6747-5"
+ id="path6743-1"
+ d="m 458.9254,397.90026 10.42983,0 -0.18882,4.13356 5.21598,0 c 0.003,-0.7665 0.003,-1.53301 0,-2.29951 -0.006,-1.49288 -0.0232,-2.98589 0,-4.4786 0.01,-0.62986 0.0268,-1.26014 0,-1.88951 -0.0102,-0.24067 -0.0271,-0.48263 -0.086,-0.71623 -0.0588,-0.23359 -0.16195,-0.46015 -0.32664,-0.63595 -0.17323,-0.18491 -0.4064,-0.3051 -0.64844,-0.38004 -0.24203,-0.075 -0.4948,-0.10762 -0.74606,-0.14027 -0.50699,-0.0659 -1.01725,-0.10621 -1.52851,-0.10621 l -1.83137,0 -7.81512,0 -2.47488,6.51276"
+ style="color:#000000;fill:#b0e1f2;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cscccc"
+ inkscape:connector-curvature="0"
+ inkscape:original-d="m 472.3316,401.27857 c 0,0 3.7083,0.79373 4.49339,2.48495 0.78508,1.69121 0.85411,1.76928 0.85411,1.76928 l -8.75642,-2.2904 0.69908,-2.67264 z"
+ inkscape:path-effect="#path-effect6749-3"
+ id="path6745-5"
+ d="m 472.3316,401.27857 c 0.83597,0.24233 1.67007,0.50677 2.44917,0.89481 0.77911,0.38804 1.50583,0.90624 2.04422,1.59014 0.40829,0.51863 0.70197,1.12699 0.85411,1.76928 l -8.75642,-2.2904 0.69908,-2.67264 c 0.90929,0.21246 1.81298,0.44884 2.70984,0.70881"
+ style="color:#000000;fill:#f0a4eb;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:1.76498926;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ transform="matrix(-0.00120505,-0.99999927,0.99999927,-0.00120505,0,0)"
+ ry="3.5612204"
+ y="405.41312"
+ x="-988.44574"
+ height="35.632931"
+ width="24.972927"
+ id="rect6675-7"
+ style="color:#000000;fill:#f2c1b0;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#f2c1b0;fill-opacity:1;fill-rule:nonzero;stroke:#213149;stroke-width:2.03783631;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect6673-2"
+ width="12.241695"
+ height="25.373695"
+ x="-971.26758"
+ y="415.67236"
+ ry="3.5612204"
+ transform="matrix(-0.00120505,-0.99999927,0.99999927,-0.00120505,0,0)" />
+ <g
+ id="g3672"
+ transform="matrix(0.1688388,0,0,0.1688388,84.007698,959.10604)">
+ <g
+ id="Layer_9">
+ <path
+ id="path3639"
+ d="M 313.25,252 H 265.3 c 1.047,-0.933 2.105,-1.85 3.175,-2.75 H 313.25 V 252 z m 0,61 v 18.75 h -80.5 V 292.3 c 1.324,-2.403 2.724,-4.778 4.2,-7.125 V 313 h 76.3 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#94c061;fill-rule:evenodd" />
+ <path
+ id="path3641"
+ d="m 232.75,292.3 v 39.45 h 80.5 V 313 h 3.7 v -61 h -3.7 v -2.75 h -44.775 c 1.307,-1.109 2.632,-2.192 3.975,-3.25 2.202,-1.742 4.435,-3.408 6.7,-5 4.153,-2.919 8.412,-5.585 12.775,-8 9.974,-5.517 20.499,-9.717 31.575,-12.6 12.134,-3.167 24.934,-4.75 38.4,-4.75 9.199,0 18.083,0.75 26.649,2.25 3,0.5 6,1.117 9,1.85 24.967,6 47.217,18.583 66.75,37.75 0.334,0.333 0.667,0.667 1,1 21.334,21.367 34.717,45.983 40.15,73.85 0.2,1.167 0.416,2.351 0.649,3.551 1.4,8.3 2.101,16.85 2.101,25.649 0,0.134 0,0.283 0,0.45 0,22.934 -4.601,43.967 -13.8,63.1 -4.601,9.434 -10.284,18.417 -17.051,26.95 -2,2.4 -4.033,4.783 -6.1,7.15 -1.934,2.133 -3.917,4.217 -5.95,6.25 -3.5,3.5 -7.066,6.8 -10.7,9.899 -4.833,4.034 -9.833,7.717 -15,11.051 -5.333,3.399 -10.833,6.416 -16.5,9.05 -0.533,0.2 -1.033,0.416 -1.5,0.649 -17.466,7.867 -36.483,11.967 -57.05,12.301 -0.533,0 -1.05,0 -1.55,0 -0.366,0 -0.733,0 -1.1,0 -40.434,0 -74.934,-14.317 -103.5,-42.95 -0.467,-0.467 -0.917,-0.917 -1.35,-1.351 -27.7,-28.3 -41.55,-62.333 -41.55,-102.1 0,-0.167 0,-0.316 0,-0.45 0.042,-14.928 2.042,-29.053 6,-42.375 0.517,-1.738 1.067,-3.464 1.65,-5.175 2.562,-7.495 5.762,-14.728 9.602,-21.699 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#658d38;fill-rule:evenodd" />
+ </g>
+ <g
+ id="Layer_6">
+ <path
+ id="path3644"
+ d="m 304.3,301.2 c -0.614,-0.905 -1.206,-1.821 -1.775,-2.75 0.907,-1.061 1.598,-2.144 2.075,-3.25 1.167,-2.333 1.75,-4.9 1.75,-7.7 0,-1.033 -0.083,-2.033 -0.25,-3 -0.368,-2.332 -1.21,-4.482 -2.525,-6.45 0.112,0.118 0.204,0.209 0.275,0.275 L 304,278.5 c 2.9,3.256 4.35,7.09 4.35,11.5 0,1.759 -0.233,3.425 -0.7,5 -0.266,0.932 -0.616,1.833 -1.05,2.7 -0.515,1.195 -1.282,2.362 -2.3,3.5 z m -7.475,5.225 c -1.841,0.65 -3.816,0.975 -5.925,0.975 -2.68,0 -5.146,-0.533 -7.4,-1.6 -1.783,-0.85 -3.433,-2.033 -4.95,-3.55 -0.894,-0.895 -1.669,-1.836 -2.325,-2.825 0.106,0.106 0.214,0.214 0.325,0.325 3.434,3.433 7.55,5.15 12.35,5.15 2.171,0 4.205,-0.35 6.1,-1.05 0.588,0.867 1.197,1.725 1.825,2.575 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#bbd89c;fill-rule:evenodd" />
+ <path
+ id="path3646"
+ d="m 333.575,324.85 c 0.758,-1.002 1.6,-1.968 2.524,-2.899 4.9,-4.867 10.801,-7.3 17.7,-7.3 3.473,0 6.689,0.616 9.65,1.85 -0.393,-0.553 -0.81,-1.095 -1.25,-1.625 0.193,0.112 0.385,0.229 0.575,0.35 0.349,0.262 0.69,0.537 1.024,0.825 1.32,1.517 2.354,3.133 3.101,4.851 0.1,0.199 0.199,0.383 0.3,0.55 1.1,2.033 1.866,4.184 2.3,6.45 0.063,0.356 0.121,0.715 0.175,1.074 -3.332,0.468 -6.757,0.7 -10.274,0.7 -9.27,0.001 -17.879,-1.608 -25.825,-4.826 z m 102.55,-21.8 c -0.209,-0.221 -0.417,-0.438 -0.625,-0.65 -1.628,-1.637 -3.294,-3.195 -5,-4.675 2.639,-5.218 4.613,-10.71 5.925,-16.475 l 25.851,-25.775 c 0.342,0.343 0.684,0.685 1.024,1.025 21.334,21.367 34.717,45.983 40.15,73.85 0.2,1.167 0.416,2.351 0.649,3.551 1.4,8.3 2.101,16.85 2.101,25.649 0,0.134 0,0.283 0,0.45 0,22.934 -4.601,43.967 -13.8,63.1 -4.601,9.434 -10.284,18.417 -17.051,26.95 -0.075,0.091 -0.15,0.183 -0.225,0.275 l 5.975,-21.976 c 0.101,-0.399 0.051,-0.816 -0.149,-1.25 -0.167,-0.366 -0.417,-0.683 -0.75,-0.949 -0.134,-0.034 -8.167,-8.784 -24.101,-26.25 3.448,-7.858 5.157,-14.851 5.125,-20.976 -0.005,-1.372 -0.005,-2.605 0,-3.7 0.547,-2.661 0.964,-5.245 1.25,-7.75 0.469,-4.224 0.561,-8.232 0.275,-12.024 0.033,-0.367 0.033,-0.783 0,-1.25 -0.4,-2.634 -0.884,-5.25 -1.45,-7.851 -2.666,-11.433 -7.75,-22.116 -15.25,-32.05 -1.333,-1.7 -2.7,-3.383 -4.1,-5.05 -1.467,-1.7 -2.95,-3.317 -4.45,-4.85 -0.455,-0.458 -0.913,-0.908 -1.374,-1.349 z M 255.05,462.1 301.775,415.526 c 1.695,2.331 3.52,4.623 5.475,6.875 0.874,0.999 1.757,1.975 2.65,2.925 l 51.075,81.075 c -0.362,0 -0.721,0 -1.074,0 -40.434,0 -74.934,-14.317 -103.5,-42.95 -0.454,-0.453 -0.903,-0.903 -1.351,-1.351 z M 368.6,340.05 c -1.316,3.908 -3.649,7.324 -7,10.25 -0.066,0.033 -0.149,0.117 -0.25,0.25 -0.1,0.033 -0.149,0.084 -0.149,0.15 -0.101,0.033 -0.167,0.083 -0.2,0.149 -0.434,0.367 -0.866,0.733 -1.3,1.101 -0.101,0.033 -0.2,0.1 -0.3,0.2 -2.434,1.8 -4.9,3.017 -7.4,3.649 l -2.85,0.601 c -0.267,0 -0.517,0.033 -0.75,0.1 -1,0.1 -2.034,0.15 -3.101,0.15 -0.1,0 -0.2,0 -0.3,0 -0.1,0 -0.2,0 -0.3,0 -0.101,0 -0.2,0 -0.3,0 -0.134,-0.067 -0.284,-0.101 -0.45,-0.101 h -0.25 c -4.182,-0.275 -7.89,-1.476 -11.125,-3.6 -2.517,-3.904 -3.775,-8.338 -3.775,-13.3 0,-2.092 0.226,-4.092 0.675,-6 9.717,4.448 20.358,6.682 31.926,6.699 2.441,-0.001 4.841,-0.102 7.199,-0.298 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#7bad45;fill-rule:evenodd" />
+ <path
+ id="path3648"
+ d="M 301.775,415.525 255.05,462.1 C 227.35,433.796 213.5,399.763 213.5,360 c 0,-0.167 0,-0.316 0,-0.45 0.089,-36.006 11.589,-67.339 34.5,-94 1.905,-2.214 3.888,-4.397 5.95,-6.55 0.805,-0.837 1.622,-1.671 2.45,-2.5 4.5,-4.5 9.184,-8.667 14.05,-12.5 0.165,-0.13 0.332,-0.264 0.5,-0.4 0.336,-0.264 0.669,-0.522 1,-0.775 0.154,-0.119 0.304,-0.235 0.45,-0.35 l 13.15,-8.95 c 0.752,-0.458 1.511,-0.908 2.275,-1.35 v 0.025 c 0.41,-0.238 0.818,-0.479 1.225,-0.725 l 1.225,-0.675 c 0.469,-0.25 0.935,-0.5 1.4,-0.75 4.524,-2.416 9.158,-4.565 13.9,-6.45 4.045,-1.601 8.171,-3.009 12.375,-4.225 1.177,-0.34 2.36,-0.665 3.55,-0.975 12.141,-3.167 24.94,-4.75 38.4,-4.75 9.199,0 18.083,0.75 26.649,2.25 3,0.5 6,1.117 9,1.85 7.557,1.815 14.865,4.231 21.925,7.25 6.836,10.689 10.252,22.79 10.25,36.3 0.002,10.708 -2.14,20.524 -6.425,29.45 -8.328,-5.511 -17.444,-9.411 -27.35,-11.7 -0.233,-0.066 -0.45,-0.117 -0.65,-0.15 -1.434,-0.333 -2.916,-0.633 -4.45,-0.9 -0.199,-0.033 -0.35,-0.05 -0.449,-0.05 -5.301,-0.7 -8.25,-1.067 -8.851,-1.1 h -0.05 c -18.967,-1.267 -36.134,2.783 -51.5,12.15 -4.233,2.567 -8.316,5.55 -12.25,8.95 -0.1,0.066 -0.167,0.15 -0.2,0.25 -0.133,0.1 -0.283,0.233 -0.45,0.4 -0.53,0.462 -1.056,0.929 -1.574,1.4 -2.051,1.869 -3.984,3.803 -5.8,5.8 -1.214,-1.499 -2.355,-3.032 -3.425,-4.6 1.019,-1.139 1.785,-2.305 2.3,-3.5 0.434,-0.868 0.784,-1.768 1.05,-2.7 0.467,-1.575 0.7,-3.241 0.7,-5 0,-4.41 -1.45,-8.244 -4.35,-11.5 l -0.15,-0.175 c -0.071,-0.066 -0.163,-0.158 -0.275,-0.275 -0.069,-0.076 -0.144,-0.159 -0.225,-0.25 -0.051,-0.051 -0.102,-0.101 -0.15,-0.15 -0.633,-0.633 -1.317,-1.217 -2.05,-1.75 -2.26,-1.695 -4.768,-2.728 -7.525,-3.1 H 293.6 c -0.432,-0.1 -0.898,-0.149 -1.4,-0.15 -0.434,-0.066 -0.867,-0.1 -1.3,-0.1 -0.333,0 -0.65,0.034 -0.95,0.1 -0.667,0 -1.317,0.05 -1.95,0.15 h -0.05 c -0.256,0.041 -0.506,0.091 -0.75,0.15 l -2.2,0.6 c -0.44,0.165 -0.874,0.348 -1.3,0.55 -0.117,0.05 -0.233,0.1 -0.35,0.15 -1.731,0.798 -3.332,1.931 -4.8,3.4 -0.2,0.2 -0.383,0.417 -0.55,0.65 -0.062,0.066 -0.12,0.133 -0.175,0.2 -1.904,2.117 -3.179,4.5 -3.825,7.15 -0.333,1.4 -0.5,2.85 -0.5,4.35 0,3.525 0.908,6.667 2.725,9.425 0.656,0.989 1.431,1.931 2.325,2.825 1.517,1.517 3.167,2.7 4.95,3.55 2.253,1.067 4.72,1.6 7.4,1.6 2.109,0 4.084,-0.325 5.925,-0.975 1.599,2.163 3.333,4.271 5.2,6.325 0.039,-0.053 0.081,-0.103 0.125,-0.15 -0.357,0.478 -0.708,0.961 -1.05,1.45 -0.7,1 -1.35,2 -1.95,3 -1.6,2.434 -3.083,4.967 -4.45,7.601 -0.016,0.033 -0.033,0.066 -0.05,0.1 -1.014,2.101 -1.964,4.217 -2.85,6.35 -0.633,1.601 -1.216,3.233 -1.75,4.9 -2.267,6.967 -3.683,14.384 -4.25,22.25 -1.522,21.336 3.803,40.428 15.975,57.274 z m 160.5,-160.05 -25.851,25.775 c 1.307,-5.716 1.966,-11.699 1.976,-17.95 -0.018,-11.181 -2.109,-21.498 -6.275,-30.95 10.682,6.175 20.731,13.884 30.15,23.125 z m -100.075,59.4 c -0.057,-0.069 -0.115,-0.136 -0.175,-0.2 0.254,0.176 0.504,0.359 0.75,0.55 -0.19,-0.121 -0.381,-0.238 -0.575,-0.35 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#94c061;fill-rule:evenodd" />
+ <path
+ id="path3650"
+ d="m 433,487.2 c -3.879,2.285 -7.846,4.368 -11.9,6.25 -0.533,0.2 -1.033,0.416 -1.5,0.649 -17.453,7.864 -36.47,11.956 -57.05,12.275 -0.523,0.01 -1.049,0.019 -1.575,0.025 L 309.9,425.325 c 0.931,0.984 1.873,1.943 2.825,2.875 2.176,2.226 4.417,4.309 6.725,6.25 2.767,2.366 5.684,4.533 8.75,6.5 10.033,6.566 21.25,10.816 33.649,12.75 0.101,0 0.233,0 0.4,0 5.441,-0.049 10.25,-0.207 14.425,-0.476 1.525,-0.091 2.968,-0.199 4.325,-0.324 5.1,-0.467 10.3,-1.184 15.6,-2.15 l 1.4,1.4 v 0.699 c 0.2,-0.03 0.399,-0.063 0.6,-0.1 L 433,487.2 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#6c983d;fill-rule:evenodd" />
+ <path
+ id="path3652"
+ d="m 414.8,207.875 c -14.804,-14.35 -32.604,-21.525 -53.399,-21.525 -21.301,0 -39.467,7.5 -54.5,22.5 -3.536,3.543 -6.652,7.26 -9.35,11.15 -2.247,3.233 -4.206,6.583 -5.875,10.05 -0.465,0.25 -0.931,0.5 -1.4,0.75 l -1.225,0.675 c -0.406,0.246 -0.815,0.487 -1.225,0.725 v -0.025 c 3.759,-9.244 9.451,-17.686 17.075,-25.325 15.042,-15.012 33.208,-22.521 54.5,-22.525 21.259,0.003 39.392,7.512 54.399,22.525 0.337,0.337 0.67,0.678 1,1.025 z m -6.1,6.075 c 0.331,0.331 0.664,0.665 1,1 3.316,3.316 6.225,6.799 8.725,10.45 7.55,11.081 11.325,23.714 11.325,37.9 0,10.513 -2.066,20.171 -6.2,28.975 -0.072,0.155 -0.147,0.314 -0.225,0.475 -0.525,1.09 -1.084,2.165 -1.675,3.225 -3.098,5.593 -7.081,10.818 -11.95,15.675 -4.908,4.92 -10.191,8.937 -15.851,12.05 -5.304,2.91 -10.937,5.027 -16.899,6.35 -1.729,0.384 -3.486,0.7 -5.275,0.95 -0.607,0.085 -1.216,0.16 -1.825,0.225 -2.757,0.317 -5.573,0.476 -8.449,0.476 -10.305,0 -19.788,-1.983 -28.45,-5.95 -2.097,-0.97 -4.146,-2.053 -6.15,-3.25 l -0.325,0.55 c -0.111,0.182 -0.22,0.365 -0.324,0.55 0.322,-0.596 0.673,-1.18 1.05,-1.75 2.078,1.124 4.203,2.124 6.375,3 7.946,3.219 16.555,4.827 25.825,4.825 3.518,0 6.942,-0.232 10.274,-0.7 0.526,-0.073 1.052,-0.156 1.575,-0.25 1.565,-0.254 3.106,-0.562 4.625,-0.925 11.948,-2.813 22.557,-8.863 31.825,-18.15 5.637,-5.626 10.078,-11.743 13.325,-18.35 0.096,-0.186 0.188,-0.369 0.274,-0.55 4.285,-8.926 6.427,-18.742 6.425,-29.45 0.002,-13.51 -3.414,-25.61 -10.25,-36.3 -2.478,-3.868 -5.403,-7.551 -8.775,-11.051 z M 295,303.85 c -6.065,-8.954 -9.948,-18.82 -11.65,-29.6 0.117,-0.05 0.233,-0.1 0.35,-0.15 0.426,-0.203 0.859,-0.386 1.3,-0.55 1.337,10.945 4.862,20.97 10.575,30.075 0.549,0.882 1.115,1.757 1.7,2.625 0.852,1.233 1.744,2.45 2.675,3.65 0.707,0.909 1.44,1.809 2.2,2.7 -0.044,0.047 -0.086,0.097 -0.125,0.15 -1.867,-2.054 -3.601,-4.163 -5.2,-6.325 -0.628,-0.85 -1.237,-1.708 -1.825,-2.575 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#e2e2e2;fill-rule:evenodd" />
+ <path
+ id="path3654"
+ d="m 305.575,223.6 c -4.743,1.884 -9.376,4.034 -13.9,6.45 1.669,-3.466 3.628,-6.816 5.875,-10.05 2.698,-3.89 5.814,-7.606 9.35,-11.15 15.034,-15 33.2,-22.5 54.5,-22.5 20.796,0 38.596,7.175 53.399,21.525 0.335,0.318 0.668,0.643 1,0.975 7.129,7.129 12.571,14.962 16.325,23.5 4.166,9.452 6.258,19.769 6.275,30.95 -0.01,6.251 -0.669,12.234 -1.976,17.95 -1.312,5.765 -3.286,11.257 -5.925,16.475 -0.037,0.074 -0.07,0.148 -0.1,0.225 -3.637,7.117 -8.504,13.716 -14.601,19.8 -10.662,10.686 -22.903,17.577 -36.725,20.675 -0.104,0.029 -0.203,0.054 -0.3,0.075 -2.47,0.547 -4.986,0.972 -7.551,1.275 -0.869,0.103 -1.744,0.194 -2.625,0.274 -2.357,0.196 -4.758,0.297 -7.199,0.3 -11.567,-0.018 -22.209,-2.251 -31.926,-6.699 -1.929,-0.879 -3.821,-1.846 -5.675,-2.9 0.047,-0.277 0.098,-0.552 0.15,-0.825 0.015,-0.092 0.031,-0.184 0.05,-0.274 0.173,-0.857 0.39,-1.69 0.65,-2.5 0.388,-1.194 0.871,-2.336 1.449,-3.426 l 0.051,-0.125 c 0.104,-0.185 0.213,-0.368 0.324,-0.55 l 0.325,-0.55 c 2.004,1.197 4.054,2.28 6.15,3.25 8.662,3.967 18.146,5.95 28.45,5.95 2.876,0 5.692,-0.158 8.449,-0.476 0.609,-0.064 1.218,-0.14 1.825,-0.225 1.789,-0.25 3.547,-0.566 5.275,-0.95 5.963,-1.322 11.596,-3.439 16.899,-6.35 5.659,-3.113 10.942,-7.13 15.851,-12.05 4.869,-4.857 8.853,-10.082 11.95,-15.675 0.591,-1.061 1.149,-2.135 1.675,-3.225 0.077,-0.161 0.152,-0.32 0.225,-0.475 4.134,-8.804 6.2,-18.462 6.2,-28.975 0,-14.186 -3.775,-26.819 -11.325,-37.9 -2.5,-3.65 -5.408,-7.134 -8.725,-10.45 -0.336,-0.335 -0.669,-0.669 -1,-1 -13.142,-12.666 -28.908,-18.983 -47.3,-18.95 -18.9,-0.033 -35.034,6.617 -48.4,19.95 -2.754,2.768 -5.228,5.651 -7.419,8.651 z m 115.775,211.8 -3.1,2.449 c -0.2,0.134 -0.366,0.25 -0.5,0.351 -0.267,0.2 -0.517,0.366 -0.75,0.5 -1.134,0.733 -2.267,1.467 -3.4,2.2 -0.1,0.033 -0.183,0.083 -0.25,0.149 l 65.601,65.75 c 0.133,0.134 0.316,0.316 0.55,0.55 l 1.1,1.101 c 1.4,1.366 3.067,2.05 5,2.05 1.634,-0.066 3.051,-0.55 4.25,-1.45 0.301,-0.166 0.551,-0.383 0.75,-0.649 0.233,-0.167 1.25,0.399 3.051,1.699 1.767,1.334 5.116,4.817 10.05,10.45 4.866,5.533 11.833,9.533 20.899,12 -5.933,1 -14.783,1.7 -26.55,2.101 -11.121,0.349 -19.721,-2.201 -25.8,-7.65 -1.462,-1.316 -2.778,-2.8 -3.95,-4.45 l -20.1,-20.1 h 0.05 L 433,487.2 l -34.4,-34.45 -0.6,-0.6 -1.4,-1.4 c -5.3,0.967 -10.5,1.684 -15.6,2.15 -1.357,0.125 -2.8,0.233 -4.325,0.324 l 33.95,-33.925 c 0.542,0.528 1.075,1.045 1.6,1.55 4.902,4.798 8.96,8.848 12.176,12.15 -0.167,0.066 -0.284,0.167 -0.351,0.3 -0.899,0.733 -1.767,1.45 -2.6,2.15 l -0.1,-0.049 z M 302.15,312.6 c -0.759,-0.891 -1.493,-1.791 -2.2,-2.7 -0.932,-1.2 -1.823,-2.417 -2.675,-3.65 -0.584,-0.868 -1.151,-1.743 -1.7,-2.625 -5.713,-9.105 -9.238,-19.13 -10.575,-30.075 l 2.2,-0.6 c 0.244,-0.06 0.494,-0.109 0.75,-0.15 H 288 c 0.633,-0.1 1.283,-0.15 1.95,-0.15 0.3,-0.066 0.617,-0.1 0.95,-0.1 0.434,0 0.867,0.034 1.3,0.1 0.501,0 0.968,0.05 1.4,0.15 h 0.025 c 0.946,7.487 3.054,14.487 6.325,21 0.793,1.581 1.651,3.131 2.575,4.65 0.569,0.929 1.161,1.845 1.775,2.75 1.07,1.567 2.211,3.101 3.425,4.6 -0.236,0.257 -0.469,0.515 -0.7,0.775 l -4.875,6.025 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#d3d3d3;fill-rule:evenodd" />
+ <path
+ id="path3656"
+ d="m 309.9,425.325 c -0.893,-0.95 -1.776,-1.926 -2.65,-2.925 -1.955,-2.252 -3.78,-4.544 -5.475,-6.875 -12.172,-16.847 -17.497,-35.938 -15.975,-57.275 0.567,-7.866 1.983,-15.283 4.25,-22.25 0.534,-1.667 1.117,-3.3 1.75,-4.9 0.886,-2.133 1.836,-4.249 2.85,-6.35 0.017,-0.033 0.034,-0.066 0.05,-0.1 1.367,-2.634 2.85,-5.167 4.45,-7.601 0.6,-1 1.25,-2 1.95,-3 0.342,-0.488 0.692,-0.972 1.05,-1.45 l 4.875,-6.025 c 0.231,-0.26 0.464,-0.519 0.7,-0.775 1.816,-1.997 3.75,-3.931 5.8,-5.8 0.519,-0.471 1.044,-0.938 1.574,-1.4 0.167,-0.167 0.317,-0.3 0.45,-0.4 0.033,-0.1 0.101,-0.184 0.2,-0.25 3.934,-3.4 8.017,-6.383 12.25,-8.95 15.366,-9.367 32.533,-13.417 51.5,-12.15 h 0.05 c 0.601,0.033 3.55,0.4 8.851,1.1 0.1,0 0.25,0.017 0.449,0.05 1.534,0.267 3.017,0.567 4.45,0.9 0.2,0.033 0.417,0.083 0.65,0.15 9.905,2.289 19.021,6.189 27.35,11.7 -0.087,0.181 -0.179,0.364 -0.274,0.55 -7.707,-4.751 -16.065,-8.167 -25.075,-10.25 -0.233,-0.066 -0.45,-0.117 -0.65,-0.15 -1.434,-0.333 -2.916,-0.633 -4.45,-0.9 -0.199,-0.033 -0.35,-0.05 -0.449,-0.05 -5.301,-0.7 -8.25,-1.067 -8.851,-1.1 h -0.05 c -18.98,-1.281 -36.146,2.769 -51.5,12.15 -4.22,2.58 -8.303,5.563 -12.25,8.95 -0.1,0.066 -0.167,0.15 -0.2,0.25 -0.133,0.1 -0.283,0.233 -0.45,0.4 -5.433,4.733 -10.1,9.883 -14,15.45 -0.7,1 -1.35,2 -1.95,3 -1.6,2.434 -3.083,4.967 -4.45,7.601 -1.034,2.133 -2,4.283 -2.9,6.449 -0.634,1.608 -1.217,3.242 -1.75,4.9 -2.268,6.971 -3.685,14.388 -4.25,22.25 -1.451,20.351 3.324,38.659 14.325,54.925 2.144,3.148 4.519,6.224 7.125,9.226 0.08,0.091 0.163,0.183 0.25,0.274 1.057,1.209 2.132,2.384 3.225,3.525 -0.952,-0.93 -1.894,-1.889 -2.825,-2.874 z M 363.8,316.05 c 0.185,0.165 0.368,0.332 0.55,0.5 2.034,1.934 3.551,4.05 4.551,6.351 0.1,0.199 0.199,0.383 0.3,0.55 0.91,1.683 1.594,3.44 2.05,5.274 -0.523,0.094 -1.049,0.177 -1.575,0.25 -0.054,-0.359 -0.112,-0.718 -0.175,-1.074 -0.434,-2.267 -1.2,-4.417 -2.3,-6.45 -0.101,-0.167 -0.2,-0.351 -0.3,-0.55 -0.748,-1.718 -1.781,-3.335 -3.101,-4.851 z m -33.9,34.85 c 0.853,0.762 1.744,1.445 2.675,2.05 3.235,2.124 6.943,3.324 11.125,3.6 h 0.25 c 0.166,0 0.316,0.033 0.45,0.101 0.1,0 0.199,0 0.3,0 0.1,0 0.2,0 0.3,0 0.1,0 0.2,0 0.3,0 1.066,0 2.101,-0.051 3.101,-0.15 0.233,-0.066 0.483,-0.1 0.75,-0.1 L 352,355.8 c 2.5,-0.633 4.967,-1.85 7.4,-3.649 0.1,-0.101 0.199,-0.167 0.3,-0.2 0.434,-0.367 0.866,-0.733 1.3,-1.101 0.033,-0.066 0.1,-0.116 0.2,-0.149 0,-0.066 0.05,-0.117 0.149,-0.15 0.101,-0.133 0.184,-0.217 0.25,-0.25 3.351,-2.926 5.684,-6.342 7,-10.25 0.881,-0.08 1.756,-0.172 2.625,-0.274 -1.101,4.872 -3.643,9.047 -7.625,12.524 -0.066,0.033 -0.149,0.117 -0.25,0.25 -0.1,0.033 -0.149,0.084 -0.149,0.15 -0.101,0.033 -0.167,0.083 -0.2,0.149 -0.434,0.367 -0.866,0.733 -1.3,1.101 -0.101,0.033 -0.2,0.1 -0.3,0.2 -2.434,1.8 -4.9,3.017 -7.4,3.649 l -2.85,0.601 c -0.267,0 -0.517,0.033 -0.75,0.1 -1,0.1 -2.034,0.15 -3.101,0.15 -0.1,0 -0.2,0 -0.3,0 -0.1,0 -0.2,0 -0.3,0 -0.101,0 -0.2,0 -0.3,0 -0.134,-0.067 -0.284,-0.101 -0.45,-0.101 h -0.25 c -5.009,-0.33 -9.343,-1.98 -13,-4.95 -0.979,-0.805 -1.912,-1.705 -2.799,-2.7 z m 100.6,-53.175 c 1.706,1.48 3.372,3.038 5,4.675 0.208,0.212 0.416,0.429 0.625,0.65 -1.864,-1.801 -3.772,-3.501 -5.725,-5.1 0.03,-0.076 0.063,-0.151 0.1,-0.225 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#b6b6b6;fill-rule:evenodd" />
+ <path
+ id="path3658"
+ d="m 462.475,367.475 -51.85,51.825 -33.95,33.925 c -4.175,0.269 -8.983,0.427 -14.425,0.476 -0.167,0 -0.3,0 -0.4,0 -12.399,-1.934 -23.616,-6.184 -33.649,-12.75 -3.066,-1.967 -5.983,-4.134 -8.75,-6.5 -2.308,-1.941 -4.549,-4.024 -6.725,-6.25 -1.093,-1.142 -2.168,-2.316 -3.225,-3.525 -0.087,-0.092 -0.17,-0.184 -0.25,-0.274 -2.606,-3.002 -4.981,-6.077 -7.125,-9.226 -11.001,-16.266 -15.776,-34.574 -14.325,-54.925 0.565,-7.862 1.982,-15.279 4.25,-22.25 0.533,-1.658 1.116,-3.292 1.75,-4.9 0.9,-2.166 1.867,-4.316 2.9,-6.449 1.367,-2.634 2.85,-5.167 4.45,-7.601 0.6,-1 1.25,-2 1.95,-3 3.9,-5.566 8.566,-10.716 14,-15.45 0.167,-0.167 0.317,-0.3 0.45,-0.4 0.033,-0.1 0.101,-0.184 0.2,-0.25 3.947,-3.387 8.03,-6.37 12.25,-8.95 15.354,-9.381 32.52,-13.431 51.5,-12.15 h 0.05 c 0.601,0.033 3.55,0.4 8.851,1.1 0.1,0 0.25,0.017 0.449,0.05 1.534,0.267 3.017,0.567 4.45,0.9 0.2,0.033 0.417,0.083 0.65,0.15 9.01,2.083 17.368,5.499 25.075,10.25 -3.247,6.607 -7.688,12.724 -13.325,18.35 -9.269,9.287 -19.877,15.336 -31.825,18.15 -1.519,0.363 -3.06,0.671 -4.625,0.925 -0.456,-1.834 -1.14,-3.592 -2.05,-5.274 -0.101,-0.167 -0.2,-0.351 -0.3,-0.55 -1,-2.301 -2.517,-4.417 -4.551,-6.351 -0.182,-0.168 -0.365,-0.335 -0.55,-0.5 -0.334,-0.288 -0.676,-0.563 -1.024,-0.825 -0.246,-0.19 -0.496,-0.374 -0.75,-0.55 -3.474,-2.444 -7.615,-3.87 -12.426,-4.275 -2.301,-0.139 -4.501,0.011 -6.6,0.45 -3.92,0.822 -7.487,2.656 -10.7,5.5 -0.233,0.167 -0.45,0.351 -0.649,0.551 -1.766,1.505 -3.249,3.154 -4.45,4.949 -0.377,0.57 -0.728,1.154 -1.05,1.75 l -0.051,0.125 c -0.578,1.09 -1.062,2.231 -1.449,3.426 -0.261,0.81 -0.478,1.643 -0.65,2.5 -0.019,0.091 -0.035,0.183 -0.05,0.274 -0.053,0.273 -0.104,0.548 -0.15,0.825 -0.114,0.75 -0.198,1.517 -0.25,2.3 0,0.033 0,0.084 0,0.15 -0.09,1.646 -0.04,3.246 0.15,4.8 0.082,0.744 0.199,1.478 0.35,2.2 0.834,3.666 2.601,7.066 5.3,10.2 0.018,0.016 0.034,0.032 0.051,0.05 h 0.1 c 0.133,0.155 0.266,0.306 0.4,0.45 0.887,0.994 1.819,1.895 2.8,2.699 3.657,2.97 7.991,4.62 13,4.95 h 0.25 c 0.166,0 0.316,0.033 0.45,0.101 0.1,0 0.199,0 0.3,0 0.1,0 0.2,0 0.3,0 0.1,0 0.2,0 0.3,0 1.066,0 2.101,-0.051 3.101,-0.15 0.233,-0.066 0.483,-0.1 0.75,-0.1 L 354,357.8 c 2.5,-0.633 4.967,-1.85 7.4,-3.649 0.1,-0.101 0.199,-0.167 0.3,-0.2 0.434,-0.367 0.866,-0.733 1.3,-1.101 0.033,-0.066 0.1,-0.116 0.2,-0.149 0,-0.066 0.05,-0.117 0.149,-0.15 0.101,-0.133 0.184,-0.217 0.25,-0.25 3.982,-3.478 6.524,-7.652 7.625,-12.524 2.564,-0.304 5.081,-0.729 7.551,-1.275 0.097,-0.021 0.196,-0.046 0.3,-0.075 13.821,-3.098 26.063,-9.989 36.725,-20.675 6.097,-6.083 10.964,-12.683 14.601,-19.8 1.952,1.598 3.86,3.298 5.725,5.1 0.461,0.441 0.919,0.892 1.375,1.35 1.5,1.533 2.983,3.15 4.45,4.85 1.399,1.667 2.767,3.35 4.1,5.05 7.5,9.934 12.584,20.617 15.25,32.05 0.566,2.601 1.05,5.217 1.45,7.851 0.033,0.467 0.033,0.883 0,1.25 0.284,3.789 0.192,7.798 -0.276,12.022 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#a3a3a3;fill-rule:evenodd" />
+ <path
+ id="path3660"
+ d="m 474.175,453.9 h -0.024 v 0.05 c -0.367,0.066 -0.75,0.033 -1.15,-0.101 -0.192,-0.096 -0.359,-0.229 -0.5,-0.399 -0.115,-0.131 -0.216,-0.281 -0.3,-0.45 v -0.15 c -0.134,-0.333 -0.134,-0.683 0,-1.05 l -0.05,0.101 6.949,-25.551 c 0.101,-0.399 0.051,-0.816 -0.149,-1.25 -0.167,-0.366 -0.417,-0.683 -0.75,-0.949 -0.134,-0.034 -8.167,-8.784 -24.101,-26.25 1.967,-3.834 4.051,-10.117 6.25,-18.851 0.32,-1.295 0.612,-2.57 0.875,-3.825 -0.005,1.095 -0.005,2.328 0,3.7 0.032,6.125 -1.677,13.117 -5.125,20.976 15.934,17.466 23.967,26.216 24.101,26.25 0.333,0.267 0.583,0.583 0.75,0.949 0.2,0.434 0.25,0.851 0.149,1.25 l -5.975,21.976 -0.975,3.575 0.05,-0.101 c -0.012,0.032 -0.02,0.065 -0.025,0.1 z m 53.775,19.45 c 6.564,5.904 9.681,14.588 9.35,26.051 -0.467,13.733 -1.383,23.517 -2.75,29.35 -0.233,1.167 -0.767,2.25 -1.6,3.25 l -0.15,0.3 c -0.333,0.233 -0.649,0.45 -0.95,0.65 -0.8,0.533 -1.666,0.866 -2.6,1 -0.8,0.2 -1.684,0.399 -2.65,0.6 -5.933,1 -14.783,1.7 -26.55,2.101 -12.402,0.389 -21.669,-2.827 -27.8,-9.65 6.079,5.449 14.679,7.999 25.8,7.65 11.767,-0.4 20.617,-1.101 26.55,-2.101 0.967,-0.2 1.851,-0.399 2.65,-0.6 0.934,-0.134 1.8,-0.467 2.6,-1 0.301,-0.2 0.617,-0.417 0.95,-0.65 l 0.15,-0.3 c 0.833,-1 1.366,-2.083 1.6,-3.25 1.367,-5.833 2.283,-15.616 2.75,-29.35 0.296,-10.23 -2.154,-18.247 -7.35,-24.051 z m -31.125,3.225 c -0.357,0.039 -0.698,0.014 -1.025,-0.075 -0.333,-0.2 -0.6,-0.467 -0.8,-0.8 -0.066,-0.066 -0.1,-0.15 -0.1,-0.25 -0.134,-0.334 -0.15,-0.667 -0.051,-1 l 0.051,-0.05 6.75,-25.051 c 0.1,-0.433 0.083,-0.85 -0.051,-1.25 1.423,1.927 2.105,3.01 2.051,3.25 l -6.75,25.051 -0.051,0.05 c -0.011,0.039 -0.019,0.081 -0.024,0.125 z M 398.6,452.75 c -0.2,0.036 -0.399,0.069 -0.6,0.1 v -0.699 l 0.6,0.599 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#8f8f8f;fill-rule:evenodd" />
+ <path
+ id="path3662"
+ d="m 410.625,419.3 51.85,-51.825 c -0.286,2.505 -0.703,5.089 -1.25,7.75 -0.263,1.255 -0.555,2.53 -0.875,3.825 -2.199,8.733 -4.283,15.017 -6.25,18.851 15.934,17.466 23.967,26.216 24.101,26.25 0.333,0.267 0.583,0.583 0.75,0.949 0.2,0.434 0.25,0.851 0.149,1.25 l -6.95,25.55 0.05,-0.101 c -0.134,0.367 -0.134,0.717 0,1.05 V 453 c 0.084,0.169 0.185,0.319 0.3,0.45 0.141,0.17 0.308,0.304 0.5,0.399 0.4,0.134 0.783,0.167 1.15,0.101 v -0.05 h 0.024 l 25.325,-6.65 c 0.434,-0.233 0.833,-0.217 1.2,0.05 0.333,0.167 0.633,0.434 0.899,0.8 0.134,0.4 0.15,0.817 0.051,1.25 l -6.749,25.05 -0.051,0.05 c -0.1,0.333 -0.083,0.666 0.051,1 0,0.1 0.033,0.184 0.1,0.25 0.2,0.333 0.467,0.6 0.8,0.8 0.327,0.089 0.668,0.114 1.025,0.075 0.039,-0.01 0.081,-0.018 0.125,-0.025 v 0.101 l 0.1,-0.101 26.65,-7 c 1.576,1.142 2.992,2.408 4.25,3.8 5.195,5.805 7.646,13.821 7.35,24.051 -0.467,13.733 -1.383,23.517 -2.75,29.35 -0.233,1.167 -0.767,2.25 -1.6,3.25 l -0.15,0.3 c -0.333,0.233 -0.649,0.45 -0.95,0.65 -0.8,0.533 -1.666,0.866 -2.6,1 -0.8,0.2 -1.684,0.399 -2.65,0.6 -21.5,-21.6 -32.816,-32.934 -33.949,-34 L 430.55,438.2 c -0.2,-0.101 -0.366,-0.233 -0.5,-0.4 l -5.2,-5.25 -0.149,0.15 c -0.101,0.066 -0.2,0.166 -0.3,0.3 -3.216,-3.303 -7.273,-7.353 -12.176,-12.15 -0.525,-0.505 -1.058,-1.022 -1.6,-1.55 z m 10.725,16.1 0.101,0.05 h -0.101 v -0.05 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#dbdbdb;fill-rule:evenodd" />
+ <path
+ id="path3664"
+ d="m 421.35,435.4 v 0.05 h 0.101 c 0.833,-0.7 1.7,-1.417 2.6,-2.15 0.066,-0.133 0.184,-0.233 0.351,-0.3 0.1,-0.134 0.199,-0.233 0.3,-0.3 l 0.149,-0.15 5.2,5.25 c 0.134,0.167 0.3,0.3 0.5,0.4 l 60.101,60.35 c 1.133,1.066 12.449,12.4 33.949,34 -9.066,-2.467 -16.033,-6.467 -20.899,-12 -4.934,-5.633 -8.283,-9.116 -10.05,-10.45 -1.801,-1.3 -2.817,-1.866 -3.051,-1.699 -0.199,0.267 -0.449,0.483 -0.75,0.649 -1.199,0.9 -2.616,1.384 -4.25,1.45 -1.933,0 -3.6,-0.684 -5,-2.05 l -1.1,-1.101 c -0.233,-0.233 -0.417,-0.416 -0.55,-0.55 l -65.601,-65.75 c 0.067,-0.066 0.15,-0.116 0.25,-0.149 1.134,-0.733 2.267,-1.467 3.4,-2.2 0.233,-0.134 0.483,-0.3 0.75,-0.5 0.134,-0.101 0.3,-0.217 0.5,-0.351 l 3.1,-2.449 z"
+ clip-rule="evenodd"
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-rule:evenodd" />
+ </g>
+ </g>
+ <text
+ inkscape:export-ydpi="134.53"
+ inkscape:export-xdpi="134.53"
+ inkscape:export-filename="/home/rlafuente/Projects/GPG/infog/precolor.png"
+ xml:space="preserve"
+ style="font-size:12.16765976px;font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Dosis;-inkscape-font-specification:Dosis Ultra-Bold"
+ x="172.80153"
+ y="1028.6682"
+ id="text16247-9"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan16249-5"
+ x="172.80153"
+ y="1028.6682"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;font-family:Droid Sans;-inkscape-font-specification:Droid Sans">Open</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#666666;fill-opacity:1;stroke:none;font-family:Droid Sans;-inkscape-font-specification:Droid Sans"
+ x="231.51491"
+ y="1028.7281"
+ id="text3883"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3885"
+ x="231.51491"
+ y="1028.7281">Keychain</tspan></text>
+ </g>
+</svg>
diff --git a/Graphics/drawables/first_time_1.svg b/Graphics/drawables/first_time_1.svg
new file mode 100644
index 000000000..eb44a8b8f
--- /dev/null
+++ b/Graphics/drawables/first_time_1.svg
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="512"
+ height="512"
+ id="svg4325"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="first_time_1.svg"
+ inkscape:export-filename="/home/schuerm/Projekte/OpenKeychain/Graphics/drawables/first_time_1.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4327" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="314.76047"
+ inkscape:cy="246.12576"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="2558"
+ inkscape:window-height="1419"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata4330">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-540.36218)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#8bc34a;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path4501"
+ sodipodi:cx="227.53687"
+ sodipodi:cy="246.58241"
+ sodipodi:rx="225.51656"
+ sodipodi:ry="225.51656"
+ d="m 453.05342,246.58241 c 0,124.54936 -100.9672,225.51656 -225.51655,225.51656 -124.54936,0 -225.5165606,-100.9672 -225.5165606,-225.51656 0,-124.54935 100.9672006,-225.516553 225.5165606,-225.516553 124.54935,0 225.51655,100.967203 225.51655,225.516553 z"
+ transform="translate(28.463135,549.77977)" />
+ <path
+ sodipodi:type="star"
+ style="color:#000000;fill:#ffffff;fill-opacity:0.16256157;fill-rule:nonzero;stroke:none;stroke-width:1.76498926;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path7021"
+ sodipodi:sides="25"
+ sodipodi:cx="237.45834"
+ sodipodi:cy="671.60583"
+ sodipodi:r1="60.973591"
+ sodipodi:r2="37.364418"
+ sodipodi:arg1="0.87061839"
+ sodipodi:arg2="0.99902889"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 276.74691,718.23402 -19.06996,-15.20673 6.23968,23.51249 -14.68908,-19.47149 0.19632,24.32554 -9.38523,-22.51278 -5.85936,23.61014 -3.49167,-24.13951 -11.54688,21.41122 2.62127,-24.24948 -16.50886,17.86696 8.56952,-22.83575 -20.43354,13.20005 13.97931,-19.98717 -23.0743,7.70373 18.51073,-15.88272 -24.26522,1.72335 21.87906,-10.7803 -23.93146,-4.3653 23.87263,-5.00052 -22.094,-10.17967 24.36621,1.09346 -18.8683,-15.35441 23.32877,7.11874 -14.45703,-19.56438 20.8255,12.69672 -9.13738,-22.54504 17.01368,17.47692 -3.24358,-24.10913 12.13283,21.15898 2.85402,-24.15834 6.48963,23.51155 8.77228,-22.6896 0.43867,24.38679 14.13936,-19.79518 -5.63987,23.72973 18.61801,-15.65696 -11.36402,21.58163 21.92682,-10.53495 -16.37414,18.07749 23.85789,-4.75101 -20.35541,13.43747 24.28988,1.33147 -23.05767,7.95313 23.19564,7.33029 -24.31112,1.96905 20.64393,12.86851 -24.03703,-4.13873 16.7951,17.59816 -22.2526,-9.98648 z"
+ transform="matrix(2.3346891,0,0,2.3346891,-297.98143,-788.87687)"
+ inkscape:transform-center-x="0.48070196"
+ inkscape:transform-center-y="0.080663394" />
+ <rect
+ ry="14.623538"
+ rx="14.623538"
+ y="778.16095"
+ x="189.31395"
+ height="91.847595"
+ width="133.37183"
+ id="rect3529"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254.33815,626.00818 c -27.93766,0 -50.4195,22.48185 -50.4195,50.41951 l 0,93.04182 c 0,27.93768 22.48184,50.44562 50.4195,50.44562 l 3.3229,0 c 27.93773,0 50.4195,-22.50794 50.4195,-50.44562 l 0,-93.04182 c 0,-27.93766 -22.48177,-50.41951 -50.4195,-50.41951 l -3.3229,0 z m 1.67456,16.74544 c 20.12817,0 35.95034,15.82142 35.95034,35.47939 l 0,74.46486 c 0,19.65806 -15.82217,35.47941 -35.95034,35.47941 -20.1282,0 -35.97658,-15.82135 -35.97658,-35.47941 l 0,-74.46486 c 0,-19.65797 15.84838,-35.47939 35.97658,-35.47939 z"
+ id="path3531" />
+ <rect
+ ry="3.9737797"
+ rx="3.9737797"
+ y="706.40234"
+ x="171.49129"
+ height="124.14557"
+ width="169.01746"
+ id="rect3533"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0"
+ id="path3535"
+ d="m 199.31408,796.34234 c 12.41682,10.27683 33.179,17.03328 56.69903,17.03328 23.51804,0 44.25559,-6.75787 56.67285,-17.03328 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(0.90538746,0,0,0.90538746,-76.624431,405.57604)"
+ d="m 316.87315,407.66223 c 0,5.18531 -4.20353,9.38884 -9.38884,9.38884 -5.18531,0 -9.38883,-4.20353 -9.38883,-9.38884 0,-5.18531 4.20352,-9.38883 9.38883,-9.38883 5.18531,0 9.38884,4.20352 9.38884,9.38883 z"
+ sodipodi:ry="9.388834"
+ sodipodi:rx="9.388834"
+ sodipodi:cy="407.66223"
+ sodipodi:cx="307.48431"
+ id="path3537"
+ style="color:#000000;fill:#4b4f2f;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.55131245;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.90538746,0,0,0.90538746,36.007648,405.57604)"
+ sodipodi:type="arc"
+ style="color:#000000;fill:#4b4f2f;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.55131245;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path3539"
+ sodipodi:cx="307.48431"
+ sodipodi:cy="407.66223"
+ sodipodi:rx="9.388834"
+ sodipodi:ry="9.388834"
+ d="m 316.87315,407.66223 c 0,5.18531 -4.20353,9.38884 -9.38884,9.38884 -5.18531,0 -9.38883,-4.20353 -9.38883,-9.38884 0,-5.18531 4.20352,-9.38883 9.38883,-9.38883 5.18531,0 9.38884,4.20352 9.38884,9.38883 z" />
+ <g
+ id="g10754"
+ transform="matrix(0.83727181,0,0,0.83727181,829.92363,-416.95697)"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <g
+ id="g5737-8"
+ transform="translate(-898.12108,631.20806)"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5739-5"
+ width="29.344997"
+ height="96.371902"
+ x="153.20558"
+ y="918.29181"
+ rx="0.84849852"
+ ry="0.95320696" />
+ <path
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0"
+ id="path5741-6"
+ d="m 192.11794,916.83294 c -7.43536,-12.87842 -23.7891,-17.26042 -36.66754,-9.82505 -12.87845,7.43537 -17.26039,23.78913 -9.82503,36.66755 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="3"
+ rx="3"
+ y="1010.0776"
+ x="133.00574"
+ height="11.311689"
+ width="69.74469"
+ id="rect5743-2"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 145.00574,916.83294 c 7.43536,-12.87842 23.7891,-17.26042 36.66754,-9.82505 12.87845,7.43537 17.26039,23.78913 9.82503,36.66755 z"
+ id="path5745-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cscc" />
+ <rect
+ ry="7.1440544"
+ rx="7.1440544"
+ y="968.78937"
+ x="145.20558"
+ height="14.288109"
+ width="45.344997"
+ id="rect5747-2"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g5749-5"
+ transform="matrix(-1,0,0,1,-472.81628,631.20806)"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ ry="0.95320696"
+ rx="0.84849852"
+ y="918.29181"
+ x="153.20558"
+ height="96.371902"
+ width="29.344997"
+ id="rect5751-5"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 192.11794,916.83294 c -7.43536,-12.87842 -23.7891,-17.26042 -36.66754,-9.82505 -12.87845,7.43537 -17.26039,23.78913 -9.82503,36.66755 z"
+ id="path5753-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cscc" />
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5755-0"
+ width="69.74469"
+ height="11.311689"
+ x="133.00574"
+ y="1010.0776"
+ rx="3"
+ ry="3" />
+ <path
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0"
+ id="path5757-1"
+ d="m 145.00574,916.83294 c 7.43536,-12.87842 23.7891,-17.26042 36.66754,-9.82505 12.87845,7.43537 17.26039,23.78913 9.82503,36.66755 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5759-7"
+ width="45.344997"
+ height="14.288109"
+ x="145.20558"
+ y="968.78937"
+ rx="7.1440544"
+ ry="7.1440544" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0.83727181,0,0,0.83727181,84.650265,61.513651)"
+ id="g5697-5"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0"
+ id="path5699-6"
+ d="m 326.98547,847.70808 57.45819,0 0,-73.83379 -10,0 0,61.83379 -47.45819,0"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5703-1"
+ width="9.4107542"
+ height="42.249756"
+ x="305.50339"
+ y="821.53503"
+ rx="4.7053771"
+ ry="4.7053771" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 390.56742,727.10519 c -6.09957,0 -11,4.90043 -11,11 l 0,10.15625 -10.15625,0 c -6.09957,0 -11,4.90043 -11,11 0,6.09957 4.90043,11 11,11 l 21.15625,0 c 6.09957,0 11,-4.90043 11,-11 l 0,-21.15625 c 0,-6.09957 -4.90043,-11 -11,-11 z"
+ id="path5705-8" />
+ <rect
+ ry="2.1935852"
+ rx="4.0765176"
+ y="771.6814"
+ x="369.11923"
+ height="12.20938"
+ width="21.740107"
+ id="rect5707-1"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="2.9156427"
+ rx="7.0489321"
+ y="829.57007"
+ x="318.22556"
+ height="26.179665"
+ width="14.097864"
+ id="rect5709-1"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g5711-2"
+ transform="translate(-34.057657,-0.65450616)"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <path
+ inkscape:connector-curvature="0"
+ id="path5713-1"
+ d="m 404.77705,825.97291 -9.16957,15.86559 9.16957,15.84038 18.38979,0 9.19491,-15.84038 -9.19491,-15.86559 -18.38979,0 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path5715-3"
+ d="m 413.97195,836.00644 c 3.23493,0 5.85942,2.61224 5.85942,5.83206 0,3.21983 -2.62449,5.83207 -5.85942,5.83207 -3.23494,0 -5.85943,-2.61224 -5.85943,-5.83207 0,-3.21982 2.62449,-5.83206 5.85943,-5.83206 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ transform="matrix(-0.83727181,0,0,-0.83727181,427.34978,1471.4837)"
+ id="g10957"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0"
+ id="path10959"
+ d="m 326.98547,847.70808 57.45819,0 0,-73.83379 -10,0 0,61.83379 -47.45819,0"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect10961"
+ width="9.4107542"
+ height="42.249756"
+ x="305.50339"
+ y="821.53503"
+ rx="4.7053771"
+ ry="4.7053771" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 390.56742,727.10519 c -6.09957,0 -11,4.90043 -11,11 l 0,10.15625 -10.15625,0 c -6.09957,0 -11,4.90043 -11,11 0,6.09957 4.90043,11 11,11 l 21.15625,0 c 6.09957,0 11,-4.90043 11,-11 l 0,-21.15625 c 0,-6.09957 -4.90043,-11 -11,-11 z"
+ id="path10963" />
+ <rect
+ ry="2.1935852"
+ rx="4.0765176"
+ y="771.6814"
+ x="369.11923"
+ height="12.20938"
+ width="21.740107"
+ id="rect10965"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="2.9156427"
+ rx="7.0489321"
+ y="829.57007"
+ x="318.22556"
+ height="26.179665"
+ width="14.097864"
+ id="rect10967"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g10969"
+ transform="translate(-34.057657,-0.65450616)"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <path
+ inkscape:connector-curvature="0"
+ id="path10971"
+ d="m 404.77705,825.97291 -9.16957,15.86559 9.16957,15.84038 18.38979,0 9.19491,-15.84038 -9.19491,-15.86559 -18.38979,0 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path10973"
+ d="m 413.97195,836.00644 c 3.23493,0 5.85942,2.61224 5.85942,5.83206 0,3.21983 -2.62449,5.83207 -5.85942,5.83207 -3.23494,0 -5.85943,-2.61224 -5.85943,-5.83207 0,-3.21982 2.62449,-5.83206 5.85943,-5.83206 z"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <rect
+ ry="12.863822"
+ rx="12.863822"
+ y="836.96265"
+ x="214.05772"
+ height="25.727644"
+ width="83.8843"
+ id="rect5685-1"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+</svg>
diff --git a/Resources/graphics/function.png b/Graphics/drawables/function.png
index 9b8983c48..9b8983c48 100644
--- a/Resources/graphics/function.png
+++ b/Graphics/drawables/function.png
Binary files differ
diff --git a/Resources/graphics/function.svg b/Graphics/drawables/function.svg
index 97bc936ba..97bc936ba 100644
--- a/Resources/graphics/function.svg
+++ b/Graphics/drawables/function.svg
diff --git a/Graphics/drawables/ic_action_encrypt_file.svg b/Graphics/drawables/ic_action_encrypt_file.svg
new file mode 100644
index 000000000..06575fea0
--- /dev/null
+++ b/Graphics/drawables/ic_action_encrypt_file.svg
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ id="svg2"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="ic_action_encrypt_file.svg">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1918"
+ inkscape:window-height="1179"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="9.8333333"
+ inkscape:cx="12.40678"
+ inkscape:cy="11.79661"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ d="M 8.098305,7.8033898 H 3.5245762 C 2.6784365,7.8033898 2,8.4818262 2,9.3279662 V 18.475424 A 1.5245762,1.5245762 0 0 0 3.5245762,20 H 15.721185 a 1.5245762,1.5245762 0 0 0 1.524577,-1.524576 v -7.622882 c 0,-0.846139 -0.686059,-1.5245758 -1.524577,-1.5245758 H 9.6228815 L 8.098305,7.8033898 z"
+ id="path4"
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff" />
+ <path
+ id="path3076"
+ d="m 18.101695,9.4661021 a 0.95762709,0.95762709 0 0 0 0.957627,-0.9576273 c 0,-0.531483 -0.430932,-0.957627 -0.957627,-0.957627 a 0.95762709,0.95762709 0 0 0 -0.957628,0.957627 0.95762709,0.95762709 0 0 0 0.957628,0.9576273 m 2.872881,-4.3093223 a 0.95762709,0.95762709 0 0 1 0.957627,0.957627 V 10.902542 A 0.95762709,0.95762709 0 0 1 20.974576,11.86017 H 15.228813 A 0.95762709,0.95762709 0 0 1 14.271186,10.902542 V 6.1144068 c 0,-0.531483 0.430933,-0.957627 0.957627,-0.957627 h 0.478814 v -0.957627 a 2.3940678,2.3940678 0 0 1 2.394068,-2.3940676 2.3940678,2.3940678 0 0 1 2.394067,2.3940676 v 0.957627 h 0.478814 m -2.872881,-2.394068 a 1.4364407,1.4364407 0 0 0 -1.436441,1.436441 v 0.957627 h 2.872881 v -0.957627 a 1.4364407,1.4364407 0 0 0 -1.43644,-1.436441 z"
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff" />
+</svg>
diff --git a/Graphics/drawables/ic_action_encrypt_text.svg b/Graphics/drawables/ic_action_encrypt_text.svg
new file mode 100644
index 000000000..92811bc94
--- /dev/null
+++ b/Graphics/drawables/ic_action_encrypt_text.svg
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ id="svg2"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="ic_action_encrypt_text.svg">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1918"
+ inkscape:window-height="1179"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="9.8333333"
+ inkscape:cx="12.61017"
+ inkscape:cy="11.79661"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ id="path3076"
+ d="m 18.101695,9.4661021 a 0.95762709,0.95762709 0 0 0 0.957627,-0.9576273 c 0,-0.531483 -0.430932,-0.957627 -0.957627,-0.957627 a 0.95762709,0.95762709 0 0 0 -0.957628,0.957627 0.95762709,0.95762709 0 0 0 0.957628,0.9576273 m 2.872881,-4.3093223 a 0.95762709,0.95762709 0 0 1 0.957627,0.957627 V 10.902542 A 0.95762709,0.95762709 0 0 1 20.974576,11.86017 H 15.228813 A 0.95762709,0.95762709 0 0 1 14.271186,10.902542 V 6.1144068 c 0,-0.531483 0.430933,-0.957627 0.957627,-0.957627 h 0.478814 v -0.957627 a 2.3940678,2.3940678 0 0 1 2.394068,-2.3940676 2.3940678,2.3940678 0 0 1 2.394067,2.3940676 v 0.957627 h 0.478814 m -2.872881,-2.394068 a 1.4364407,1.4364407 0 0 0 -1.436441,1.436441 v 0.957627 h 2.872881 v -0.957627 a 1.4364407,1.4364407 0 0 0 -1.43644,-1.436441 z"
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff" />
+ <path
+ d="M 7.0423722,23.016949 A 0.72033898,0.72033898 0 0 1 6.3220339,22.29661 V 20.135593 H 3.4406779 A 1.440678,1.440678 0 0 1 1.9999994,18.694915 v -8.644068 c 0,-0.799576 0.6483057,-1.4406776 1.4406785,-1.4406776 H 14.966101 a 1.440678,1.440678 0 0 1 1.440678,1.4406776 v 8.644068 a 1.440678,1.440678 0 0 1 -1.440678,1.440678 h -4.394068 l -2.6652535,2.672458 c -0.144068,0.136864 -0.3241529,0.208898 -0.5042377,0.208898 v 0 H 7.0423722 M 4.1610172,10.771185 v 1.440678 H 14.245762 V 10.771185 H 4.1610172 m 0,2.881357 v 1.440677 H 9.923728 V 13.652542 H 4.1610172 m 0,2.881355 v 1.440678 H 11.364406 V 16.533897 H 4.1610172 z"
+ id="path4-3"
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff" />
+</svg>
diff --git a/Resources/graphics/ic_action_safeslinger.svg b/Graphics/drawables/ic_action_safeslinger.svg
index 1575846db..1575846db 100644
--- a/Resources/graphics/ic_action_safeslinger.svg
+++ b/Graphics/drawables/ic_action_safeslinger.svg
diff --git a/Resources/graphics/ic_action_search_cloud.svg b/Graphics/drawables/ic_action_search_cloud.svg
index 0eef58ee3..0eef58ee3 100644
--- a/Resources/graphics/ic_action_search_cloud.svg
+++ b/Graphics/drawables/ic_action_search_cloud.svg
diff --git a/Graphics/drawables/ic_action_verified_cutout.svg b/Graphics/drawables/ic_action_verified_cutout.svg
new file mode 100644
index 000000000..c50b64a4b
--- /dev/null
+++ b/Graphics/drawables/ic_action_verified_cutout.svg
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100px"
+ height="100px"
+ viewBox="0 0 100 100"
+ version="1.1"
+ id="svg2"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="ic_action_verified_cutout.svg">
+ <metadata
+ id="metadata16">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1918"
+ inkscape:window-height="1179"
+ id="namedview14"
+ showgrid="false"
+ inkscape:zoom="2.36"
+ inkscape:cx="51.694916"
+ inkscape:cy="50"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <!-- Generator: Sketch 3.0.4 (8053) - http://www.bohemiancoding.com/sketch -->
+ <title
+ id="title4">signature-verified-cutout</title>
+ <desc
+ id="desc6">Created with Sketch.</desc>
+ <defs
+ id="defs8" />
+ <g
+ id="Page-1"
+ sketch:type="MSPage"
+ transform="matrix(0.83321313,0,0,0.83321313,8.5695807,8.551208)"
+ style="fill:#ffffff;stroke:none">
+ <g
+ id="signature-verified-cutout"
+ sketch:type="MSArtboardGroup"
+ transform="translate(0.110156,0)"
+ style="fill:#ffffff">
+ <path
+ d="M 50,97 C 75.957383,97 97,75.957383 97,50 97,24.042617 75.957383,3 50,3 24.042617,3 3,24.042617 3,50 3,75.957383 24.042617,97 50,97 z M 46.273291,77.5085 20,57.830916 27.91844,47.63497 43.309686,59.515226 70.31112,23 80.867825,30.778219 46.273291,77.5085 z"
+ sketch:type="MSShapeGroup"
+ id="path12"
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff" />
+ </g>
+ </g>
+</svg>
diff --git a/Graphics/drawables/ic_cloud_search_24px.svg b/Graphics/drawables/ic_cloud_search_24px.svg
new file mode 100644
index 000000000..3b20e2d90
--- /dev/null
+++ b/Graphics/drawables/ic_cloud_search_24px.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="ic_cloud_search_24px.svg">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1364"
+ inkscape:window-height="747"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="9.8333333"
+ inkscape:cx="12"
+ inkscape:cy="12"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ d="M 12 4 C 9.11 4 6.59375 5.63125 5.34375 8.03125 C 2.33375 8.35125 -1.1842379e-15 10.91 0 14 C 0 17.31 2.69 20 6 20 L 19 20 C 21.76 20 24 17.76 24 15 C 24 12.36 21.94375 10.21125 19.34375 10.03125 C 18.66375 6.58125 15.64 4 12 4 z M 11 6.8125 C 13.421061 6.8125 15.375 8.7664396 15.375 11.1875 C 15.375 12.273268 14.973402 13.293695 14.3125 14.0625 L 14.5 14.21875 L 15.03125 14.21875 L 18.40625 17.59375 L 17.40625 18.625 L 14.03125 15.25 L 14.03125 14.71875 L 13.84375 14.53125 C 13.074945 15.192153 12.085769 15.59375 11 15.59375 C 8.5789402 15.59375 6.625 13.608561 6.625 11.1875 C 6.625 8.7664396 8.5789402 6.8125 11 6.8125 z M 11 8.15625 C 9.3207692 8.15625 7.96875 9.5082682 7.96875 11.1875 C 7.96875 12.866731 9.3207692 14.21875 11 14.21875 C 12.679232 14.21875 14.03125 12.866731 14.03125 11.1875 C 14.03125 9.5082682 12.679232 8.15625 11 8.15625 z "
+ id="path4"
+ style="fill:#ffffff" />
+</svg>
diff --git a/Resources/graphics/ic_launcher.svg b/Graphics/drawables/ic_launcher_old.svg
index 2532ed83c..2532ed83c 100644
--- a/Resources/graphics/ic_launcher.svg
+++ b/Graphics/drawables/ic_launcher_old.svg
diff --git a/Resources/graphics/icon_sizes.txt b/Graphics/drawables/icon_sizes.txt
index 2e960f6fd..2e960f6fd 100644
--- a/Resources/graphics/icon_sizes.txt
+++ b/Graphics/drawables/icon_sizes.txt
diff --git a/Resources/graphics/key_flag_authenticate.svg b/Graphics/drawables/key_flag_authenticate.svg
index 045abdd1e..045abdd1e 100644
--- a/Resources/graphics/key_flag_authenticate.svg
+++ b/Graphics/drawables/key_flag_authenticate.svg
diff --git a/Resources/graphics/key_flag_certify.svg b/Graphics/drawables/key_flag_certify.svg
index d27c83313..d27c83313 100644
--- a/Resources/graphics/key_flag_certify.svg
+++ b/Graphics/drawables/key_flag_certify.svg
diff --git a/Resources/graphics/key_flag_encrypt.svg b/Graphics/drawables/key_flag_encrypt.svg
index 4c08e39aa..4c08e39aa 100644
--- a/Resources/graphics/key_flag_encrypt.svg
+++ b/Graphics/drawables/key_flag_encrypt.svg
diff --git a/Resources/graphics/key_flag_sign.svg b/Graphics/drawables/key_flag_sign.svg
index 196638033..196638033 100644
--- a/Resources/graphics/key_flag_sign.svg
+++ b/Graphics/drawables/key_flag_sign.svg
diff --git a/Graphics/drawables/material-launcher/Feature Graphic.psd b/Graphics/drawables/material-launcher/Feature Graphic.psd
new file mode 100644
index 000000000..b984a9bd8
--- /dev/null
+++ b/Graphics/drawables/material-launcher/Feature Graphic.psd
Binary files differ
diff --git a/Graphics/drawables/material-launcher/Feature-Graphic.png b/Graphics/drawables/material-launcher/Feature-Graphic.png
new file mode 100644
index 000000000..3d53a63ea
--- /dev/null
+++ b/Graphics/drawables/material-launcher/Feature-Graphic.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/preview.psd b/Graphics/drawables/material-launcher/preview.psd
new file mode 100644
index 000000000..54ccb75a3
--- /dev/null
+++ b/Graphics/drawables/material-launcher/preview.psd
Binary files differ
diff --git a/Graphics/drawables/material-launcher/preview1.png b/Graphics/drawables/material-launcher/preview1.png
new file mode 100644
index 000000000..a26b6a3fa
--- /dev/null
+++ b/Graphics/drawables/material-launcher/preview1.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/preview2.png b/Graphics/drawables/material-launcher/preview2.png
new file mode 100644
index 000000000..2c034243d
--- /dev/null
+++ b/Graphics/drawables/material-launcher/preview2.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/preview3.png b/Graphics/drawables/material-launcher/preview3.png
new file mode 100644
index 000000000..e1b7f4e7e
--- /dev/null
+++ b/Graphics/drawables/material-launcher/preview3.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src-blue.png b/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src-blue.png
new file mode 100644
index 000000000..37d0958ff
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src-blue.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src-purple.png b/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src-purple.png
new file mode 100644
index 000000000..f9c611990
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src-purple.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src.png b/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src.png
new file mode 100644
index 000000000..4809acc39
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/144/vector-src.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src-blue.png b/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src-blue.png
new file mode 100644
index 000000000..e5183fb05
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src-blue.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src-purple.png b/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src-purple.png
new file mode 100644
index 000000000..a730b4320
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src-purple.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src.png b/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src.png
new file mode 100644
index 000000000..fab324e93
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/192/vector-src.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src-blue.png b/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src-blue.png
new file mode 100644
index 000000000..e709f735d
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src-blue.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src-purple.png b/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src-purple.png
new file mode 100644
index 000000000..b8789fcd9
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src-purple.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src.png b/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src.png
new file mode 100644
index 000000000..d945a01de
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/48/vector-src.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src-blue.png b/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src-blue.png
new file mode 100644
index 000000000..c4ffab9b6
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src-blue.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src-purple.png b/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src-purple.png
new file mode 100644
index 000000000..3dd98f5ed
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src-purple.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src.png b/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src.png
new file mode 100644
index 000000000..c3416bef3
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/512/vector-src.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src-blue.png b/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src-blue.png
new file mode 100644
index 000000000..bb5104aec
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src-blue.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src-purple.png b/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src-purple.png
new file mode 100644
index 000000000..8acde1dd3
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src-purple.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src.png b/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src.png
new file mode 100644
index 000000000..6133816d2
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/72/vector-src.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src-blue.png b/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src-blue.png
new file mode 100644
index 000000000..fb4f2737a
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src-blue.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src-purple.png b/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src-purple.png
new file mode 100644
index 000000000..7d455a4cb
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src-purple.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src.png b/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src.png
new file mode 100644
index 000000000..825b18b38
--- /dev/null
+++ b/Graphics/drawables/material-launcher/ready-launcher-icons/96/vector-src.png
Binary files differ
diff --git a/Graphics/drawables/material-launcher/vector-src blue.ai b/Graphics/drawables/material-launcher/vector-src blue.ai
new file mode 100644
index 000000000..b6753791b
--- /dev/null
+++ b/Graphics/drawables/material-launcher/vector-src blue.ai
@@ -0,0 +1,671 @@
+%PDF-1.5 %âãÏÓ
+1 0 obj <</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R 6 0 R]/Order 7 0 R/RBGroups[]>>/OCGs[5 0 R 6 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 20419/Subtype/XML/Type/Metadata>>stream
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c060 61.134777, 2010/02/12-17:32:00 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/"
+ xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/">
+ <xmp:CreatorTool>Adobe Illustrator CS5</xmp:CreatorTool>
+ <xmp:CreateDate>2014-12-08T09:10:12-04:00</xmp:CreateDate>
+ <xmp:ModifyDate>2014-12-08T09:10:12-05:00</xmp:ModifyDate>
+ <xmp:MetadataDate>2014-12-08T09:10:12-05:00</xmp:MetadataDate>
+ <xmp:Thumbnails>
+ <rdf:Alt>
+ <rdf:li rdf:parseType="Resource">
+ <xmpGImg:width>236</xmpGImg:width>
+ <xmpGImg:height>256</xmpGImg:height>
+ <xmpGImg:format>JPEG</xmpGImg:format>
+ <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADsAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYqtkkjjUs7BVHc4qld3r8MZKxLyPif6Yqlc2t3snRyo9tv1UxVCNd3DGrOTirX1ib+c4qqR6je&#xA;xmqysPauKo638xXSUEyiRfuOKpxZ6rZ3VFRuMn8jbH6MVRmKuxV2KuxV2KuxV2KuxV2KuxV2KuxV&#xA;2KuxV2KuxV2KuxV2KuxV2Koa9vorVKtu56L/ABOKsZvdSnuXJLGnb+zFVWx0S7uQHb91Ef2m6n5D&#xA;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&#xA;/9k=</xmpGImg:image>
+ </rdf:li>
+ </rdf:Alt>
+ </xmp:Thumbnails>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+ xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/">
+ <xmpTPg:NPages>1</xmpTPg:NPages>
+ <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
+ <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
+ <xmpTPg:MaxPageSize rdf:parseType="Resource">
+ <stDim:w>626.000000</stDim:w>
+ <stDim:h>626.000000</stDim:h>
+ <stDim:unit>Points</stDim:unit>
+ </xmpTPg:MaxPageSize>
+ <xmpTPg:PlateNames>
+ <rdf:Seq>
+ <rdf:li>Cyan</rdf:li>
+ <rdf:li>Magenta</rdf:li>
+ <rdf:li>Yellow</rdf:li>
+ <rdf:li>Black</rdf:li>
+ </rdf:Seq>
+ </xmpTPg:PlateNames>
+ <xmpTPg:SwatchGroups>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Default Swatch Group</xmpG:groupName>
+ <xmpG:groupType>0</xmpG:groupType>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpTPg:SwatchGroups>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/">
+ <illustrator:Type>Document</illustrator:Type>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <dc:format>application/pdf</dc:format>
+ <dc:title>
+ <rdf:Alt>
+ <rdf:li xml:lang="x-default">vector-src blue</rdf:li>
+ </rdf:Alt>
+ </dc:title>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
+ <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
+ <xmpMM:DocumentID>uuid:5398bb06-0ed5-46db-8860-36df0b9c1ca8</xmpMM:DocumentID>
+ <xmpMM:InstanceID>uuid:0cdedc76-ced3-4e87-824e-d641f4bdbc61</xmpMM:InstanceID>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+ <pdf:Producer>Adobe PDF library 9.90</pdf:Producer>
+ </rdf:Description>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?>
+endstream endobj 3 0 obj <</Count 1/Kids[8 0 R]/Type/Pages>> endobj 8 0 obj <</ArtBox[213.5 89.3184 537.323 441.675]/BleedBox[0.0 0.0 626.0 626.0]/Contents 9 0 R/LastModified(D:20141208091012-04'00')/MediaBox[0.0 0.0 626.0 626.0]/Parent 3 0 R/PieceInfo<</Illustrator 10 0 R>>/Resources<</ExtGState<</GS0 11 0 R>>/Properties<</MC0 5 0 R/MC1 6 0 R>>>>/Thumb 12 0 R/TrimBox[0.0 0.0 626.0 626.0]/Type/Page>> endobj 9 0 obj <</Filter/FlateDecode/Length 11276>>stream
+H‰¤—¹®dÇDýþŠk è;µ/®F‚,B dèiÌ õÿ€NDV¿E®@ðMGÝZ²r‰Œúò÷¯×—Ÿ¾¦ëÏùz=~¤k”áÿŸúóÇ¿ÿ¼~{¤»¯+ݳWþÖuýñËãËßþ‘®_þóøýÊWâ¿|Õ\ïÒõÏõíÇCcúûÌ‹u×÷Çs±Ëÿ¦sßyŽ«Ô;§v=缧`¿ÛÜÀq׫Ì{±ý·GÀIJ_enæ˜g›÷îúÍ^mÜ;UÀ½k½ž­ß«ñ­Ü‹ã[cgP•ß´¾†=¿>þý§ÇÏÜ4÷É%KÒ…;Fp×÷;–Z4½VV¥T>]´î»i§¸çgtî¹Ú]>ƒ†?_³>ý®wÒòÚïY>Ày§Êª†™ûªë®XË K+'ò[¾ùöh\óÚºS‹é•M˜Àµ˜Ò®ž=¯sA혒·þY¹\}Ü _uÅÄÿhæ
+·ëžŽÃ»=´\˸zÛãõ„ðwæ g&)²ö—‚«6d ‰`‹"öE¥ ¶*¹”Zõø5O‡“~Èï'¾Ï¬ìÓÓˆ%›(†{1)s󱢤äq­¬.Îc”2HÙí‘Úó¥úÐ óZ>DXŽÕý*Ö<KÎö|î%<[È{™••j‚ãX•kRHßF¾?NQ|á”iKψëÓ–ç{.Å/ÂûæÍN.Ú{ÅÅVÈ«z°ãÝî ý¬$#¹PÃikr‚¯œÖgL}‡Å¬- ‡<±¨–¢Œ L†àee`\ŽX8‘Ø8L‘‰UR˜
+Õ·œÉàÛΊÓ­-cOQè-Ï’b³˜~¿Eÿõ':Õ—è[9úÖÏÿgç"ÍSéðæ×Ò?òú­ñgr{b³dP!_sÞ3÷¨>Zч:–gešcZñ¬œý…¤àKò’4ÚÇÛQÈK'½ÿýÜ€(/.ÞïVâ¤DB,J§É¥»-R•~逨¾äfE#GýîÈŸL ¦PDÎÞ¶ ø¢j¬ŽZÃ=²\ežôS]á¹Èzˆ˜2Qy+ÆëT7Ï®Fjú‚Š=7èWXEÊ’r‘ŸòO1Ï“Íe*îƒ Å*&U½5q‚.©½º7Q^ÚÝ&‹Ð€é2Zq@
+D^N»°šAñ—íÝè.Úmµq‘“2SÕ#3—SÙñœàîÇJ+GrQ3=ê<›~tüÁ6«qvf±[µüÁxõýÖ2’}®˜ÇÙ0iKÕÁpùt
+DM–ådzˆ ÖÕåmÖÂkC­2€¬¥KmåÚMµ˜ÜwQ_Þ–-<}ªŒ³¼7¥:¦OÚä2mO´SÔȳ•c``ÐTô‡¡R~%OS…oͦGùê¹²'C­u¤%àÚƒOñOM¨nÔsù†wPXŸaE.¿>8s¾6ÐÆÀ’5«oC
+ÆZ’YjÈ|Ù¡Œ ¶Då; XÉJ`¡ 2u©Ë½j/kto 䵃,ò,¶ õs»-U;Ù«eEoá–@-½îfÈŠD©ê¦n”ó”Ï–f‰%"çÁ ÿ‹(Š¿6T¥8Þ~X"KA»XèÞ66Ѳ麙'{d½D'5°´Yxƒ:sŒíÕ³¥$Å´‹µåi
+6ÇK”†-¨ç±¬½œq½÷ا»)œzy~xÌBjÐCë/¤§ëË ø’èó]âBÄ"4ŽÁk*Rˆ¿w´:á7[b2"¡ÆÀðÞûµÉƒ¼3m8|¥ö¬É"Õx¼*ynðˆUO)iFM”4ü¡Ýq)=oEN~$’Ëär?<e„GÂE=‘´e¯á.]Ü]d©š´ô^Ü?Ï3ï]
+Qö€Û¨’R²ˆG´
+›äØ,qeÍ p¸w–t,ÊmDñ¯}Ø"Çß0’Ë•øG(তÀ=>SôݸÅwž
+¤°0¡—ƒG<ÐÒ:Â`L™ËÅ‚øpm)Rv6Ìx¶îþ—b…Ó'ôížæJ|Ö¦;gršKÓiUÿ>—¨ÙËŠOT"ª])ž1bÀ¥i dèF]L”«2K¤ ‚C[û>hÚÑûUý&éØ¿ý@¬ç–ú%Ù`p8<lwí !æ6ÝE¢ZR¼H™¥ªZ/ך£åIHo”–‹Ã­È×–®VÛ3o˜~×›®{k …’–‡›_Fž<b.?21#rÕwœM½=ôDÕ¤gZÏTØ^§‘rÞNžkEÌÆb¥Ò?<ÅZåˆÎÿr]&YrÃH Ý÷)|ôgòNîûo ²ìÞTeHŒˆ_Ê\¯¹¬úæ]Â,fÇ4IîÚÚ֎ͽÌtŸ—5ûŠêõuh³6£{Z¹LÙ4)‹Fâm4Ö,?‹É3&îõ¹‚”}Œ°[òÑã4¼†ýk˜³Ÿ‰b– ÔÔÔì‡+ÓÎ`y.A¼L<ö†tþ¶9T-5D;xñ.a)Ô¦Uír…aæeܨ&K($2´v§I“W†[1úŒâu
+›‰´n+
+HЄyB?Jœ`—¢vU‘”Ë=ðJf…Èœ
+»LGEfÏg¾7¼CŸ¢Î¼{TÕ·,/ÔSg MŸ÷’†.þ‚â‚=¿iòo¥ð¾šÝÚŽ8åjfí =ª”f'Ò£äkMÉëŽf:©¶CU×J3†YqÇØo‚|Gõüš7ä*~C‚⬎ÓÌ
+§ÃWȃ<9[í§&šT”BµÈËsA^Aé
+´!ZÚº?ô¤Pî*Y †QÝû:6÷4X1˜6â£M^éŠ]G5\”â×M€à¢µÕùÝî¾Ã.hCbÁaD{µ-<ÚÆ `6&#•››ž±WŽ]¾D êK‘–cbh‡›½ô7
+S
+àéߤ]ÚÜM}ñ˜6<f‡ïŽhéª+ «b½ù=]èŠJ?>¼hüb…ðüÔÌêìAcíô@³ýRùß3sH3ÏÌ]}‡RéO‰êS» c¬ã0óvLN~T§x\Àøú7-í¸N¿—¯Ôpq\õd­†ãÛ nÓÞ+gqQ·™ÆÐó:¼–˜ªâF3ùQ°iÖÿêjÁ¼NœËˆ>Týk†•Á´Æ¼$MòŸ!XÍd`Êj»IZ°‹Qì3«eÚçÜ— QÏT‡Ì
+0ÂòMÙšÞÍóO¯FŽL“íZ°â³n©ØŒãËÅøy‰;vµƒòÚên¦I†ó‘¡ùÚ—’Q”½¨®›iWK(ñ65´ÅN;J
+K*oŸz—ÔrüÍ™ TÀ•¬þ3^¥..¶6Úp–Q£ìŒa ¥gúà"V³¡@aĪà —»ã:ý16o™@¼¨âª®NÎ~…¿YåœgcvåG^¨²`o?>Ò&jFz Èý×OBÛ¨jD ÁH®+òGˆPklóä
+‰gQ)Ä$¬›î˜yÄ–#½óÍIuÚÆrî°\ÉÂfœëß·|m¾¸ÿµÇ?vHÕûŽðîè‚_3M«…EHà—’wʵGºiöóµù¢àAchr Ó«\!`b³(’ž£€¾ÜÅÚØr§p{Ê1œ•Â´éx4sALnõÉHVÒ ®¹lºù¡3dyÆÈмÖåÑÎmÏÕÌ+ [¬–Óê=À¬«ÚéŠQÌ¢üÓ Ö –K÷Tf¼“ºŒÄ@2§-D_Ö]X«Îs—’²‰TЀI!.ˆÑ㓯þÁ²[3n=¿_\âé“ûÌßwé­cßõq2¿¿Æ¼ ³ãÌ«uXùlÛØÑsõ&8HrÓµÞh–›|³ÆhŽ:_mÿpQ쟢HÉJf±Œ™]¬¶•B­·« ñÏBqç÷ÉGÝžR®·”Û­õúÖzÿ>¸½V©ßV_‹åó÷þÚi­òö»ÝÏ“´s½í¼n³W7û
+Ô ûnç6ªÈœ繤é5m[]h‰ìȨJ')Ë逕K¯ý7Ä}uêlç×ßÿÑ©}ÂÄ.*ê§Jc}u*sÏùWí톔ò7°•<æÈFÈèàÓÍ°ËòŒºÐ¨ÕõîGó¯GDO 3 îž¡\@VfÝîBû­n…tuWQPk4
+/W"àÞ“¨êLUì%¥¡÷8{ï¡'•ëa‡qÛ.&Oâx)›Úôݱғö®àŠsÝ{É^ùbÜ›+K¢°Ÿb(ŸþkÑÉìЪ½Vbß|€Fâ6tâ¹<úO'R+êJqÉ ê÷Á?`äl&í_eºU.³¿¯xŸ˜Üó f[™×=˜š¶ÕBSŸú¯^?6:™#ËÝšy@ˆá€ÃË;¾ÉäPÌËlu¬æ¯pÂŽnÔlõ§GFWŸÐÙ]áž"rªØA©²\£h¶ÐvñfÊP{îì®*|Ä›;¼š»A#„ÊÀÞÆ+)°ãb'®Bq =hpGÅŠóC é£ꨒÏjÙPP9šT³³µïqš+Hî> º=(Äá4‡·§Å0G–ÔÝɯžÒýœéè®ô³-?F
+å"ÙÏ¢7žÓü^Q“E Oºù§oαdЃŨ‘ ä
+L¶Ñ ¨ÉwqmQȉ›aYŸÑ‹ÃE/:M#°sÖöT¬Y/Æä€ð±?Y*ç+¾J¶”#UTb8ãÞù¾¡¡Ìd}Ñå­ÞarT|øp#„@?•—­. bÂGþ¯¥À¬;˜;Ž$»wmUÌ¡¤q×™°òÝ‚±ÜYxV ˆF¬Áº´à5βó-N< .ëðá• —$¯p)g+Åe<+–:*š€uîtËp=ÄkLÌÊžãkÅÁ¤6„¬®ublŸ5·ªW¥=pÛ·ŠæB¤š§ϳô¿×1D3~h'*“IW®5m#õ{çšÝ±S—¹Ó+PuË#sg)YŸRÖTp{‡68#ŸAw FUª¸”n™¯Lü¡^ŸSa™›âþÄí’kè䀲
+*QŠÙÁñROµ²é|‚Ê“ª¹BÂ5]ÇmÏ2$öÛM%1R縒H”Eº=+‚¢Î±O¬ÆoýV%W#Â÷Á–¥<VŸ_+®ø3A™1¢^w⧽)u0}D=íÁ5‰ÒšZ–égà~¾7O«û‹Þu¯iýo“\˜bèã•Tš[” æ¢=ÙéÀ¤ï¶Rõœ8Ô„ÔÈë¾H´RNW Hnäµ{^{{Íc`_þ>Ü°ÒuS­Edë&ï%â­¬»6èôf—}ŠšÏC)½šî2p»eZ\ô>† $öŒ—¨
+ÍJÎÒBw¢Þ\éY^¸ÿ¸Þ´Ô´«xLÊbÓþ4Ì
+t7¨n†^ý©b-õ\ªÖªGiG¡–duµâKÌû-Úã4Õ´é¼^I’/I‚¨#:ŒcÆh瞪;à
+¯õ¤ö®uÅŒVÃ䯒à˜H‘[â8,X¬ú)Èþv@WP‰íP™nI
+`eé-´”6Õ¼Ò‚â-ÿ`—í—ú<Ì«õƒú±‹ÒÊ0Hjö ëÐF3‮2Àß_¨« qB-° ¨–—ôSÿ înh³žúOƨ›#‘(¼[Š®ëy;š¤øïÞëå&Ÿ§ë×kù È0n³6ˆé«[À¥ŸÆv2‘O“³§áõA…¾n¯íÐÎëVÁð°B^øº˜mæf¶¨êÝh>`³f›T1IPwœVBÀ—HÐPánÞ¤Oµ+¯É4p tã{×\BJfÙƒ´-~®û¼í4m|C Û'+¯>¨BÞ¹ygÎz®©K–s©šKµëwzËçÒë<ª¼å÷¿·£KØP¡J>ÇŽÕVÆažÝìuÛ-îŠ{è@¸/“íÞÅŸvQ¼=ÞOpÌ#±3NìÌ„–:Ô'´z¢Ý'ôˆÌùD&ðràRX^ÇåÀ¦áû'òÿü:M¨wÁ=À}~¡p‚VHþ­»d}ø ¯Z‘ˆ°®¾,pTG
+ÙÒa©ªþ™Å b×¥$€åÄ™·›ÃJñ³_æí‰üÓ'ÑFuYîòè…6ùXq¼ü˜.7^Í= Œ}-×i*­¼B­×T0ï~>ÚƪJÏÌn™s¡8Äõüö-hoîÙrOLʆŸ $óó.?OÃñìs̘£ÅT3¦r´·ùرÛÆ#6î쀟¦O ³+5\ÐMÓŸÿ„Íñd2äÛøkyfµ]¾Bù]Áoõ5ßÿþ¨àCyЩÞuËÃûgÇT/³*ùû×(c‹5 ¦üý5"SŽûü% w«]2ˆRPh ÐÄ
+Ñ}¨!l¿0%…¦6œ°ŠB\ø1é\/b(ñLÖë, ìˆ{ôo@òÍD¥]&È”uˇËæå‰"Í–ˆ¼µ[­'&—)¯¦† n£r…RÓ_ÔÌå|]>ÙgÃ¥‘G§âkÎÔj´¶ÎÀîüÕ
+…‡¬”°Å’R-š»³RTûµ#Ae—ÓH2qX"žfW
+¢Ù&›ÎçË):È<nò õ7Â!ÝÂ`º~“¯‘³=kF¯5yУ5+# "›qJÄÔ7%inˆ1ÀÜÚäÅBþ÷’%([åX7å*-¸™ãwvÓ“Jž©0tIÛ1àˉ3ýÌ¿L¨;´œþœ‹*=pe²£ö¤Íçòå 7{P˜"Wª}¥¾wº¼ª‡â¬ºo ûìý¼4zZx<× Ï÷‚
+Li*…ßnôÿÎÌX…qh p«=έã€#˜^ji|Ì¡å›±zª–þ鈥å£rêã[ý¹œAï,kê0ô  DÅÏ$k÷¢D7Iªž_2ÏÂÎEAF©´ •6âöF"·”.vŒ“H¤ìé>š¤‹èsw;S­í!ÍÄ!ÂÓäñ¡'š1õ`Rá"2²USå Çm£v`7«BE3bP±Jm¥3…Uš[O5¢],AÁ·òn!Å
+:W©¹Œ–7UnÜÕt´uøDËéH:eàz#órÓ=Þô'·ïˆ¸»Zk+œ_30ýÎ?Ћ(áÌ‘–TÚ]yÀÅ_ñïöKww;Jú­SÖényÑ«»¼W‰m3sùžp3Ç~÷Ìà $Øцâ…CԲɀèæci-“å(ËrÆE™†X½ •‡ìü—}™
+wï–‘²]
+ ヴyv×vGg4žoOŸž× ïµ\xž>ÉðŠÜ7äuØôšBUa
+›äÿ[ö iß,íÖÎÓ¯ c‰‹u¼ ¿7e«Ë»ˆTkÜ执Tïÿ“m¼a§
+ùŸáî"Üß³c
+’ª§~Ò#ÞÉl&Šµ‚(e0Žijç]ðñ½¹MÛ¢š‹˜é7<Wk¸fDYTD]Æ;N®7%êü›
+“¢HÛ¶&oäB¥FõµSž;âT 4W°˜–hlGÞ,av𰶸…®NO¨L©=RqêC>-:ái¨Ï÷éO«œ~£ÕHÿõ‚y4†Ï5µD‡«wRò¡×¯ã©¹ËsÅÜsãŒH«jÙºLgU›^ºw
+‘lŠÒeAnⶢ;@Ú¬—šónEŸ`Ò­§ØIƒ'H¢Ò_
+â'JNê‡i óißR¯*áÍ êDSÈ'ÃÌWŽz¸ØžÀiÒQ7ÈdÉYÒ«¯>À.ÔÎs~ ´ì%©€˜N…ë& iìØשú
+ÖÂyöÜ<êArf$©Ñ±¸J§èq³ïöhFàT2ûÒaÚ쎫‰¬å¶ñ0€^5Hž&+ jй¸ñ»§JŸzV¥Ö([§nëJºãIc¬ ZÄŒLW2§ˆ­Ø×Õ|*Þ-Ç jGþ„@Ñc/sGL»MÆ =JÚu
+(Ò®úà~»"µXý•¨AQþÛIö•qÕU¥BnT>¶(Ŭ~èÙ¾ Ïö¢ +·¥‡ª=áijk2Vn* .GÎDòç5Þ~õÐ{°©èG ëyèê›"µ\,ºùÀžŸè³îÏ
+@ã-¥BX˜í)nš‰U?QÛ†¼Ie•¾¹fר’/=€BIŠÉ"ñ*ÿà²`gVm-¹MmnZ`Ðk.›çºÃ£ßýÀmfQÄ{Ež‡#
+…ó'œèŽç´ÖÅpËH"åÆw#þC¼þ?k}šOÙRX2¹Ê…@xŸÿµöyÖšpŽJw¬xŒd>(Ðe„‹ÜÑ2•¯H/ª\J‘Fßf®*YMÌH‹c<1ìPyz7\¾"ÑÃÅåyèÀÔô¢4+Û› o@ðÄ%pæ–½ÂRç¶Hm“ñ™ãõ»
+î«°¿Üådº¤ÌÜúçƒ=£3|ºÅM»Qqnö>Ÿ“Þ8)ÍàãaËn|ëzãp "ÝQ¥u8MÝM÷â%G$gdŸWTÒÕMù„ú/¡²’|R±3Ñã2NçvÚåWµ®þ±¢v®¨YÚ•êÌ{k¶–Õt£ÄßO ©táñ<’T8Õ%5¨M2æ5$±à_; ±U®f›ÆÑhÿ|éóìMÒR›N¥`Q<–éÔ^U}âR!o‡€¦«0u‡Œ '<!ÊᛣéfÌe“ÁñyÔ"„Ý™8æ%’“ÈõŠ¨p‰fU¦a™e†Æ\âÌž;<«2f5гÁß>9×Ø"­¾jÈP-¿`ÖH¬6rú|"í¤‹x¸§Ùá¨ÈÄ ¡›óĉ“>"ø)‹ÍiúK¶Ž/˜4v§8žªº–úy7Y0ÿýß^úù¿
+endstream endobj 12 0 obj <</BitsPerComponent 8/ColorSpace 13 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 78/Length 542/Width 78>>stream
+8;Z]!96.rn$q.SM@C3maRBXh>\.A>m3fuZ5@5FkpAsK)rWqfUg:\,-iPd\$/[^NWQ
+hCDVY0dAc_k@P?A5s.aB*_ra-1`]bjqKZTf4a>T/"1LHqIHJfPT]YU\aT0-$QsGMf
+na*DM7bP#iaU0>DUGanCj[[u%0#%dinsq"G[WG1Lh1"iNLAH/:BGtR0iVYWD%pDfO
+*<n<nk"eYb<)&HQF'&Kp;s=WL9/c#fUfDFbFuFB@]CK2r+r)DoZ0,)9&M4kUe)NZ]
+ba(hCoBIm-[A+LH7u]`Cfs?Bp\E?%uCTFc0[8L_-gE7@d?/%tOqjHT3+$@ND/%)!J
+/NQn6HQ9[C8*=ZV?`.jO7OnB1\Q_t0J>O*'[ci^?H-:BHKc6.2QjL;afKtQN?C@>*
+9q;7hHjMYRQY]`ZFoj)BCSB8ea'/3ld_XK%R8uCt+Q(V0REZ9W3N:Zp))$&J%j%U+
+.2^P471M\Rgn]ouHq3@A<]AMOjN;+(DSkcf*bLqb2R'6G]#$!E?>+,uaR9jMbKRE'
+rf_d9!%&eO[K~>
+endstream endobj 13 0 obj [/Indexed/DeviceRGB 255 14 0 R] endobj 14 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>
+endstream endobj 5 0 obj <</Intent 15 0 R/Name(Layer 9)/Type/OCG/Usage 16 0 R>> endobj 6 0 obj <</Intent 17 0 R/Name(Layer 6)/Type/OCG/Usage 18 0 R>> endobj 17 0 obj [/View/Design] endobj 18 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>> endobj 11 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 10 0 obj <</LastModified(D:20141208091012-04'00')/Private 19 0 R>> endobj 19 0 obj <</AIMetaData 20 0 R/AIPrivateData1 21 0 R/AIPrivateData2 22 0 R/ContainerVersion 11/CreatorVersion 15/NumBlock 2/RoundtripStreamType 1/RoundtripVersion 15>> endobj 20 0 obj <</Length 984>>stream
+%!PS-Adobe-3.0
+%%Creator: Adobe Illustrator(R) 15.0
+%%AI8_CreatorVersion: 15.0.0
+%%For: (PHLASH) ()
+%%Title: (vector-src blue.fxg)
+%%CreationDate: 12/8/2014 9:10 AM
+%%Canvassize: 16383
+%%BoundingBox: 213 -537 538 -184
+%%HiResBoundingBox: 213.5 -536.6816 537.3232 -184.3252
+%%DocumentProcessColors: Cyan Magenta Yellow Black
+%AI5_FileFormat 11.0
+%AI12_BuildNumber: 399
+%AI3_ColorUsage: Color
+%AI7_ImageSettings: 0
+%%RGBProcessColor: 0 0 0 ([Registration])
+%AI3_Cropmarks: 0 -626 626 0
+%AI3_TemplateBox: 312.5 -312.5 312.5 -312.5
+%AI3_TileBox: 7 -709 619 83
+%AI3_DocumentPreview: None
+%AI5_ArtSize: 14400 14400
+%AI5_RulerUnits: 2
+%AI9_ColorModel: 1
+%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0
+%AI5_TargetResolution: 800
+%AI5_NumLayers: 2
+%AI9_OpenToView: -258 70 1 1140 742 26 0 0 354 173 0 0 0 1 1 0 1 1 0 1
+%AI5_OpenViewLayers: 77
+%%PageOrigin:7 -709
+%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9
+%AI9_Flatten: 1
+%AI12_CMSettings: 00.MS
+%%EndComments
+
+endstream endobj 21 0 obj <</Length 20136>>stream
+%%BoundingBox: 213 -537 538 -184
+%%HiResBoundingBox: 213.5 -536.6816 537.3232 -184.3252
+%AI7_Thumbnail: 120 128 8
+%%BeginData: 19978 Hex Bytes
+%0000330000660000990000CC0033000033330033660033990033CC0033FF
+%0066000066330066660066990066CC0066FF009900009933009966009999
+%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66
+%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333
+%3333663333993333CC3333FF3366003366333366663366993366CC3366FF
+%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99
+%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033
+%6600666600996600CC6600FF6633006633336633666633996633CC6633FF
+%6666006666336666666666996666CC6666FF669900669933669966669999
+%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33
+%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF
+%9933009933339933669933999933CC9933FF996600996633996666996699
+%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33
+%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF
+%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399
+%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933
+%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF
+%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC
+%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699
+%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33
+%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100
+%000011111111220000002200000022222222440000004400000044444444
+%550000005500000055555555770000007700000077777777880000008800
+%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB
+%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF
+%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF
+%524C45FD33FFA8FFA8FFA8FFA8FD6AFFA8FFFD0FA8FFA8FD64FFA8A8A8FF
+%A8A8A8FFA8A8A8FFA8A8A8FFFD05A8FFA8FD5EFFFD1BA8FD5CFFA8FFA8FF
+%A8A8A8FFA8FFA8FD0BFFA8FFA8A8A8FFA8FFA8FD58FFFD07A8FFA8FD0FFF
+%A8FFFD07A8FD54FFA8FFA8A8A8FFA8FFA8FD17FFFD05A8FD52FFFD07A8FD
+%1BFFFD05A8FD52FFA8FFA8A8A8FD1DFFA8A8A8FFA8FD4EFFA8FFFD05A8FD
+%1FFFFD05A8FD4EFFA8FFA8A8A8FD09FFAFFFA8A984A97EA984A984A9A9FD
+%0CFFA8A8FFA8FD4AFFA8FFFD05A8FD05FF7E7E545429302930292A292929
+%30292A29302954537E7EA9A8FD05FFFD05A8FD4AFFA8A8A8FD04FFA97E54
+%295429302954295429542F5429542F5429542930293029302954547E84FD
+%05FFA8A8A8FD48FFFD05A8A95430292A2930293029302930293029302930
+%2930293029302930293029302930292A295A7EFFFD05A8FD46FFA8CFA8A8
+%545429302930295429302954293029542930295429302954293029542930
+%29542930295429302930307EA8FFA8A8A8FD44FFA8A87E54293029302930
+%293029302930293029302930293029302930293029302930293029302930
+%2930293029300754FD04A8FD44FFA9543029542F5429542F5429542F5429
+%542F5429542F5429542F5429542F5429542F5429542F5429542F5429542F
+%54297EA8A8A8FD42FFA85A29302930293029302930293029302930293029
+%302930293029302930293029302930293029302930293029302930293029
+%A8A8A87EA9FD3FFF7E542930295429302954293029542930295429302954
+%293029542930295429302954293029542930295429302954293029542930
+%7EFFA8A8297EFD3CFFAF5329293029302930293029302930293029302930
+%293029302930293029302930293029302930293029302930293029302930
+%29302954A8A8A85A02547EFD39FFA9293029542F5429542F5429542F5429
+%542F5429542F5429542F5429542F5429542F5429542F5429542F5429542F
+%5429542F5429542F5429A9A8FF7E30292A5AFD36FFA95429302930293029
+%302930293029302930293029302930293029302930293029302930293029
+%3029302930293029302930293029302930292A7ECFA8A82930292929FD34
+%FFA854293029542930295429302954293029542930295429302954293029
+%542930295429302954293029542930295429302954293029542930295429
+%5AA8FFA85A2930292929A9FD31FF7E302930293029302930293029302930
+%293029302930293029302930293029302930293029302930293029302930
+%293029302930293029302930293053A8A8CF5329292F2929077EFD2FFF7E
+%3029542F5429542F5429542F5429542F5429542F5429542F5429542F5429
+%542F5429542F5429542F5429542F5429542F5429542F5429542F54295429
+%54A8FFA8A8295429302930297EFD2DFF7E2A293029302930293029302930
+%293029302930293029302930293029302930293029302930293029302930
+%29302930293029302930293029302930293029A8A8CF7E29293029292930
+%0754FD2BFF7E302954293029542930295429302954293029542930295429
+%302954293029542930295429302954293029542930295429302954293029
+%5429302954293029307ECFA8A829302930293029302954FD29FF5A2A2930
+%293029302930293029302930293029302930293029302930293029302930
+%293029302930293029302930293029302930293029302930293029302930
+%29A8A8A87E2F2929292F2929292F0754FD27FF7E30295429542F5429542F
+%5429542F5429542F5429542F5429542F5429542F5429542F5429542F5429
+%542F5429542F5429542F5429542F5429542F5429542F54295484FFA8A929
+%302954293029542930297EFD25FF7E2A2930293029302930293029302930
+%293029302930293029302930293029302930293029302930293029302930
+%293029302930293029302930293029302930293029A8A8A87E3029292930
+%292929302929077EFD23FFA8302954295429302954293029542930295429
+%302954293029542930295429302954293029542930295429302954293029
+%5429302954293029542930295429302954295484FFA8A829302930293029
+%30293029302984FD21FFA830293029302930293029302930293029302930
+%292929302930293029302930293029302930293029302930293029302930
+%2930293029302930293029302930293029302FA8A8A87E29292F2929292F
+%2929292F292907A8FD20FF5A29542F5429542F5429542F542930547E7EA8
+%A8A95430295429542F5429542F5429542F5429542F542954293029542930
+%2930293029542F5429542F5429542F542954295AA8FFA8A8295429302954
+%293029542930293029FD1FFF7E29302930293029302930293029295AFFA8
+%A8A8FFFFFF7E3029302930293029302930293029302930292A29542F5453
+%5A535453542F30293029302930293029302930293054A8A8CF7D29293029
+%29293029292930FD04292FFD1DFFA929542930295429302954293029307E
+%FFFFFFA8A8A8FFFFFF7E3029302954293029542930295429302F5A597E7D
+%A87DA87DA87DA87DA87D7E537E5354293029302954293029FD04A87E2930
+%293029302930293029302930292A5AFD1CFF2F2929302930293029302930
+%292A29FFFFFFFD05A8FFFFFF29302930293029302930292A295A7D7D7DA7
+%FD127D2F302930293029307EA8A8A82FFD04292F2929292F2929292FFD04
+%297EFD1AFF7E3029542F5429542F5429542F5429A9FD04FFA8A8A8FD04FF
+%7E295429542F542954295459A87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87D7E2F542A3054FFA8FFA8542930295429302954293029
+%54293029542954FD19FFA830293029302930293029302930292A84FD05FF
+%A8A8A8FFFFFF543029302930292A297E7DA7FD1C7D5354297EA8A8A87E29
+%3029292930292929302929293029292930077EFD18FF5A29542930295429
+%3029542930295429A9FD04FFFD05A8FFFF7E29542930293053A87DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87DA77D7E
+%A8A8A8FF532A29302930293029302930293029302930293029AFFD16FFA9
+%2930293029302930293029302930292A84FD05FFFD04A8FFFF5330293029
+%3053A8FD237DA8A8A87D2F2929292F2929292F2929292F2929292FFD0429
+%53FD16FF543029542F5429542F5429542F542954297EFD06FFA8A8A8FF7E
+%54295429547DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87D7D7DFFA8CFA87E29302954293029542930295429
+%302954293029542929A8FD14FF8430293029302930293029302930293029
+%3029FD05FFFD04A884542930295AFD257DFD05A82F2A2929293029292930
+%2929293029292930292929302954FD14FF5A295429302954293029542930
+%29542930293054AFFD04FFCFFFA8CF5A30297E7DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DFD04A8FF
+%7D7D5330293029302930293029302930293029302930293029A9FD12FFA9
+%2930293029302930293029302930293029302930297E7EA9A87E7EA8A8A8
+%2F5AFD257DFD05A8FD047D532A2929292F2929292F2929292F2929292FFD
+%042953FD12FF7E3029542F5429542F5429542F5429542F5429542F302954
+%54542F54A8FFA8A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA8A8FFA8FFA8A87DA87DA853302954
+%293029542930295429302954293029542930A8FD10FFA954293029302930
+%2930293029302930293029302930293029302930295AA8A8FD107D53FD14
+%7DFD06A8FD067DA75329293029292930292929302929293029292930077E
+%FD10FFA92954293029542930295429302954293029542930295429302954
+%2930297EA7A77DA87D7D7DA87D7D7DA87D53FD05295353A17DA87D7D7DA8
+%7D7D7DA87D7D7DA87DA8A8FFFD04A87D7D7DA87D7D7DA82F302930293029
+%302930293029302930293029302FFD10FF54292930293029302930293029
+%302930293029302930293029302930293059A7FD0A7D5329012907292929
+%072929FD0E7DFD07A8FD0A7D2929292F2929292F2929292F2929292FFD04
+%29A8FD0FFF5429542F5429542F5429542F5429542F5429542F5429542F54
+%29542F3053A87DA87DA87DA87DA87DA853FD042954293029542930297E7D
+%A87DA87DA87DA87D7D7DA8A8FFA8FFA8A87DA87DA87DA87DA87DA87D7E29
+%5429302954293029542930295429302954297EFD0EFFA929302930293029
+%3029302930293029302930293029302930293029302FA8FD097DA7530706
+%29292F29302929293029292FA7FD097DFD07A8FD0D7D5329302929293029
+%29293029292930FD04292FFD0EFF7E302930295429302954293029542930
+%295429302954293029542930297E7D7D7DA87D7D7DA87D7D7DA853292930
+%2930293029302930293059A8FD057DA8A8FFA8A8A8FFA8A87DA87D7D7DA8
+%7D7D7DA87D7D7DA87D54293029302930293029302930293029302930A8FD
+%0DFF5A073029302930293029302930293029302930293029302930293029
+%54FD0B7DA8A8CF7E5A2930292907FD05290753FD057DFD07A8FD117DA753
+%29292F2929292F2929292F2929292F29290784FD0DFF2F542F5429542F54
+%29542F5429542F5429542F5429542F5429542F307DA87DA87DA87DA87DA8
+%7DA8A8FFA8FFA8FFA87E5A7E53542F5453547EA8A8FFA8FFA8A8A8FFA8A8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87D7E29302930295429302954
+%293029542930293054FD0CFFA83029302930293029302930293029302930
+%293029302930293029302F7EFD0B7D7EA8CFFD05A8CAFD12A8FD157D5929
+%3029292930292929302929293029290754FD0CFFA9293029542930295429
+%3029542930295429302954293029542930297E7D7D7DA87D7D7DA8FD047D
+%075353A8A8CFA8FFA8A8A8FFA8A8A8FFA8A8A8FFA8FFFD04A87DA87D7D7D
+%A87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D542930293029302930293029
+%302930293029FD0CFF7E2A29302930293029302930293029302930293029
+%3029302930293053FD0B7D532907292954537E7EFD04A8CFFD08A8FD1B7D
+%A15329292F2929292F2929292F2929292F292984FD0BFF7F295429542F54
+%29542F5429542F5429542F5429542F5429542F302FA87DA87DA87DA87DA8
+%7DA87D7E29292954292A2954535A5AFD067EA87DA87D7D7DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87D7E295429302954293029
+%5429302954293029A9FD0BFF543029302930293029302930293029302930
+%29302930293029302954FD0D7D2F072F293029292930292907FD04297EFD
+%217D2F293029292930292929302929293029295AFD0BFF54295429302954
+%293029542930295429302954293029542930293059A87DA87D7D7DA87D7D
+%7DA87DA75329293029302930293029302930297E7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8533029302930
+%29302930293029302954297EFD0BFF2F3029302930293029302930293029
+%3029302930293029302930297EFD0E7DFD05292F2929292F29290754FD23
+%7D592929292F2929292F2929292FFD042953FD0BFF5429542F5429542F54
+%29542F5429542F5429542F5429542F5429547DA87DA87DA87DA87DA87DA8
+%7DA87DA82F302954293029542930297EA1A87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D30295429302954
+%29302954293029542954FD0BFF2930293029302930293029302930293029
+%302930293029302930297EFD107D5329292A29290730297EFD267D292929
+%302929293029292930FD04292FFD0BFF5429302954293029542930295429
+%302954293029542930295429547DA87D7D7DA87D7D7DA87D7D7DA87D7D7D
+%A87D7E535A535A7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7D542930293029302930293029
+%3029302954FD0BFF29302930293029302930293029302930293029302930
+%293029302FFD417D292F2929292F2929292F2929292F292929FD0BFF542F
+%5429542F5429542F5429542F5429542F5429542F5429542A547DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%5429302954293029542930295429302954FD0BFF29302930293029302930
+%2930293029302930293029302930293053FD417D29302929293029292930
+%29292930292929FD0BFF3029542930295429302954293029542930295429
+%3029542930295A7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7D
+%A87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7DA87D7D7DA77D3029302930293029302930293029302954FD
+%0BFF293029302930293029302930293029302930293029302930292A2FA1
+%FD3F7D7E2929292F2929292F2929292FFD0529FD0BFF5429542F5429542F
+%5429542F5429542F5429542F5429542F5429547DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87D7D7DFF7E2A2954293029
+%5429302954293029542954FD0BFF54302930293029302930293029302930
+%2930293029302930293029A8FD3D7DA8A87E292929302929293029292930
+%FD042953FD0BFF7E29302954293029542930295429302954293029542930
+%295429547DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DFFA8FF53302930293029302930293029302930297EFD0BFF5A
+%2A29302930293029302930293029302930293029302930293029FD3C7DA8
+%A8CFA853072F2929292F2929292F2929292F292959FD0BFFA9295429542F
+%5429542F5429542F5429542F5429542F5429542F3059A87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DFFA8FFA8A82F30293029
+%542930295429302954293007A9FD0BFF8430293029302930293029302930
+%2930293029302930293029302954FD397DFFA8A8A8FF7D29293029292930
+%29292930292929302929A8FD0CFF29542930295429302954293029542930
+%295429302954293029542F7E7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA8FD057DFFA8FFA8FFA87E2930293029302930293029302930293029FD
+%0DFF54293029302930293029302930293029302930293029302930293053
+%FD367DFD07A8532A2929292F2929292F2929292F29290753FD0DFF5A302F
+%5429542F5429542F5429542F5429542F5429542F5429542A5A7DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87D7D7DFFA8FFA8FFA8FF7D54293029
+%5429302954293029542930293053FD0DFF84293029302930293029302930
+%293029302930293029302930293029FD347DA8A8FFA8A8A8FFA87D293029
+%2929302929293029292930292F077EFD0DFFA95429542930295429302954
+%2930295429302954293029542930293053A77DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DFFA8FFA8FFA8FFA8FF7E2A295429302930293029302930
+%29302929A8FD0EFF53292930293029302930293029302930293029302930
+%293029302954FD317DFD0AA8FF7D29292F2929292F2929292FFD0529FD0F
+%FF8529542F5429542F5429542F5429542F5429542F5429542F5429542A7E
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA8A8FFA8FFA8FFA8FFA8FFA8FFA8FF
+%5A30293029542930295429302954297EFD0FFFA830293029302930293029
+%302930293029302930293029302930293029FD2E7DFFA8A8A8FFA8A8A8FF
+%A8A8A8FFA8CF53FD04293029292930FD0429A8FD10FF5430295429302954
+%293029542930295429302954293029542930293053A77DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%FD047DA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF533029302930293029
+%30292929FD11FF8529302930293029302930293029302930293029302930
+%29302930293053FD2A7DAFFD12A853FD04292F29292930077EFD12FF5429
+%542F5429542F5429542F5429542F5429542F5429542F54295429307DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87D7D7EFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF54
+%2A2954293029542929A8FD12FF7E29293029302930293029302930293029
+%3029302930293029302930292F7DA7FD257DA8A8FFA8A8A8FFA8A8A8FFA8
+%A8A8FFA8A8A8FFFD04A82F292930FD042953FD14FF293029542930295429
+%3029542930295429302954293029542930293029547DA87D7D7DA87D7D7D
+%A87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA9A8
+%FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF2F2A2930293007
+%A9FD14FF7E29302930293029302930293029302930293029302930292F29
+%29292F2953FD237DFD1BA8292929300753FD15FFA95429542F5429542F54
+%29542F5429542F5429542F54295429302954293029547DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA9A8FFA8A8
+%A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA87D295429297EFD
+%16FF7E292930293029302930293029302930293029302929293029292930
+%292F0753FD1F7DFD08A8A9A8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFFD04A8
+%532929292FFD18FF30302954293029542930295429302954295429302930
+%293029302930293007537DA77DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA8FD057DA8A8FFA8A8A8FFFD05A8FFA8FFA8FFA8FFA8FFA8FFA8FF
+%A8FFA8FF7D53293007A9FD18FFA929302930293029302930293029302930
+%2929292F2929292F2929292F2929012953FD1A7DFD0BA87DFD12A87D2930
+%025AFD1AFF7E29542F5429542F5429542F54295429302954293029542930
+%295429302930292953A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7D7D7DFFA8A8A8FFA8A8A8A9FD07A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8CF
+%5330292FFD1BFFA930293029302930293029302930293029292930292929
+%3029292930FD0429072929FD167DFD09A87DFD08A8FFA8A8A8FFA8A8A8FF
+%A8A8A8FFA75329297EFD1CFFA83029542930295429302954293029302930
+%293029302930293029302930FD042907537DA77DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7DFFA8A8A8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8
+%A8292953FD1EFF7E292930293029302930292F2929292F2929292F292929
+%2F2929292F2929072907290129297D7DA7FD0D7DFD0DA87DA8A8A87DA87E
+%FD0DA8532929FD05FFA8FFA8FD18FF54302F5429542F5429542930295429
+%302954293029542930295429302954FD072953537D7DA87DA87DA87DA87D
+%A8A8FFA8FFA8A87EFFA8A8A8FFA8A8A8FFFD09A8FFA8FFA8FFA8FFA8FFA8
+%5329FD05FFA8FFA8A8FD19FF293029302930292929302929293029292930
+%29292930292929302929292F292906292929062907292953537D537D5353
+%537E5353FD042953CFFD0EA87DFD04A8FFA8A8A8FFA8A853A8CFFD06A8FF
+%7DFD1AFF29302F5429302930293029302930293029302930293029302930
+%2930292FFD0A290729292907292929072907290729292953FFA8A8A8FFFD
+%0DA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD1AFFA92930292929
+%2F2929292F2929292F2929292F2929292F2929292FFD0429062906290729
+%062907290629072906290729062907290629072953CFFD0AA87DA8A8A87D
+%FD13A87DFD1BFFA929302954293029542930295429302954293029542930
+%295429302954FD1C2959FFA8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8
+%FFA8FFA8FF7DFD1DFFA92929293029292930292929302929293029292930
+%292929302929293029290629292906292929062929290629292906292929
+%06292929062953FD09A87EFD08A8FFA8A8A8FFA8A8A8FFA8A8A8FFA87DA8
+%FD1DFFA92930293029302930293029302930293029302930293029302930
+%2930FD1A29072953FFA8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8
+%A87DFD1FFFA92929292F2929292F2929292F2929292F2929292F2929292F
+%FD0429062906290729062907290629072906290729062907290629072906
+%2953FD09A87DA8A8A87DA87EFD0DA87DA8FD08FFA8FD18FF2F3029302954
+%2930295429302954293029542930295429302954FD1E2953FFA8A8A8FFA8
+%A8A8FFFD07A8FFA8FFA8FFA8FFA8FFA8FFA8A8A8FD05FFA8FFA8FFA8FD18
+%FF2FFD042930292929302929293029292930292929302929293029290629
+%292906292929062929290629292906292929062929290629072953CFFD0E
+%A87DFD04A8FFA8A8A8FFA8A87DFFFFFFA8FFA8A8A8FFA8A8A8FD18FF5430
+%293029302930293029302930293029302930293029302954FD1E2953FFA8
+%A8A8FFA8A8A8FFFD09A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8
+%A8A8FD18FF7E2F0729292F2929292F2929292F2929292F2929292F292929
+%302929062907290629072906290729062907290629072906290729062907
+%0753FD0BA87DA8A8A87DFD18A8FD18FFA95A293029302954293029542930
+%295429302954293029542930FD1E2953FFA8FFA8A8A8FFFD0BA8FFA8FFA8
+%FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD1AFF7EFD0529302929293029
+%292930292929302929293029290629292906292929062929290629292906
+%2929290629292906292929062953FD12A8FFA8A8A8FFA8A8A8FFA8A8A8FF
+%A8A8A8FFA8A87DFD1CFF5330293029302930293029302930293029302930
+%2930FD1E2907297ECFA8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8
+%FFA8FFA8FFA8A8A8FD1CFF7E540729292F2929292F2929292F2929292F29
+%292930292906290729062907290629072906290729062907290629072906
+%29012953FFFD0EA87DFD14A8FFA8A8FD1EFFA95330293029542930295429
+%302954293029542930FD18290729297EA9FFFFFFA8FFA8A8A8FFA8A8A8FF
+%FD09A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A87DFD20FF845A29292930
+%292929302929293029292930292907292929062929290629292906292929
+%062929290629062F5AFD07FFFD10A87DFD04A8FFA8A8A8FFA8A8A8FFA8A8
+%A8FFA87DFD23FF7E542929293029302930293029302930292FFD10290729
+%072953A9FD0AFFFD05A8FFA8A8A8FFFD09A8FFA8FFA8FFA8FFA8FFA8FFA8
+%FFA8A87DFD25FFA97E54292907FD04293029292930292906290729062907
+%29062906290129062953A8A8FD0DFFFD0CA87DA8A8A87DFD0FA87DA8FD29
+%FFA87E5454293029292930293029290729072907290729292F2F7E7EAFFD
+%13FFA8A8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8A8A8FD2EFF84
+%A87E7E535A535453545354537E5A7E7EA9A9FD17FFFD13A8FFA8A8A8FFA8
+%A8A8FFA8A87DA8FD5AFFA8A8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8
+%A8A8FD5AFFFD1BA8FF7DA8FD5BFFA8FFA8A8A8FFA8A8A8FFA8A8A8FFFD05
+%A8FFA8FFA8FFA8FFA8A8A8FD5CFFFD10A87DFD04A8FFA8A8A8FF7DA8FD5D
+%FFFD05A8FFA8A8A8FFA8A8A8FFFD05A8FFA8FFA8FFA8A8A8FD5EFFFD10A8
+%7DFD07A87DFD60FFA8A8A8FFA8A8A8FFA8A8A8FFA8FFFD05A8FFA8FFA8A8
+%FD61FFFD13A8FFA87D7DFD62FFA8A87DFD04A8FFFD08A87DA87D7D7DFD65
+%FFA87DA8FD0B7DA87DA8A8FFFFFF
+%%EndData
+
+endstream endobj 22 0 obj <</Length 30478>>stream
+%AI12_CompressedDataxœì}gWãʶà|¾kñl É¶•-‘£&6©¦¡ pcl°Í ïÃüöÙ{WI*I¥àpÞœ7kîY—¶Ë¥
+»vª/ùãÓÂÚcë¾VЋJnä?_¾l´kÕn«=Ÿ£æÜn£ñÙ鶱iêd:§šE{­íÚw¼çE­Ý©·šóôûµ‚ÏOïì¯îL禦±í¬ÞmÔ õÚ<Tè´r÷ÏZñé¯çio^g³Ú…nªV²Kš¢9g^UrkÔ¥Úü£ÚéÔÿ ;Xº­cãzë³ùXo>¯·þšÏiªž+˜z9gêv® ÚöØ©ŸÔ:ánE;ZEËV-è].êš®Ñ#ðÉÔð¹ÍÖÃç[­Ù=n·jÎF«ÑjwæsW›¹ƒê3üRÍ]ÕÖŸ¹õFõážYÛ5ï*õF
+–fåðÿ
+ÿõ¬ööÞ
+eÅÉYª“#èã>˜jÔkÎç[͇ÅZ»{ÊŽË0…ýå?|6jíóf½ ëÓ¨ÍaÀ8h=Öð„?D¥Q%Ъÿ—÷8«¶Ÿk]8ãVã³K˜h{³
+ÿ>á¿Åjý}:åùÍÚ‰?
+;ôG÷Û2 ýü‹¢>¡):?e™ê¬]}€ƒÈÝÿ†‡àyÞ
+/Eµ .</×ðÕýö7~û
+Ÿ~CÛŸ9Ðîr?~*¹Çø†¥9a™ŒU/Œü'W‚]àÚ2€IØp:䎫 –5œUÉßg_wX¯" àò¿ªa…ëøþ¿î¯Æ›³·܇A‡Ý2ëÒ'¾¨
+û‘qhê¹í0X¸5n¾hWï…0âË]Ém@œÂ¯õOµý7o¸<Ø?Ý.æç…ÜÔ_o&t(
+À7¡3N¢3»l$i3"gIbCÔYà.©}³pêä.š¥©q Æ݉ë5mÇVú
+Ë_Ù·%¤,÷é©SsÁ«Æò%¤Š 0MÝžZü
+vZ &[ÍÑ¥ ÇöÆeD”íJîÉ3a@®7êÍZ®Óm·^=û<­wÚ—Scp;÷¥Û}Ÿ/•šbQŠ­·ÒÓ_Ï%MQìì¤ÖnVÙÜ9ÙFŠè" õwP0Òñh/Ï
+t;ó)J˜Œu Ï•¶#Z%ŸâJ¿[÷€­†hMÊ{ÑTÕF#B_‘Ž ž‚šýœ6`çµþ~ø÷:¼¼v 6Ú©áFÚ×è*ã.d¦¢®“ð£î#âÊ<…“¬¾¶î1•-‡P–ZF„
+Æyg:tÈêzLÍwDré“F•³F²*¨¸Dfèt®ä!ÉSS`ŠÏñ„ÃÊòÐû#¯Ñ̾®÷Çìóóó‘“›:Ö6óxêfëÙõZ‚hf]Û‚°KЬ3‹â§ËÙ–è×H´á~R=þ±Ö©?7Å
+žür©¯~›šÂi'TÆ‘xíŸ3«E}ßþœ]ÞÎOø‡A³­“Ófܬ·íŸw/§¡Y½ÝØÛK¿Ì™wE:ë­u}7ëÎXã¾t-Ÿu1ÿ£3vquŒÓH·ûmiry~ãÇWÙ¬³ Æb̬ÖØØÅõ¡š•¦¡‰«k¥²nIg­ü¶Ç›ú±lV¥òô°;ë„f\m1ò”l׸zT¶·ÛWò½V>ε³{<W£9×É·y>ëñä$ÍʦáG«·/J/4+`æýVðh´n^ã¬ÓQ„2~ÝâyA>ëûÎW˜&4±?«u¨,ŒÅÍúоµÕKù¬‡[3cÖç?+LãOÜ{_¯Äͺ³¢5Õkù¬ÆôÕìBãüP:ëh¥Š¯9 M,íÞ·õ˜Y­±/¦m®ÄÌzu§TZggþ¬¸aâíñ¥‰ýÚ˹tÖíoöEì^'
+ù"?×­›×J€xFñ¥aÉÕ¹N<ÙîÎÝ›K²å÷ð¬û»‡?ù¬W…©Ð^Ëf±xíÏŠ˜&n÷z]ÙûV–Ϻ;úiï_=ØÒYµØYaš½âÇûœ|»ÆYåtÿãS>ëž~»_©¬ä¥³žíÖwýYñl‚ŸXg¿âfÝT.”[G>ë~aììñnfA6+2›‹Û¥Nìv/¦jwïq³(ß +ë1³nÍ~_µÛ4+LÞîõÜÙm쬿GÏö×cf½±”ŸÕ_³²YÓFÏë¯ó_ç¤@¾½½¼‹µU[™zŽ›õ@ùµµ¿I³¦…©ö\½ì~Û•ÍÚnÆø¬÷útˆxf™-ÍZínû³’ʱ˜Ÿoê
+N<™õhiêãvërf]j‡%Ï|ëjŽÏúêÌ„fýòôcô‰f…i´õ+u7È+N”­ÃÛ8k!Ê ®äÙè†!¼µõ»Èf]™ÚšógE]ê˜/“³œCéãó{A¾X›]²ଥè¬Ö—Ñ¥«˜õk>4k^[?z¡Yélæ¿CÛýÝZÚze³®œïïÅ;€ù÷K‹ä²óëxCüUë¾åµùæ}èW_HkŸyýñí]þ¸1 ijlÖâ~mFÔc~e*ÇÖâÑë‘Ô×KÊþª®Ñ¯Q~½¢ìŸ¬q¿®)û{ý
+ÓH:l(ùïvÜã[ÊÑÃîIܯwÊéÆk7ô« Ùü˜SN/Æò1ÿ(*g«Sq¿šÊyþ£(ÿu1¯Únæ˼C”kí(çù%ökâðׯÊÅsa%î×}åû¸³æ-ÚáPùnmmÄ=~¬\•Æýú[ùyy=úU
+ùKjy'Ýï’wmra¶GxÅcÄÂ\h(ß™’„örœß¾zOÆ/¹8BÇã—ò¤Ž^e€~2èI
+ZPd wÏ&^A.TlE¸ÐÕÜ{`oÿ0<NÓÉláF¶…1¼E¸Ðôáf,y^ÍucWÄW¬žþpð‘«V¾­›‹0yŠ|\NžÌ2’lnEÝÛÏ°9v6âþ›+Œ%oŽý©'–ߧßå`Þ>~Cå6F>ùûš`û’ãüí–Rë¼~OÞí&zd! "™á-B—£ûöÞDH‘`œÖfi°¹‹ܸ›Z÷¼Ä1ÈChf
+á]Þiƒ%–ÐJB‡ìÇù¹Ìê.wÄŸÌx¤Ð¨kF‘{œÐˆ?T eù~pXÑï]àÕ­ì3ÜAÍæg§™ï…“ÄÊïÝ.2
+S—XSw,++¥óDhow8¬€ ‚ß»ÙYAò»³“²ânz|šöÆ\£å ‚ ò®LmvÕ™õß•!ì°ó¢ Zg6iŒéÑöÍG,Fp'dvx%» ^4
+ù¡£ðê‘Øð
+RzÑkbû$ö3.եώfr¦$:Þ¾&˜‚QG®˜ E7•yÒéŽ\Òóê䀕·¯úÊÅÙAìæˆÙ¤úBôqçCĹÀW˜æ¢5ð–ÂRVôÜ&ûõGõõ3Èà3;‰òacöæ.‰ñí| ùvzLî’ªÙ+óÇÝš­¯œɇàïeB&jÚÑsxßëÉÇæ3› j­œ«Énð–'÷H.ºÒ3É#šAK~ß ÊÅ>éfå|iztgý¾ˆÝØ"ºÏË¡°%7Y¶ôÅ蓈˜¶‘€}°
+c¡ù8¡e‰d¹^Ž/ãn`Ú˜Ó!îmóÔ»1
+¬¤¨—çs7:P8{Ò %án<ɢ׌Öw‹Q Ð¡­Ì0®?3 .M¨ˆÇ´Ô²°“äQX>ôBN’¾œR¬íO{kvÉÅ¥ˆ'Lrh³I1%Ä?%_q z9˜ÈsI¢™pδe9ŒL]ðÛnl ;£Ævyás\Ozö†ÑÒ9®ïëLcºY*dÇçÛWïÉFw5›N.˜0ÏlRŠUücG IOo A³*Ø(žÙÈO(kN“—™K4ZNn_8ŠâIÅÛ³aùXÝÏ`ó¤ØÞÌ(¼ü> íÿ&>ÂWÕ3ËG-Qû— Ç8Ï-ŽÖ§ö/ž«:jE¬UG†#Ö` Á¥+¾889‰–ïÙ dÛ¥¤ÆÊÇdá(c6êh¡wù˜ ç§(»;,ç§z42b 7`%?ºž_ %5ËOíˆåGóSñ&+A“È3L™q!<°%úT‚%1­g:]y²û!‰óf%Ÿf0Š›h2Á^dÑ?eaXÑ(¼LôyÇgìÅ­I@‹ ¯3Îdfœ¶~yU‰©P2F&?t¬w•$¦ÄÔ8äi’ì¸0Ö/_Â있,è³yÚ(¦OY³±p(3élz
+ÿàh)¸Üƒ3E[¿èEï':Š}EŽ¹¬£Åý}G–é+L#bFjþ%­)Þ›&2÷lB#‘<^ðõ6•;)Vós º½å£—íÆEõnsìñs«âŒ¯ÞVΖ·¨–¦N9ßlb-߈P´4P9Ÿ˜¡­å_c0H9_r-߈_º8X9Ÿ0«¤–OLT¨œ/¹–oD,]¤œ/¹–/¨@ PΗ\Ë7"–.RΗ\Ë7,]ì¿œ/¹–‹µÁËù’kù¡‡QΗ\ËÇwÓ[9_0:¡
+f…˜ ~º,i'€âܦ!„Ž£äP: 0ÌÉp@Úâ1BLK]ô]™²ÖÜâ¼aWæ%§]­2/Ó†S™Ç¼ƒ‘â¼ÞJ®Ìë!vÊ<Q‡Šó†]™5
+³&FöT™—”jå*¡C¨Ì/t’Ðã*óxæ}¸8oØ•y1g3ìʼk-..´}ÑFá?Š¼”üõÌ©—0”šQëÌz £iÃà
+'FQz
+QžžR¬c_p,ͼϔb ZúòL˜·n6’aÈs3ÐãÕ@/»õ|O“iïxÉž
+=ù¦  <-6zò#sk‚ª¾!Ë–èÝ.†ôªc(í]8YL\¨Gz”‹µ‹¡ÐãE¬p}6í¾§CΆ|6¡” Øa$a Ûz6»Åi‚uP'±ïgÎ
+ÃïC-’ý>Ô"ÙïC*’½ùB‘¬:ZN‘, 4œ"Yhð"Ye(E²XF—þ¢ëpî`lJ«`3å/ÓyWDéñ®=°Œ3¡.oà\!YQ^@¬eÉ
+n3«u/œM¬?„¢<<y]Þ?R”׿íÙSQ^¼ó~¨Ey<É"¥\sࢼz3ìm²lÉhÁÝwbySn¾­ú*˜s‘þöûïö8É!‡_œÜ÷+á8Ð>¤!¤žϸ°®TïëG³¹
+¿B9=21[*åtb@IoFÆ^"8W‹›^uZSè}æA´Ó®“Ó]}m~ÞA"™P¼P~êd¼œŸ{ù}Š·Éce1^¼~—ŸÙ[Pós›'ßñâõS¼xý,?s¶fá§c캑/ìÝ™JéòµÌ…ÓRëU\´ëŸ
+^¡Ç*ÂDÛ3Pvw\RDH
+à:“ã-ñŠÙ`ÙÝÔýøÉkl±Ÿ1}“Tvw[ˆ•n"™Õ£Ú¬‘øb¿Û¤²»¼?+ÞDîͪKî)Œ/€[ÌÿL¸VîÛê‰0kè
+=¼{$¶ØÏ|™Yý>óWŠv•Tv÷¬„f ÞSøs'¾ØïËkéâ>nÖj¬ÛÊ|Pë ×6>‹53fÇAx.±Øo´²;:Z¤ÛÍOŸÜ¢ÀÏÇLýŽÆj¡ ⸮£GKù C¶?ï^Å·ã®}Õ÷§¹D ÏM…dl’Ï9=¿7ªÜO¼…óóÃ~ؾŠ‹FØ^ï±~*¹ƒ%þN¯U黨ã3ºâ‹‹R¯¨‰ÆϤÞÁÁ®× ®é3œà?¬ëõdÇ—Õmw<9:Hq¦à þ±™~ÛJ w0án·ðµzÜv=ܬ»Ã‘ô»ðÒ.ZɲÃÙÛàú®ŠÍtÇJVÀ§\?ÑÝ(OûÆM&P‰~Òø[ù|£ph…}2ë£WŸM†Â>™• wÛ TØ'«ê‹Õ¡û/ì“y¹ƒx˜…}²ª>¢›áöÉÐÇ‹­ ¯°/ÞÝ=ÔÂ>YzŠÀ¡‡UØ—š 9œÂ>Yœ'&Š;Ha_ð\YU_B`¥ß¾˜(î° û*V†YØ—õ]ö ùþ^UŸ<¼:PaŸL81ÔP ûdkCßC*ì“Uõ…2º†QØ';Cn†WØ'Ê ±°OVÕ'«X°°¯o õVØ—´!öɪúzZ†Â>YUßHL¥×
+?©Ê‘ T©w
+ûÌblÏÐý}ÏùnæØ<›ŒúzÆËÿ\LK>‚/ÿc^Ž´ûÿ2Öô ãá]þ'èi ÷ÿe/•Š¹ü¯W'dŸ—ÿÉáûÿz¬—Š^þ7yá¹ìþ¿>2H@L×Ø»5±I¹ ÅsëñxßÎ;Éélæ¿ \M´—œßá'\¦ÖôÉ2{Íîƃø– ½ØLãHLêµ}ñ™!™Ëãèƾ”ºlIjr6„Ž½o,?™žŠšÓX|k­§€zõ3×—%¥ÄÃRd_z/©Vd 'ÕŠÞM08¦̳dYe)ÄB$…F ¨²2È8P/20>q ê‹#£€¤›ž+íÅÑâ_’˜åòúpµïïÚT¤Ú÷w-=•½
+z¥e#%ÜÊP‡¥×ºe]VÖ„Ïh¬, àð*Éïʪo†œÀ#’‹i2û~l¦Þ
+E3*RÛ8¼Ë
+ÓÜCº¬Ðéüc€Ë
+Ã<íº¬»Tû½0ëe…žÛ¬0 —õÏ^V(fÞÿƒ—Êݸ¬šôÚQÒ«ÙrÒÞj%Þvè¥Á zá¡‹ªòÛ{Ͷ‹½ð°Ÿ·Zõqáaìæ†ñV+ÿÂÃr ²_x˜\
+.&"i$ž;ØÕl”§óùRØ# m ü>9ß?XDÉJI¬z¹¼à€Ž7|ˆÓÎ6E P}‚W‡UmnpÂP¡ä¤»ÚF»½|R_-u¿®©ö÷Smryt“º`U×ÎìÙqµÿr3;‘G¯Q~òvç%_\ú½6»°üáÌ..œ\ÍžÕ_[ÊÖÖï’²õ»0¯Tö¾­¡ ¨´êûÊö7§ ìïÞ)ûoOÏÊQ£ö¢œèŽr¶[¿PÎ;/OÊ…Òm(·KŸÊ÷ÂÅ”r=w>­ü¼=Rno/Ÿ”»½«üÒ/'•_SßÚíöV©Ý¹i-´?ÕæLÓþ¼³§:“å ÔNºXm:Y¨?îí:O«?¯Ÿó3_.Çí…Æú—ãÓí¯/¯_FGÒáÔXãáË®áLÝÿ¾Ü\œq‹óŸsïÆá/:*ƒiòk•³³/Êxíš[RvÂφJ^;,pÝÏÖ¯ á‚L~Ãâüz^,Úö·y òù¡üZ¼n· ³þv#{5¦/gõÉU¥²¾·®Tž¾*ÛG‡o±[ë‹ió|Âå­Ù%ûð‡RªÜåGX…ä7eë¢|G÷*¥£Ú\H ’Qà*Ã_So¾—VØœ/|]€ÕÿNä§|¡4yeÀ›ùñM»”Ÿ›^]Ŷ¯ùÙo£‡X |ˆ?¬ä kúc~îàr'?ó1{­~صÙý¢Ú,2ÑqufC]€i6êÕ’Š[»[]ØÏ·é€*[Ú ŸNßÕ¹ççeøtñAæ¿Rz-Òãú¸óÖU”©b‰¾"‡œâŸ~×fà‰i6áÓäÇ,£›YÞ2?UÀ¯þußàc
+ð™ç“ÚæÃÑJ$©/ËîûÜ:Þîÿ1tCLKß½¾ÖÎoúâš|g¡å$óT˜Æg«‹‹…îâægu{Øêé>˜Ó+{k;f¾ œtót}KÛYu¶ì‡¹­öíüíÂõ~sy»qqy]~(«¥Îû í0`ìsH0.0|²¡` ?-;ÇyßØXlÞlË“ (ˆ»ñȾÏÓÏ°aßö”ìy
+æyÍ[*º3L PÜÊÉÌÍÚÙùïÛL|Ž>Uîòði~‹¶$ïXNª+y]Ã#]ø®Uî^3•µFõwm‡>Á(³•N~¥vábšï9íç&§6êùÓ©ÎÙ¦á§ÂÌÄîËÔZ¿¬vûа½ÓÏ®r tútô#¼ðÿŸ;ýìZç@§ï¦Äÿçýs§OG\àŸ=ý`¤ð;}:z:›ôôéèû•7ÙO_àñ§Ïÿ £í,’œåË ç@›
+{‹-¡¨ÂÇ}ö0µÈ]ŒTÐ…óç«Á¸ç„ÙªsQÛèÆÚ¨«ºÜCÄƘ„ÿÄ\}+4ÀìÆøÊ–ËHAÕ¦œ+ÝßµŽ.¯l»FlkF<C<øÑJEð^)µQ³àòòxm[¬Ô§„² ÂB–͈©t[7 }bá‡
+–Ù机}[dµŠÔgxQdm?;w˜´zÓqsMïº~º; .Ú$^íäÝ`ôÓÇÙ…‡£̘ ]mÄ
+2Ü-½Ì¬~Ÿ©
+7y¤ ÓLO­üø K5¶á75ÈÝf›îÙ|æýìý¼Ñù1á’çô%þ0æÖœŠØt5×ô¶>½7ëÞͳó³8úûœHŒ]l…ò´"\NÇ>»Š•a³sêáFÂç#«#  p˜àð£­ß»p˜W}8à-E·.‚÷lý*·C@ðZ„Ã̸
+F1ÛnÐšÑ £#^ Vÿ5£³é£ìl«ÍP0Šn»P'ÙˆnçDl¥hJ™hp”‘ð»»SêCû,Eè¥>t¶¿âPœ¦—úÐ>‹C‘nz©í³8”0­‡úÐÄâP¼=¯¶. 
+ñ(‘nŸkü/ÿ â l—ý)|6jí£vý¹ÞÌmº0òŸÒÚ®ªž7[•v­vVû«»Ùzø|«5»¹ù\iítcw×67k­ÇZŽ³¿Êž³`ŽK,žª'¾$ÃǸÁ擳ýº3v²TÝ|R®–Ã~ÓúÎføŒ°×Y$lî¥þ‚‰|Åüìçü)Æ¿6óå@C9)}+œI¸¶Þ® ¿*­òw]yéŒåF²t¿6÷~øuuÏé,Û;‹ß‹•Öµq±Õ¾¹V6¯+Wg•¥µ¥@ɲør*þ†•}'nÃ|K3?+èÕÄ÷i\ò<ăï—ù©BuÔ«ˆ^ÀècØøD(Šç Ç&ZÝÖ]µ‰ò|Fˆ
+Ó0\­Ž¿ÝPå°6¹te2Ù±~y7‡hRp9¥KƒœBw<ŠÆÚèÊgk£I'ðk£©Tš¡
+ñë%è¦Yäò¼8ÍUº«]:ÍYQ¥¹:*¢h µÛ駫r´Þ°Çl3é|±ÄŸ~a©ûŠQò¤$¦éÈsE Ïó¥ùµó‰…_/å½÷µ³µæw¢*mýÇÌ-"4¡ñôÃ¥'kÏt_sù~ßWèªÀL‹ EïOŠôR
+]6KÕʼnùçæäyeqËøòÕGÞ)à¾q@Håß_‘²û£„«Dœ[›aŸ¶n¾Î²OÂÊ»Ï:µiëW³[¡åX×o;ͧ/,ñ_]\¹4Öö.•1‘Ǽ}Ç \|ø¯˜’%¡-[_6>íÖ.)© ösûärþçQkjëûúÁ×õéFûxµÔµvÖ·”♘afåïg½h¢r›ä¦?¯i—[·8A_¾ÎºÊÒ2ƒ©>z<áLWá(²w×ÑËá«1Íôöês,ƒñßËÄ&}Vˆq…å-#^#S¤sÃðÎ5còW«ï(A•}Âý©îò‡:§4yºÆŒ«Æªs_Þù¢™2…½Ñì'÷{EQÃyßPÜ×J„,)8 F¼`N¹;<œuSĘzAã俤bû}u¨Ã’§ýÔ8c#Êp>ÿ™üòŽÐþ[×#o®Ž¼ÃæPÀã[·¦6ü& B¡Ç{/zÌw§:ÞÇ‘1Œ™mJ³‹ ¶Û‹ö.¼øУ5–ÿ²>îåÏ>LDÆX/øN
+µr¹­ú¯Õà"î6)Õ—Ï·ÏKõ¹ùe¢ ·íâÃm»j—êGMf‹‹¿ˆÙO=Ü P{W×ðJ®Å…·ám\‰q=’ ,žEžY<K-ÎÆõ¾¼³é+žåûûû:¨ïnE8P¬•7¯E ÀrD ÐýÏ «ú¯é\EFɇ®èUˆ¯Ó+3“°2ÿÚt0ó…epÈEJò’Ñ}j‘/*·Yƒ¼+óÇ]Žß½Fx½\avµM¯Rñnœßµ©Ø²ŒÑydä9›ü˜„2È•¼/î?ÆüÔÜ@Ð#
+Ö¤ÜAwøiš"™Ôñãšì±ð8ðÌ_o&t(T»Ývýþ³[븮µÛÕh¿‡—zã±]kò^j®´Ûìú?ãŸîßï5þs®t
+Ã6Ÿƒþ¨6>ÝS/Ýîû|©Ôì«­ûZñ¡õVzú빤)Š]àÖÚÍjcZ>P³úæŽKÌ8ëŽFþ£äÖðÏåŸ#ÿ™ùÄOGð§hX–aÙ9¥¨˜¦cÀ¿¶bk¶… ð?ήhÚŠîhð¡ljŽ-:k¹¬â0x¼ðkîòoüö>ý†¶?sª’;Èýø©äGÔÜåÉÈtU/jf® ™ZTrÍ2‹šãجa¬¢nXelP‹Še99Í* Å >JQ5l²‹FÙT¡Épp¼ adÖ²œ ¾>ù-ð/Îî}ÕUØM¯køIÒ¢9[)µE¥¬ã"m§h;–™ÓtVdàŠìrÑÔTl²ŠŽ©hØdÕ2ì`Ÿu[qûÁ5±UÎœ#í(EÇPlv
+†¢”é4LCÇCPM˶tø )eÛÀfÙ2Ê*FdÅo²}E÷Zˆ®Fêí‡4ßèDŽ‰ÚœbÙVv† §©ª9­¬UNšÀ¸7mlÒŠ›Ë°le£h™*õ1`([‡>VѶM›´¢é¨ÀZÊChRé1[/ꊎãèvQ±q6<KŅ♩0¾æ¨EG# ÓuÂ%E…cµq ÏÖœ®ÂŠ`l‚}Ú0¦p ˆÁIñAÒÒ©—Z.Âhð lÓÐu ›àG\nÁ|ŠbMð,€Aqœ@G؃³C“Å&Ñm»hŸÁvç…¸­6ïè^“STTË‚¦²ÐT&²14€þû0±Í
+ºb0h›ŠÉÏ_ÌÕ ‡
+2S(¢ž‚<ÔäÜÂ?Täš@Ò€´*¶ŒaQ&5Vb!5¹ Ò48LSÁgúèh!¾S¥âß9­xß- _‰Ú„ï&Çrj2T¢f`&šL]-»MÀ/ D¡†'ˆÂËñe/ž3c4ÐßÐQn3lp° –«* \
+ˆklÑÝb£9vYg¼…‰-œ€)بn?[1ËÔOaƒÆAr’3ô'+&T@ŸAH•uS%–mT¸ت«ÁŒÑ¤Ó‚~C£‚R¢0®óÆZ5•µÉi€Þ Åšˆ_`(k*sÂD½ñ. ô_ÒQQ7ÝÊ¢­bk”ë6ºï°&ÇÒ R mÔy Hò® ¶ÇÙg+4mÔ߀Ï8 CÂz@/,›8 ŠÊ¤
+)r ø‹Ì“ìÐý@=ÍTY#ð
+A
+¨86ÐùA:,k0“ ÈÉÝó&”V†Âeµß8©N4­ù¯ )Û‡Èb®h¨§uP)Á˜°˜â¬"óÖ|åWSèÄ@ÖëŠVæ=j,@I ŸxˆpzÈD‚y ³uè¡2eTãªÝkµ§ÌZµÐdkhƒè€†Šº9XœÐ`“6׈à@5lutʸÄNE×Ùp¼ f+›ô¬á?k¨Ìê„VTC
+½ÊJhê‚yoó&›,qR¯#ÇeŽŽ”u…[°–혴£l0+Î%cÕ êA*
+ëh($%¦íP“Î8»£ V3çÈ›t2@``C¥n
+áìʬ•œ:
+jJe")ÔèT2T`IŠÅH¯ !0Ï"ƒ\qÕh[€·KÄ…°Ä4lÑ þ$Ç4¸å2›ÒrLÜñC-×´Ëm铸Ob–.ˆp`A@iÛl„ßAôÙðœÊ\·4T‘P9ÐM½LlÕ0Ê8€Ø”}@eÜ@—<½è›ã
+j3pdrõ‚ˆØç tÚóíû¶ËÔĈÖcàäͱ9ÀÑ9l;ƒŽ ëh
+ îâÎ.sŽXd -À¤{Yã<ù˜Åä6*6뢤̚À2Y[.jž x€El΀BÈè‰(·&קjºœõ ¶\è¯êtò¨óè€;::«Ø“°ÐrTrú*Œ6tÛ;y½ŒZãÁÐjØøS j*‹µ]ãOçWdéºÂX"=(!vmGeMŽJ*)ØDCpõVi²V»Œ6‘a+¼ÉA³@·lî+#-Þ C‚¦£±VZ%—m¦ MæØ85¹Ú¬CÎ Öˆ®v˜ ¾/ÅAƒ5SÆwáÈIÌ7.»bý1eâ²èæ£ÑtDM$TÍ5}¸ô¢'qq–+äP‡§&‡ÅM€J›ùü]Ñá0µ†?ëX×—qåÔb«\Ó.£^ k®Þí­ØkYs¸üEK5;›‰n@8‹¸ÇTïA´õm•É/ÇDТ†ÉõHÎ(]¸·ë
+רÌáâ**›$,$éø€¢H¤Ñ¢‚S"^eRX"¬%"].ûeJBT“jQÍD¢½Dœˆ
+$Q“¤ú”Dñ’¨gr=.ªðEµÂí1ªeJTQ¹Î*Sn%*°LS–*Ôµ[¦ŸKùˆ²Ÿ`øfCIJ[ 2S%jÐÈ-¹‰1¤d—Ž2ÜDuŒi興Zv\ †ÕÈ;ç9NN,Ho¼R
+‘,†"pKEöêNîͤ"/fó—9¡¡l™‹d’vã)äñ a?ÀÌ° ¦¥¨Ž£±@©¥Ãöå©gEâ ùh$~©·Gê’ø$^&¹;Jâ·Šz·¤^0Ä!U§ýÃbTGsH
+ Xt30½…4ÎcÉÏÀÂ@®*g¸nj¢È† é›Ë´p·,J‹ñ<âŒ;ö˜:i™(‡Ü ÅÛR+obϱp$kaK×Ý}ƒôðC¡<Y0. pç¨[Ù:kdãA‹O+³H6™ì»¬´¾6
+¦á¸8šMÃ;<Ü<
+ÃÙSE}Ó
+¼n‚J¦`tG¡("0é0ò=¹Ú¡‚3th06p‡Ô-Ø9”0ÊŠœCqÓÁp`7
+Ó%
+‹=Xædc°/ž
+n”vYe¬ÊvÈ9‘¨Ü‹¡[Ì»AºOôbù¾
+÷Sj`Z“&0™ªb˜”$×ÄÄu¢ÑŸHŒu=Ke3h
+.ñˆ jYZ:ËOU4ß‹ˆ‰¯ŠÍÉ›-ŽÊU# Òè67¸aÁm²Žt^&ƒ­ŠB‰»!@…¾% ÕUrº:ŽÁ5&lÐ|Á¥  5f©†Íüg`õ¢¥ƒ>Ì·A –É®@G©1¾ˆ¶¥ # ‘TO4 ´2ú±Ðž$ß3Æž}äv ÑeÎî‘rQg-s>®1®€j8³Õz¹îÎÂÒ˜ÊÜ”Òl,‹gõr%Zõ"7ªŸt
+¸eó”#>:¨­:E 4‹åJ¢Rm1EQ3¸wšÚh¥š;…ÛPYKAv<ÝGó½ ¨J+,sØM+öÝ—˜¼G~2DW;- ÞPæ F‡=ã 
+¯!ayœ¬IexJ©ô´R>Vå°::=‡Wî`b¥°ŽèÏû¬U¢hKÔq™Þî¸i×mFg.Z¾<H„E4Ôq¥,9Ta^]ÚîpÚÅüUÝ‹M%ŒA‚Õà º›À¤Vf”QÎ&‰©ÜI…-ÄÉuÊgáÛ·P°•åyÙ ´Øâ;l^#£š<»,8Í7áÕPH†/Ce¦N¡nÛqUtîŠGÏ S ®,PH]gŽF*drÖØÄVî¶î³|N&YÑg»Š
+N\™GˆŽénÌVÜ‘( ïlï^õ“­ ÄAi+.(5àhî3€+î¡ØŠ{(îÁ9üà&³ÊÜ  {þ`¯‰0À#£²ÃEóÉv‘É++ [uÏÒCDÔ#1üDècZ6Ó+tŠì"x, ^WÌn¬šÂ½ä¤0mžØKN>rG˜R5x. ¢º²ûv Ä°‰(˜rh{,ÝŠÿ(qæ³ ŽPvU$EqÙ†§Î)ŠÀ_xó§¡GHWx®+Duù²%ðeÍcàeŸ3&o se' øÐÉ„†í‰Ã-žÆ¨Y‚ 2ÝÅb ¬ ¬t2ñ¼C”)áËLôP™\Ü¢¾Â´¬(óUÖä
+i/q¾l³¬ “2O‘×-×Á¡ƒ¥ÅÄ=›ÑRD­À !m¸YÝ%SbPÅpGc’‹9›ýšYr8Y¤ž ? K–A•sèr%µÆáÚ!h?œ Õ"a«ƒIÐdPè›HUVˆ ãW/!6fYeJ™„È
+”V0VK]$1Hç£êRšÃ:juÄø‹J1ͨšÇõ?Ë;+»ÞX«ƒñVjÕTJÑ6ŠÄ~°…ܾØÂ-MUpa*73ž0äÍÌ·²«{k<^„VµÛ$D ,ž¢°>ŽOÂ*`-ÇËc×}/"Ô¬^J3Yî1%…;:Oo ±<)\’;Í0—§¢c+ñ|lň-Ï´ÜI4“¬^æ€ÑÊâ.yõe
+1ÛÛ÷о\ ù)ûÞV-‡ b0)³oh–
+o,!ï7å“bj :YYxÎæat›ë|$—n1—Üf<óý°B=¡,a>Šé‡Xó äewëîëìÄ…tWÞcSt7•^<ã,æWÛ†{ŠŠÉÊt Eåg­˜”ß-¯¯”bJË5£E9’dê}¦TD²®%¹Ùò$nI®w$<Ê—d•KSÏ¥)ê’\vIÆ»,1žg
+÷ Ãbƒ¹*€7W90÷ÐÀ ÚµCiÜK:Ö½!ªKð&4Ü“ÁY¿§2P4’ïÓž†€“Àp¼€'ïÇ#V(´5^®à<<ö¦ñx°âåŠÑy“/‘‚\X`D‡Mº Eg­<~" ´ÈÂ1ò¸M4À# EãE\ü‡bKû,, BÉ"UòˆV8î% Éch’`[$$ ÛÉB{²
+É1rÿß6‰ÈI‘o^Ã&Ü ©wîjˆÔ\[ýþΦƀI£)aL:ñy,°ÚOñ*l”Ò«k‡ƒ‘Q›:Õm¸Dgñ?0d2øA ÔEÎ+rM>EŽiÂݺ{"LþßÎnÚê$&DómÕî’ÛØb‰UC!xby¼SS)Üñ³kŸÅZÄO¬– ?oßlà{å` ?·o¶mü\<u»/ÍîËšúݳ &¿ÍuÜæ5õÇQõq¬©?³jÏlMýá¶Gp꣠9GpêßÑ\l2õAµÕŠ¢€Ãøž×3wȆÎfïºÚü’Ç)Þ
+c`2Ķõp©,Õ$0“í;Š”ä4UtˆŒeéÔ>l¿Š~,± Þ–w¹K*ûºSº„uÿ—~ÀE‘e¼XŸ(ŠçÇxø‡Éy”Wú¸ÿQù{SºX"â™IŠ`’Sk\œHN–žáGd»4{n¸­&ÉYìàÚWàä¡ÀP8VGù+pDy ÌN»°q²Š§ 1Ñ3þ›žT‚ƒ"t½Üy!œ(Ò‰Jªø  ¢â#8F»ó¸~ÃæqÃô¾N÷Õoÿ4n¿_›ÃäO3žf×péîºH!šŒä#õ4*cû_U‡ÔäãpÞd4ù8m6Nç>škÍ‹ùÔ‡¼ÍŠiÌ
+Ÿ=í0{ eCàŠ<AØ‚¿5e
+èj“—'2ku:玲ÈÍêŽÞÔª¢HX«Ôhˆp¥ÙûD*¼y¨*&.¤)IJU½X˜Ìí&ølrieH7±ŠUÂ61i,Ñlœ?šz\°u.i3Ú§˜ä+²-W[öŒUËŸô¿—{AkI~´ª¯äÅR ©®nê
+Iì ðÚõ‘kwóPߥÙ}õ™eäI"
+{Ç´©©öˆ¢»ù­ö««ýêäqÙ/©CÂ+ tjEu˜š$…‡­1yÔ–×ގ⶷÷W
+8-eTÛŠ³³m=ÆVX³ûŸê{ʇ¿}ìj!;mMÐÙÈ>‚÷‘6gò bC>ô¦NïjÕ5‡Ö›Ç! x–di]®CÃÐH‡„D$vb ÅHÌÆ"»«0†Š$žd'‰Pi{
+x‡@:Äàp“¨ü¾Ÿ‚ú¥CÜ ýÙU½GØ¡„] ÛéÄýPØ8Ý~ºÉzŒ·dbkê97#´Ã`ž§bJÙNƒ†E–©”\íé‡b7ua6œ É—†©T†Ä•‹Þîì O>óÒ¿_lÖಉ[çþŸ-çå$,9lYb‹WXââ:HËèjÅ*t±Ö’ŸÔËW7•VÕTüʺžùÁZ‹ßÌŽyö÷b±ê‡ïKk1 ‹#ü¨Û,¦I<<N` ;x|ã˜ê°x(FMQÕ1è²(ì›ÝÕJ‚¸Ç@ǃ,p$á%‹BI°JBZû&?o…Ò_=íæ¿“¿êLðÄ9Bï>D«;¨wµºLÚá}—"ˆ‰j®AègsŸ«~wµÚðòd…YÍsÀŠ©+&}mÜö Úò(@¿ªE{”½Ÿ„ÛÏhQf~ïåÖôÛ$”<ï{`D4û^Z0Ôû ÑH§kZ× nSü"28°ÉŽ†r À‡†`ð™ 4Šˆ¬¸B[DÆ™“ÁŒ¼Aø„âqâ|Ì
+±xçHñs»È9ÃIÄäfEëÀ“»Z#åŒNa€•b!´–@taÔƆa™@š!<š¶æv5!®'›hû@Ðœ!ÁXH gïDØÉÓ]{ÅèAÍJ\-qÈ'Ïmóçäåï:!OËY4øêò ¾i÷±…ôîà“ú?æ=D(Z¾ŠÞExsÚ֤ΉÐÔßÎV_}(¢€Üñýf¼ˆG:ü]­#PósxX„šu…×B³`0A®Bu
+íYˆRÅ”´ÒϊɦM”€7Õ'É‚&~)€IŽˆÞ'RSÍ…½½ŠÛ—
+'.…ºÐLeUL|ETZQËô^\v–1qYРEZ´ÝLævÒ¸}QÑEvDƒG”zTÐGuQÈE„QlH‰LºH4ŽD Ô’QQIt—MB`!œ–K Ë´z±°JM«6þÀÏÂD’ZseÚlmj$9%hZ?,Î&‡(‡]ÀJIÍô¸³ñ ¡i–è5ÆÑ-LF´ÆšTPD|0%ñEÀ`m•
+ì\ñ±*M6lZèWPLžá‚µIÁ¥L–"½9PüÖlîíWÄdÞ»­‡òn¨ÕÅfZJIƒÛ´n“šœÐ}(­M‹Õ`ŠÕbÊ«ÍÁº­MMÆj£¢7y#Xu(c˜¬
+Pª6 {1;&×€Ná)v^8ŽŒñÀ¤æU¨OS›¶§H(º¶èftwMÙ‰zDØH¢DhK„ÉÄáM”òôH‚âÀ(F–"ü©õôó#ÊÊ0X„yEÈX'„–üÅò4H[w…¯Ôzä±sn;¼ |¤Å£z_(S iî†O&#“a4M+zØ´Þƒð0e&õ±-³KçLµÙ£Ý<›¯E~+1]–ÕÞ#î^>¿ú„•,¦Ù'^k¬UáЦL DM–|–¦´/úsËêÆe.¦¼f¸Œ•¦««,zþBKeNy–cFlùȵ;+Ü•y.†‰è vYÿÒ¦ÎsßcéO¨¥˜—4͸‘˜Æþ’«S’­oâÄ´H)!Gñ£¯CÑ"¨ª%4žµªi¨5&P7}Ô‰›”*<Þ(­ßìIQóœIàõqÏIøŒ—™ú e@˜”ŒÀ
+µx WØÂw Ž‹ \ Ÿˆ
+B²ˆ¸ ŽÅ üŒÙ8s8«ƒ=øƒðAΑ ØH)½™à¬?
+«(z¤GêîÌñËK“·4-„˜‹í‹žg§—͵¯{˜ˆµ¸ƒÏÖ}un©wÌÕ;ŠxP¨w
+nö;: ìt2SCq.Lv…ylEÑ‘WƒbÝÇE–&½uÚÌ$3nnSÿ쬎A>‹)œÕØ:•H½‡¹ V¯âq]5S߯=â^ ±|7áxšgµê"Ï-ûâeVÐ590¸Š×}ĉVvEÿ´HìÛÃÿ5{ºÚ"N!
+úyùA–7yØ…„
+%y×–­)µ¦©äè]ßW}ªI?ëØôšiï£FŸ
+ù™âŸ`{܇S€IA %D™CNDFtDpHšÄèJ¤#phÌÛ “>Ĥ[1mkü‰ž X«…Ó)‚à¶)! 2P*á©Fè*£vadks), }çò]édÖ­ÊËÁÔ¦ž]í¦šÏµŠ2·âhEwDX1Ç!A®£ØwkÓZR<lµáy7©5Åt#ÝxKo½²[á-§U;Ûï_®éû‚–8Õ«˜XþPKŲ÷Ú2ÔtK4{j}‚2,e3¢.'¯ßÀ
+m"MZM³üŸÅ ÷?½÷á.ÿåË?î/ÿ}ýöü¼>üõåóëß¾½üó_¯ßÞ¿ûüýå߯O/_¾|ýñòãõ÷ý¿ž>{ýþãë·×§ï¿}ý,øPÿÀ‡¿üå×÷ïþ—ŽÎƒ
+endstream endobj 7 0 obj [6 0 R 5 0 R] endobj 23 0 obj <</CreationDate(D:20141208091012-04'00')/Creator(Adobe Illustrator CS5)/ModDate(D:20141208091012-05'00')/Producer(Adobe PDF library 9.90)/Title(vector-src blue)>> endobj xref
+0 24
+0000000000 65535 f
+0000000016 00000 n
+0000000156 00000 n
+0000020653 00000 n
+0000000000 00000 f
+0000033640 00000 n
+0000033710 00000 n
+0000086128 00000 n
+0000020704 00000 n
+0000021047 00000 n
+0000034125 00000 n
+0000034012 00000 n
+0000032394 00000 n
+0000033078 00000 n
+0000033126 00000 n
+0000033896 00000 n
+0000033927 00000 n
+0000033780 00000 n
+0000033811 00000 n
+0000034199 00000 n
+0000034373 00000 n
+0000035408 00000 n
+0000055597 00000 n
+0000086157 00000 n
+trailer
+<</Size 24/Root 1 0 R/Info 23 0 R/ID[<6B46032228D913458EBF161BD5836C1D><D3BDC2C72055D7499821118BE899D42C>]>>
+startxref
+86336
+%%EOF
diff --git a/Graphics/drawables/material-launcher/vector-src purple.ai b/Graphics/drawables/material-launcher/vector-src purple.ai
new file mode 100644
index 000000000..b20fc8340
--- /dev/null
+++ b/Graphics/drawables/material-launcher/vector-src purple.ai
@@ -0,0 +1,683 @@
+%PDF-1.5 %âãÏÓ
+1 0 obj <</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R 6 0 R]/Order 7 0 R/RBGroups[]>>/OCGs[5 0 R 6 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 21052/Subtype/XML/Type/Metadata>>stream
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c060 61.134777, 2010/02/12-17:32:00 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/"
+ xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/">
+ <xmp:CreatorTool>Adobe Illustrator CS5</xmp:CreatorTool>
+ <xmp:CreateDate>2014-12-08T09:10:30-04:00</xmp:CreateDate>
+ <xmp:ModifyDate>2014-12-08T09:10:30-05:00</xmp:ModifyDate>
+ <xmp:MetadataDate>2014-12-08T09:10:30-05:00</xmp:MetadataDate>
+ <xmp:Thumbnails>
+ <rdf:Alt>
+ <rdf:li rdf:parseType="Resource">
+ <xmpGImg:width>236</xmpGImg:width>
+ <xmpGImg:height>256</xmpGImg:height>
+ <xmpGImg:format>JPEG</xmpGImg:format>
+ <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADsAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYqtkkjjUs7BVHc4qld3r8MZKxLyPif6Yqlc2t3snRyo9tv1UxVCNd3DGrOTirX1ib+c4qqR6je&#xA;xmqysPauKo638xXSUEyiRfuOKpxZ6rZ3VFRuMn8jbH6MVRmKuxV2KuxV2KuxV2KuxV2KuxV2KuxV&#xA;2KuxV2KuxV2KuxV2KuxV2Koa9vorVKtu56L/ABOKsZvdSnuXJLGnb+zFVWx0S7uQHb91Ef2m6n5D&#xA;FU6t9C0+IDkhlbxc7fcNsVRscEMf93Gqf6oA/Viq/FVOS2t5P7yJH/1lBxVAXPl+xlBMVYX8RuPu&#xA;OKpLe6Vd2Z5MOUY6Sr0+nwxVGaZrzxkRXZLR9BL3Hz8cVZArKyhlIKncEbgjFW8VdirsVdirsVdi&#xA;rsVdirsVdirsVdirsVdirsVdirsVdiqhe3aW0JdvtH7IxVid1cy3UxJJYsdh3JxVPNK0RIgs1yOU&#xA;vVYz0X5+JxVV1LzL5d0uo1HU7W0YfsTTRo30KTU5bDDOX0glshhnL6QSxy7/ADm/Li2PE6uJW8IY&#xA;ZnH/AAQTj+OZMezsx/h+5yY9nZj/AA/clcn5/wDkFCAv1yQeKwin/DOuWDsrN5fNtHZWXyWf9DBe&#xA;Q/8Afd9/yJT/AKqYf5Jy+Sf5Ky+SKt/z3/LyUjnc3EFepkgc0/4DnkT2XmHQfNgey8w6D5p1Yfmh&#xA;+X98QINctlJ6CcmD/k8I8onoc0ecT9/3NMtFmjzifvZFbXVneQiW2mjuIG6SRsroR81JGY0okbFx&#xA;pRI2KTavogRWuLUfCN3iHb3XAhQ0bVjbOIJjW3Y7E/sE/wAMVZN1xV2KuxV2KuxV2KuxV2KuxV2K&#xA;uxV2KuxV2KuxV2KuxVxIAJOwG5OKsE83+btI09jJqF2lulP3cZNXYD+VBVj92XYcE8hqItuxYJ5D&#xA;URbza/8AzxNrI/6E09XkFRHdXhJA7VWJCN/CrfRm2w9j9Zn5O1w9kdZn5ML1z8xvOutFhfatOYm6&#xA;28LejFTwKR8QfpzZ4tHihyiHZYtJihyiGN5kuS7FXYq7FXYq7FURZahf2MwmsrmW1mHSWF2jb/gl&#xA;IORlASFEWxlASFEWzjQPzw896WyrcXCapbigMd2tXp7Spxev+tXMDL2ZilyHCfJwcvZuKXIcJ8me&#xA;+W/zH0XzPdtDDbvYXxQyNauQ6GlOXpuONfkVGafV6CWEXdxdPqtBLCLu4vR/L+oGWM2shq8YrGT3&#xA;Xw+jMBwU4xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVSvLy0sraS6u5kt7aFeUs0jBUVR3LHY&#xA;YYxMjQ5pjEk0ObxHz/8Any8vq6b5VHGE/DJqki/E3j6MbdB/lMPo75vNL2V1yfL9bu9L2X1yfL9b&#xA;xu6u7q7uHuLqV555DV5ZGLMT7k5uYxERQFB3MYiIobBSySXYq7FXYq7FXYq7FXYq7FXYqi9K1K40&#xA;zUra/tzSa2cOo7GnVTTsw2OV5cYnExPIsMuMTiYnkX0faapcSafHqWlFTPLD61n6oPAl0qgcAg0N&#xA;d9848w4Z8Muh3eQMOGdS6HdEeRfzb0DzOy2U/wDuN1r7Jspm2dhsfSc05H/JNG9j1zL1Wgni3Hqj&#xA;3uVqdBPHuPVHvZ1mA4LsVdirsVdirsVdirsVdirsVdirsVdiqRecPOeieVNMN9qcvxNUW1qlDLMw&#xA;/ZQHwruegy/T6aWWVRb9Pp5ZZVF80ed/zE1/zddl72T0bBGrbafGT6SeBPTm3+UfooNs6fTaSGEb&#xA;c+96XTaSGIbc+9i+ZTlOxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kvcfyov2uvKEUbdbOWS3qTUmhEg+&#xA;5ZAPozmO1MfDmvvFvNdpw4ct94t5f5+sf0f5w1GNKqryidCNv74CQ0+TMRm70M+PDE/D5O60M+LD&#xA;H5fJ6J+Wn54T2zRaR5qlMtsaJb6q1WkTsBP3df8AL6jvXqMHW9mA+rHz7v1ODrOzQfVj5936nusU&#xA;sU0SSxOskUih45EIZWVhUEEbEEZoiKdGRS7Ah2KuxV2KuxV2KuxV2KuxV2Ksa89+e9J8oaSbu7Pq&#xA;3ctVsrJTR5XH6kH7TfxoMydLpZZpUOXUuTpdLLNKhy6l8ueZPMur+Y9Vl1LVJjLPIaIoqEjTska/&#xA;sqP9vfOqw4Y448MXqMOGOOPDFK8tbXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq9Y/JSRmsdVjNeM&#xA;UsTKO1ZFYHb/AJ5jND2yN4n3ui7YG8SkX5xwqnmiB1FDLaIW9yJJF/UBmT2Qf3R/rfqcnsk/uj/W&#xA;/UwTNq7R6L+Vv5vXPlm4j0nVnafy/I1A27Pasx3ZO5Sv2k+ld6htZrtAMo4o/X97q9dohk9Ufq+9&#xA;9KW9xBcQR3FvIssEyrJFKhDK6MKqysNiCDUHObIINF54itivwIdirsVdirsVdirsVdiqU+afM2me&#xA;WtFn1bUWpDEKRxj7ckh+zGg8W/t6ZdgwyyyEYt2DDLJIRD5R81+adV8zazNqmovWR9ooQTwijH2Y&#xA;0B6Afj1zrMGCOKPDF6rBgjijwxSfLm52KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV61+ScLLp2r&#xA;TH7Mk0KDwrGrk/8AExmh7ZPqiPe6Ltg+qI96R/nMR/iW0HcWSH75ZMyOyP7o/wBb9Acjsj+7P9b9&#xA;AeeSSdh9JzbOylJTxYPV/wAl/wA020O6j8v6zP8A7hbh6Ws8h2tZGPcnpG5O/ZTv/Nmq7R0PGOOP&#xA;1D7XWa/R8Y44/V976OznHROxV2KuxV2KuxV2KtO6IjO7BUUFmZjQADckk4gKA+W/zX8/Sea9fZbZ&#xA;z+hrEtHYp0Dno0xHi9NvAfTnVaDS+FDf6jz/AFPU6HS+FDf6jz/UwjM5zXYqn/kjyhfea9fh0q1b&#xA;00IMl1cEVEUK05NTudwAPE5j6nUDFDiLRqdQMUOIvff8AeWPLkFvFp9kleNHuZQJJnYdSzkfgKDO&#xA;YzavJkNkvM5tXkyGyUbH5M8q+YdKmtdS0+F5AxC3CKqTIGGxWRRyG/0YMWqyYzcSxxanJjNgvnrz&#xA;95MufKWvy6bI/rW7D1LS4IoXiPSo8R0PvnT6XUjLDi6vTaXUDLDi6sbzJcl2Kq9nYXt7L6VpA88n&#xA;dY1LU9zTpleTJGAuRphkyRgLkaT+08g6vJQ3MsNqK0KlvUcfRGGX72zAydq4o8rk6/J2rijyspjF&#xA;+XtmP76+kfxCRqn4ln/VmJLtg9I/a4su2D0j9qr/AIC0r/f0/wDwSf8ANGR/lifcPx8WP8rz7h+P&#xA;ioSfl9bmpjvnT+VWjD/iGT9WTj2yesftZx7YPWP2pZdeRtYiXlC0VxXoitxb6eYC/wDDZlY+1cUu&#xA;dhysfamI87CR3Vld2j8LmF4WPQOCK+48c2EMkZi4m3PhkjMXE2o5Nm9y/KvTjaeT7eRgRJeSy3NC&#xA;KfCxES/hDX6c5jtTJxZSO7b8fN5rtPJxZSO7b8fN5r+a2ofWfOV3GrcltkjhBHsgZh9DOc3HZkOH&#xA;CPPd2fZ44cI82HZnuY7FXYq+ifyI/MY6tYf4Z1OWuo2KVsZWO81uu3A16tF+K/InOd7T0nAeOPI8&#xA;/e6LtDS8J4xyL1zNS6x2KuxV2KuxV2KvKvz586nS9FTy/ZvxvdUUm5ZTulqDQj/now4/INm27L03&#xA;FLjPKP3u17L03FLjPKP3vnjOiehdirsVe4f841wwcNfmoDODbJXuEPqn8SPwzR9sk+ke/wDQ6Ttg&#xA;n0j3/oeua5bGaxYgfFH8Q+XfNG6RJ9AuhDe+mxokw4/7L9n+mKvL/wDnIqSF9SslWhkijQSHuORl&#xA;IWvy3zf9kA8J/Hc77sgHhP47nj0EE08qwwo0krmiIoJJPsBm3lIRFnYO3lIRFnkzTR/IkMQE2rt6&#xA;knX6nG1FHtI4/Uv35pNT2r0x/N0mp7V6Y/mymKOKGEQQRrDAvSKMBV+4dfpzTzySkbJsuonOUjZN&#xA;ldkGDsVdirsVdiqnPbwTxmKeNZY26o4DA09jkoTlE2DRZQnKJsGixy5/Ltb68ij0p/SaZwrRPVlA&#xA;PVgeuwqTXNxp+1iBUxfm7fT9qkCpi/N647WOkaSSKpYadb0HciKBKd+/Fc1XqyT85H73VG8k/OR+&#xA;98z6jfS3+oXN9N/e3UrzPTpV2LED787DHARiIjo9VCAjEAdEPk2TsVdiqL0jVb7SNTtdTsJDFd2k&#xA;iywuPFT0I7qRsR3GQyYxOJieRYZICcTE8i+w/KfmSy8yeXrPWbTaO6SskdamORfhkjP+qwI9+uch&#xA;nwnHMxPR5bNiMJGJ6JvlLW7FXYq7FVk00UEMk0rBIolLyOegVRUk/IYQLNBIFmnyD5z8yT+ZPMt9&#xA;q8lQk8hFujfsQr8Ma/Qo3987DTYRjgIvX6fCMcBFJMvbnYq7FWYflf56/wAIeYTczIZNOu09G9jX&#xA;7QWtVkX3Q/gTmFrdL40KHMcnD1um8aFDmOT6W07zV5b1O2Wa01CCSNxXiXVWofFWoc5meCcTRBea&#xA;ngnE0QWP3Etl9dlSyuY51jINYnV+NdwDxJochKEhzFMJQI5injP5jaf5h1Hzf9VdWma6JminOysp&#xA;2qewEY+H/bGdDos+OOHi5V+Pteg0efHHDxcq/H2pnouhWWjQ8IKSXTCk92R8R/yU/lX9eajV6yWY&#xA;90e51Oq1ksx7o9yPzDcN2KuxV2KuxV2KuxV2Ksp8vaWbaD61Mv7+daRg/sxnvv3f9WFUs8/r9f0m&#xA;XR45jE84DSOu9Ap5Kp9iRvl2mzeFMSq6btPl8OYlVvBtQ0+6sLp7a5ThKn3EdmU9wc63FljkjxR5&#xA;PTYssZx4o8kPljY7FXYq7FXsP/OO3m5rTWbnyzcP/o+ogz2YP7NxGvxgf68a1/2IzT9rYLiJjmOf&#xA;udV2nhsCY6PoTOfdI7FXYq7FXn/54eYTpPkae3ibjcaq4s0p19NgWlPyKLx+nNh2Zh48oPSO7sOz&#xA;cXHlB6R3fMedQ9M7FXYq7FXYqr21/e220EzIta8QarU/5J2yJgDzYmIPNOvLfm3W9O1uC5iZrkuR&#xA;FJa9BIrEDiANuXgfHMbU6aE8ZB28+5x9TpoTgQdvPuep6vqjXUlACgApx2qK9Rt+Ock8mluKrXdI&#xA;0Z3YIiglmY0AA6kk4QCTQSBbEtT/ADH0y3kMdlC14w2MlfTT6CQWP3ZtcPZE5C5Hh+1z8fZ8j9Rp&#xA;CQfmW5f9/pxCfzJJUj6Cor9+XS7G7pfY2nss9D9jKNI8waXqqVtZf3gFWgf4ZBT/ACfp6jNZqNJk&#xA;xfUNu/o4ObTTx/UEyzGaHYq7FWQaJoJqt1fJt9qG3b9r/Kcfy+A7/LClNdT1KOyhMsh5SvX007s3&#xA;9BgQw2aaSaVpZG5O5qxOKpN5i0CDV7MoaJdRgmCY9j/Kf8k5l6PVnDK/4eocrS6k4pf0ery64gmt&#xA;53gmUpLGxV1PYjOrhMSAI5F6SMhIWOSnkmTsVdiqL0nU7nS9UtNStTS4spkni8C0bBgD7GlDkMkB&#xA;KJierDJASiQer7R0zULfUtNtdRtjyt7yFJ4T/kSKGX8DnGTgYyIPMPKSiQSD0RORYuxV2Kvn3/nI&#xA;rWPrHmTT9KVqpY25lceEk7bj/gI1+/Oh7Ix1Ay7z9z0HZGOoGXefueS5t3bOxV2KuxV2KuxVmfkH&#xA;R1/eaxMteBMVmD/PT4n/ANiDQZpe1tTQ8Mdebpu1dTQ8MdebL80LonYqlnnDyT5n1fSIpdNlQwUL&#xA;y2JqkklD8JDbhvEKafTmy7Oz4scrkN+/uc3R5YQPq597yy50y80+X0by3kt56VKSoyNTxAYDbOkj&#xA;MSFg29BjMSLBtSyTNXsryazu4rqE0khYMvvTqD7HpkMuMTiYnkWGSAnExPIvXrS5S5tYbmP7EyLI&#xA;oPWjCu+cbkgYSMT0eVyQMZEHomdno2o3dGjiKxGn76T4E39z1+jI0wZDp2hWdmRI3+kXA3DsKIp/&#xA;yVPU+5+7FVXUtWt7JSXPOdhVYwdz7nwGBWI3V3PdTNNM1XPQdgPADwxVSxV2KsP8+aGJIRqsC/vI&#xA;6Lcgd06K3+x6fL5ZueytVR8M8jydr2bqKPAevJgmb93bsVdirsVfTv5Ba2dQ8gx2rtyl0ueS1Nev&#xA;A0lj+gCTiPlnMdqY+HLf87d53tDHw5T5vSM1zguxV2Kvk3809Qa//MHXJia+ncm3HsLcCGn/AAmd&#xA;boYcOGI8vv3es0MOHDEeX3sVzLcp2KuxV2KuxVtEZ3VEBZ2ICqOpJ2AwE1ugmt3rlnaJZWcFklON&#xA;sgQkbVbq7fS1TnG58vHMy73j8+UzmZd6rlTU7FUr8ufnXZ+lFbaxYPA0YCNPbnku1AKxtRh77nN1&#xA;m7IPOBv3u0n2aTvEs7stf8q69B6MF3bXiS9bZyORp/NE9G+9c1s8OXEbII/He4UsWTGbIIUrnyJ5&#xA;PuXLS6TbiopxiT0R/wAkuGTjrsw5SLKOsyj+IqKflx5GQ1XR4q/5Uk7D7mkIyR7Qz/zvuZHXZv5y&#xA;eWen2FkqpaW0VuiCkaxxovEexA5fjmJKZkbPNxpTMjZ5rLnVrCCplnVnHw0B5tt2NKn78DFJb3zN&#xA;M4KWiekv+/GoW+gdB+OBUld3dizsWY7liakn5nFWsVdirsVWTRRzRPDKvKORSrqe4YUIwxkYmxzC&#xA;YyINh5Dqtg9hqNxZv1hchSe6ndT9KkHOywZRkgJDq9VhyccBLvQuWtrsVdir2j/nGjUymra3pZba&#xA;eCK6RfD0XMbEf8jlzS9sw9MZfB1HasNgXvuaF0zsVdir4v1q5N1rN/ct1nuJZT83ct/HO1xxqIHk&#xA;9njFRA8kHk2bsVdirsVdiqceUbYT+YbMMCViYzmn/FSlx/wyjMPXz4cMvl83E18+HDL5fN6VnJvK&#xA;OxV2KvJfMekyaZrVzEVpDKxlt27FGNaf7E7Z1uizjJjB6jYvSaLKJw80uzLcxHWuu65aLwtNRubd&#xA;f5YppEH3KR4ZXLDCXOIPwa5YYS5gH4Jvo2s+ddWv47O31e9+LeWT15KRoPtOx5dBmLnx4MUTIxj8&#xA;g4+aGHHHiMR8npMs0rhVaWSVUAVTIxdiFAFSW7mm+cvI2XnCbKzIodirsVdirsVdirsVYB+YdmI9&#xA;Qt7tQAJ4yjU7tGep+hhnQ9j5LgY9x+93nZeS4mPcxPNu7R2KuxV6L+QV2YPzHtowaC6triE+4CiX&#xA;/mVmu7VjeE+RDr+0o3j+L6gzmHn3Yq7FXxHncPbOxV2KuxV2KuxVlH5fxk6pdP8AyWxofdpEH6q5&#xA;qu15VjA8/wBBdX2tKsYHn+gs6znHnXYq7FUDq+j2eqWpt7lem8ci05ofFScv0+olilxRbsGeWOVh&#xA;h1x+XepKx+r3UMkfbnzRvuCuPxzdw7XxnmCC7eHakDzBC6z/AC6vnf8A0u8hij7+mHkc/IFUX8cc&#xA;na8APSCSs+1IAbAlmWl6Vp+lWptrGMqjEGWRzWSQjoWPt2A2zS6jUzym5Opz6iWQ3JF5jtDsVdir&#xA;sVdirsVdirsVYp+YkanSbeQ/aWcKD7MjE/8AERm27HP7wj+j+kOz7LP7wjyef50TvXYq7FWZ/k1K&#xA;YvzO0FgK1knT/g7aVf45hdoi8Evx1cPXj90X1lnKPNuxV2KviMgg0OxHUZ3D2zsVdirsVdirsVZZ&#xA;+Xv+9d9/xhX/AImM0/bH0R97qO1/oj72bZz7oHYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWMfm&#xA;NHImh2jMKJLc/uyf2uCNyp8uQzb9jx/eE+X6Xadlx9ZPk87zoXeOxV2Ksx/J5Gf8zdBCip9WU09l&#xA;t5CfwzD7Q/uJfjq4ev8A7ovrTOTebdirsVfGWv2ptNd1G0bZre6miIPWqSMvenhnaYpXAHvAeyxS&#xA;uAPkgMsbHYq7FXYq7FWS+Qp0j1eZG6ywFU/1g6N+oHNX2tG8V9xdZ2rG8QPcWe5zbzjsVdirsVdi&#xA;rsVdirsVdirsVdirsVdirsVTfQ9De+cTTAraqdz3c+AxVh/56yqt1o9kgCxwxSuqjYDmyr/xpm97&#xA;GG0j7v0u57KG0vg8tzdu3dirsVZ/+RNsZvzN02QD/eaK5lP0wtH/AMzM1/aZrAfOnA7RNYn1NnLv&#xA;POxV2KvlD82NONh+YWtRUoss31lSNgfrCiU/8M5zrNBPiwx+Xyer0M+LDH8cmJZmOW7FXYq7FXYq&#xA;mPl68+p61aTkhV58HY9AsgKMT8g1cxtXj48Uh5OPq8fHikPJ6hnIPIt4q7FXYq7FXYq7FXYq7FXY&#xA;q7FXYq7FU30PQ3vnE0wK2qnc93PgMVZlHGkaKiKFRRRVHQDFXz5+a2qrqHm6cI1Y7ZREvhUdafPr&#xA;nSdk46xX3l3/AGZCsd95Ydm0di7FXYq9c/5xs04y+atU1Aiq2lkIa9g1xKGH4QnNR2xOoAd5dV2p&#xA;L0gPonOedI7FXYq8C/5yM0Yw63pmrovwXcDW8jDpzhbkK+5WT8M6DsfJcTHuLv8AsjJcTHuLyDNw&#xA;7d2KuxV2KuxV2KvT/Lup/pHSoZmblMo9Oeu55r1J+fXOS12Dw8hHTmHlNbg8PIR05hM8xHEdirsV&#xA;dirsVdirsVdirsVdirsVTfQ9De+cTTAraqdz3c+AxVmUcaRoqIoVFFFUdAMValRnidEbg7KQrjfi&#xA;SNj9GKvmDzPp2p6frl3balGY7oOWPUqyk/CyE9VI6Z2GkMDjjw8qep0xicY4eSV5kN7sVdir6L/5&#xA;xv0c23lG91V1o+p3ZEZ8YrdeCn/gy+c72vkvII9w+90HaU7yV3PWs1LrnYq7FWDfnN5dOteRbsxL&#xA;yudOIvYaDekQIkH/ACLZj88zuzs3BlHcdnO7OzcGUdx2fLmdU9Q7FXYq7FXYq7FU78qa0NOv+ErU&#xA;tbiiyE9FP7LfR3zA7Q0viw2+oOB2hpvFhY+oPRuucs8w3irsVdirsVdirsVdirsVdiqb6Hob3zia&#xA;YFbVTue7nwGKsyjjSNFRFCoooqjoBireKuxVjPnryTZ+aNN4bRajACbO5PYn9h6fsN+HXMzR6s4Z&#xA;f0TzcrS6k4pf0er541HT7zTr2axvYjDdQMUljbqCPl1B6gjrnU45icRIci9JCYkLHJD5Nk2qSSMs&#xA;cSl5ZCEjRRUszGgAHzxJpjI0LfZvlDQY/L/ljTNHQCtlbpHIR0MpHKVv9k5Jzjc+XxJmXeXlcs+O&#xA;RPem+UtbsVdirTojoyOoZGBDKRUEHqCMVfI35geVpPLPmu90viRbBvVsmP7VvISU3PXj9k+4Odfp&#xA;M/i4xLr19712lz+LjEuvX3sdzJch2KuxV2KuxVSkk7D6TiwlJm3kvzOsiJpl69JVotrI37Q7IT4+&#xA;GaHtLRUfEjy6/rdF2hpK9ceXVmOaV1LsVdirsVdirsVdirsVTHR9KkvZg7Clsh+NvH/JGKs2gEax&#xA;qkahVUUCjYADFV+KuxV2KuxVh35ieQYPMtj9YtgI9YtlP1eTYCRRv6Tn/iJ7HM/Q604ZUfoP4tzd&#xA;HqziNH6S+f7i3ntriS3uI2inhYpLGwoyspoQR7HOojISFjk9FGQIsM+/Izyq2ueeIbyVOVjogF3K&#xA;SKgzVpAvz5fH/sc1/aefgxV1lt+twO0c3DCupfUecw8+7FXYq7FXYq81/PDyS2ueXRqtnHz1LSQz&#xA;0UfFJbneRfcr9sfT45s+zNTwT4T9Mvvdl2bqeCfCfpl975tzpXpHYq7FXYqpSSdh9JxYSkp4sHb9&#xA;RsexxUhnHlXzqspTT9UcLOKLDdMaCTwDns3v3+fXQa7s0x9ePl3dzotZoeE8UeXczPNM6x2KuxV2&#xA;KuxV2KphpOkyX0nJqrbqfjfx/wAlffFWWxRRwxrHGoVFFFUYquMgj+ImmKqtvdJNUD4XH7J8PHFV&#xA;bFXYq7FVlxMkEEkz/YiVnb5KKnFXy95ivJL/AF28uApeWaYqqr8RZq8RSnXkc67RQ4MMQe6/nu9N&#xA;pY8GIX3ftfUf5U+SR5S8pQWkyj9J3R+s6i3X964FEr4RrRfnU9853XanxchPQcnRarN4k76MxzDc&#xA;Z2KuxV2KuxV3XFXzL+cP5et5Z1o6hYx00TUXLQ8R8MMp+JoTToO6e237OdP2fq/FjR+ofi3puz9X&#xA;4kaP1B57mxdg7FVKSTsPpOLCUlPFg7FXYqslTku3UdMWMhaeeXvPOoaaFt7qt3ZigCk/vEH+Sx6j&#xA;2P4ZrtV2bDJvH0y+x1ufRRnuNi9A0nzDpGqIDaTgyU3gb4ZB/sT1+Y2zQ59JkxfUNu/o6nLp5w5h&#xA;Msxml2KuxVMNJ0mS+k5NVbdT8b+P+SvvirLYoo4Y1jjUKiiiqMVX4qhbhGDciaqeh8PbFVNWZWDK&#xA;aMNwRiqZW1ysy0O0g6jx9xiqtirsVY5+YWqDTfKt5NUB3HBK+J3/ABpTLsGPjmI95bcMOOYj3sJ/&#xA;IT8vTqmpDzXqUVdPsXI01GG0typ3l3/Zi7f5X+qc3famr4Y+HHmefudp2hqaHAH0O8kcYq7BB4sQ&#xA;B+Oc86ZtHR1DIwZT0INRireKuxV2KuxV2Kpfr+habr2k3GlajH6lrcrxamzKequh3oyncZZiyyxy&#xA;Eo8w2YssoSEo8w+UvO3kzVPKetSadejnE1Xs7sCiTRVoGHWh/mXsfahPWabUxyx4h8XqtNqI5Y2P&#xA;ixuSTsPpOZDbKSniwdirsVdirsVQ86UPIdD+vC1TCmCQQQaEdCMWCc2PnHzFZgKl20sY/YmpJ9FW&#xA;+L7jmHl7Pwz5xr3bOPPSY5dE3T8zdVC/HawFvEcwPu5HMQ9j4+hLjns6HeXN+Zuq1HG0gHjXmf1M&#xA;MR2Pj7yo7Oh3lFS/nN5uMIhtktLNFFF9GJiR/wAjHkGWR7JwjnZZjs/GO8oex/NrzpDqUN3dXn1u&#xA;GM/vLRkjjR0PUfAq0Pge2Tn2ZhMSAK82UtFjIoCnuPl3zFpnmDTI9Q0+TlG20kZ2eNx1Rx2I/tGc&#xA;5nwSxS4ZOmy4pQlRTMgEUO4PUZS1oWWIoajdD+GKrFZlYMpow3BGKplbXKzLQ7SDqPH3GKq2KpH5&#xA;s8qW3mS0is7q4khtlblKsQHJxUGlTWn2fDLsGY45cQ5hsxZDCXEGQWcpsbGCwsVW1s7ZBHBBEOIV&#xA;VFAK9fxyuczI2eZYSkSbKx3ZiWdiT3YnIoR3kUzyaCLuVmIvJ5p4kY/YjZyFUe1Fr9OKshxV2Kux&#xA;V2KuxV2KpF5z8m6T5s0aTTdQXid2trlf7yGSlAy/xHcZfp9RLFLiDdgzyxSsPlPzf5P1nyrq76bq&#xA;cdDu1vcLX05o67Oh/WOozqtPqI5Y8UXpMGeOSNhI8vbnYq7FXYq7FWmUMCD3xUi0IylSQe2FoIpr&#xA;FDsVdirsVdiqd+U/Nmp+WtTW8s25RNRbq1Y0SVB2PgR+y3b7xmPqdNHNGj8C058EckaL6J8u+YtM&#xA;8waZHqGnyco22kjOzxuOqOOxH9ozlM+CWKXDJ0OXFKEqKZkAih3B6jKWtCyxFDUbofwxVYrMrBlN&#xA;GG4IxVMra5Ey0Ozj7Q7fMYqrYq7FUv1+aSLSbgRDlNMBBEo6l5SIxT/gq4qznT7OOysLezj+xbxJ&#xA;EvyRQv8ADFVckAVJoPHFWldWHJSGHiDUYq3irsVdirsVdiqT+afKeieZ9KfTdWg9WJqmKVdpInpQ&#xA;SRt2YfcehBGXYM8sUuKLbhzSxyuL5h8//lnr3k67rcL9Z0uRqW2oxg8G8FkG/B6dj9BOdPpdZDMN&#xA;tpdz0Om1cco7pdzEMy3KdirsVdirsVUp0qOQ6j9WLCYQ+FqdirsVdirsVdiqd+U/Nmp+WtTW8s25&#xA;RNRbq1Y0SVB2PgR+y3b7xmPqdNHNGj8C058EckaL6J8u+YtM8waZHqGnyco22kjOzxuOqOOxH9oz&#xA;lM+CWKXDJ0OXFKEqKZkAih3B6jKWtCywlDUbr+rFVqOyMGU0IxVMre4WVfBh1GKquKqE9qk1zZSu&#xA;apZ3C3Hp/wAzIDxFe1GNcVTeXW71/sFYx/kip/GuKoOSeaU1kdn+ZJxVUtdQms25rV4xu8Q/aHtX&#xA;v4YqyP61bfVfrfqL9W4er6tfh4U5cq+FN8VVcVdirsVdirsVUruztby2ktbuFLi2mUpLDKodGU9m&#xA;U1BwxkQbHNIJBsPD/P3/ADj66mTUPKDcl+0+kytuP+MMrHf/AFXP+y7ZvNL2r0yfP9bt9N2l0yfN&#xA;4tfWN7YXUlpewSW11EaSwTKUdT13VqHNzGQkLBsO2jMSFg2FDJMnYq7FXYqhpU4tt0PTC0yFKeLF&#xA;2KuxV2KuxV2Ksm/L3V/Mmn+YYV0OCW9lnIW4sIlL+rGDvUDoVrUN2+VcxNbhxzh69vPuaNTjjKPq&#xA;2830o8U8RCzxNDIQCY3pUVFaHiWX7jnJF54rCK7HAqGmh47j7P6sVWI7IwZTQjFUyt7hZV8GHUYq&#xA;q4q7FXYq7FVD6836D/RvL4v0j9W7f3VPrnGnhw+DFWb4q7FXYq7FXYq7FXYqk3mXyd5b8y2wg1mx&#xA;juuIpHMarKn+pItHX5Voe+XYdRPGbiabcWacDcTTx7zP/wA433kbPP5a1BZo+os734HHssyDi30q&#xA;vzzcYe1xymPiHZ4u1P54+Ty/XvJXmzQC36W0q4tY1NDOU5w/8jU5R/8ADZs8Wpx5PpILscepxz5F&#xA;JAQemXt7sVWugZSPuxQRaFIIND1GFpaxQ7FXYqyLQPy+86a+VOlaRcTRP0uGX0oaf8ZZOCfjmPl1&#xA;WPH9Ug1TzwhzL1fyr/zjO1Un8z6iKdTZWPf2aZx94VPpzV5+2OkB8S4GXtH+aPm9k8veVfL3l2z+&#xA;qaLYxWcRpzKCruR3kkNXc/6xzT5c88huRt1+TLKZuRtFajp0V7Fxb4ZF/u5O4P8ATKmtilxby28r&#xA;RSrxdfuI8RiqkRXY4qhpoeO4+z+rFViOyMGU0IxVMre4WVfBh1GKquKuxV2KpL+9/SvKo9H9I049&#xA;+X6P64q9KxV2KuxV2KuxV2KuxV2KuxV3XY4qx7Vvy98kasS1/olpLI32pliEchr4yR8H/HMjHqss&#xA;OUi3Q1E48iWLX3/OPn5d3FfQju7KvQQXDNT/AJHibMqPauYc6Pw/U5Ee0co62lE//ONPlsn/AEfW&#xA;L6MV29QQybfQiZaO2J9YhtHak+4Idv8AnGLQ2NTrd1X/AIxR5L+WZfzQg9pSPQKtv/zjH5WU/wCk&#xA;atfSCv8AusQx7fSkmA9s5OkQg9oy7gnVh/zj1+W9qR61vc31P+Wi4YV/5EiHKZdq5jyIHw/W1S1+&#xA;Q+TLNI8heS9HKtp2i2kEi/Zm9JXlH/PR+T/jmJk1WSfORaJ55y5kp9lDU7FXYq7FUJqOnRXsXFvh&#xA;kX+7k7g/0xVilxby28rRSrxdfuI8RiqkRXY4qoNbGvwnbwOKtGOSIh0PTviqOt7hZV8GHUYqq4q7&#xA;FUn+H0vre9f056NabU+p+n/xLbFXpGKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2K&#xA;uxV2KuxVCajp0V7Fxb4ZF/u5O4P9MVYpcW8tvM0Uoo69f6jFVPFXYqh3R4n9SPYfqxVG29wsq+DD&#xA;qMVVcVSz0x/gv9If7r/S31vl/kfWvSr18MVeh4q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F&#xA;XYq7FXYq7FXYq7FXYql+r6Qt/GGR/RuYwfTkpVTX9l12qPxGKsTvI9SsCRe2UoQf8fFupniI8fgH&#xA;Mf7JRiqAPmDR1JDXSow6qwZT9xAOKrf8S6Idhchieyo7H7gpxVamrWzsHtILqVu3pW8jV3p4DFUd&#xA;z8x30BisNIuIJnBX17sLAiVH26MSxp4UxVk3+GYf8JfoDnt9X9L1e3qfa508Oe+Kv//Z</xmpGImg:image>
+ </rdf:li>
+ </rdf:Alt>
+ </xmp:Thumbnails>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+ xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/">
+ <xmpTPg:NPages>1</xmpTPg:NPages>
+ <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
+ <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
+ <xmpTPg:MaxPageSize rdf:parseType="Resource">
+ <stDim:w>626.000000</stDim:w>
+ <stDim:h>626.000000</stDim:h>
+ <stDim:unit>Points</stDim:unit>
+ </xmpTPg:MaxPageSize>
+ <xmpTPg:PlateNames>
+ <rdf:Seq>
+ <rdf:li>Cyan</rdf:li>
+ <rdf:li>Magenta</rdf:li>
+ <rdf:li>Yellow</rdf:li>
+ <rdf:li>Black</rdf:li>
+ </rdf:Seq>
+ </xmpTPg:PlateNames>
+ <xmpTPg:SwatchGroups>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Default Swatch Group</xmpG:groupName>
+ <xmpG:groupType>0</xmpG:groupType>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpTPg:SwatchGroups>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/">
+ <illustrator:Type>Document</illustrator:Type>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <dc:format>application/pdf</dc:format>
+ <dc:title>
+ <rdf:Alt>
+ <rdf:li xml:lang="x-default">vector-src purple</rdf:li>
+ </rdf:Alt>
+ </dc:title>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
+ <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
+ <xmpMM:DocumentID>uuid:230bb5ef-8b14-4d54-94f2-9f621119cab6</xmpMM:DocumentID>
+ <xmpMM:InstanceID>uuid:794ba64e-bc01-45e5-86fa-ac3328095722</xmpMM:InstanceID>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+ <pdf:Producer>Adobe PDF library 9.90</pdf:Producer>
+ </rdf:Description>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?>
+endstream endobj 3 0 obj <</Count 1/Kids[8 0 R]/Type/Pages>> endobj 8 0 obj <</ArtBox[213.5 89.3184 537.323 441.675]/BleedBox[0.0 0.0 626.0 626.0]/Contents 9 0 R/LastModified(D:20141208091030-04'00')/MediaBox[0.0 0.0 626.0 626.0]/Parent 3 0 R/PieceInfo<</Illustrator 10 0 R>>/Resources<</ExtGState<</GS0 11 0 R>>/Properties<</MC0 5 0 R/MC1 6 0 R>>>>/Thumb 12 0 R/TrimBox[0.0 0.0 626.0 626.0]/Type/Page>> endobj 9 0 obj <</Filter/FlateDecode/Length 11380>>stream
+H‰¤—ÍŽ$·„ïýu6еüÿ¹Z6| Á?ÀÀ–²Éïø‹HvÆb{*X$+™™üö×®o?þ®?þé‡ëñÛ#]£ ÿêç÷<þ~ýû‘î¾®tÏ^ù­ëúýçÇ·¿ü-]?ÿçñÛ•¯Ä¿|Õ\ïÒõçúø×Ccú}æźë×Çs±Ëÿ¦sßyŽ«Ô;§v=缧`¿ÛÜÀq׫Ì{±ýÇ#`bÙ/27ó™g›÷îzf¯6î*àÞµ^ÏÖïÕxWîÅç[cgP•Z_Þ_ÿüÃã'NÚVá¹èwÔ®³~?c©EÓkeUJåËAë¾›vŠs~E眫Ýå+høó5ëËs½“–×~Ïò Î;UVµ;÷}Õu×>/NXZ¹ø"ÏòÍÇ£qxÌkëN-¦s’Æ„´4¥]={^ç[µcJÞú³r¹ú¸¾êŠ‰ÿhæ
+~”-3Ù«[H—Åã…T®c®!+QQ3pq r°5—¥Y"DÜæÒ
+eÌÛÅ}•|GÞ=‰%ñØëwýùxl¶m*L-agÕ¸2qd6[°D¹¹DÁb¨–$?Š E­KÍÇì›QG§Òh+Ln²ÛPÎ¥ü¢)ƒ®9‡!Ó†DÖy†cì»ßï`#—D±§Î07ä‚o)‡Å‚j â’¸MÜè%ðÅê Ôf8¥Hª§Wú$Ç©Äñ¶ÉrçF>ùíµ19ó9m\ª·&µ$‡ô¬yÔâ¹b™A£o©Ú:Ãõ­ˆ«ó (ÖvÕ‚8$9=šýцŠØz¨‹¶˜Üq%žŽ°ô¨Æ©.“=hËS¢xúK{,EÑyÚé¸=¬ƒ¦jÓ0ÔÝd%OSÚ¦R‰£ãÕ¶Lgo5:[ZÒ¯Öw=HŠªº˜Š¿R•wx§¡”êJ~éQp.JÈMñ1kG߆€z¿4A_’=ì0œ©: ¢¢\4„7¯Ïk±Ê¹)‘’¯±îlXL‹¹‚{JºMᢞHSd )l‰ ŸJVL¤vw—*¸·œú$Y6”–±Zž0 ¬ªz“T*öe/—¾ ãà–î*K›©¹è<(¼ušcrt†%çšq´vµ³¾ä åkV J¸¦yUú¦ÙKó(FBÆ×IÒ÷Ía€³Ú3Ue˜wKe|º—Ïyõ ÆRI•!Ó¸â4—0ÄÙòÜžÌp ›-‰ÜnºÈ®(xPÀì`‡¨ƒí÷[QN¥/«.êºãm5E² é:FlÑŒ$¾¾ì»z(Ò+ß¿¨‡šŽr hœ_$„T’dÉR?%X”z€ÊA …ƹ(…Õw¸ÊÕÑúþ¹7Bç<£nN×um8½¢XŒuLV±/ËRE"’”[œŸ^“ãn ’U÷‰g¶¨V.¿Î4|ëuŸÀÅ=`XÖY-/¬VÿU±“®Á¾uØœóZi«—Æ5#»}Ä=ïÈÜ×¥Ïb †¼^JçÕ÷Ê}ÌŽM ü?ßêԶÄÝøeñ2S^“Y0ž¬Wý’sgÖÀH›/2ƒâL†ËïV ]*® …UiŽP®mÔŽ(¢:Lå‰ü#5AÀj ’a‚µ˜Ø¾îcºC8üIŒ¨Ò`½™ ă"g½tHæû/æ±{»î£RG”FÁ×
+du£Ûs‚³¶è†#ÀpNè«5–ߦuàÖ-G£vý}é²<b@‡QžÅí”~ÜuGÓ½bYÔ
+×ö‚uÈë  Q6‡ónîÄ‚Û2à (d9n¢ÈlÑ@=—ÕJ¡ïPÿ÷û(…S7ÏO—Yje³õÒÕõå|H
+üy/Á©‚+4ŽÁk*RœQßwÈá·-1áXc`xïýÚ òQØχ¼3Ò,|%ɦɪ]qy¹mp‰Ué.iFN”4| ¡s(]oUœ|I„ËPO³Î8i„GÂE: Ú²×°r+.â²TÂM 5΋Ÿç¡î]
+Qö€¥•’(YTG´€n:ê
+›äØ,Ám© pXO•t,ÊmDò¯}Ø‚ãoLw@¥nÀ
+j“nŠÂ=^“ôݸÅ{4–߯Ž÷¢ÒªQ±j$è<ú¸Åµ z©~ûöpŒÓ̀Ą^q?KëˆI‚1e.‹Â‡kK‘Ú·aƳuë‚+LŸßyöt­ÄgmºA%Ó\¢ƒ†¦ü÷w‰š½¬øD&2 Ü•
+#œš–ņî‡Åeƒt³¤B£œ²µïƒV”¸:-]È(Ž"ŸTŒjÄ­¯%~¥k"¥Œ ²†µ·;¾;ݸЌ#
+î掤HB Ò”\J\7(ÂNk7öHŠ{*Ѳ¯¦!ø­¹¹í»¼o+©V. ÉÚÂ%r§P:ò8brňK¿'/ãä Wÿ¥ºJr$Éqà½^‘碠…ÚžÑo(`æ’}èþÿal¡<"Q@eP.—S\Œf׆UÏ–3š
+„Àò)ïè
+5¡Œ!EošÙÙB\!3pÀhŸ{°"‘‰N5Sù_Ó¾©‡Öˆ80º¬²BÞJ‘j†ÑU9ÿÇ“€+‡»ÉNIgFh¾˜¹2î7°‰ð¼
+7~"µöè<Ú[œ–Çmè…o-tLý»B›Ø'{lÙ>îä#<ù>ÅÏO»ý°b=ž•(¡ÏãØ|ÌØZ˧#ä:\a6`Ïj{j¿5Ošx”Ò6GUèT,‚Ý,ºÊT´^«êc¡šâ»¶£ GV㥗 ’VîDOgJA„]
+õɱFHs½TÇ’û½»[ôª‰ÇxwÚÄÌiÐíùTMó9»xA•àªOÁÖá[Á
+Ud¨kÝÍ¡æ(y´“02 ë·[§>G;‰#“¸3É#¿µUóAFvºD¦«x˜#YOaeáí,¼Pä\”R¼Ó²„{* 3+ø¸äs…¶Z¶[B CëiÛOCñR°o»µÇâ¿íÙyÉ;ò´·í:) a¸ ­óÅq®ùG/ìÇæp_¹O!Ï9¤ë‰/‚´í˜û:‡cÏI#
+ZÚ¯4)j"¿ááŠìÝ|uvÅ“AÙõÑKˆ²ÆZïüC­ÄêÌ</tñ$,tK£}³‰zrñŠß^hDLöã †éNFÒ—÷—õT•®<±Âoá Ó‹H#4ùö$‰,ˆné"¸wT7øƲäj×GØBÁ„`ÚeËŠ®ÃHÝD/„« ¸ohompäa®ñÁÅΑ=7Ö‹„{á{+~®PNîÛ  ø„øJÂlîÁ‰Š°T¸~{9iË5–EHäD¯/9UÈèm¼Bº—5mÙt
+ ëlš[£Í tk¸¹ÄÛ-ñD“wt7I»MÒÝDí6‘ͻɶ!m%p6¹±ññs˜lѹ`´íoyƒS7º} Ùñ0K¼k ˆó¢ÈPÛŸ)—8—?@ûš±]®O(ïµx@…«T6ÿýÃé¾`²[íØbzÊÔž¤xö;ÛŸƒiT±½í™rrn¤oGíÊ 0rþê19N†x ñc.ásÍq;ßã–ýâ¥5§÷”+Û¹©¶Nf‰öU ÎÜÎYaDë­{f%Þ°Úò®¡pÒïÃIÃ÷ú ~ý÷?¿þú…0­Ïÿÿý߯¾êWÁ¿ú“5‰È‚·3‚ñõçï_|2„múóÈ×­¾Y—½jtlÌ–zÄ^‰
+´ëJ6!Š¿I&¦»
+>|,}g+´[v¥q“!Ì|,ï,NÃùÔ÷PM”c²‘ÒÄ>òXŠª| ¸¡1 &VºX“™¥0cÉÔ8ê
+ˆtxä<
+Sõˆz(¸Ì~<Dé@/Ðäh²°aòX˜é.Rp,4Xø‹^?2:˜ãѧ'b*¢¡íq,øÑýP´Ï€@Ýá£9®+Nq¯@Ÿ° rô£úÏüBÅ–*·CQÁ±k0?X†8ó-v `U6(ÓØ;Ø$U[xz.îo™Í…^©’Ž4ÌÂ>:Uáìº$aˆÓ®,yAÈ+€‚ÁѺÇéª ¸[ôcõÃ9Æ8k€p‹ÑÞ>\wÇ¿Â¥û:S9 ÒÛ[2i”;·±ÐËboR;˜ˆ,Æð¸›ß}sx#=^µ«Ü9ÿg¼Ì±#Û‘ê×*r©ÃyØÑ7ô÷ï6.‚|JU·ÑF•|c‚ˆQÇÖ×òõÌÞªsÂn-Tëó6å`<$]g¢ÔÕWïÑÒ ±’ì¢ ZËAàTÍŸVuJ¥Í-x²f¡ñdù¸:H¶äÊ—T«6Se}M[¼8ÿ!ªQO·U ÆêÉñbLôtíO–ÊùŠ¯[Ê‘"ˆÓ{Ú½ý¹“FZ”YŸt9y´ÍSÈQÕÃ[‹!êa^¶ZF…E‡Ø°©}P
+ô¼sÇÉîd[‘¹"”2®:“ª¼ÊQ^ÔñùTeF ™®üº´àhgÙ)ÜûßUËhj,¶ØZ]‰pJg™âGa“KYÓƒ?ÁK†«ý
+ÈК²gûYqF0© !«ëA•Ûgz
+4i9{à¶F3‰óôá>K_$™ö¾´ß²Î•I¨Àtenqox®Y;yºvz…F”bŒXà “’ùR xº+Jå !lpF¾cÝA+QEg°Ýg僉¿<~Â*³ ÷·“¦MuìhK ‘‚J© zezê¡\‘oê•œ<z?Ÿzìï¨Ôkbe44—<•ûÙp'æàä_ù÷@³‚ŠPŠ±Ãmªî[DObs…„9]ÇmÏ2$öã¦1EãRD¢,RíY(xŽ}¢€åð[}Ò*áÒ­ÙÂë`ËŒ”®ÕûÏ
+„+~ÀL”LŽh¡^wÄ)N{Jjcz õ´CØÎ(ÍÁe1ý ¬û½xú=,Ü?å]÷Ê!m(ÿ›ÃäSúx%˜f©$¨½©$H=.“íîˆÞCœ9Ö ÑR:]"¹_jõ¼òxÍc`ï@n˜ +Óƒ­UÈæ"ï%â­¬«
+ Õ@λEƒ†š‡B½šnXnJ§½a{†—`…b%gi¡;Á7#z–w!î_ã)KE»ªŽIY¸­lRò‚©n†ŽzY¬ŸKÕZõ(í jIV§í'ô²ÑN§uçõ´H’|‰$uD‡qÌÚ¹F UÔ
+¯õ¤òp]rEËQÉß)‚£; UÜ"Ž£
+&«~Ùߨ
+ª3±œR¦Û À¯RùÔäpE¶¾ÐR>)S>ÿÿÕ‘Ö6UdÉ`îùô£:Š[¦:øC8€†ÿx(ŸGÑè*¡ÿù³×ñXµÊû÷Ï¿QbØèÚPq³éà
+è¹(0cjö®ˆÀÁWøX(UïêÈwj¬Ta§@QüÕ‚ùts¥$@7 Œ
+Cnߤ)SYPÝjà#qx7ý±¥xŸ‰©ÑàPN3¥"X9Ãhâ€â1ßÖkµ·¼˜i€Ø"Àlc>šÅÈYêîÌ[çÀ}"ôŸì¤äÔŸI÷8¿Üø®c:ß¿ûþÔÞ6ü6êAw“ØdØ&ÊUÛkØ^먭~ŒYÂÒ=,]b›†
+¾i®êsøQÅ"áûD䈨K÷ëÚ†Ëo>šAsEöÃãKÝÍçÿ¿x\ #¥ ï„þ0¹â ÐǦç×?ècK6ɦüû§…X9Jìû„L=ºR¨¡ÓdèPh"¹ ›„G.Ç.è
+U@3”ÁÚ¢ÛSÓ†s¯é‹,©§|è\®«»ÉÕÄQFyÔ§><‘Ò¹Œ¨…9GŽé\Go¥L"J«Ñ X§­î.#Ç\Îß®z=jªËsGêѯøš=!—ÊÀ%ä×=ú66ºP7ÉãõL×UÚ>Û«wí!/U@ºbàÀ ¡o)E«oÁâöâçcs¤(“{Ž˜{*~
+"a„­MŽ¨Ñâät¤¶Ò.ì‹>™ðpCš+‘ÔÁxX±6g¶j‚ㇵ„@ï\©!vË™nïYì¸[­æxr”ÏêfãsŠ
+Š¢èuÏ;»%J¡R[×”“&?°Ì³^NS¤tÊŽ"Ñ_B6)¥ÅòB›4îZRÝ#'pdh½ê?T—9rDÉ D}ž¢mEQûbOÈ”¡30B’1cH÷7”/Qõ›tÈ~­¨D"!¸f‡wž6·»—2‡¯öv5+qÅS:¦HWZÓ!¼ê;š0é½j®,\õ²é8Ìh
+U®‡¹Áð »ù³Â4üyZ`KëÍhNærPE#FC@Åsaç#¢‘bó±)¹Õ­Ò°c!Hf:%„ç‘Zí±˜ü8ü],ns…þñš:ÏŒÕE¹Y(Ì#ÒjÊ.¿µÍ”¯ì?èDìQuµ¦S ’Ù€ùZP¿?ŸÝ ÕŽÎÌAÁ· Þ„…Ë7ª&i¤õ‡þ‹ÿ ì†9N6‚œ˜@:ìÖÁâ8Ä ;n»b ì8u8ÅŒ¤(R,ÿ…Þi›‘ÃöIyàé]…÷3"ö(‘Òó0é±™±ý`¢“©‚½BŽŒYñBØ5fà™ýñ€tñÆôåÑ>¤•º«í“«ð8Ïêá³ú°SÖ+wÆ(Ò¾]nº?.rüÙžÓâÇÕÈ…ÃpøÀ­\Ôàr¶·Ûû5!œ­åØ>žŽB{W ¹f
+W‡fI®R³–œû0{·}¯¤ž×²CV0I‚N”T lÔ-9>{ÐœçôÀ†,ÎM’oo<;rÌ
+0€ë;iôŸ&fc
+ÏpÏØJxq+ñâ8f€>‹¸Hý;F, ‹bÅfÇ>ÛÔ÷Î{Æ:ù ûêTÇQÚqœ¤Éw'%=@W ¥êŽ D‰º#Ò›ÝUe¢f}y#„§Q"Nrñ˜‡çs8<óí".âH5}vƒyÀ¦±ÌSWÒ™tÏ‹
+ð¸¢êœ>ø¼c#›¯ã;ê׌ÁwLñ{ýX%Âøk'¥Ô.?OS|¸çWÚ¼¯9۳ν&Ú|Å´Š,űj8â-ÑëgËj.béu¥®éádïù–Mô ®„£ŸIãžgˆ=᧟ˆIóŠÀ(êAâLZHk­ÇûŠ(K·2 &Q÷y¸ô ¤U߀ŒC(ãR`¸ÇN¸J¹¥
+W­Ðe]€cǘ@ß²Žù™`K”dÕG#æu…ºÂF3H6¯“•äí=îoŠÎ7D§fÕzð8Þùÿ¸Ö—EáB°NOŽ Wí3£ÇñÅfÛo´`"ÞZ?âµß“)¶@RŽESTW•åvŸÌÇøAµ“zR,j`*ïv<ÍÏpß‘oÅÝÕ3/Ë1"‹[l³Ÿ4w#ÌÙÜ çδwbà’ƒ,X©Ï«%ìÉ9\åð Íc'‹®}æÜ%—û=·’5Æ,·
+¼‹äÛ¬‡"GˆG”T¼èíðIŽ(Ÿ#¿'µˆ¿þ'罄™£¯ÿ‡þf̆œî$¹
+œgáŠe·øXBT§ò N[ìÍŠè¿­–~ ¡¹¸¹úÕL~üëoÿü
+±ƒK¹ª M˜8Ý×Q~ê-FØ€b’øïü
+¹þuÆÖcU­;†vêìÛgpŒñ±Ÿ]fL cY~%|jö2[Š^=4Ç.z /«,rŸ?ÑF‚ õQº¤èWô^R·'Ä(þÊ.–Þ»ÝÆR-MÈ÷ªäûÓž þð`ïql®‚VÝ1£y‰’G.-Þ|¸Kûtx-†×HÛÚ^gúõ´gÁ·§ž5ÙNal[㶠ޡ=+º–©ÓHÖO#€^QF–9"ãBÚ‚¥DŒØ´‘*U)É:S/X‘üÔŒÄB4åP’í±`ƒqGê ´z:ÇÁ¥Ç
+JD
+LVU¥]àcò³³C2“Rš‚'XgÀ¢\­Áô€Få%c«P+k9°¨²f& ƒ1ë
+?™/3’úam'ÌO{sîÇA㧜÷#*D[‡â©Ü«éð)¿yÂ]œ’~óŒzÛ¦“å4Üíå t±Æ1…ÃìÏ#L_=ÖG H
+µ91¤bÆR @ow² ìÂV_
+–b¦H”Sl¤ (AÅΠͽJ0Ĭ~¶Q:Ôq÷ºåU›'6Vˆ"U'uç:œáÊÃ-éV‡Åì›àè`y¨À”Z‹KP ` rbH×5VÄû%vŽJE™†‡¸tɦ·ÒO™o0¿ô®U½ãýªòKehZg:!ËÉu™H?j\òÇ­»‚uÇ3ö8bCìDí õ*»Û`æÒµ¨uå¬ }—S§x -ËÅK‡5Áêºss)×OýÓRªèn4↠¦Å¥t}Å‚#GXf ã´x ¢hQh•*)¾¹ÏL¤g9KÉdç×|³Þ#c48Ë gŽÄÜ­²‰¢¥·V}DŒÃÐ9Çr3£Ë„] i.–ÚûŸÏþ¨É¦Õhø;´û/5Ù̧º$Rõ-$I6ó¨D&¥z|%ÜXG•ñJqžLaad5Ö°|¢ÂÉXG9(æ=òn¢ÜU*×´0XÔ6`ß#ƒO¹Ug Ï¡ð‡EYNc¹}_WÔü:] ªNO®®àE¯³­³*ä|uÅÕ5ø¶8/«„NãÈ®ä³Þ¥ §ž%XUü¼uE€¢g4›$zWÕSu™Q @`»¢ø )ª½ÇQõ`Á³îQ^Þ{Ïc…¨©j20|ndLce¸^ËÜÓÈìì©t·¾ïÕ:
+&qWør˪ NôÙQŸ„웘`BæV1ùünWåÔ³O5ìšëI% šMÓ——øÏ…á”0KÖƒ„­ý†aÙÖr:`v¯ù»©YS·
+endstream endobj 12 0 obj <</BitsPerComponent 8/ColorSpace 13 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 78/Length 572/Width 78>>stream
+8;Z]!0p9Es$q1]jb"]%t$CX],27@P5Q0uP4<^I(F9m/)SC59"?A<PrupPZ83EGB6'
+C2.MKZU"/=);4,cDcT1f&<@GacP>oG"5*P6C>Z<!n%N)V2r$)_VZtD!f<If/\Sf$A
+A-ZS?8(.'u;7=H5dg;fDIce),dkN#9ri\^?OOA%Tf4m%`PgJe&59WSJKGHLYo\Qi4
+QRG^(D0X>mD>0DGW(tiYjOAQS+<mZ1E>dQsHm()eH";-P:/)P$nN`m8_C`cq;mSp"
+QrKoKaVhAj\O*=l?W16QCT&ts:hL8s'3D_uT(:*2FfX<O=lYN)DqjAiA_oJiE9l/d
+WV;hCPmY!foq]%fVF=^SkO&+M`-ih"q_drW>rIW?"$+)V=O3rjf1[*YCgc'.C(%NR
+[7nkR-KL!0;GUu?GS)sbRllhV)Z[KH/**Gl$DH<$/*>lXCS<PQiNngZ_"gm[H`#>r
+C]I/jUpZW8:c?*<>o:-ZGK;AMVLo_%l2Dr`+\ci/Y*klCbBNTKcK^.ajS6>22rJjW
+IS:U$f!1E'oa.rAo0I`CN;R#@opFF^e:5p8!0Ub]Gl~>
+endstream endobj 13 0 obj [/Indexed/DeviceRGB 255 14 0 R] endobj 14 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>
+endstream endobj 5 0 obj <</Intent 15 0 R/Name(Layer 9)/Type/OCG/Usage 16 0 R>> endobj 6 0 obj <</Intent 17 0 R/Name(Layer 6)/Type/OCG/Usage 18 0 R>> endobj 17 0 obj [/View/Design] endobj 18 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>> endobj 11 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 10 0 obj <</LastModified(D:20141208091030-04'00')/Private 19 0 R>> endobj 19 0 obj <</AIMetaData 20 0 R/AIPrivateData1 21 0 R/AIPrivateData2 22 0 R/ContainerVersion 11/CreatorVersion 15/NumBlock 2/RoundtripStreamType 1/RoundtripVersion 15>> endobj 20 0 obj <</Length 986>>stream
+%!PS-Adobe-3.0
+%%Creator: Adobe Illustrator(R) 15.0
+%%AI8_CreatorVersion: 15.0.0
+%%For: (PHLASH) ()
+%%Title: (vector-src purple.fxg)
+%%CreationDate: 12/8/2014 9:10 AM
+%%Canvassize: 16383
+%%BoundingBox: 213 -537 538 -184
+%%HiResBoundingBox: 213.5 -536.6816 537.3232 -184.3252
+%%DocumentProcessColors: Cyan Magenta Yellow Black
+%AI5_FileFormat 11.0
+%AI12_BuildNumber: 399
+%AI3_ColorUsage: Color
+%AI7_ImageSettings: 0
+%%RGBProcessColor: 0 0 0 ([Registration])
+%AI3_Cropmarks: 0 -626 626 0
+%AI3_TemplateBox: 312.5 -312.5 312.5 -312.5
+%AI3_TileBox: 7 -709 619 83
+%AI3_DocumentPreview: None
+%AI5_ArtSize: 14400 14400
+%AI5_RulerUnits: 2
+%AI9_ColorModel: 1
+%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0
+%AI5_TargetResolution: 800
+%AI5_NumLayers: 2
+%AI9_OpenToView: -258 70 1 1140 742 26 0 0 354 173 0 0 0 1 1 0 1 1 0 1
+%AI5_OpenViewLayers: 77
+%%PageOrigin:7 -709
+%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9
+%AI9_Flatten: 1
+%AI12_CMSettings: 00.MS
+%%EndComments
+
+endstream endobj 21 0 obj <</Length 20656>>stream
+%%BoundingBox: 213 -537 538 -184
+%%HiResBoundingBox: 213.5 -536.6816 537.3232 -184.3252
+%AI7_Thumbnail: 120 128 8
+%%BeginData: 20498 Hex Bytes
+%0000330000660000990000CC0033000033330033660033990033CC0033FF
+%0066000066330066660066990066CC0066FF009900009933009966009999
+%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66
+%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333
+%3333663333993333CC3333FF3366003366333366663366993366CC3366FF
+%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99
+%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033
+%6600666600996600CC6600FF6633006633336633666633996633CC6633FF
+%6666006666336666666666996666CC6666FF669900669933669966669999
+%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33
+%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF
+%9933009933339933669933999933CC9933FF996600996633996666996699
+%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33
+%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF
+%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399
+%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933
+%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF
+%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC
+%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699
+%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33
+%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100
+%000011111111220000002200000022222222440000004400000044444444
+%550000005500000055555555770000007700000077777777880000008800
+%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB
+%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF
+%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF
+%524C45FD33FFA8FFA8FFA8FFA8FD6AFFA8FFFD0FA8FFA8FD64FFA8A8A8FF
+%A8A8A8FFA8A8A8FFA8A8A8FFFD05A8FFA8FD5EFFFD1BA8FD5CFFA8FFA8FF
+%A8A8A8FFA8FFA8FD0BFFA8FFA8A8A8FFA8FFA8FD58FFFD07A8FFA8FD0FFF
+%A8FFFD07A8FD54FFA8FFA8A8A8FFA8FFA8FD17FFFD05A8FD52FFFD07A8FD
+%1BFFFD05A8FD52FFA8FFA8A8A8FD1DFFA8A8A8FFA8FD4EFFA8FFFD05A8FD
+%1FFFFD05A8FD4EFFA8FFA8A8A8FD09FFCBCBA8CBA2CBA2CBA2A9A2CBCBFD
+%0CFFA8A8FFA8FD4AFFA8FFFD05A8FD05FFA2A2787871726B7147716B7147
+%716B716B727172719CA2A9A8FD05FFFD05A8FD4AFFA8A8A8FD04FFCB9C9C
+%71726B726B7271727172717271727172717271726B726B726B9672A2A2FD
+%05FFA8A8A8FD48FFFD05A8CB78726B726B716B726B726B726B726B726B72
+%6B726B726B726B726B726B716B726B71719CA2FFA8AEA8A8A8FD46FFA8CF
+%A8A878726B72717271727172717271727172717271727172717271727172
+%717271727172717271726B72719CA2FFA8A8A8FD44FFA8A87E786B726B71
+%6B726B716B726B716B726B716B726B716B726B716B726B716B726B716B72
+%6B716B726B716B726B72FD04A8FD44FFA972726B72717271967172719671
+%727196717271967172719671727196717271967172719671727196717271
+%9671726BA2A8A8A8FD42FFA89C6B726B726B726B726B726B726B726B726B
+%726B726B726B726B726B726B726B726B726B726B726B726B726B726B726B
+%7171A8A8A8A2CBFD3FFFA2726B7271727172717271727172717271727172
+%717271727172717271727172717271727172717271727172717271727172
+%717278FFA8A871A2FD3CFFCB716B6B726B716B726B716B726B716B726B71
+%6B726B716B726B716B726B716B726B716B726B716B726B716B726B716B72
+%6B716B726B72A8A8A89C4772A2FD39FFC571727196717271967172719671
+%727196717271967172719671727196717271967172719671727196717271
+%967172719671727196717271A9A8FFA2726B729CFD36FFCB9C477271726B
+%726B726B726B726B726B726B726B726B726B726B726B726B726B726B726B
+%726B726B726B726B726B726B726B726B726B726B7178AEA8A871726B6B71
+%CBFD33FFA8966B7271727172717271727172717271727172717271727172
+%717271727172717271727172717271727172717271727172717271727172
+%71726B9CA8FFA89C6B7271726BCBFD31FFA27147726B716B726B716B726B
+%716B726B716B726B716B726B716B726B716B726B716B726B716B726B716B
+%726B716B726B716B726B716B726B716B7271A8A8AE77716B726B7147A2FD
+%2FFFA2726B96717271967172719671727196717271967172719671727196
+%717271967172719671727196717271967172719671727196717271967172
+%7196719CA8FFA8A26B96717271726BA2FD2DFF9C726B726B726B726B726B
+%726B726B726B726B726B726B726B726B726B726B726B726B726B726B726B
+%726B726B726B726B726B726B726B726B726B726B7271A8A8AEA2716B726B
+%726B726B9CFD2BFFA2726B72717271727172717271727172717271727172
+%717271727172717271727172717271727172717271727172717271727172
+%717271727172717271727172A2AEA8A871727172717271726B78FD29FF78
+%716B716B726B716B726B716B726B716B726B716B726B716B726B716B726B
+%716B726B716B726B716B726B716B726B716B726B716B726B716B726B716B
+%726B716BA8A8A8A2726B716B726B7147714778FD27FFA272717271967172
+%719671727196717271967172719671727196717271967172719671727196
+%71727196717271967172719671727196717271967172719671727172A2FF
+%A8A971727196717271727172479CFD25FFA2716B726B726B726B726B726B
+%726B726B726B726B726B726B726B726B726B726B726B726B726B726B726B
+%726B726B726B726B726B726B726B726B726B726B726B726BA8A8A8A2726B
+%726B726B7147726B7147A2FD23FFA8727172717271727172717271727172
+%6B7271727172717271727172717271727172717271727172717271727172
+%71727172717271727172717271727172717271727172A2FFA8A871727172
+%6B7271726B72717247A3FD21FFA87247726B716B726B716B726B716B726B
+%716B726B716B726B716B726B716B726B716B726B716B726B716B726B716B
+%726B716B726B716B726B716B726B716B726B716B7271A8A8A8A2716B7247
+%71477147714771477147A9FD20FF9C6B9671727196717271967172717272
+%A2A2A8A8CB7272717271967172719671727196717271967172719671726B
+%7271726B7271727172717271967172719671727196719CA8FFA8A8717271
+%727172717271727172717271FD1FFFA26B726B726B726B726B726B726B71
+%78FFA8A8A8FFFFFF9C726B726B726B726B726B726B726B726B726B726B72
+%7172717877787178717271726B726B726B726B726B726B7278A8A8AE7871
+%47726B7147726B7147726B71477171FD1DFFCB6B72717271727172717271
+%7271729CFFFFFFA8A8A8FFFFFF9C727172717271727172717271726B7271
+%9C77A27DA87DA87DA87DA87DA87DA277A277726B727172717271726BA2A8
+%A8A8A26B726B7271726B7271726B7271726B7278FD1CFF71716B726B716B
+%726B716B726B7171FFFFFFFD05A8FFFFFF71726B716B726B716B726B716B
+%78777D7D83FD127D71726B716B726B71A2A8A8A871714771477147714771
+%4771477147714771A2FD1AFFA2727196717271967172719671726BA3FD04
+%FFA8A8A8FD04FFA371727196717271726B7277A87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87D9C7172717272FFA8FFA87271727172
+%7172717271727172717271726B72FD19FFA8726B726B726B726B726B726B
+%726B71A2FD05FFA8A8A8FFFFFF9C726B726B726B7171A27D83FD1C7D7772
+%6BA2A8A8A8A247726B7147726B7147726B7147726B71477247A2FD18FF9C
+%6B7271727172717271727172717271CBFD04FFFD05A8FFFFA26B7271726B
+%7277A87DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D
+%7D7DA87D837D9CA8A8A8FF71726B7271726B7271726B7271726B7271726B
+%7271CBFD16FFCB6B716B726B716B726B716B726B716B71A2FD05FFFD04A8
+%FFFF78726B726B7177A8FD237DA8A8A87D71477147714771477147714771
+%477147714771477171FD16FF787271967172719671727196717271966BA2
+%FD06FFA8A8A8FFA29C71726B9C7DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87D7D7DFFA8AEA89C6B72717271
+%7271727172717271727172717271727172A8FD14FFA2726B726B726B726B
+%726B726B726B726B7271FD05FFFD05A89C71716B9CFD257DFD05A871726B
+%7147726B7147726B7147726B7147726B7147724778FD14FF9C6B72717271
+%7271727172717271727172717272FD05FFAECFA8AE78726B9C7DA87D7D7D
+%A87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D
+%7D7DFD04A8FF7D7D777271726B7271726B7271726B7271726B7271726B72
+%47CBFD12FFCB6B716B726B716B726B716B726B716B726B716B7171A2A2CB
+%A8A2A2A8A8A87178FD257DFD05A8FD047D71714771477147714771477147
+%71477147714771477177FD12FF9C72719671727196717271967172719671
+%7271967172719C789C729CA8FFA8A87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8A8FFA8FFA8A87D
+%A87DA877727172717271727172717271727172717271727172A9FD10FFCB
+%726B726B726B726B726B726B726B726B726B726B726B716B7271726B9CA8
+%A8FD107D77FD147DFD06A87EFD057D83717147726B7147726B7147726B71
+%47726B71477247A2FD10FFCB6B7271727172717271727172717271727172
+%717271727172717271726B9C83A77DA87D7D7DA87D7D7DA87D774D724D71
+%4D7877837DA87D7D7DA87D7D7DA87D7D7DA87DA8A8FFFD04A87D7D7DA87D
+%7D7DA871726B7271726B7271726B7271726B7271726B7271FD10FF786B6B
+%726B716B726B716B726B716B726B716B726B716B726B716B726B717783FD
+%0A7D5371474D4771477147714DFD0E7DFD07A8FD0A7D4D71477147714771
+%477147714771477147714771A8FD0FFF9C6B967172719671727196717271
+%96717271967172719671727196717277A87DA87DA87DA87DA87DA8777247
+%72717271727172717271A27DA87DA87DA87DA87D7D7DA8A8FFA8FFA8A87D
+%A87DA87DA87DA87DA87D7E6B72717271727172717271727172717271726B
+%A2FD0EFFCB6B716B726B726B726B726B726B726B726B726B726B726B726B
+%726B7271A8FD097D834D4747716B7147726B7147726B717183FD097DFD07
+%A8FD0D7D7747726B7147726B7147726B7147726B71477171FD0EFFA27271
+%727172717271727172717271727172717271727172717271726BA27D7D7D
+%A87D7D7DA87D7D7DA87872477271726B7271726B72717277A8FD057DA8A8
+%FFA8A8A8FFA8A87DA87D7D7DA87D7D7DA87D7D7DA87D726B7271726B7271
+%726B7271726B7271726B72A9FD0DFF9C47726B716B726B716B726B716B72
+%6B716B726B716B726B716B726B71FD0B7DA8A8AE7E787172476B47714771
+%47714777FD057DFD07A8FD117D8377714771477147714771477147714771
+%477147A2FD0DFF7172717271967172719671727196717271967172719671
+%727196717277A87DA87DA87DA87DA87DA8A8FFA8FFA8FFA8A2789C717871
+%78717878A8A8FFA8FFA8A8A8FFA8A87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA271727172717271727172717271727172717278FD0CFFA8716B
+%726B726B726B726B726B726B726B726B726B726B726B726B72717EFD0A7D
+%77A2A8AEFD05A8AEFD12A8FD157D7747726B7147726B7147726B7147726B
+%714778FD0CFFCB6B72717271727172717271727172717271727172717271
+%7271726B9C7D7D7DA87D7D7DA87D7D7D7E477277A8A8CFA8FFA8AEA8FFA8
+%A8A8FFA8A8A8FFA8FFFD04A87DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D726B7271726B7271726B7271726B7271724DFD0CFF9C716B71
+%6B726B716B726B716B726B716B726B716B726B716B726B717783FD0A7D53
+%4D476B477277A2A2A8A8AEA8AEA8AEFD06A8FD1B7D837171477147714771
+%4771477147714771476BA2FD0BFFA36B7271967172719671727196717271
+%967172719671727196717271A87DA87DA87DA87DA87DA87DA24D7271726B
+%726B72719C78A27EA278A2A2A87DA87D7D7DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87D7E6B7271727172717271727172717271
+%7247CBFD0BFF71726B726B726B726B726B726B726B726B726B726B726B72
+%6B726B78FD0D7D71477147726B714772476B4771476B47A2FD217D714772
+%6B7147726B7147726B7147726B6B78FD0BFF9C6B72717271727172717271
+%72717271727172717271727172717277A87DA87D7D7DA87D7D7DA87DA777
+%7271726B7271726B7271726B726B7E7DA87D7D7DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA871726B7271726B7271726B
+%7271726B7247A2FD0BFF71716B726B716B726B716B726B716B726B716B72
+%6B716B726B716B7EFD0E7D4D71477147714771477147714778FD237D7747
+%71477147714771477147714771477177FD0BFF7271967172719671727196
+%717271967172719671727196717271967DA87DA87DA87DA87DA87DA87DA8
+%7DA871726B727172717271726B9C83A87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA877727172717271727172
+%7172717271726B78FD0BFF6B726B726B726B726B726B726B726B726B726B
+%726B726B726B7271A2FD107D7171477247714772717EFD267D717147726B
+%7147726B7147726B71477171FD0BFF727172717271727172717271727172
+%7172717271727172717271727DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D787778777877A87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D837D7271726B7271726B7271726B72
+%71724778FD0BFF6B726B716B726B716B726B716B726B716B726B716B726B
+%716B7271FD417D477147714771477147714771477147714DFD0BFF967172
+%71967172719671727196717271967172719671727196719C7DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D72
+%71727172717271727172717271726B78FD0BFF6B726B726B726B726B726B
+%726B726B726B726B726B726B726B7271FD417D47726B7147726B7147726B
+%7147726B714DFD0BFF727172717271727172717271727172717271727172
+%717271726B9C7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DA77D726B7271726B7271726B7271726B726B78FD0B
+%FF71716B726B716B726B716B726B716B726B716B726B716B726B717183FD
+%3F7DA24771477147714771477147714771477171FD0BFF9C719671727196
+%7172719671727196717271967172719671726B9C7DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D7D7DFFA27271727172
+%717271727172717271726B78FD0BFF71716B726B726B726B726B726B726B
+%726B726B726B726B726B7271A8FD3D7DA8A89C477147726B7147726B7147
+%726B71477177FD0BFF9C6B72717271727172717271727172717271727172
+%7172717271727DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DFFA8FF777271726B7271726B7271726B72717247A2FD0B
+%FF78716B716B726B716B726B716B726B716B726B716B726B716B726BFD3C
+%7DA8A8AEA8774771477147714771477147714771476B78FD0BFFCB6B7271
+%967172719671727196717271967172719671727196717277A87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DFFA8FFA8A8717271
+%7271727172717271727172717247A9FD0BFFA2726B726B726B726B726B72
+%6B726B726B726B726B726B726B726B78FD397DFFA8A8A8FF7D7147726B71
+%47726B7147726B7147726B71A8FD0CFF7172717271727172717271727172
+%71727172717271727172717271A27DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA8FD057DFFA8FFA8FFA87E71726B7271726B7271726B7271726B72
+%71FD0DFF7247726B716B726B716B726B716B726B716B726B716B726B716B
+%7277FD367DFD07A84D7147714771477147714771477147714772FD0DFF9C
+%727172719671727196717271967172719671727196717271966B9C7DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87D7D7DFFA8FFA8FFA8FF7D7871
+%72717271727172717271727172717278FD0DFFA26B726B726B726B726B72
+%6B726B726B726B726B726B726B726B7271FD347DA8A8FFA8A8A8FFA87D47
+%726B7147726B7147726B7147726B7147A2FD0DFFCB726B72717271727172
+%71727172717271727172717271727172717277837DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DFFA8FFA8FFA8FFA8FFA2726B7271726B7271726B72
+%71726B727171A8FD0EFF71716B726B716B726B716B726B716B726B716B72
+%6B716B726B716B72FD317DFD0AA8FF776B47714771477147714771477147
+%714DFD0FFFA36B9671727196717271967172719671727196717271967172
+%719671787DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8A8FFA8FFA8FFA8FFA8FF
+%A8FFA8FF787271727172717271727172717247A2FD0FFFA8716B726B726B
+%726B726B726B726B726B726B726B726B726B726B7271FD2E7DFFA8A8A8FF
+%A8A8A8FFA8A8A8FFA8AE77716B7147726B7147726B714771A2FD10FF7272
+%717271727172717271727172717271727172717271727172717271837DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA8FD047DA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF777271
+%726B7271726B7271714DFD11FFA26B716B726B716B726B716B726B716B72
+%6B716B726B716B726B716B7277FD2A7DCBFD12A8716B4771477147714771
+%4778FD12FF726B9671727196717271967172719671727196717271967172
+%719671727DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87D7DA2FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF
+%A8FFA8FFA8FF77727172717271727172A8FD12FF9C6B6B726B726B726B72
+%6B726B726B726B726B726B726B726B726B7247717D83FD257DA8A8FFA8A8
+%A8FFA8A8A8FFA8A8A8FFA8A8A8FFFD04A8716B47726B71477171FD14FF71
+%727172717271727172717271727172717271727172717271726B726B787D
+%A87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7DCBA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8
+%CB71726B72717247CBFD14FFA26B716B726B716B726B716B726B716B726B
+%716B726B716B71477147714777FD237DFD1BA8717147714772FD15FFCB72
+%6B9671727196717271967172719671727196717271727172717271726B78
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DCBA8FFA8A8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF
+%A87D6B727171A2FD16FF9C6B6B726B726B726B726B726B726B726B726B72
+%6B7147726B7147726B714777FD1F7DFD08A8CBA8A8A8FFA8A8A8FFA8A8A8
+%FFA8A8A8FFFD04A84D71477171FD18FF7172717271727172717271727172
+%71727172717271726B7271726B72717247787DA77DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA8FD057DA8A8FFA8A8A8FFFD05A8FFA8FFA8FF
+%A8FFA8FFA8FFA8FFA8FFA8FF7D71717247CBFD18FFA96B716B726B716B72
+%6B716B726B716B726B71477147714771477147714771477177FD1A7DFD0B
+%A87DFD12A87D47724778FD1AFF9C6B967172719671727196717271967172
+%7172717271727172717271727172477277A87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87D7D7DFFA8A8A8FFA8A8A8CBFD07A8FFA8FFA8FFA8FF
+%A8FFA8FFA8FFA8AE77726B72FD1BFFCB726B726B726B726B726B726B726B
+%72477147726B7147726B7147726B71477147474DFD167DFD09A87DFD08A8
+%FFA8A8A8FFA8A8A8FFA8A8A8FF83774771A2FD1CFFA8726B727172717271
+%72717271726B7271726B7271726B7271726B7271726B724D7147787DA77D
+%A87D7D7DA87D7D7DA87D7D7DA87D7D7DFFA8A8A8FFA8A8A8FFFD0BA8FFA8
+%FFA8FFA8FFA8FFA8FFA8A8716B78FD1EFF9C6B6B726B716B726B71477147
+%71477147714771477147714771477147714771474D47714D7D7D83FD0D7D
+%FD0DA87DA8A8A87DA87EFD0DA8776B4DFD05FFA8FFA8FD18FF7872717271
+%967172717271727172717271727172717271727172717271724D7147724D
+%724778777E7DA87DA87DA87DA87DA8A8FFA8FFA8A8A2FFA8A8A8FFA8A8A8
+%FFFD07A8A9A8FFA8FFA8FFA8FFA8FFA87747FD05FFA8FFA8A8FD19FF7172
+%71726B726B7147726B7147726B7147726B7147726B7147726B714772474D
+%4771474D477147714DFD04777D777777A277784D71474777CFFD0EA87DFD
+%04A8FFA8A8A8FFA8A853A2AEFD06A8FF7DFD1AFF71727172717271726B72
+%71726B7271726B7271726B7271726B7271726B724D7147724D7147724771
+%4772477147724771477147714772477177FFA8A8A8FFFD0DA8FFA8FFA8FF
+%A8FFA8FFA8FFA8FFA8FFA8FFA8A8FD1AFFCB6B726B714771477147714771
+%477147714771477147714771477147714771474D4771474D4771474D4771
+%474D4771474D4771474D4771474777AEFD0AA87DA8A8A87DFD13A87DFD1B
+%FFCB71727172717271727172717271727172717271727172717271727172
+%717247724D7247724D7247724D7247724D7247724D7247724D72477278FF
+%A8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF7DFD1DFFA947
+%7147726B7147726B7147726B7147726B7147726B7147726B714772474D47
+%71474D4771474D4771474D4771474D4771474D4771474D474D77AEFD08A8
+%A2FD08A8FFA8A8A8FFA8A8A8FFA8A8A8FFA87DA8FD1DFFCB71726B727172
+%6B7271726B7271726B7271726B7271726B7271726B724D7147724D714772
+%4D7147724D7147724D7147724D7147724D71477178CFA8FFA8A8A8FFFD0B
+%A8FFA8FFA8FFA8FFA8FFA8FFA8A87DFD1FFFCB476B477147714771477147
+%7147714771477147714771477147714771474D4771474D4771474D477147
+%4D4771474D4771474D4771474D474777FD09A87DA8A8A87DA87EFD0DA87D
+%A8FD08FFA8FD18FF71727172717271727172717271727172717271727172
+%71727172717247724D7247724D7247724D7247724D7247724D7247724D72
+%47724D7177FFA8A8A8FFA8A8A8FFFD07A8FFA8FFA8FFA8FFA8FFA8FFA8A8
+%A8FD05FFA8FFA8FFA8FD18FF7171477147726B7147726B7147726B714772
+%6B7147726B71477247714771474D4771474D4771474D4771474D4771474D
+%4771474D4771474777AEFD0EA87DFD04A8FFA8A8A8FFA8A87DFFFFFFA8FF
+%A8A8A8FFA8A8A8FD18FF78726B726B7271726B7271726B7271726B727172
+%6B7271726B72717147724D7147724D7147724D7147724D7147724D714772
+%4D714772477177FFA8A8A8FFA8A8A8FFFD09A8FFA8FFA8FFA8FFA8FFA8FF
+%A8FFA8FFA8FFA8FFA8A8A8FD18FFA2714771477147714771477147714771
+%47714771477147714771474D4771474D4771474D4771474D4771474D4771
+%474D4771474D4771474777FD0BA87DA8A8A87DFD18A8FD18FFCB9C477271
+%72717271727172717271727172717271727172717247724D7247724D7247
+%724D7247724D7247724D7247724D7247724D72477277FFA8FFA8A8A8FFFD
+%0BA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD1AFFA247716B
+%7147726B7147726B7147726B7147726B7147726B714771474D4771474D47
+%71474D4771474D4771474D4771474D4771474D474777FD12A8FFA8A8A8FF
+%A8A8A8FFA8A8A8FFA8A8A8FFA8A87DFD1CFF78726B726B7271726B727172
+%6B7271726B7271726B72717147724D7147724D7147724D7147724D714772
+%4D7147724D7147724D7147477EAEA8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FF
+%A8FFA8FFA8FFA8FFA8FFA8A8A8FD1CFFA278476B47714771477147714771
+%4771477147714771474D4771474D4771474D4771474D4771474D4771474D
+%4771474D474D474D77FFFD0EA87DFD14A8FFA8A8FD1EFFCB71726B727172
+%717271727172717271727172717247724D7247724D7247724D7247724D72
+%47724D7247724D7147714DA2A9FFFFFFA8FFA8A8A8FFA8A8A8FFFD09A8FF
+%A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A87DFD20FFA29C476B47726B714772
+%6B7147726B7147726B714771474D4771474D4771474D4771474D4771474D
+%4747477178FD07FFFD10A87DFD04A8FFA8A8A8FFA8A8A8FFA8A8A8FFA87D
+%FD23FFA27847726B726B7271726B7271726B72717247724D7147724D7147
+%724D7147724D714771477277CBFD0AFFFD05A8FFA8A8A8FFFD09A8FFA8FF
+%A8FFA8FFA8FFA8FFA8FFA8A87DFD25FFA978784771477147714771477147
+%7147714771474D4771474D4771FD05477177A2A8FD0DFFFD0CA87DA8A8A8
+%7DFD0FA87DA8FD29FFA2A378784D72477147726B72477247714771477147
+%724D7271A2A2CBFD13FFA8A8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8
+%FFA8A8A8FD2EFFA2A97EA2777871787178777877A278A2A2CBCBFD17FFFD
+%13A8FFA8A8A8FFA8A8A8FFA8A87DA8FD5AFFA8A8FFA8A8A8FFFD0BA8FFA8
+%FFA8FFA8FFA8FFA8A8A8FD5AFFFD1BA8FF7DA8FD5BFFA8FFA8A8A8FFA8A8
+%A8FFA8A8A8FFFD05A8FFA8FFA8FFA8FFA8A8A8FD5CFFFD10A87DFD04A8FF
+%A8A8A8FF7DA8FD5DFFFD05A8FFA8A8A8FFA8A8A8FFFD05A8FFA8FFA8FFA8
+%A8A8FD5EFFFD10A87DFD07A87DFD60FFA8A8A8FFA8A8A8FFA8A8A8FFA8FF
+%FD05A8FFA8FFA8A8FD61FFFD13A8FFA87D7DFD62FFA8A87DFD04A8FFFD08
+%A87DA87D7D7DFD65FFA87DA8FD0B7DA87DA8A8FFFFFF
+%%EndData
+
+endstream endobj 22 0 obj <</Length 30497>>stream
+%AI12_CompressedDataxœì}gWãʶà|¾kñl É¶•-‘£&6©¦¡ pcl°Í ïÃüöÙ{WI*I¥àpÞœ7kîY—¶Ë¥
+»vª/ùãÓÂÚcë¾VЋJnä?_¾l´kÕn«=Ÿ£æÜn£ñÙ鶱iêd:§šE{­íÚw¼çE­Ý©·šóôûµ‚ÏOïì¯îL禦±í¬ÞmÔ õÚ<Tè´rïŸí÷F­øô×ó´73Œ´YíBGU+Ù%MQœ3¯*¹µêRmþQítêÿ…,ÝÖ±q½õÙ|¬7Ÿ×[Íç4UÏL½œ3u;WPm{ìÔOjp·¢‰­¢e«ô.uM×èødjøÜfëáó­Öì·[µNg£Õhµ;󹿫ÍÜAõ~©æ®jFëÏÜz£úð
+Ϭíšw•z£ x«vsªJYÛUµ»õÏzãñðóí¾ÐчÚõ;õ¼ÃÁÈø™ÚËw»oÐtZëvaÍ0)öd{]\ ´ÒS?NjÏu:&€ßÏiwävëý­Ú~ŧsK³rø…ÿzV{{o
+5ÜÁ¹·ëMxä?‡ì7ûî¸ñ ?n·[Ÿï»Í§ÖȦk€eµk9ö+P9}…Ÿðßbµþ>òüfí ˆÄ€µn5ÿ¨5ZïÂÀ^Kµù˜û^m¿gü¸QmVÛ9úÁ{¿þüR…ú£ûm™†…ƒ~FQŸÐ „Ÿ²LuÖ®>ÀAäŽîÃCð<o€OS.Öþª¥.ºÚ}Uk>v¼u²¯!0°Æ,‹;ýûí¾Õ¨wÞ¼Åïs&"r·›GM¶Ìögç%wÖj5|²ü']Ú]öÌ¿f¯³løñß;øFµÑ¨?·«ï/õÙø’ß½‰bžÍ„EuÙŒÁŸ¼É¢Oü;æA@?Õ›ðÈég½[ó!×z{GÅ#wúR}ÇfìYzúãšwÀ£E\(¤rg‡ý†R¶ûw£Œ¿´×lýÙ¤o¹yXÙ`³ÕÏF÷çt®tX}«åæ ÏidÍë¤äŽàOQÿé Žâ?°ÿ.«øÈ >R6 ·ÊŽeëôAÑ4 …—¢Zž—kø€ê~û¿}…O¿¡íÏhw¹?•ÜãüÃÒ°LƪFþ“+Á.ðmÀ$l8rÇÕHËΪäŽï³¯;¬W‘pù_Õ°Âuü
+zloXPFDÙ®äž<äz£Þ¬å:ÝvëÕ³ÏÓzwA ýw95·s_ºÝ÷ùR©Ù)V1¥øÐz+=ýõ\ÒÅ.ÁNjífµ‘Í“m¤ˆ. Âð¡Qå#öò Ðê¤<òî*­?jíwL@ðžP%B|¤MjU¥çî« AŒyÓ€|\mákçx³‚: ·JŠ¼3ö„EuÍÞ×î=O?ï*-Xó ÊĽÚß¡ƒ tÿþRx9n·žêšßU‘uÝz»¯=Fº.à*ZíÇڣĢȕ[ÝàïÞ#2¼Y}-•4µ­ãÓÜQä „£Ór`9qR9%¬@·3Ÿ¢„ÉX—ð\i;r¡Uò)®ô»uØÚhˆÖ¤¼MUm4"ôéê)¨ÙÏiv^ëï÷€¯ÓÉËk×`£n¤q®2îBf*ê: ?ê>"®|ÁSØ1ÉêkëSÙre©eD =7ßþm¶|bÍÕ›Dðèñ˜’Üý$øèì“|M”Û@βÁ9ËI€³”ÍR1³«tÁøÃz?ˆ¶ë¾Ý®>ÖÑ:ÁÄcfì%šwì©}„&dâSdEžR#MØE´³œÊÒËžN‚®1Ö;;ÈXÿžaÆË
+’͵&&2f¤)&͉¨„£Íò_ ®Ýå5SJ Ø(͉2)_>š¿u°Óúµ…ò˜TucJ÷Õv'‘xÚÐX:çôö¹G†Îí ²œÖ=ÀA¬ØþT†Zy†ÞßKï,®<C÷ÀÊ¥º[`£ŸÚfëa¿&Q7S.ßÛO­f" u.ìN‹é,5¤…éJŒîÓŽp+2Re]Ÿ316ÔÚ_ëFUòŽÌ«œ¦ATûdš7×;‰<õæ.mu_=IBׇ·¿]Þt­¹ÝãÜA¦¹=®ÿUk×ÚOµhψsñ¥õçNýQâž?­þQ;
+ ØGOÒFì“gž\êÝÂtå~H ö’R°•bŒöì 4‚g2<@–¤©‘ß[¬)íñä€XÚÓò
+æÚ¨¾³´¨ºà¿ºåð4$ñ»
+`í÷Ú=fúdERƬ™©’_$ÄâÓćtš¤IB2'óâð¹ÖæNœ/|ÏÚõ7L/NRÖܾ'µç¬]  ë)é@†í&›h>~’ W!¦´Æ‹á=~¯¥™Jîd5ì§ØlÎ'= }–làú®§™=ÁE×›¯É} ìëZFn×DµÅO Ü€ Kñ‚áY(œ ‰3!4ù©”T—$^}Ú­6ASÏÐu³Ö¾Çó{gåÂã³ðÞæ/úø;ÁjŒ8ªïï¾çì$@ß“fYŽûTsþò®ÜŸ/µf®Sýg¯6Å—íåPZåªlæo(Ú¬xéÉÅÜy‡†„¿ÁÁþn}æÞAÉ^Sc²†¦fÃ=WëM Ì Íå`2ïÑ& q®ÛÂ!j¹:Eñ«¹FõoL…†ÁÉ1©óùð‚ËÛmn’;Ó†ÍÖ"ü„ÕµžüéëÜgó_OSÌ|êíú»;NáÔáDž¤£<Ãs‰b
+i¤Ú­½|¾Ý7«õ†Ph ¿35vÃÉÞQ“Ux“Mè%*8{»
+FÁÝGþC‹›Ð^;ÝØݵÍÍ’Fž]6•gW.îKJiö`nv奫ã'ÍXü6¯{?|ó>Ñ úÊYw}óÉÙ~Ý;Yªn>)WËÞ¯ÚìÒ‰õ’ŸÖw–ò…Òä L“Ÿ]~]ÌO^;ù¹—:üö멘Ÿýœ?ÍÏ\næ ʦ”–®¦h~3¿1ýÍèhXÝ櫱rôkY_·uÛº¶Þ® ¿*­òw]yôUvîj0M»½¼t¿6÷~øuuÏé,Û;‹ß‹•Öµq±Õ¾¹V6¯+Wg•¥µ¥uf­ÜäÓèã½mÆö×nù¹‹ÛÝ|Á.ØùÙ‡â)îËƶ­üÜÝ£™Ÿ®¿6òÓÝõ:nnZÜœ1w‚ŸÖa%7k´‘eggü·¿%˜†vÕÉÿœÜÔ&—G7C½Š¥Ž½­­ŒíÜÂ×í†ò8qµénd¿Ón/t.Ú7 {O)§ ®>¨àÉ/—úê·©)œæqB%`ù‡×þ¹1³ZÔ÷íÏÙåíü„4«Ñ:9mÆÍzÛþy÷ršÕÛ½½ôËü˜yW¤³ÞZ×Çq³îŒ5îK×òYó?:cWÇ8t»ß–&—ç7~|•Í:»ð`,ÆÌj]\š¡YišØ¸ºV*ëÖ‘tÖÑÊo{¼©/ËfU*O;±³NhÆÕ#OÉv«Ge{»}%ßkåã\Û8»Çs5Z‘s|›ç³ONÒ¬l~´zû¢ôB³fÞoöGûçæÅ1Î:E(ã§Ñ-žä³¾ï|…iBû³Z‡ÊÂXܬí[[½”Ïz¸53öa}ø³Â4þı÷õJܬ;+ZS½–ÏjL_Í.4Î¥³ŽVªøšÓÐÄâÑî}[™ÕûbÚæJ̬WwJ¥uvæÏŠ»&Þ_šØ¯½œKgÝþf_Äîu¢/òsݺy­ˆg_Ö™\ëàÄ3‘íîܽ¹$[~Ϻ¿{ø“ÏzU˜
+íµl‹×þ¬ˆiâv¯×•ý·oeù¬»£ŸöþÕƒ-õ¨QÛ‰¦Ù+~¼ÏÉ·kü˜UN÷?>å³îé·û•ÊJ^:ëÙn}ןÏ&8ñéuö+nÖMåB¹uä³îÆÎïfd³"³¹¸]êÄn÷bªv÷7ëò½°²3ëÖì÷U»½A³Â4áí^ÏÝÆÎú{ôl=fÖKùYý5+›1môð¼þ:ÿåpN
+äÛÛË»ØY[µ•©ç¸Y”_[û›4+aZ˜jÏÕÑËî·]Ù¬íöaaŒÏz¯O‡ˆgÖ™ÙÒÙ¬ÕÑî¶?+©‹ùùö§¾¡àÄs‘Y–¦>n·.WaÖ¥vXòÌ·®æø¬¯ÎLhÖ/O?FŸhV˜F[¿Rwƒ¼âDÙ:ü±³¢|ñ°àJžnÂ[[¿‹lÖ•©­9VäÐ¥Žù2ù8Ë9”>>¿±䋵Ù%ûðÎZŠÎj}]ºÚÙY¿æC³æµõ£š•Îfþ[1´Ýß­¥­W6ëÊùþ~P¼˜¿´HÞ);¿Ž7Ä_µî[^›oÞ‡~õ…´ö9‘×ßÞåÓ@<Ëf-î×6`ÄA=æW¦rl-m±I}½¤ì¯êýå÷×+ÊþÉŠ÷ëš²ÿ¸gѯ0¤Ã†rÿnÇ=¾¥=ìžÄýz§œn¼vC¿
+šÍ9åôb,óø¢r¶z0÷«©œç?Šò_óøªíög¾Ì;D¹ÖŽrqž_b¿)ýª\<Vâ~ÝW¾;kТ•ïÖÖFÜãÇÊõXùgܯ¿•Ÿ—×3¡_ Ý”•Ÿ¿Ÿæb¿q”Ûó=î×Uåκsb~½Ã×¼«Å™=3¦CuJu~i1¿Þ©ë·•¸_OÕ½o£_ãöÐR_µzÌãÓêÕï½ ù¯æmóla±{ 4­sœŸœþJºÖX:S;êî¬å‹;«Ëì×0Ôºü¢ñõ·üWcú™Í¢öü-®ÃÏÙÅ…·á×ÂÌ 7
+»-¿O=žÍ®·:‡Œ“-/½Œ·­›ÚºË:Cö±Äv{Eý²ZêNnTÎVÊWd€n^o-¡M©l¬66ÖK{³ðØé;ì×—.Gg
+Sé“LUÿúÆì¡ó÷ÆŸ‰–ìæ$Ø™—Ÿd«}Zô Û±R}é~Hqt Œ¡ùã
+JóQý 7믄Y· NPxœ˜ógmwæg;Þ¬z`V{Ǹ|Ù_pgÝn <:%ÎjœŽÃ4þÄíÏ_j1vV¹˜YÁâ»âF>«qõƒ™QâÄ ¿i±³’i;+Úþ¬¸›ÀĵøYíÃo—ñ³¢’ a˜õ”»¸í~‹íØüŸŸ>qtŸOîĞw]È4¤q³Ÿ­ßô1ë‡|ƒYûVП âÊ'˜ó“?68TOÖI1d|Æ®Oû«êܹ:çýùáž W4¸?é]$¬_³MãDðÝ-O´p¨éŸ®Š<
+çÿj~ùBðH¿‡¬5>Ñ·¢M´.+ÔËðë
+wMmŸÃ׉/üOõrÓ7BN=èücSÝúÙÙæ>¾gaÑË[_øŸ¹ƒ³\æìïðp#
+ºf¹Ç øCZ–ï‡ýÞ~PÝÊ>CÀýÔl~všù^8I¡üÞ é"!£0uY5uDz²‚P:O„öv‡Ã
+˜ ø½›$ï°;;)Û!î¦gÀ§iaÌ5Z¾ "ïÊÔfWYÿ]Â;/š ufsƘî`mß|ÄbwBf‡W"±ËàE£:
+¯‰=
+[òw“eK_Œ>Yˆi{ Ø+
+A]ø´mSo黨/ÞýpyÚgtCÜ×öñ›Ê"Ü[8šç¥M¦› ^Z-™
+³qh$uP7>žÜôTh”˜Haú@3=-Ga§f‡²/Q³h B†åð˜dYH£«Ð\xz:jv^ž ž˜ Œ²Ìú?¸°@Ô(c¤0šZ–H–ëåÙñ2î¦9ânÐ6ŸA½£ÀJŠzqy>0w£³…³'ý>‰»ÁPîÆ“,zAÁh=q·
+ÚúÀ\
+%cdòCÇšqWIbJLCž&ÉŽ ƒ`ýò%ìÁî‰È‚>›§bŠñ”5 ‡2“Φ§ðŽ–‚Ë=8S´õ«Ñ‰^ôŽp¢£ˆÐWä˜Ë:Z Ùßwd™¾Â4"f¤æ_Òšâ½Éa"sÏ&ä1Éã_oS¹“b5?ªÛ[>zÙn\Tï6Ç?·*Îøêmålùx‹jù`šá”óÍ&ÖòEK•ó‰ZÑZ¾ñ5ƒ”ó%×òø¥‹ƒ•ó ³JjùÄDåÊù’kùFÄÒÅAÊù’kù‚
+ð<ÿÂKSøâëÀ>2¬)‹ƒ–•–+~ÐJÖÜyZÂf8
+ÐwâíÍ b¬ â >žì)=!Røc3èêTn}[¤Ì'šÊ0Ê’êSþ¤‘„ÑÒ²¼bv©XÉPÄ—y‡G×
+‘ÌŽˆX¯zZÁ^DÞÅè3¸%#´¥h–jÐ
+„/J!EzÄ­ôJ)ͤHïÅæ\ŒôR!9ÿ-å c-‡hF—¾r^ÎPÌšáµg{~–nlq¦ÍMgÅRò§Éu/c2DZ&C}}–ø¥s\f{¦”øe©hM¤`Vˆ™à§Ë’v"
+šØ©Ë‘úlh _@£pb¥§åé)Å:öÇÒÌûL)Ö ¥/Ï„éqëf#†<w0=^ ô²[Ï×ù4™öŽ—ì©Ð“a
+ÊÀÓbS¡'?2¸&¨ê²l‰žÑíbH¯:¦ÒÞ…“ÅÄ¥z¤G¹X»
+=^Ä
+GÑg“Qñ§Ñî{z1älÈgJ™€F–°­g³[œ&Xuû~æ¬0ü>Ô"ÙïC-’ý>¤"Ù›!ɪ£…áÉÂ@Ã)’Å/’ÅQ†R$‹eté/ºçÆ–‘¡$¼
+6SþR0yE”ïÚ»Á8³êòÎ’åÄZ–\¡à6³Z÷ÂÙÄøC(ÊÈ“×åý#EyýÛž=åÅ;ï‡Z”Ç“,RÊ5.Ê¡7ÃÞ&Ë–ŒÜ}'–G1åVà Ùª¯‚9éo¿ñn“røÅÉ}¿ŽíCBêÙñŒ ëJõ¾~4›«ð+”Ó##±¥òXN—!”ôæadì%’#qµ¸éUס5…ÞgD 1í:9ÝÕ×æ×é$’ Å å§NÆËù¹—ߧx›<VãÅëwù™½5?·yò/^?Å‹×Ïò3gk~:Æ®ùÂÞ©”._Ë\8-µ^ÅE»þ©àz¬"L´=ewÇ%E„t 
+ü|ÌÔïh¬Ê Žë:z´”Ï0dûóîU|Û8îÚWQ}šKÄðøÜTHÆ&ùœÓó{£ÊíñÄ[8??ì‡í«¸h„Ýéõ맒;XâïôZ•¾‹:>£+¾¸(õŠšhüLêìz½àš>à þú^Ov|YÝvÇ“£ƒg
+â›é·­rîv _«—Ám×ÃÍz±;I¿ /í¢•,;‘½ ®ïªØLw¬d|Êõ=Ðò´oÜd•è'¿•Ï7
+‡VØ'³>zõÙd(ì“Y r·Ý@…}²ª¾XºÿÂ>™‘;ˆ‡YØ'«ê#ºnaŸ }¼ØÚð
+ûâÝÝC-ì“¥§zX…}©™Ã)ì“Åyb¢¸ƒöÏ•Uõ%Vú-싉â»°/¡be˜…}YßÑ5`aŸïïUõÉëöÉ„ó@ µ°O¶&1ô=¤Â>YU_(£k…}²3ôèfx…}²¡Ü`ñ ûdU}²Š• ûúZo…}i@RaŸ¬ª¯W e(ì“UõÄTz PØ'ÓIGÂU߃öÉx ¤‡UØ' ¶0Ûs¨…}Á&RMÜ> ûdgXé»°O<%72“$oú,싱=c!ÒgaŸ
+¡W?s}YRJ<,ÕHö¥÷’jEÁpR­è݃cÀ<K–U–BÌ!DRh”€*+CŒõ"ãÇp ¾H12
+عAºé¹Ò^-þ%‰Y.¯Wûþ®MEª}×Ò£QÙ Ð~×2Ý,Ñû$Iä0ÚL&Æ&³Xhž6 šÎF46“‚S ÅES¶/Øë|“ãž™œ…‘|”> c·z¹ãùð.w<•PôË.Z=)÷1fÝE7ˆŽá’œ>ÚË@Cx¨¿¾ƒö ”Ô[Z,Š¤„b`1èdQz„6I E?Îû>îý“f¦ˆWÿõIÂPC¼ë;íÞ¿Œªú ÷þ¹ªzìÕ=–þÄÜû׫‰Ûç½±¼úo}E|6½]Ö-ýÞ¿ƒ8±Ú·¯{ÿ2¿¾}ûæcàú2DÐúRÞ¼‘½ÚW•š–B÷Ví«Žöv¿¼Ü™‚0¯e¨ûH-ÄtKï}‹ ß29¿R2ºh Áª}i&=¯öýžøn»U’ž½TßG²v2Ý"ÐlµTѬ,#;O–hR7˜,ÏvŸ@=R]R¬*^¬Ék©’ªåîã½}Ó2ø0ÚK†œÄ°uCž0ÚkòÌPHuI&þlÏ»v²±=c„ÔüT1!c2Uc »`Y‰µT½jŒ÷,pžš‡ñú9,”{ÞŒâöQw»QŒOåó™ÂHè÷ •iƒ¼U+
+´¡]†yßñC¹±Ñ¨¬šÍF±œAŽŽd¼@ðò.ûE©±Ñ(º§oh—ašß2’¹îÖ'ãeó )Â~§ÝÖºXÅ ¿:WXjx†Vó³ůXb¸Au†E}ß÷Žo"4þ)P#×î¨_Úþ¬„ÐÁ«éFµyG^™·8:[™×þüUŒ¯ÄiµçðM|³þÕt’[½jµë¤*ÄßjȾ ">žÆÎ:¡~½{ˆ›õ1¶F¦é؇ë§Âvƒ5r±—Z\ež½³ü1þæí5T™7-ÔŽx·Ç @^ÒbgU*Žr3«56~ò¦ÝÊf…ip» 壕Ž?ëöܯ‹ØY'kSåÁÑ. ,&ͺ?;k»s¾œ—Í
+Ó°BÄÕŸ…³ÀÑÖw~úÄczãúñ-K¿ÛÏ·f€ÙÄtµÆ>n·.R‡4_8öqÁ‰%:7k!uTH²˜z‹x`*Ÿíx™åI¾ Ù™Ü`—D”~låÚ…M4Æ*¡ WZ6R­|uXz­[ÖeeMøŒÆÊ‚
+Œí h •q‘*æ`°¸Ï’Ĭj£XÓGIb<ãëG$¯ÿè¡$1¸ˆøzÄ‘Ð}Ò=–$f­GtA¬7Fo Êbk=”$Æ°½H=¢Ì`ï¡$1]ÔÄe?ôT’ÒH=bHêµ$1“y¯·ÔSåRJ=b¼%}t.ßW_—Š\༬P4£"µÃ»¬0Íý0¤Ë
+}AÎ?¸¬0ÌÓþ¡Ë
+¹Kµß‹³^Vè¹íþÙË
+ ÓpYÿìe…bæý?xY¡Üý€ËªI¯%½š-'í­Vâm‡^Ü º¨*¿í°×l»Ø ûy«UÆnnoµò/<(*û…‡É€#Cx«]x8„·Ze¹ð0[½çÀú
+†Ç`öXPÖï…‡a´ÞvI€é÷ÂÃäÍ$ÞïÙÃ…‡É·&ø:{»ð0yKLUÂ…‡©É°Ã¹ð0ùR0ÎÓ¿ð0™Œ=U=\Õ녇ɒ/¬§õ}áa ý)rÛ¡Ô¾éçÂÃä¼,!íz° 3”’ ãÂÃäÛ=y3è…‡=ÞSØï…‡ÁQ·FÄ}^xŸ®Æ§Î…‡ÉñÎÓ¿ð0±:†åª«Z-þ¶CÑ"èÂÃä8éøð09Å;ÖsÛë…‡qÅhb(bÀ’ -…¸@JÉE-éÂøÀ zè&½í0â³é÷ÂÃäQFbï)¼äB¸íp°R’óX =mΖڛáÂÃäÚïý=öwáaò›G|ÃcÀ ½Â/iÅöˆX´”½*záaž6Œ “o;\Uç¡;Ë…‡YLÜ!\xèŽ"·¸#b­× S¯(L`6}\x˜TèqóÁmÏÁ/<”"™wÛá`<í{VåGŒ{táa²ò#d? vá¡pYip¯ÞÁØ {¯ÅíëÂCé(+N®XéáÂÃþ3º$ö[ª?Â+$¾ð0@‘ÛÙ4C¸ðЭª“ßvÈyÚà&'Q1åv&[÷.ІVx%¿í°_ghá û·={ºð0Ž²Û‡•¢¸‘|ÛáHèÕú}_x˜|Û!W9¿ð0¹HW.¤û¸ð0ù¶Ã4=-{‘nâm‡¢r  ûÑlú¸ð0ö4)
+‚J«¾¯ls
+Êþîá²ÿöô¬5j/Êéî(g»õ å¼óò¤\(݆rq»ô©|/\L)×sçÓÊÏûÑ#åööòI¹;Ñ»Ê/ýrRùu0õ­Ýno•Ú›ÖBûSm^À4íÏ;{ª3Yž@=ᤋզ“…úãÎÑΡó´zñóú9?3ñåòxÜ^h¬9>Ýþ:ñòúetÔ)N5¾ìÎÄÑýïËÍÅ·(1ÿ9÷nþ¢c¡8˜&¿V9;û¢Œ×¡ù¸%e'ül¨äµÓÁ×ý|aýÊ.Èä7,ί‡àEÀB m›7
+;Ü®›œ\:ù€¯û%żßCqÈ ©îXûþàxJï×1qï ¬ƒ«Òé+ç•_¥‹ès+ÏåùŸÇÎÚŽe­ÂŸÅõõ_‡c‡ôu~¢µ9¿9V›ÛÝú¾^Ã÷Ù¬>©ÐA;­8cærÅ?yÜøùulgáóTú¢Ñ¾
+Í:õÂÞøæÍæööÒëÚÙ¦þ!ƒ:kñ€×´õ+u·÷3Óº“Ecg}2h™²÷΀²¸ô½tÅ/õÞº©|xŒÕÕ@ W&Ú«“—«­öUånnglíèyqà`Œo>}ëœQvò?'7•Ç/ÍM Ïùo²ã–|„ÞËÑ7Ì¥
+òÓ²sœ÷õ×ÉæÍf±<ÙÉ€‚¸ìû<ý ömOÉž@¼Ð†ašä=º½A‘3eùünf«÷©‘ÙôvÒèiìF˜ã$n=Óúå8AŠ­eæò=Šõ
+ÿ±Ó§£§³ùGOŸŽ¾_y“ýô.úLñ:ÚÎ"ÉYÞ)±Ìp´©°w°ØŠ*|Ü'aS;ÜÅH]8ÿ1q¾Œ{N˜­Š0µn¬z±ª‹À=DlŒiAøOÌÕ·BÌnŒ¯l¹\€TmʹÒý=PÛèèòʶkĶfÄ3ă­Tï•R5K¡./׶…ÀJ}J(› ,dÙŒ˜J·u³PÐ'~¨`™mΩ۷EV«Hmp†EÖö³s‡I«77×ô®ë§[°³ê¢MâÕNÞ F?}ܘ]x8:ÀŒÉÑÐÕF¬ ÃÝÒËÌê÷™ªpÑGÚ0ÍôÔÊŸ°Tc~SƒÜm¶éžÍgÞÏÞÏ.yN_âcnÁù¡ˆMWsMhëÓ{³îÝ<;?‹£¿Ï‰ÄØÅV˜!O+Âå4|賫X6;§nD |þ8" °:Z‘
+¦é‹ÎçfzbÈl¢c ÊlææB0Kº§™+Ä,"€â"Ôˆf3WÌp"úê·©)>Fuå(8@I†ß h™7¢ôId#þµnsj`$ÐÈœæ`ùDÖÝÞÛ­4ãwoê ÇîE{oZ°_,ñ÷Å€ZVi®OØx„±DÀ´¬ØZÊ‚%¡ED€&E”^6¢È É€–y#ý2 ÓJÚ€´_Ò3 écé`c–Ñ^6õÀÚ@ ˆ im.É‹ˆc@|®¼I†V-´R &ÝÓ²0 !MFØ^›*·—®ŒØšÑ £l7ƒÕŒÎ¦Œ"
+ Z3š¡`³í­ÍP0:â•`õ_3:›^0ÊÎf°šÑ £è¶ x’èxNÄVŠ¦”‰G ¿»;¥>´ÏâPD^êCgû+Åiz©í³8馗úÐ>‹C Óz¨M,ÅÛójë
+p˜P~{1 °¤iƦª£_§ yÝ^ÀŠ€ Š¸‘)òcà¯%n¸élªSôrOø³ô_ËT
+9 ãÓÆ‘}¸gµ@þ4dI×@gmÆñjÇåEVÇ
+ìé‡ôí@O·«7aóW©s“/ˆU{ÓuÏ9]d‰{³Þ¢Q Ü}'^Eà÷¯¬ürî¶\sqcN¤|±³ñëuíQ_¹x_'L''äöü´_~
+PËF‘j©‹Þ“Eû¨N•Î‚b€åÎ~­³ ÿ·nçÝVqá“+ûËîobͳ(;–÷ýCœèŒ(Dœz{u6ø2 aö튯}ÜÒE¬šq9 7dR³L›â¤66#*<@xØeŽ¾î|ÝßQÄHæx¿H½`†Ë|=Q…¨ðç¿^²qnšE.ÿÇ‹Ó\¥»Ú¥ÓœUš«£b Š¶P»~Úx±*Gë {Ì0“ÎKüÙhá–º¯…!OJ²ñ`šþ‡<Wò<_šßX;ŸXøµñRÞ{_;[k~'ªÒÖÌÜ"BO?\z²öL÷5ñï÷}…®
+Ì´Rôþ¤H/À›_§Ù§êè±ë9ÿ•L¿Ôw(jq—>ñó½6‰n¸Bùz^D?³
+'gOÒ0øÚû$h°¯UÍ[Î=©¯¾~ùúlxjéíæÞ­Œ§0Ðua³T]œ˜nNžW·Œß!_}äî„TþýE)»?J¸Jŵöiëæë,û$¬¼û¬S›¶~5»ZŽuý¶ÓØ|úÒÁÿÕÅ•KcmïRypÌÛwÜðÇŇÿŠ)YÚ²õeãØní’’Êh?·O.給¶¾¯|]Ÿn´WK]kg}K)ž‰fVþ~Ö‹&z!·In:ñóšv¹Õq‹ôå묫\P!-3˜ê£ÇžÁÔqŽ"{w½\¾ÓL_a¯N0çÁ2ÿ½LlÒg…ÇQˆQŽð×2â52E:7 ï\3Ö)µúŽTÙ'ÜP‘ê.¨sJó—§k̸j¬:·ñå/˜)SPØÀ~rßè°W5œ÷ Å}­DÈ’‚bÄ æ”»ÃÃY7EŒ©‡°4NùK*¶ßçQ‡:,yÚO360¢üÁçóŸÉ/áí¿õx=òæêÈ;l <¾ukzaÃo’°a!z|°÷¡Ç|wªãqØ٦4»Ø°a»½X`ï‹=Zcù/ëã^þìÃDdŒõÒï¤P+—ÛªÿZ ÎñP!ân“R}ù|‹ð¼TŸ›_&ÊpÛ.>ܶ«v©~Ôa¶¸ø‹˜-ðÔý
+ÄAï·ì µø
+¡ôàMìÓ•HÊmÞÄ>]‰<‰7³7±OW"ºT{ñ&öéJô}Ù¼‰!W"Ú’æÿìÿÀwÀb°_¾!Å»­æ£N„æ/ÐtZë~¾Són½ö\oîWÿ®µGþ£æØ
+ü‡ËNNÕìœfšðÅÄÖýû‘ÿLQïœ3ÛG'×]i­Ýݬ?të­fµýwnžÚ.öÏw7só9Öûz/ä¦`MÊt‡Ÿ¦)’I1®É ÏüõÖhB‡BµÛm×ï?»µŽûèZ»]ö{x©7Ûµ&ï¥æJ»Í®ÿ3þéþý^ã?çJ§0ló9ØájãÓí1õÒí¾Ï—JÍN±úغ¯Zo¥§¿žKš¢Ø%
+š©å@%×,³¨9ŽÍö±Á*ê†UƵ¨X–“Ó¬rÑP ê£UÃÁ&»h”Mš ÇÛFf-ûÁ¹àë“ßÿâìÞW]…}Ñôº†Ÿ$-š£±•R›QTÊ:.ÒvŠ¶c™9M7aE®È.MMÅ&«è˜Š†MfQ-Ã6ðY·±\[åÌ9Še”-ű G1ÄÃð>6Ì«Ã&PÁS:žJdåo²ýEaZ®Fìí‹6çèADŽ‹ÚœbÙV†† §ªª9­¬U¶M`ä›66iEƒÍeX¾²Q´L•ú0”­C«hÛ
++‚A° öiØ:|Àa4
+&ÅaHK§^j¹£Áƒ°MC×-l‚quºó)p¶~Ó< `P'ÐöãàìÐd±ItÛ.š†Ãg°Ýyan«Í;:†×äÕ² ©,4•‰| `‡?Â>Ll3
+®Ÿ-›^«Á
+/Ç—ÁxÎŒÑ@CGùÍ°ÁÁ&X®ª€’hĈ®ì1úÙ°@
+’:Â"u†øŠnhÔT.³g×sÍ‹:²9€Ó) è±æâ qì2›6¸`†ýdlÀS
+¨3¨²nª²ú–
+¬ŽØ2&d½&dŽ†ÂEƒßøIjΦ& wÒ°`Z›5‘rÕ2PïT9 tÐ`@wµ˜ž¦"¯Ð|]KSˆ‹€hÑ­ÌH
+ Õe™
+Uӥ"إŗ
+v¶ª 7@CEØ­Ãì.u6:øH© N XîýT&ÐF|@›L‰ŽM èÀQPg\Šã»ÍTÊ$PŸwPçSA¬*e°A¸yö ˜ãŠ«B+X¼Ä:¶(D@Øà Åc‹fð'9·„)U³\fSZŽ‰›"™®³åšvÙ ­3% ÷IßL
+Øêìžv€"’¸Ö ãýe+y¨(YŒ«£Ø±Y/ÐUˬ ìM“5±å¢Üð|{ dX¤w
+c\ºí‘¥^F™Ì”<h5 ìWF“šÊ¤ÃÙ®u­s_8ꌺÂt.4ÓPEÆj;*k2pTà$š°‰†àÂVi²V»ŒV‘a+¼ÉACF·lîÆ$ôvµRÐ0@j¬†VÉi¤‡@Eâ=‘š\]Ç!?kÄ(Ì¦ß—â  †z SìàÈI'š+»z4ºÊʤơ–FÓ5‘‹j®±ÆÕczg¹Z4jxÔä°°0ÇfáW7u˜ÝÄŸu,ƒkS¸rj±U®‡•ÑðÐ5W+óÖ
+²¯¬9\mBÛå¾Íl@8‹x0TïAt¦Ø*SA‹ú×Az#¯E­”‡(p»®VUj¹>U~%rH•æŠ:7ÕÌ%ú»LÍ—X›An\Ȭ¨©"5i¢¦Ä<ŠXPKb‡I 6‰e'±ÿä†bÔ¢Œš1æiÔŒ•Øºr£Xf=Kll™).µØ%v½Ì ñD¼ .ß/q]È]2_HÔc"w­È}0OL×QÁ2Q—S :"¢–×ÄOrzŠ‚Ééw@J!’Å(Žb©È^Ýɽ™TäÅlþ2'04£,“, …éZõ‹{¤
+1q4t˜l¤Ó1Y:,
+äª †ç¦&
+¬a´¾¹„gÇ‚´Î#ê#õˆ=f RZ¦Óä7hqöÔÊ›Øs,ÉZØÒuwßÀ¡üH(FL…3AÜ9Êo[gl<hqÃieÈÃ&“}÷b•¶Â×F±4G³ix‡G0š]0UÔi 0Ëø#ôFqA…M èˆ5YèŽ(Ñd¼›¼ý8
+— ¸:*l2¼°N-Â2]:
+“Ø•Æù Gõ¦°yøÔÑÝ…¨Šïĸ©J{Rù‚7Ìj"êªe
+l3²15Å3q`e5QÖÌMŒÚ¡ÂP0‘ßb‹æÆ…M7Þ“ªÍá¨sÆãšÈ°ÅE0ÆWfc€˜)ÈØŠl‘@'Í'
+»"þ¹#B걈º5dΉ$êH‘ù["^™ç&âÝq}§è9s8~c«a°œ´™
+B
+ΉU+£ ¹<YèævŸi{ž`Ò@‘Ÿ˜
+K·BL*Y¡ºJz*ã (G8E1o1æ×!Y’ûݲxª GmÕ³ÙU?Ȳy(‚®c¢j™YR”†€¨n±ãÓ n—P­Tó\šÐb*kbyAŽáÚQš¯ ‚+,ÇÍõñý†h&í±ÛÅ™²à†d¦ šjԆϒ£(E‚5©Ì?NyžÑ­§ÁTY–\J§çðtZLwPcýȬÞg­ô—‰Œš7
+ÀèEEyÄݘÙj¡ŸWÊEæN¥ é#~J Ñ=«”äò)‚KREt7ù"ŒUR,ƒG*W±…Ø…Ni[Ì´}¾­,þc3Ðb‹kæÚ<qU5ynUY0—×u3]ÉçËPß×ÉÉi3o¿¡»FêCˆÌÀ¸RJÎLDt©ÿ”]ìz‹±‰­ÜmÝg¹L¯`™È8œífE"á¡ï€»)ËÂÒÑ£ 4éž@M,­Ðæ*ºVf§êpªÅlTm¾›o×ÑÝøz ½ì`–¨Œ6 Ê Õâ½ÈŠÂ&Wž
+VEL;Ñ!¥Ž9;‘Ëh˜s$ºIcs’ž$Ô‡JÉ$À´L=À
+ÒÌÙ Â1çÐ,w“ì}«[ùÆlÅÝåÒw¶w/%ÙVâ ´”š p àŠ{(¶âŠ{p?8‡y´Ë\8ëž•æ5xdTv¢h2Ù.2y9Ýe!ra«îYzˆˆZèx ô1-€—n€œ"Ÿ‚ÇR‘àu…Àìz)ÉÑGªƒióô'R½II0-¤î𠢺²ëõt³¶±‰(˜B[Œ‚=–‹Jƒâ?JiÄÊœm`ge×3ª(á®{¦å¢ž†EZ5ËÎDuù²%ðeÍcàeŸ3&o se' øÐ2`BÃöD‹áŠË“A– ƒLw±èBD++;2<|ä¾ÌD½ÑäâU@æšc•˜ ²&WH{I^e›ùóNÊ<K·LžÞ®Ûå2÷lFKµƒ„´MàfÅL‰AÃQÀh&ÉÅL@¿ …Ô@‹Ô´²1
+PXGˆ$°²Ëñò[t_·/+,FJ.}ÊI dGçŽm2ÛäÉ"’œ’hæ‰<E[‰çc+(Fly¦åN¢™È3-:m
+¬ø»ä)ù#"÷„ç…¡}¹@óSy¼­ZA)Ä`Rfß8Ð,Öþ”~¡°
+æŒÛvPiŒ­”™?K‚ I0èÄ5ù o,9
+“±y˜¦RZ‰ÉIÓÀ<^ô•]jõx­xN©&º â¢l°`›Éü¦…Î
+MôYlòWBMìA×::Átà ?æJH±W²#6§g]o»Ð±,lŠ‘—a‹Ml“6¯·À&æK3¸»•5Q½Æ.L÷A¯±ã3=+^79ÄLrNa_V|‚™ë~F˜ë÷£5¸u=ôCBåJé‘°ÉÃ{…W§`+¥¥p/,¶hä.Ä,ÄP/yÍR™SŒZËŒZTö
+sÓc“ {ÅxZ9•rb*| ®Z<èúÛ°µ*ðð–ÁtsÕÛ·â)‡ÈP9bÑêeθ‹€µc£ÞÑð¸$ˆmg>5Ã`NKœÕ´iR@ URK÷Ö« ëÕ½}i|_º·wï]÷`¤ 0âõ˜¦Æ!© kØb“*ºw|š{|ºwÈš{È:ûæ#‚æ!‹î"‹æa”yBL8*£¨ÅÊoLn& ahòqÝöˆÂt‰Âb–9Ùì‹gÞ&»Ôg{NYÂhN¦nY”‹’¬‰ˆÙT¼E¸9†#6¹ŒÁe¶Ï>4Ï£âóOüˆ]ØûMáÇ<ñã÷±ßœ?k†Çç
+Mô !øl¶.ÒºÑÐgIé˜CÇŽ™à~’%/H3<ì
+o²0žgî«ÿSØÙôÈaønÀÿa.>N@J")“Æ. ä{0pÆÞ
+ùÿ`Iç.P9ÏH\jò!rLGÚ­ûL„Áß0wAf[ÊÌb‚7YPíSr[,±ª+„™X^ïÁÔTlu¼víî³X‹Ì«%ž·o6ð»r°…Ç후m‹·níÒ¬]ÖÔ[Ï|$˜¼™ëhæ5õ×Qõu¬©¿³jïlMýå¶D0÷^Ð"˜ûo4—šäÞ©Ö1cµbǃÄÜóñÈ"‚¡²Ù¿»®6¾äuÊl€–  É¡Pñ»{t!njŸ9 é(Y4r´ë2CUž6•VlHÀ…ÉäÛÖÝ¥2WÀdÛw9âoªçËÜ‘}Ø~½l1&b¿-ßò)©ìëNé"Éý_zËîÊ< ±"=QÎñ*ðó(4®ôpÿ£ò÷r—¹X¤3Y’a’SkÜœNæážá!»5{ohVäÌvðeŽëo–¡¿ÒLõ7–¯ ñëoDw ÀN»±q²Š· >Ñ3^þ›Î*ÀA
+ºÞî4N”èDÕûYQq…&FkŠi4…7Ø4LÛ5ŸÚÕ›?æ÷{³Ãc˜üm¦ÃÛì
+.Ý]‰øhÇHÞ1RïA#äÝÿ
+¬Ú¥²÷Ãi“Þäý´Y?zo®½7ÏÞåSïò6*ò>zÚaô@ÈÇ/8CÖ‚¿•
+èj³ÌOdÔZ¬®“,–fùÍojUê¬UrAE¶Òì{"FÝÜU“tÒ”`ÙªÞ,L6í&•÷lrke7£°ŠUÜ61©/ѬŸŸMÝ/Ø:”´êSLò‹-WÛ⫶œ®ô¿·ôHuI~´ª¯äÅB ©ª.w}$öøìêȵOóÐÞ¥ÉçêÝ3[LŽ'(ìÓ¦¦Ú=Š>Íoµß]íw'¯Ëž¤¬
+̧`žwQ¢+¼æEÇéìXý.sÄ.îÙ]­Ä;ûzÜ%d¾#ñ0™#JüUâÕR÷7ù‘+¤þ:ÓnþÜüUG‚ÇÎá}÷.â´Ù…¸«ÕuÒNèaLTc= ìD?î˜úXõ{¼«Õº—Ç+Ìj3¬ºbÒÏÆmÂñ(.
+ôJu"iº÷«ƒpûŽ#êÌïá»Ü:Ôçš6åÝñ“ ûvZ0ÔûQO§‹Z×p øñlÞ ¿vÛAEO”ö\’ϤûDß
++²`gI®JŽ?Þ§„¦ºaû4Š`Ͷá©ÔŠ`!oGÞvž­¶Uñ$–núxLù_l­ÁZ¼Ví…¬ÊHÇ\»L¿WËÚ¦nj^«LNÿDÒn]ôAK~kØ¢¶Ò®"æ™  0úÿ¥‚:rª‰°žèï£JŸËùèþ¯h
++›½ý折lönëA:€äÇ:ÛA­II—‘Dn˜Ö-«Éáí4[~¯X‘‰#¦eµ1X·µ©É¨Vmd‹'¯Œ«vet“UÑ\Õ:dJ`p œÞbGÑ#&ùÔÂË-oO‘}u3 Ö“uw.Â…§E¨[ÏE8^„öű`”vfŒqc–²ÙzyüI3À¡©æÚΦÎÒÓ`¸Ý•ë(þõÏKÐÚ¤Â@,D
+©¢½ešˆ["Ö57¶b'¹ ¼Tí;y?Di¯½Ýt!_|›*Ojµ·ûÀšGÝ‘D$B0Í
+˜{ííÉko÷,“ydu¢HwÑYßjo×#L¦œ Û¡ööÑjµ·&­½Ý-z´{0 –ƒÖÞî^¶E¢½öö|H›uyû⹚ ÔÈV{;{ÂȨ²=Nè` “X3æI+C;˜&(úbríM³u/y¸wµ’„ÝÖËói¢pÌ&æYÇ×ôd’Ä̳cV4I~œcM’±IÊ6ÍíiV$‹I˜4‚ê'¢Ì‚Š1¢`ƒÈ:‚úƒhD¨˜$ŠNˆ2…KX˜Ö…(b˜p&êkΦÐ!:¢ö!ª O4ÈóFBv´ÈÉ„¯Ì0Ì„Ö‘ÎŒ wD‹–`¶é "dìI…œnUJÚa˜ú¹w7}Ô“v¯Ö^½ZûÒ«µOV­Ýã=Kùeh­MÓÇЗ±É@7Ý$½ >Œl¶c“ÞŒmXYo*}»2µ"w‹ó¹Ç+²¾8ìJcp1J!#¸²5ÓOCHàh ÆIkÉfZÄNmcl7»`âlFégx‘6wWÝiÀÒQx]@ÜÁåq®ðELßõ2‚û£P@N$˜ÁrùÌy…‘kà‡’(—¢â]¡Wô"4r’cRúÏ3ÞfZDýz @KŠiã`š·ÑkÓRDð„ 1—a"%×Hm¶P¿—ycõàHÕ8Úë)Jui5!×z« jT° éî_͚ƴ{ôuL²4GéT8EÒ“6cH#‹dY±UC¤HÆãv(”eþÔvÈÃ|¼÷¼˜R7iRQö¡ÏîOÉaQ•¤„‚Š
+! ゥGJ†Â"*XdkkJHÁäÉpT3¤Ç°xl°œ¢Š´ts+µ<¢g1ÕaZáµ~ÔP¦›ª:aR_GÿÖZ†I|%~ÒqÎ œþ õÚ{ip#ÿ$¨G¢$Fx &ʵ=àx×»I·|Û<Æ?C”4DRi´5Ädyð6ÄxI˜Œ?iþË%Bð¦gß!”@42AB,ÐAÂ!$hC+,Ã5$œó(î3ÏÙ¬eFP‚°›¡@w“§l~Îö™íßfä¶f÷iüBz¬'½‘ÌôQúSËóñ‹ŦÅ6|õ„;ѦU©Iíjõ1ïáþ§÷ï>üñÏåï¿|ùÇý忯ߞŸwÇ¿¾|~ýÛ·—þëõÛûwŸ¿¿üûõéåË—¯?^~¼þ¾ÿ¯§Ïß^¿ÿøúíõéûo_ÿ .ê|øðË_~}ÿîYuß
+endstream endobj 7 0 obj [6 0 R 5 0 R] endobj 23 0 obj <</CreationDate(D:20141208091030-04'00')/Creator(Adobe Illustrator CS5)/ModDate(D:20141208091030-05'00')/Producer(Adobe PDF library 9.90)/Title(vector-src purple)>> endobj xref
+0 24
+0000000000 65535 f
+0000000016 00000 n
+0000000156 00000 n
+0000021286 00000 n
+0000000000 00000 f
+0000034407 00000 n
+0000034477 00000 n
+0000087436 00000 n
+0000021337 00000 n
+0000021680 00000 n
+0000034892 00000 n
+0000034779 00000 n
+0000033131 00000 n
+0000033845 00000 n
+0000033893 00000 n
+0000034663 00000 n
+0000034694 00000 n
+0000034547 00000 n
+0000034578 00000 n
+0000034966 00000 n
+0000035140 00000 n
+0000036177 00000 n
+0000056886 00000 n
+0000087465 00000 n
+trailer
+<</Size 24/Root 1 0 R/Info 23 0 R/ID[<D98B661074D70E45A20426C1DAEFD398><8D13EF9123BA3B4D8555814E15E60883>]>>
+startxref
+87646
+%%EOF
diff --git a/Graphics/drawables/material-launcher/vector-src purple.psd b/Graphics/drawables/material-launcher/vector-src purple.psd
new file mode 100644
index 000000000..21e8ebcf4
--- /dev/null
+++ b/Graphics/drawables/material-launcher/vector-src purple.psd
Binary files differ
diff --git a/Graphics/drawables/material-launcher/vector-src.ai b/Graphics/drawables/material-launcher/vector-src.ai
new file mode 100644
index 000000000..ec23f59ad
--- /dev/null
+++ b/Graphics/drawables/material-launcher/vector-src.ai
@@ -0,0 +1,635 @@
+%PDF-1.5 %âãÏÓ
+1 0 obj <</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R 6 0 R]/Order 7 0 R/RBGroups[]>>/OCGs[5 0 R 6 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 18065/Subtype/XML/Type/Metadata>>stream
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c060 61.134777, 2010/02/12-17:32:00 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/"
+ xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/">
+ <xmp:CreatorTool>Adobe Illustrator CS5</xmp:CreatorTool>
+ <xmp:CreateDate>2014-12-08T09:10:02-04:00</xmp:CreateDate>
+ <xmp:ModifyDate>2014-12-08T09:10:02-05:00</xmp:ModifyDate>
+ <xmp:MetadataDate>2014-12-08T09:10:02-05:00</xmp:MetadataDate>
+ <xmp:Thumbnails>
+ <rdf:Alt>
+ <rdf:li rdf:parseType="Resource">
+ <xmpGImg:width>236</xmpGImg:width>
+ <xmpGImg:height>256</xmpGImg:height>
+ <xmpGImg:format>JPEG</xmpGImg:format>
+ <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADsAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYqtkkjjUs7BVHc4qld3r8MZKxLyPif6Yqlc2t3snRyo9tv1UxVCNd3DGrOTirX1ib+c4qqR6je&#xA;xmqysPauKo638xXSUEyiRfuOKpxZ6rZ3VFRuMn8jbH6MVRmKuxV2KuxV2KuxV2KuxV2KuxV2KuxV&#xA;2KuxV2KuxV2KuxV2KuxV2Koa9vorVKtu56L/ABOKsZvdSnuXJLGnb+zFVWx0S7uQHb91Ef2m6n5D&#xA;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&#xA;/9k=</xmpGImg:image>
+ </rdf:li>
+ </rdf:Alt>
+ </xmp:Thumbnails>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+ xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/">
+ <xmpTPg:NPages>1</xmpTPg:NPages>
+ <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
+ <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
+ <xmpTPg:MaxPageSize rdf:parseType="Resource">
+ <stDim:w>626.000000</stDim:w>
+ <stDim:h>626.000000</stDim:h>
+ <stDim:unit>Points</stDim:unit>
+ </xmpTPg:MaxPageSize>
+ <xmpTPg:PlateNames>
+ <rdf:Seq>
+ <rdf:li>Cyan</rdf:li>
+ <rdf:li>Magenta</rdf:li>
+ <rdf:li>Yellow</rdf:li>
+ <rdf:li>Black</rdf:li>
+ </rdf:Seq>
+ </xmpTPg:PlateNames>
+ <xmpTPg:SwatchGroups>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Default Swatch Group</xmpG:groupName>
+ <xmpG:groupType>0</xmpG:groupType>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpTPg:SwatchGroups>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/">
+ <illustrator:Type>Document</illustrator:Type>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <dc:format>application/pdf</dc:format>
+ <dc:title>
+ <rdf:Alt>
+ <rdf:li xml:lang="x-default">vector-src</rdf:li>
+ </rdf:Alt>
+ </dc:title>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
+ <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
+ <xmpMM:DocumentID>uuid:78383aa4-a5ab-4b53-91d1-df5b56dc318d</xmpMM:DocumentID>
+ <xmpMM:InstanceID>uuid:8dda4bb2-97cf-4d11-84a6-9bd04c76dc7b</xmpMM:InstanceID>
+ </rdf:Description>
+ <rdf:Description rdf:about=""
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+ <pdf:Producer>Adobe PDF library 9.90</pdf:Producer>
+ </rdf:Description>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?>
+endstream endobj 3 0 obj <</Count 1/Kids[8 0 R]/Type/Pages>> endobj 8 0 obj <</ArtBox[213.5 89.3184 537.323 441.675]/BleedBox[0.0 0.0 626.0 626.0]/Contents 9 0 R/LastModified(D:20141208091002-04'00')/MediaBox[0.0 0.0 626.0 626.0]/Parent 3 0 R/PieceInfo<</Illustrator 10 0 R>>/Resources<</ExtGState<</GS0 11 0 R>>/Properties<</MC0 5 0 R/MC1 6 0 R>>>>/Thumb 12 0 R/TrimBox[0.0 0.0 626.0 626.0]/Type/Page>> endobj 9 0 obj <</Filter/FlateDecode/Length 11276>>stream
+H‰|—ËŽ$IE÷ù±FÊh?¶ ˆB#|@ †Eðÿç^ó̪Fµº2®‡‡»½íÚ·?ýt}ûãOéúíï~ºÿ|¤k”áÿOýù×_¹þñHw_Wºg¯ü­ëú×/oøsº~ù÷ãŸW¾ÿòUs½K×ÏõñëCkúûÌ‹ï®ïçâ”ÿ†…Cæ¾óW©wNízÎyOÁ~·¹ã®W™÷âøGÀÄg—¸™kžm޻뙳ڸwª€{×z=[¿Wã]¹×·ÆÉ *)>ô} yþþøÛo?£iÝ%»U-Eª~ªXjÑîZù(¥òƒžußM…š?¢£æjwù4î{íúá¹ÞIŸ×~ÏòÎ;U¾jwîûªë®}^(XZ¹¸‘g™æãÑÐñÚºS‹í•CØ–¶´«gïë¡hG”¼õ³r¹ú¸¦êr‰´s€Ú¾†¶Œ wÙ.Sž×Vd\“;Ù˜†^íšýNc\9÷{Ž{ô+Žé°×¼ÞáÂÃøp_¹ãµk6De[_UëxÕeU@(è ] ýƼÆ.¹X¶ÎWC•µZõÁÇCH2›_ôŸ‚µ·Æ^NÐ^Îkz9’[žàÌráz¾KB€Åþ:° hÆ\ÏÆÇFU!X77îÙe¹‚ÞDÌs$ý¼Ñ¾KœûÆŠÜåU''w&¬4„Ñ$t˜C&.r?Š?s?‚"†;Ò‚x2&ipWA»îí¼ÛBË©Œ©·Í9^ï ¿gzf‚"ëü0)¸ê@>!,Qø¾(ÓロD.%‡B«»æiw²Âƒì~üûÌŠ>éœF|²ñb˜7áóØ27ï_””¼®/«“ó¥Rt{¥ö|i¡¾¤a^Ë—Ë°Ò¯"ͳälËç^²…¸—XY¡&8ŽT¹&¹ô½òýq’âË
+·LKzVœŸ–<ßsÉáÞ·5;±hë'[!®êÁöw»3$ô³ŒÄBµ§¥É‰zå°ì8cë',.ÚÂÔ'UŠ#˜ÁÊŠÀP_888D‘ˆURˆJ¥o9Á··áZKÆ™*¡·,KˆÍâòûú÷¤Q}‹¶•£mýü—n';ÚäïÈå·®BlÐ\(¢yß}ö/•ý‰Ñ‚&›¼F€$„RâÞ[ÚBþEb¿±l‘ØšLEL±›s¢‹aºŒé2-ιDæ­ ÿñWM’¿š+°ö!ƒMIÝŠç{7ª/áœÝN(ÈÚÅSÛZ_»y½.,BÄ8‚}"ÙvNd—š†[‡Š™Ú ù"}¦Õ
+ÀV¹·×;_!1ì^™†µ"‹ùL‚ˆw—‘½Š8éΛV”xá“_\/Ùˆ}þ´’ï¯'OaNdMãRE¡EÜec+‚'k«Z¸BÍ.¬H„3¦ÛSyÃÏËú|<T…ÑÆÆW˜%€ŒCî׉IE‘Xž=TŠ®Éš¼tºÖ‘p"¨}*fP¥MñÆlÍåÆf%ßé”ܱ¤†¤BUû !³$/¬½Ã*²„LÏÂÙ§F¾µÜ¶ß*+Ñ—ÝÛÖZv°lP$My+|aÐs¿øæãE„Ú*ŠÖ)/–™dBuÐ6T©,² §3ÆE“Ϋ@ %5q8¢_ÌÎ%àð83c•„i†!XU‰^…é>{ëAÕ[뎭]5⎳9öŽxÙÏ-3> °"a“ë$]JW.ÓAßB­÷±Alžç‘~KÕÊJ?xK9Õ];†[Q)Ë.’Ù}hD“½ßIݬðp³ùî•™Ç{ʼn>^‘ÒqÝP÷WÆç÷‚Úk‰rï‹Rv‘ýDÚ^£«7^çó×J{ø¹RÏ™6
+8:õ0±má]£ï~è~¡6¿²qqù Ð¬m#$…ÌÁ¿¹„E,TmÉÀ=Ì¢Õ\ð`= ÙÕÚ)­ÚÙo:t´½‘’¼v"Cs¡Ý¶ér_~*芃Nò&“ÜgsÖ;5³bzý”ÑÇ)b¦Xf2Ø:©=‡['iXRzt×5M1‹šñdĨê 0û¤Ë`g
+æUìeçãÓç
+‚Ø•¸Š¿æŽñ„þ*8»‹”Ã{”C¿NàÐxÂêïÈ~·XâìLÊ úr»ôW“lãÑK¨¶Û
+: •¶ÏÊí©€Óõ‰²ÿ«ž•÷Ì(з ¤öj ŒfŠ<;?‡4ñÀRÖÔ
+9U0m”ºO“ç,­•Œ*@_оcúÄÛÍáµÐbŒ²1ÑaU¾¦ðe
+á·\È ”´s\g ‰"s9¹]áµäÍ_8Ì~=Zu [¼"Ò
+ÔåÁÔâë§&1½ëâörm¾„‹ 鹆 q~Ï5\à…ã¸75Î!·V<;²›¾˜YËuìXNè»ÃTã“úœÂW£X÷£«Í:4Ô `Hõz!jÒüÜÛÙ"’²h›F¢ ØU± rdæC3Æ«ÈjÍ¥v®ØjuØy;îÄì©v-öÚ *~¸õ ©¡¸íµ·§ç¦C"åSP‰µ%±ŠŠ+6Pôv';ÁN qº8*6Óyš c–ç0/ÆØY¢BÌujtDÈ$Ý/†Jžš?º¸ö“¿ôIt®ÃNn¸œf@Rì³ ¨FG•× JÉYRB½@U¥VÛ‘"öW‹N¥6­:4<¹¼¡K´ù¦Êß_å UüøzËÙšTwB–“ëÀÛUK~¹Ø¬ÛžqÇ¡Ür'õqmS¶ IåËU<e­CVù.§OÉ~[–›¶3vÍ-¥Ü?ùá(Ñ>]ÖPQÓB©{˜·šdÛ,3¶IHÐÐ&5-5ZR%EÂ}Y€=åÊÎ{ŠâlÖ¨šešãG67mRÓÂ×ôG‘1…aðœƒ$!0WgCš¦²[Íþ«Ûßl²«wÏ®aŒ~ð_\’«SÒô•Ýº?©$áÝ5¹yîû×
+ê­]ÜÊñ%öv-©ÈPÝÛê2*E¯²z¬Î|—93§Â4.'MÄYÓaÞNƒï5«mU(Š2ŠÎÔMkå¢õw²áb´š}(ÛTmɳ„­Æö@ïéj%w¿©.}mØ¡dšh¾ŠsXBPbó\í4O͘UÒKuCSK öÀ²ÂñÀÖÃÐ÷Bssø #›ƒ O›Tͬœ¢P•+¢¬\ð‹z P¥~ÝÑ>*6íÅ3’棫÷S‹-u#å:ÝIÚ}ˆY±«Ë›œ³U}ýk´3[Ó•wWË¡yQ½/«–QªÎáàŽþÔ±$ÊlÐ
+°«p'Zæy˜”ÈYÐ'ðÒD4»¥YJ8ÁfMW1ÉøCˆœ=¼°³U3˜Ü›!!°‰›ÿáºìÑìæuÜgg3Dý¯'ÍWdÿõÅ Êžä6ÉЖu$´°ªv¹+¬¾RR‰R_•D4rõ%2)¬¢)¦A¨p„ª®ª«5„õ˜î„ó¦ORR8TFunºNt ¾nD±x¤1è …~W-ÄÔ'ºØWG)è—‡¤¯æç5A¤]B
+Ô4çÝ@“Ènã‰Yj!S¼ÎEPxßX7ä]3%IH] µdKè8G-©£ªÛu©¨Vût@2ÔÚ{¢…±£& díˆid
+Ž,V“î[dÝ´è…‹Z³ øIÆ’(«2Ÿ§ˆN©šÃ+‡¢f¸·q ÖRèSÉÑߧûïê¿óîÚkzF7P Fx4<ž¢i §(ï6—(Ø|Ùü·~. ¹û·–ç¾¥Ñ?L}+±êLK|¯$|¢?mJ
+×ÊÅÓ/çz,3[A!âTaç}Y“"UîrÝSp°¸jÆzH¶žÐg[”Éí Õ0ðê'Úôä¬Õ發ƒaëñŠ¥Ï6¿%py[n·çà¼e2÷<ɘžŠ: ¬¨Þ+º`'YŽniÈhèÍ!ù:ï¡ÅJI@zÛ$J½,Òý\0ã“ä§ßi@T†ÄvÕ8¹ô ‘”‡”_ajðy_5{5ÄVœ
+‘2zP§Ê·D!†]Ûá X÷g·;–>£jÍýJÚÖåZå/m†u@$;8¸Í dàåKqŽ¿Ê½Ûƒ¶f>6£Êy÷Dl2µÃ™ÊñÛæÈÈØ9žð½áˆƒQò4Ǥj
+Š-W6Í@›ÜcèÆÚ2¾ —9v½ÁÛaZB°é‚Xµ™Ï›¼Ž­Ì¥ŒªcùO–ïòg¢ŒO&j¼y û>¤¶÷*ö#)Kó^ZÜYâA$¶QÌ2u%×3²'þ >ï4ú½Ý+V3÷¤ê£¥Vœé4>á% >%Œñ(Ó™Jˆfƒ–ÃÛˆ9XÏÒ®#^Ý61D ‚œLÂò*œÊ©ÊmÅ0ÓÕ1ŒQìßV'ž’H#Òö%.1A¨ÌØ¢ ]BèL`2„,Vø,öêýÄH)­:NS¨Ýζܾ'šoóÖl¼zaCçWì ¨Ä
+2l¢>©[A-Ð¤Ï ÅXœGcÖ¦°4ÙÅ°Úôí)Éµá “tMéŸÿ·¯©ë6\ãà9C’ö[×A™úqÁæÇÒiKª}e³näj¡é„è×¾¯³³á×Ì*…'´"¤ŒlÉ·DJA™ÂEj;ÉNy1Rézó!̬åÉΔÂÊŽñ…¨þÈ/"Ï¢éö™ÙÕ¨˜ÀœÏDa³ ºr§¡k$RÂæ-=…8¶<þUt„d¹&îô×ôªãs}±:XVÖË2mÝÚj”kÑħ?‰:\Úšjîä¾a‘èìá}R?Þ{¯1šÔÂaÏô»eÙ1Mâ
+Áhʃ Í•™z é­gï0eUÃ+¬Ì†œ¡oy
+Å|A¡æÑÔv>bñ9øµ^Üßi²b“‰ »Ãî€-þ{`¸7
+ÊB}ë'ŠçO¹MO/w˜j*Í:ØÔIâ’ÞW:M’á×R |ôW÷œD pI;
+o¢èŽ3ͺ爣!ŽW@óf¤Þפ¤”’îÀãêûx·jÅäÎmæ
+¡ƒPKó
+:»–âWõU}‹YkyIõôìÎǸÂeR±ý>@~õ\<”Je:Ë2®P!¿0l¥. žÐ/ÍÙåÁñõjMÿ]óÁÔÜ4¢ vI)+dC)òêÈ
+‚a9¬Ó³v®ò”PÉôëjÒv}«Q€¶ ‹²5» /ýU³¯þ
+óS!BjXG£pá6WΚ’Mæ”Ûß¿€b¯FKQoK‹bGLx‚€ÑŸÂ;ï[ g?äáÅM!Ö­I…þ‰¹Ew$ ðù§`¯ˆ¥Ûþþ÷õÐÊUê Î$Rê|(ýØì@ªÅí‡.p°}{0õjO½²÷Èq¦¾{ÃLmaz'Y¦+Ý÷È=Ö‰ ¸Ýr[÷׬ñä®feÉÀ¬gµhV.®2‰—ç**Ñaìûen´ý¡S-/§ÍN­yR”Çý;µÒa––šêˆñÑíÔˆbÜàŠ%!äy‰Ìmï—ç;7U…ÿû{ÊLí“x?'ÞFÊsbu–¯®·Tr—tàȈ/Cä¬'@amRVÚ A¯©9%"€Ÿtô¤þ³]õ”O5&[­n´K®£ú]ÂéŸÔ!lt#Aõ˜6BJ¤²­žQ¶ÛêHÔH8HãŸ_ˆ“1™#\vˆ ‡3ƒéžàW[>Ø~[ö Ïœ–Ö
+ðï£ËêÌ\†>ù…2;áÄz=Ù¶¨%nOìjòìû Ãekz0ŸîILx|B=ð"²šW²FgááôœÇ5õ0ÿ½Ç¹Š‡rê ©š‘[hv*lwýJòÞOôÀ—Áß÷N—èÚ•ºwFâ”Ms˜ò‡ø=K.–plù`zïóì&ð‰ØïygI³Ì’Åp€å6J5uGYÙQ¦mˆFp³µâÒ¬+0Ó¬3n)#™@' ¶ÚkZ¹…Iœ“"ܨy_åyÝ'â½%ª~`iŃ$áMÓÙvž‰ÄV·u$†Já´žŠrOTûÌæßç°'ÆßX3ÞEÝ(ÎRˆ›
+)ùZM?÷|/å÷û¤€Ó{ ´[2VË]W÷´e‚üíØîág ÆÒFÜx¦?+ûŠIcq\]ìTWIn$9¼ë:W'ùŒ~C3õ¡ûÿ‡±ÅJ¡€R:ƒÁpúbnfàCh[#Û—c²×˜âÅo¨|þHóœ%¬DÌÆÒ€**s’ 4ö¿¾‹¬)ÊÌ; ì]²à/¨5E‹ej6ÁÚ••Ej HØ:_imÃŽ¥Ó¦ 8²øÈbˆ$
+mŠ^*
+áîSÓ"KðŽ$A(«auEäÖ¬ãB±e=‘`YÚÞ‹ÈÀHÀÀ2!³RE¹¯.y/i¾wŠöJSâ`bx›oš…ßR¶A2Á\×\!‘ۉNj“6$3%—ìGæ^ÒŠåêN]h´ðÄaÄš^SkŠl{³°d²œf݉âˆ*ùI“d‰›/C7íî| ;MÈ󛵧`’óW:•úL©X$6rA+5b5ãÃK4m/‚6¾¿eNTK³Tõ´YšŒä¤kó–ÈZª0š~h7š¨å‹,áýQZJx
+ —;•­®v±{8ÜW3C´ÄÈš2R§T€Š¤&S£WR¬]f ìŠÍO‡_Ó½ÉÒð*ò<uŽ Õ·Š˜ÊúŽ/g @óˆ¼$pd€íP4ëM“~#¥T%÷Q ÉIÆù Wáɽ¨Q)]|1¨ùNõãÆI\ß‚×EÌ7cFËîhbŒLÐHÜY‘!GñúTˆ3:Þ ˜¾ŠPj¦³Ñ~h¢`E!Ô´óRr$"(£’0naʸ°'1,^жqçz¿’¼ÆA; ÑõP`›Ô“Š¶‘}7ÁE­zÜ*ZYƒ¿{ž;5ñ
+5Ã쪌ÿãIÀ•ÃÝd§¤3sh¾˜¹2ï7°@x^¿N‘Z{Mtí-ÎËã¶ô·:¦þ]¡Mì“=·lwò€™ž|Ÿâç·Ý~Ù@±>ž•(¡ÏãØ|ÌØZ˧#ä:\a6`GµÚoÍ“&^
+¶ߺP>•p
+Y÷dTƒÔ¾ ÝˆÌCÜ£~þNç]SöÌb¨vùï[EXù·NȈb‰²vsÐvç´žµ’»‡(8” »¢$¡ÞZz<R/ Fj¹‚Ž¸1!¥™Ãƒî"–3Ýœ]†æ ›¬€½%ô„C¯ˆ}¿ú,òði‘]HM:é†),l~¦;¤z>’3»:ïî®Ý¢OI^3]ã
+OEàÎi¹¥Z˹sÁæ}ƒO¯ ¥ýJ“ò &ò®ÈÞÍWgW<”]½„(k¬ÕøÉï1ÔJ¬Fæ¡x¡‹'a¡[í›MÔ›‹WüöB#2`²
+¿… 0L/"DP8òíIYþ!ÜÒEpï¨nðe{«]a ‚i—-{*>¸#Yt½0\Å}C{kƒ#sÍ7¦(vŽì¹±^$Ü ß#Xñs…rrßÁ'ÄWfsNT„¥²xÀõÛãø”ÈIû[v·Í­cY„Œœè•â%§
+½×î¥Eg`…-{ƒ €bA€â:wìz§ùA[—j‰n£Æ5
+ >kBÓÕ¤,1§Fý*í<U‡pnì ×Ve2¼8è°(kx(!C·Ëƒµ;>9³˜ ðy çþdÙSÏI9qO½1¤0M…ÊlÀ dëø £ ýÎ*å+G+²ÉwfI{¹ƒTÝ7¨c¹y&£Šo‰o˜¢³y¦p ×qÂ&ÌÁ6 ÌÐKجÍÆ
++ýîà#§(´ß˜ys¢:a?É„ÌÀ Fï3„™ÀøA|€ÂN¤´„<øËNd­ cXŠ{«ÉH‡¬Usá[ ßälû
+Sõˆz(¸Ì~<Dé@/Ðäh²°aòX˜é.Rp,4Xø‹^?2:˜óѧ'b*¢©íãüŸñ2Çr䂨ߧàØûbëÉÔ=ÆhÝßUüHT‘É1Ó
+WIU^å(/êø¼«2#
+LW~a]Zp´óÙ)Üûµ¾«–ÑÔXl±µºá”ÎfŠ—Â&?–²¦‚— Wû% CkÊžíõÅÁ¤6„¬®UblŸoÔS IËÙ·½1š‰Hœ§‰ëYš‘dÚû’ Åø*ë<Q™„
+L—Ì-î Ï5«c'O×N¡¥#x¤d¾¨<Ý¥r‡68#?1‚î •Š¨¢3Øî³òÁÄ_¯0¤Ê,ÈýŠÛIÓ¦:v´%†È¯ R*(Yžz(Wä›:FG%'Á·Þϧ{à'*õÚ†d™ Í%w@å~6\ç‰98ùc 4+¨¥;\MUÀ}•Ñ“Ø\!aNÄqÛ« Ɇ}»)EÌGQ縑(‹T{V
+žcŸ(`9üVï´JA¸tk¶ð:Ø2#¥ËêýõÂ?`&J&G´P¯;â§Ý%µ±¼…zÚ!lg H”æà²X~Ö5_¼ü:,ܯò®{å6”ÿÍarƒ‰) }¼L³TÔ‰Œ^‚ÇT¤ÉvwDï!NŽkh)®@‘\È/µz]¹½Ç€Ö1°‡ç;fÃÊrÁ`k²¹È{‰x+ëªH5P‡ólÑ ¡æã¡P¯–›–›Ò)ÁEïcÄžá%X¡XÉYZèNð͈žåYˆûǸËRÑ®ªcRnk›”¼`§pª›á…£^,V‚Ï¥j­z”vµ$«ÓˆözY·h§‰ÓºózZ$I¾D„:¢Ã8f í\£…ªŽj…¿õ¢rs]rEËQÉŸ)‚£; UÜ"Ž£
+&«~ÙsTÕYXN)Óí‡àw©L59\‘­ZÊ»#eÉûÿiÝhS…@– æžw?ª£¸eªƒ?„hø‡òy®ú××^ÇcÕ*ïï¯-~£2 Űѵ3 âfÓÁlÊMéID¡‘²Q¡JÊîô±´ÖÀK
+èµ(70ciö®ˆÀÁ,|,”ªwu äki|©ÂN¢%8ø»óéæJI€n@<P¯Ú"'¢Ti¤DPž«ÀéßCû‘æ©{;‰=[ç°‡aºÆ8¨†Ý&†’®ýÍÊ:µ„N$˜‡¬en?s¸Ñ4kÓìj<CY°td­?¯l¯ýéxË•Ýb*Ú lçíèV†“ËÓ­Ì5™QÙÓ@ù*s‡He vÛ´Öð²`?pgýJþ Ç—*QDð­åü+È“ŠÝ°,o„}3ec„È¿–×Éõž!X ¸Âk(Ç'ª²hé‚ØøR/P½ñã
+"±¨å@ÉEdÜ0sU] ÅÁè«^Ÿ¥(q3òB󅆈d¸­äuBRjÉ«PÏ2³P ds
+òd&»UNÞ±É
+Cnߤ%SYPÝjà#qx7ý±¥xŸ…©ÑàPN3¥"X9Ãhá€â1ßÖkµ·<˜i€Ø"Àlc&Íâä,u×Ê«ÎûD&è?ÙIÉ©?“îq~»ñ]Çt¾÷ý©¼mømÔƒ0ï&±É°M”«¶×°½ÖQ[ý³„¥{XºÄ6 |Ó\Õçð£ŠEÂÏD䈨K×ìÚ†Ëo>šAk?"ûæñ¥îæýÿWÂHéÂã;¡ßL®8ˆ
+——È6—GPô/+ÄÇSŒœ™ŒŸý”5ßQõ×O<µñYwÔÎÏ“Sˆ5PŠÚð‰àä¾ç³–¬o87—m¿®Ýµ»
+ÕX»ÎÚŒ‘Ù™ôÐí!ÖÞ2ç (µE1ËË®F°)]<kÝK®çóõˆÔïçký½j0ÿ¸j̼§‘©‡¯•X׈ì†êVA$ŒÐ¡µÉ5ZœœŽÔVÚ…}Ñ'nHs%’:Ø+ÖæÌVMpü°–hø•‹ 5äÑn9Óí=‹w«ÕOŽ2­n6¦Sè®hœ¼ôÜÍŒe׎Çì°ü–U-ÄW°pí†Ý ÄK‚*žö e£‡.%®ÉÆØFgq:©Z,Iy‹4AÌ‚ X5-áˆe¾{Ú_y^1øhÐÚ:dÕ…ÆâíNGl!mÏkĸ æ+òâÚ¢ £8à~ôÛ4ä¶À7(&27#úÔ?“W´hÇ"¹BMÉ“^P]Žî)}­\Ù]ß„Ï¢)‘k3b¡û,ßxáf ©yÿÿ3Ћ}>¹Èük!ŸíGí
+®e'ñ,ó®yb*<¹ªT9É=£bÑ.eë'w’´«³ÄU45s" ŸªM¼E<,nQÇÅ_ã æ­DýŽ“332w¬³ËðÄý×)z‘˜Yíw_a´Øµ»Ò!ì.í8 ÉկㅓHZn±CtÓ”f¨—¾@°×zQ60â©úÙ}¿Ÿ¯§>ua~{BàþÞ¾è–Ïa–R@´ušŸñ¤KUÅsm6S¶Pþ³ü‡_㊂'J}\á቙åUt$‡}E¦üù×ýùG€
+endstream endobj 12 0 obj <</BitsPerComponent 8/ColorSpace 13 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 78/Length 547/Width 78>>stream
+8;Z]!9od(E%#*"aLD`#4/s&MC)W/Te);B01g+o\WXAE56+[A/<H$2`8QBmi&QBmh#
+$aZ^tM4N1FZN;ub:Pba%ma;Ef4$p<c7jl'3XmW^4#igi2C9`1,1lE`E'Sjn)>-U_\
+?RLs^[K3u6/hnl@,QWY@nuRNVO@qdrDns'>110qt)BituYkdKT9#qa9K`oQ\Ei\dH
+p>XTS%"@#GgcS62Xi0?mY0L,.JW;?/2o(a.MJ[O^jQ_+q+&Q6>P`g*_786DRj%bcL
+l;g]WZ#"hm6'HAr"[$'S[W3i._j5<GS[f?@j1GtMHYUYC:P*cBG>eIa9l;]K8aY]C
+Q!QSeH)#iFRM%Ac]50t0-9,P5P'O\-p*i!Ib]HX9></[%9MI#3DMH@>mEF79(GDt]
+VP\FbVO!DJni];V)6Z!OUm39?G!>0(W@+tWX8I.&([j=`DrrhYYe+sP=1::]pLH06
+Uc,jCUt[3IA1+fL2kjSu@*e%+kB1;5PiU9i-Fj/dK5@#:`-,UVRl\HGa:?oD1\#gF
+a#(-!V/Of>!,P5Hq>~>
+endstream endobj 13 0 obj [/Indexed/DeviceRGB 255 14 0 R] endobj 14 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>
+endstream endobj 5 0 obj <</Intent 15 0 R/Name(Layer 9)/Type/OCG/Usage 16 0 R>> endobj 6 0 obj <</Intent 17 0 R/Name(Layer 6)/Type/OCG/Usage 18 0 R>> endobj 17 0 obj [/View/Design] endobj 18 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>> endobj 11 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 10 0 obj <</LastModified(D:20141208091002-04'00')/Private 19 0 R>> endobj 19 0 obj <</AIMetaData 20 0 R/AIPrivateData1 21 0 R/AIPrivateData2 22 0 R/ContainerVersion 11/CreatorVersion 15/NumBlock 2/RoundtripStreamType 1/RoundtripVersion 15>> endobj 20 0 obj <</Length 979>>stream
+%!PS-Adobe-3.0
+%%Creator: Adobe Illustrator(R) 15.0
+%%AI8_CreatorVersion: 15.0.0
+%%For: (PHLASH) ()
+%%Title: (vector-src.fxg)
+%%CreationDate: 12/8/2014 9:10 AM
+%%Canvassize: 16383
+%%BoundingBox: 213 -537 538 -184
+%%HiResBoundingBox: 213.5 -536.6816 537.3232 -184.3252
+%%DocumentProcessColors: Cyan Magenta Yellow Black
+%AI5_FileFormat 11.0
+%AI12_BuildNumber: 399
+%AI3_ColorUsage: Color
+%AI7_ImageSettings: 0
+%%RGBProcessColor: 0 0 0 ([Registration])
+%AI3_Cropmarks: 0 -626 626 0
+%AI3_TemplateBox: 312.5 -312.5 312.5 -312.5
+%AI3_TileBox: 7 -709 619 83
+%AI3_DocumentPreview: None
+%AI5_ArtSize: 14400 14400
+%AI5_RulerUnits: 2
+%AI9_ColorModel: 1
+%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0
+%AI5_TargetResolution: 800
+%AI5_NumLayers: 2
+%AI9_OpenToView: -258 71 1 1140 742 26 0 0 354 173 0 0 0 1 1 0 1 1 0 1
+%AI5_OpenViewLayers: 77
+%%PageOrigin:7 -709
+%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9
+%AI9_Flatten: 1
+%AI12_CMSettings: 00.MS
+%%EndComments
+
+endstream endobj 21 0 obj <</Length 17417>>stream
+%%BoundingBox: 213 -537 538 -184
+%%HiResBoundingBox: 213.5 -536.6816 537.3232 -184.3252
+%AI7_Thumbnail: 120 128 8
+%%BeginData: 17259 Hex Bytes
+%0000330000660000990000CC0033000033330033660033990033CC0033FF
+%0066000066330066660066990066CC0066FF009900009933009966009999
+%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66
+%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333
+%3333663333993333CC3333FF3366003366333366663366993366CC3366FF
+%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99
+%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033
+%6600666600996600CC6600FF6633006633336633666633996633CC6633FF
+%6666006666336666666666996666CC6666FF669900669933669966669999
+%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33
+%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF
+%9933009933339933669933999933CC9933FF996600996633996666996699
+%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33
+%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF
+%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399
+%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933
+%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF
+%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC
+%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699
+%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33
+%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100
+%000011111111220000002200000022222222440000004400000044444444
+%550000005500000055555555770000007700000077777777880000008800
+%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB
+%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF
+%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF
+%524C45FD33FFA8FFA8FFA8FFA8FD6AFFA8FFFD0FA8FFA8FD64FFA8A8A8FF
+%A8A8A8FFA8A8A8FFA8A8A8FFFD05A8FFA8FD5EFFFD1BA8FD5CFFA8FFA8FF
+%A8A8A8FFA8FFA8FD0BFFA8FFA8A8A8FFA8FFA8FD58FFFD07A8FFA8FD0FFF
+%A8FFFD07A8FD54FFA8FFA8A8A8FFA8FFA8FD17FFFD05A8FD52FFFD07A8FD
+%1BFFFD05A8FD52FFA8FFA8A8A8FD1DFFA8A8A8FFA8FD4EFFA8FFFD05A8FD
+%1FFFFD05A8FD4EFFA8FFA8A8A8FD0BFFA8CFA8AEA8CFA8AEA8FFAEFD0CFF
+%A8A8FFA8FD4AFFA8FFFD05A8FD05FFA8AE83837C827C8257825782578257
+%8257827C8282A7A7AEA8FD05FFFD05A8FD4AFFA8A8A8FD04FFCFA7A7FD1B
+%82ADA8FFFFFFCBFFA8A8A8FD48FFFD05A8AE838257827B8257827C827B82
+%7C827B827C827B827C827B827C827B827C82578257827CA7A7FFFD05A8FD
+%46FFA8A9A8AEA7837BFD23827B8282A7A8FFA8A8A8FD44FFA8A9A7837C82
+%578257827C8257827C8257827C8257827C8257827C8257827C8257827C82
+%57827C8257827C8257825783FD04A8FD45FF83FD2E82AEA8A8A8FD42FFAE
+%A77C827C827B827C827B827C827B827C827B827C827B827C827B827C827B
+%827C827B827C827B827C827B827C827B827C8282FD04A8CFFD3FFFA7FD33
+%82A7FFA8A882ADFD3DFF828257827C8257827C8257827C8257827C825782
+%7C8257827C8257827C8257827C8257827C8257827C8257827C8257827C82
+%57825783A8A8A8A75782A8FD39FFAEFD3782FFA8FFA883828283FD36FFCF
+%8357827C827B827C827B827C827B827C827B827C827B827C827B827C827B
+%827C827B827C827B827C827B827C827B827C827B827C827B827C82A7A8A8
+%A87C827C827CFD34FFA8FD3A82A7A8FFA8A77B8282827CCFFD31FFA78257
+%827C8257827C8257827C8257827C8257827C8257827C8257827C8257827C
+%8257827C8257827C8257827C8257827C8257827C8257827C82578282A8A8
+%A8838257827C8257A7FD2FFFA7FD3C82A7A8FFA8A8FD0782A7FD2DFF8382
+%7C827B827C827B827C827B827C827B827C827B827C827B827C827B827C82
+%7B827C827B827C827B827C827B827C827B827C827B827C827B827C827B82
+%82FD04A88257827C827B825783FD2BFFA7827CFD3B827C82A8A9A8AEFD08
+%825782FD29FF83827B8257827C8257827C8257827C8257827C8257827C82
+%57827C8257827C8257827C8257827C8257827C8257827C8257827C825782
+%7C8257827C8257827C827CFD04A882578257827C8257815782FD27FFA7FD
+%408283A8FFA8FFFD06825782578257A7FD25FFA78257827C827B827C827B
+%827C827B827C827B827C827B827C827B827C827B827C827B827C827B827C
+%827B827C827B827C827B827C827B827C827B827C827B827C827CFD04A883
+%7B827C8257575782575757A7FD23FFA8FD428283A8FFA8A8FD0482578257
+%825782578257A7FD21FFAE8257827C8257827C8257827C82578257827C82
+%578257827C8257827C8257827C8257827C8257827C8257827C8257827C82
+%57827C8257827C8257827C8257827C82578282FD04A88257825757578157
+%575781575757A8FD20FFA77BFD0E82A8A8FFA8CFFD2F82A7A8FFA8A88282
+%57825782578257825782578257FD1FFFAE57827B827C827B827C827B827C
+%8283FFA8A8A8FFFFFFA7827C827B827C827B827C827B827C8257827B827C
+%827C837C837C837C837C827C827C8257827C827B827C827B8283A8A8A9A7
+%82578257575782575757825757575D58FD1DFFCF7CFD0D82A7FFFFFFA8A8
+%A8FFFFFFA7FD0F827CA77DA87DA87DA87DA87DA27DA87DA87DA78383FD08
+%827CAEFD04A85782578257825782578257825782578183FD1CFF82825782
+%7C8257827C8257827C827CFFFFFFFD05A8FFFFFF7C827C8257827C825782
+%7B827C83FD167D7C827B8257825782FD04A87CFD04578157575781575757
+%81FD0457A7FD1AFFA7FD0D827BAEFD04FFA8A8A8FD04FFAEFD0982837DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA27DA87DA7FD048283
+%FFA8FFA882578257825782578257825782578257825782FD19FFA8827C82
+%7B827C827B827C827B827C82A8FD05FFA8A8A8FFFFFF83827C827B827C82
+%7CA7FD1F7D827CFD05A85782575757825757578257575782575757825783
+%FD18FFA757FD0E82CFFD04FFFD05A8FFFFAE7CFD058283A87DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7E7DFD04A8
+%FF838157825782578257825782578257825782578257FD17FFAE57825782
+%7C8257827C8257827C825782A8FD05FFFD04A8FFFF8382578257827DA8FD
+%237DA8A8A8A78257575781575757815757578157575781FD04577CFD16FF
+%FD1182ADFD06FFA8A8A8FFAEA7828282A77DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D7D7DFFA8A8A8A757
+%825782578257825782578257825782578257825781A8FD14FFA8827C827B
+%827C827B827C827B827C827B827CFD05FFFD05A8A7828257A7FD257DFD05
+%A87C8257575782575757825757578257575782575757825782FD14FFA77B
+%FD1282FD05FFA9A9A8A9A78282A77DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DFD04A8FF7D7E7C8257
+%8257825782578257825782578257825782578257AEFD12FFCF578257827C
+%8257827C8257827C8257827C8257827CA7A8FFA8AEFD04A87C83FD257DFD
+%05A8FD047D7C8157575781575757815757578157575781FD04577CFD12FF
+%A7FD1682A783A782ADA8FFA8A87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8A8FFA8FFA8A87DA87D
+%A87D825782578257825782578257825782578257825782A8FD10FFAE827B
+%827B827C827B827C827B827C827B827C827B827C8257827C8257A7A8A8FD
+%107D7CFD147DFD06A8FD067D7E7C57578257575782575757825757578257
+%5757825783FD10FFCF7BFD1C82A87E837DA87D7D7DA87D7D7DA87D7CFD05
+%577C7C7E7DA87D7D7DA87D7D7DA87D7D7DA87DA8A8FFFD04A87D7D7DA87D
+%7D7DA87C815782578257825782578257825782578257827CFD10FF838257
+%827C8257827C8257827C8257827C8257827C8257827C8257827B82FD0C7D
+%58572D5751FD0657FD0E7DFD07A8FD0A7D57575781575757815757578157
+%575781FD0457A8FD0FFF83FD1C827DA87DA87DA87DA87DA87DA858FD0457
+%8257825782578158A87DA87DA87DA87DA87D7D7DA8A8FFA8FFA8A87DA87D
+%A87DA87DA87DA87D8357825782578257825782578257825782578257A7FD
+%0EFFCF7C827B827C827B827C827B827C827B827C827B827C827B827C827B
+%827CA8FD097D7E58572D5757815782575757825757587EFD097DFD07A8FD
+%0E7D57825757578257575782575757825757578158FD0EFFA7FD1C82A87D
+%7D7DA87D7D7DA87D7D7DA87C7C5782578257825782578257827DA8FD057D
+%A8A8FFA8A8A8FFA8A87DA87D7D7DA87D7D7DA87D7D7DA87D825782578257
+%82578257825782578257825782A8FD0DFF8357827C8257827C8257827C82
+%57827C8257827C8257827C8257825783FD0B7DA8A8A9A8A77C82FD09577C
+%FD057DFD07A8FD127D7C575781575757815757578157575781575757A8FD
+%0DFFFD1C827DA87DA87DA87DA87DA87DA8A8FFA8FFA8FFA8A883A782837C
+%8382A783A8A8FFA8FFA8A8A8FFA8A87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA858825782578257825782578257825782578282FD0CFFA88257
+%827C827B827C827B827C827B827C827B827C827B827C827B827CA8FD0B7D
+%83A8CBFD07A8CBA8A8A8FFFD0CA8FD167D57825757578257575782575757
+%8257575782FD0CFFCFFD1B82A77D7D7DA87D7D7DA8FD047D577C83A8A8CB
+%A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8FFFD04A87DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7DA87D7D7DA87D825782578257825782578257825782578157
+%FD0CFFA7827C8257827C8257827C8257827C8257827C8257827C8257827B
+%82FD0C7D58FD0457837DFD0FA8FD1B7D7E7C575781575757815757578157
+%5757815757A8FD0BFFAEFD1B82A87DA87DA87DA87DA87DA87D83577B5782
+%5782578282A783A8A7A883A8A8A87DA87D7D7DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87D835782578257825782578257825782
+%578257AEFD0BFF82827C827B827C827B827C827B827C827B827C827B827C
+%827B827B83FD0D7D58578157825757578157575781575757A8FD217D7C57
+%8257575782575757825757578257577DFD0BFF837CFD19827DA27DA87D7D
+%7DA87D7D7DA87DA2585757825782578257825782578257A77DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87C81
+%57825782578257825782578257825783FD0BFF828257827C8257827C8257
+%827C8257827C8257827C8257827C8257A7FD0E7D51FD0457815757578157
+%575783FD247D575757815757578157575781FD04577CFD0BFFFD1A82837D
+%A87DA87DA87DA87DA87DA87DA87DA87C81578257825782578157A77EA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87D8257825782578257825782578257825782FD0BFF7C827B827C82
+%7B827C827B827C827B827C827B827C827B827C827CA8FD107D7C7C578157
+%5757827C83FD267D575757825757578257575782FD045758FD0BFFFD1A82
+%837DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D837C837C837DA87D7D7D
+%A87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7D8257825782578257825782578257825782FD0BFF57827C82
+%57827C8257827C8257827C8257827C8257827C8257827CFD167D7EFD2A7D
+%5781575757815757578157575781575757FD0BFFFD1A82A77DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D82
+%57825782578257825782578257825782FD0BFF7B827C827B827C827B827C
+%827B827C827B827C827B827C827B827CFD417D5781575757825757578257
+%575782575757FD0BFFFD1A82A77D7D7DA87D7D7DA87D7D7DA87D7D7DA87D
+%7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7D
+%A87D7D7DA87D7D7DA87D7D7DA87D7D7DA27D825782578257825782578257
+%825782577CFD0BFF7C8257827C8257827C8257827C8257827C8257827C82
+%57827C827C7EFD3F7DA8575757815757578157575781FD045758FD0BFF83
+%FD1982A77DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87D7D7DFFA78257825782578257825782578257825782FD0BFF82
+%827B827C827B827C827B827C827B827C827B827C827B827C827CA8FD3D7D
+%A8A8A7575757825757578257575782FD04577CFD0BFFADFD1A827DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DFFA8FF
+%7C81578257825782578257825782578257A7FD0BFF83827C8257827C8257
+%827C8257827C8257827C8257827C8257827CFD3C7DFD04A87C5781575757
+%81575757815757578157577DFD0BFFCFFD1A827DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DFFA8FFA8A858825782578257
+%82578257825782578257AEFD0BFFA8827C827B827C827B827C827B827C82
+%7B827C827B827C827B828183FD397DFFA8A8A8FF7D585782575757825757
+%5782575757825757A8FD0CFFFD1B82A87DA87D7D7DA87D7D7DA87D7D7DA8
+%7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA8FD057DFFA8FFA8FFA8835782578257825782578257825782
+%578257FD0DFF8257827C8257827C8257827C8257827C8257827C8257827C
+%825782FD377DFD07A852815757578157575781575757815757577CFD0DFF
+%83FD1A82A77DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D7D7DFFA8
+%FFA8FFA8FF7D7C578257825782578257825782578257817CFD0DFFAE5782
+%7C827B827C827B827C827B827C827B827C827B827C827B827CFD347DA8A8
+%FFA8A8A8FFA87D5782575757825757578257575782578157A7FD0DFFCF82
+%7CFD19827D7E7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DFFA8FFA8FF
+%A8FFA8FFA88257825782578257825782578257825757A8FD0EFF82825782
+%7C8257827C8257827C8257827C8257827C8257827C825783FD317DFD0AA8
+%FF835757825757578157575781FD0557FD0FFFAE7BFD1A82A77DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA782578257
+%8257825782578257825783FD0FFFA88257827C827B827C827B827C827B82
+%7C827B827C827B827C827B827CFD2E7DFFA8A8A8FFA8A8A8FFA8A8A8FFA8
+%CB7D815757578257575782FD0457A8FD10FFFD1C827D7E7DA87D7D7DA87D
+%7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7D
+%A8FD047DA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF8382578257825782
+%5782575757FD11FFAE578257827C8257827C8257827C8257827C8257827C
+%8257827C825782FD2B7DFFFD11A8A97DFD045781575757825783FD12FFFD
+%1D827DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA8
+%7DA87DA87DA87DA87DA87D7DA7FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF
+%A8FFA8FF83815782578257825757A8FD12FF83827B827C827B827C827B82
+%7C827B827C827B827C827B827C825782577CFD277DA8A8FFA8A8A8FFA8A8
+%A8FFA8A8A8FFA8A8A8FFA8A8A8FF7C575782FD045758FD14FFFD1A825782
+%57837DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D
+%7DA87D7D7DA87D7D7DCFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF
+%A8FFA8FF82815782578257AEFD14FFA7578257827C8257827C8257827C82
+%57827C8257827C8257825757578157FD247DFD1AA8A958575782577CFD15
+%FFCFFD178257825782578257837DA87DA87DA87DA87DA87DA87DA87DA87D
+%A87DA87DA87DA87DA87DA87DA87DA87DCFA8FFA8A8A8FFA8FFA8FFA8FFA8
+%FFA8FFA8FFA8FFA8FFA8FFA8FFA87D57825757A7FD16FFA7827B827C827B
+%827C827B827C827B827C827B827C82578257575782575757FD207DFD08A8
+%AEA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFFD04A85857575758FD18FFFD12
+%827C8257825782578257825782577C7DA27DA87D7D7DA87D7D7DA87D7D7D
+%A87D7D7DA87D7D7DA8FD057DA8A8FFA8A8A8FFFD05A8FFA8FFA8FFA8FFA8
+%FFA8FFA8FFA8FFA8FF7D7C578257CFFD18FFAE578257827C8257827C8257
+%827C8257827B7B578157575781575757815757577CFD1B7DFD0BA87DFD12
+%A87D57815083FD1AFFA77BFD0F825782578257825782578257825782577C
+%7DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87DA87D7D7DFFA8A8A8FF
+%A8A8A8CFFD07A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A87C82577CFD1BFFAE
+%8257827C827B827C827B827C825782575757825757578257575782FD0657
+%58FD167DFD09A87DFD08A8FFA8A8A8FFA8A8A8FFA8A8A8FF7E7C5757A7FD
+%1CFFAE827CFD0B8257825782578257825782578257825782577C5757577D
+%7DA27DA87D7D7DA87D7D7DA87D7D7DA87D7D7DFFA8A8A8FFA8A8A8FFFD0B
+%A8FFA8FFA8FFA8FFA8FFA8FFA8A858577CFD1EFF838257827C8257827C82
+%578257575781575757815757578157575781FD0657515858FD107DFD0DA8
+%7DA8A8A87DA883FD0DA87C5757FD05FFA8FFA8FD18FFFD0A825782578257
+%8257825782578257825782578257825758577C575757827D837DA87DA87D
+%A87DA87DA8A8FFA8FFA8A8A8FFA8A8A8FFA8A8A8FFFD09A8FFA8FFA8FFA8
+%FFA8FFA87C57FD05FFA8FFA8A8FD19FF7C827C827B827C7B578257575782
+%57575782575757825757578257575782FD095758587D7D7D7C7D7D7D7CA7
+%7D83587C57577DCBFD0EA87DFD04A8FFA8A8A8FFA8A858A8A9FD06A8FF7D
+%FD1AFFFD04827C8257825782578257825782578257825782578257825782
+%57825757577C575757585757577C5757577CFD09575883FFA8A8A8FFFD0D
+%A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD1AFFCF578257575781
+%5757578157575781575757815757578157575781FD1E577DA9FD0AA87DA8
+%A8A87DFD13A87DFD1BFFCF82825782578257825782578257825782578257
+%8257825782578257825758577C5758577C5758577C5758577C5758577C57
+%58577C5758577C83FFA8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8
+%FFA8FF7DFD1DFFAE57575782575757825757578257575782575757825757
+%578257575782FD1C5783A9FD08A8A7FD08A8FFA8A8A8FFA8A8A8FFA8A8A8
+%FFA87DA8FD1DFFAE57815782578257825782578257825782578257825782
+%5782578257825757577C5757577C5757577C5757577C5757577C5757577C
+%5757575883FFA8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8A87DFD
+%1FFFAE575757815757578157575781575757815757578157575781FD1E57
+%51577DFD09A87DA8A8A87DA883FD0DA87DA8FD08FFA8FD18FF5782578257
+%825782578257825782578257825782578257825782577C577C5758577C57
+%58577C5758577C5758577C5758577C5758577C575783FFA8A8A8FFA8A8A8
+%FFFD07A8FFA8FFA8FFA8FFA8FFA8FFA8A8A8FD05FFA8FFA8FFA8FD18FF58
+%FD0457825757578257575782575757825757578257575782FD1E577DCBFD
+%0EA87DFD04A8FFA8A8A8FFA8A87DFFFFFFA8FFA8A8A8FFA8A8A8FD18FF82
+%815782578257825782578257825782578257825782578257825757577C57
+%57577C5757577C5757577C5757577C5757577C5757577C57577DFFA8A8A8
+%FFA8A8A8FFFD09A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8A8
+%FD18FF837B575757815757578157575781575757815757578157575781FD
+%1E577DA9FD0AA87DA8A8A87DFD18A8FD18FFCF8257825782578257825782
+%5782578257825782578257825782577C5758577C5758577C5758577C5758
+%577C5758577C5758577C5758575883FFA8FFA8A8A8FFFD0BA8FFA8FFA8FF
+%A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8A8FD1AFFA7FD055782575757825757
+%57825757578257575782FD20577DFD12A8FFA8A8A8FFA8A8A8FFA8A8A8FF
+%A8A8A8FFA8A87DFD1CFF7C81578257825782578257825782578257825782
+%57825757577C5757577C5757577C5757577C5757577C5757577C5757577C
+%FD045783A9A8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8
+%FFA8A8A8FD1CFFA7825757578157575781575757815757578157575782FD
+%1C572C577CFFFD0EA87DFD14A8FFA8A8FD1EFFAE7C825782578257825782
+%57825782578257825782577C5758577C5758577C5758577C5758577C5758
+%577C5758575757A7AEFFFFFFA8FFA8A8A8FFA8A8A8FFFD09A8FFA8FFA8FF
+%A8FFA8FFA8FFA8FFA8FFA8A87DFD20FFA883575757825757578257575782
+%57575782FD185751587DFD07FFFD10A87DFD04A8FFA8A8A8FFA8A8A8FFA8
+%A8A8FFA87DFD23FF8382575D5782578257825782578257825782577C5757
+%577C5757577C5757577CFD0557587CAEFD0AFFFD05A8FFA8A8A8FFFD09A8
+%FFA8FFA8FFA8FFA8FFA8FFA8FFA8A87DFD25FFAE7D82575756FD04578157
+%575781575751FD0B572C5751587CA8A8FD0DFFFD0CA87DA8A8A87DFD0FA8
+%7DA8FD29FFA8A77C825782575757815781FD0B577C58A7A7FD14FFA8A8FF
+%A8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8FFA8A8A8FD2EFFA8A883837C83
+%7C7C58827C7C7C837DA7A7CFCFFD17FFFD13A8FFA8A8A8FFA8A8A8FFA8A8
+%7DA8FD5AFFA8A8FFA8A8A8FFFD0BA8FFA8FFA8FFA8FFA8FFA8A8A8FD5AFF
+%FD1BA8FF7DA8FD5BFFA8FFA8A8A8FFA8A8A8FFA8A8A8FFFD05A8FFA8FFA8
+%FFA8FFA8A8A8FD5CFFFD10A87DFD04A8FFA8A8A8FF7DA8FD5DFFFD05A8FF
+%A8A8A8FFA8A8A8FFFD05A8FFA8FFA8FFA8A8A8FD5EFFFD10A87DFD07A87D
+%FD60FFA8A8A8FFA8A8A8FFA8A8A8FFA8FFFD05A8FFA8FFA8A8FD61FFFD13
+%A8FFA87D7DFD62FFA8A87DFD04A8FFFD08A87DA87D7D7DFD65FFA87DA8FD
+%0B7DA87DA8A8FFFFFF
+%%EndData
+
+endstream endobj 22 0 obj <</Length 31053>>stream
+%AI12_CompressedDataxœì½gW#ÉÒ0¸Ÿçþƒ4^Ryƒ áMãhL  FHBcžûÛ7"2«*«TNfžwÏÞ9—–Ri##ÃGæ·ìÉYnã¹ùXÍ©y)3öÇ·oÅvµÒm¶3TœÙ­×¿:Ý6ÍœÎfd=/a­]ë×¼¬¶;µfc‘~c¿–±ýÌÉÎÁÆÙÎlffËÎkÝzJÿ¬>A£\§ý”ùûuÖº(UºPCV
+VA‘d-c/ÊRfãªTV:Úÿ`CµT,Ül~5žk×Íæß‹EV39]53ºjer²¥aÚiµ¬–×±¢‘7,Ù€Úf^UT…šÀ']Áv¥æÓ×GµÑ=i7ŸªN±Yo¶;‹™â?•Fæ°ò
+¿T2×Õz½ùWf³^yz‡6»úC¹V¯ÂÚ?*ÝŒ,(6veåaó«V>úúx¬XTÛ¦rõz½è@wÐ3~¦róa÷ŠÎªÝ.Ì%ˆžnoŠsRúoæçiõµFûð»›uzn7[•ö;¶Îä ÅÈàÿ%þëyõ£UP<TYAx°Ä/NeXU439S²3†lgúø£¦êŸµê_‹™£f£Êa±Ñîž±íÒ4IbùO§_õjû¢QëÂü*³0›ÏÕ:´ðº(×+úOöþòç•ökµ {ܬu -w
+ÿ¾à¿ùJ­5›Ð¾T}CâuÀJ·Vë͖б[Ri<g~TÚ­4ŸÔ+J;C?¸}Ôþ„_*°B¯w¯,U·°Ñ- ]Ԉꆈ© ü”f¨óvå 6"süøA{^
+2/I64Î<¯6°ì|û¿íÁ§ßPöW¤»ÃÌÏ;)ó<?B·4Æ3L“‘ꥱ?2X~ %˜„'Cî¤RnYÅQ¥ÌÉcúyå*’
+]ý_N9t,OÚ‘û@`ŒøöPp
+§ðkí ÁSiÿà ®Ž@¶‹øy)3ó÷G½rpøڵǯnÖUÞh·+ÿ«ÝŒh¡ÞÓÈÿíjƒ×R2…]
+~)×›Íöe¥Që¼P©A
+Óžé·¾)$L÷å¥SuÀ+GÒ%<EPMšJô všÀ&›Ѥ FÖÆŽaDäíRæÅUa€¯×kj¦Óm7ß]ý<©vÚÿ–Qcx=÷­Ûm-
+N¾‚(ù§æGáåïׂ"IVVRm7*õtæœt=õÈ" Ÿêµèéø¤—W€V'¡IË$šVÛ- @p[H‚!6i“X•c±Å™ÇJ]`cî0 #ŸTÚ°B¨Ú9)•1Bø–OH ¯Œ5aRA²÷¤;_ͳ¯G8å&Ìùyâ~õŸÀÆúªÿx«=½´›/µzÕ«*…UÝúx¬>÷T]ÂY<5ÛÏÕç"S8jvý¿» ìááJ+0U’Ô¶NÎ2Ç=!l’Íᘕ³Èƒå«vî(a0V%8VÒŠh¼WøÝ|l­×Em2¼ U©×{ÎWOEOAÌ~Mê°ó^k=þ½ÏÆO¯]……vª¸vÊ9:¸™™^ÓI°©ÓDœù’+°cÕ^óCÙ2åP͈ tß<ý·Ñôk¦Ö f—(…›Ÿ»í}œ­©åŠHYŠœ²œú(‹©Š©]…KF6ýôAÔíXõívå¹†Ú 3e/V½c­B‰­H êi%÷@6f½•ÃOY2pYë8èŠcµÓƒŒÕïf¬Y
+  B
+úi1:`F T9¦ê"|±ôq½ƒÈY%^å\zFètëç!™É`Šíxa³Ò4j=#üêôój=§ïžíŸ×$ü賩an#—nºš]— Å°fVµ-0»Í*3/~2ŸmŠvN¬*Ç?W;µ×†è
+Ã>Wâä>üØ>©¦ˆÐ±+ÇZ÷£G‹°.«Ô
+bQüÈ3ˆ6]ôDÅM«ºZÂ#¦Í:»¥D1ÐfEÊJÒ æ PØ·fûËVDµwÎ&J0Ïz¥•BDáã„
+âÍÕ2¦<SŒ›Ó¡¶6M#ؾ.fZ;ÓÉ+zèIÀºpÒQ“áÓGõ·zbR½¶“(® Oé±ÒîÄÒWú3–L9|µ=ê‘¢rÛ/,'U÷Q#²>¥afž¢¶@÷’+‹3OQÝ7óPÙͷЯNµÔ|Úįq§› —­öK³KHœ šÓ"*I Haª!û´{¨)©aU_S6”Ú]ëö«Â+2«r’å'¡Ò'“´¸ºÞ‰¥©(Ï0si³ûkIª>}üãÐ^¿1héeÒ=ÏíIíïjý¤Ú~©öÖì1.¾5ÿÚ©=‡˜çÏ*VAܨµêÕ€}+Ñ–ºÃ¸œ“R™Ý(PjþÕ`qö=fE c­éN†Ç¦«©Im›ñ~­ñ³1Q;UDËtìb·Û•^«¿qÏRãæŒM£§Óð°Ùh>½µ›UodNáç<®qÏšµX€a1kÖR¾Ç¡$ØiÌeeh ØþW³ý~À"n&2 È¦§I #²å¹Ë—ú×0N¹½d‡t¥¥=}
+ž¯îf’ÚãŸt­ñ_WúŽfäT[¼à
+ÃdçWß—³³G7vvá­¿ýzÉgç¿ϲ ‡W¥lN:T¤ÂÊõ ¯g‹³ßµŽÒ9„Ù•Þµµã_«ê¦¥ZÆñq³œûUnš?TéÙûUÚy¨a˜v{uåqc¡u´·¾owV­åùróF»ÜjßÞH¥›òõyyecåIžÛ0|u²¿Å!ÐØúÚm-»py¿›ÍY9+;ÿ”?ÃuYX¶•]xxÖ³³µ÷zv¶»YÃÅÍŠ‹ÓNñÓ&Ìävƒ²jïLþö–ÃЪ:Ù»é’2½:^
+ÔÊ:Ö¶²6±s_·ëÒóÔuÉYÈA§Ý^ê\¶oëÖ¾TÐÎ\=PAËoWêú÷™æyJ&`{›×¾+έçÕëk~u;;åmª5OÏQ£Þ·ïÞΣº«±¶W~éŸs-)tÔ{ãæ$jÔ‰úcá&|ÔåìÏÎÄåõ ºÜï+Ó«‹ÅŸ{a£Î/=iË£—7Gz`T†Ö®o¤ò¦q:êxù·5ÙP—NÂF•Ê/O;‘£N)Úõ;ž!ËÕ®Ÿ¥ííöuøZËŸJñü÷UköìëôÇ"õdzšFeÃð­UÛ—…70óqË¿µ?Ûw¥Ëu¶¡´;­›¿È…ÚÚÙƒa{£GÒÒDÔ¨Oí{K¾
+õhknâÓø:ôF…a¼;­ÍrÔ¨;kJC¾ U›½ž_ª_…Ž:^®à5§Å­Ýÿ¾1ª1ñM·ôµˆQ¯¤róüÜW# ¼=¹2uP}»uû»u¹Ö©\6Ï÷uëö½ì;<ãxiXgz}¡ƒÏõ,wçáÃ9²f+8êÁîÑõ:7X«©çó7Þ¨ˆiâro6¥ƒïfø¨»ã_ÖÁõ“:êq½º9* ³Ÿÿl-„/Wû9/|~…º¯Þ”ËkÙÐQÏwk»Þ¨¸7þÏó_Q£–¤KéÞõ 7qþü0·6*›Ëû•När/gª­¨Q¥¹µÍˆQ·æ¬[í"
+×{³p~9êïñóƒÍˆQo é®òk>lTÄ´ñ£‹Úûâ·£…P ßß_=DŽÚ¬®Í¼Fz(ýÚ:(Ѩ„iÁS{!_u¿ï†Únå&ø¨êlàðÌÛs[*µ2ÞÝöF%‘c9»ØþR‹¼Ð3êñÊÌçýÖÕ:ŒºÒržÅæõõÝž Œúíåçø
+Ã(›×ò®ŸVœJ[G?·qÔ\/]<Ê9œ§Ø Bxkëwžº6³µàŠºÐÑߦŸç9…R'‹û~ºX_±Ž~⨅ÞQoã+×;;0ê^60jVÙ<~£Qio¿çËýÝ\Ùzg£®]øÙ;€ù÷[“ø´óë¤(þªt?²Êbã1ð«Ç¤•¯©¬úüÑ
+o®ÍÂáYÕ«Q¿¶#k¿2‘ckùx‹UèáÔ7+ÒÁºªÐ¯½ôþfM:8]Ó¢~Ýž÷ ú† ©P”³?¬¨æ[ÒñÓîiÔ¯ÒYñ½øUl~.Hg—Ùˆæ?óÒùúáLÔ¯ºt‘ý̇ÿºœÅ«¶Û_Y“Wè¥Z;ÒåEv…ýê?qøëžtùš[‹úõ@ú1io¸@ë­p$ý0¶ŠQÍO¤› ó.ê×ßÒÝÕÍ\àWh·¦t÷ûe!¢ù­-Ý_,©Q¿®Kƃñë^ó.ççöõˆ
+•Ùþ¥Füú8!oNÝ—£~=“÷¿ïEí©)½+µˆæϳòõïý©ð_õûÆùÒr÷&hJç$;=»G²Ö h:3;¾ÓÝÙÈæwÖWÙ¯A*¨tëÙemïwø¯Úì-›eåõ{T…»ùå¥Sá×bnî”+…@ÝV[3Ïçó›ÍΣd«+­o‚ò¶u[ÝtHg@#’Øn¯ÉßÖ Ýébù|ͼ&´t³µœ‡2©\ÜÌ?‹›…ýyhvÖâÍ~}«ãtT6 0ô„:ÍDõ½¦]´ê?="Z8´Ó g^}‘>¤öeÙUl'
+µ•ÇY8Šã[  -žøHw{\™^9É9ÊÐñ¡_ÀQõ·¹oËÙfø¨ÚõUô¨ãåçB`TdkîÀRù|ó{Ĩ 4×+Q£þŠu;gûeç©© oÔvgq¾ãŽªúFµv´«·ƒ%gÔíºÂã3â¨ÚÙ$ ã Üþú%ç#G%œ‹4NÐ+nÃGÕ®25JØä%rTR-"GE½âÙWã¸=ªuôý*zTR"! àœòµÜï=[;±¸ÀǧOÝãë±áU—Ru©Ý¤«7{Âê!Ý`Áá·'ùqù ÔùéŸE~
+*§›$2:ã
+ÇßÓ¿}£?¸¥?ÚáØQ µË2ÕrÜ[㦩í‹ø:õÿ©\•< `ÔƒÊ?KòÖ]g›Ûløš…I¯n}ã› @L#pˆ³·Àâ†"è7 oÕÒ7Dhø0sMÚŸ–[%bN [ ì©,˜—þ+àé_!©î¡+<Éz+dܳg‘îŸSQG
+ÙC¿“öðá‹Ô(>}¦2ì¥ µÜtÉ:ȹ4ß'¼¢1bi!ЕgL‰Cûpœß¾nÅã—‡\¡£ñKz‘ǯS@?ô$
+âWØŸ[!®¦oÀ'IAÌÕš#ð#ïÚL©+Ïmþ.`…7E:ÓH#TwЈ¶o?#1‚!ÓÃ+ö°‡Á‹z!;t/¼ú<ì>xùOzÞak¾Ãþ±ç?ìj\¢-J\OeL‰5:|ìŨ‚½†\1²ÝdfQH2$r‰I/ÊÓCZT>öÔµËóÃÈűI´…¨“ö§4Œ!„S=æ²9ô’‚\V´ÜÆÛõ|[µ÷å'ð©D>~ƒ°Ñû3—DØvö¶„ž7IøÅìµÅ“n@ÌV×.¾eðw#!c%íÞ}hí÷ecóˆµÖ.äx³aPJŽâ‹ûÄîgM!%·öý|qÀs³v±2; º3„níbJ3¶ˆî‹ß³~F(,É[Mš%}Ó$"¦í÷pÀH
+ñn‚+ âÅÕÅÐÔöξäû8ê]…P7dѯ
+z닺EPhÐV‡¦èןè ¨ˆÆ´ÄŽÒ“ø^X<ôRJ’<B¤îO
+{s~ÅÁ¥KXȦÍÇù”¸ÿ<ÁÅoå`,Ï92¨ÍcÆ ,Íf¤Šè*Âo»‘Žì”ÛÕ¥Gq]î9°OzK¦¸ž­3‰è^¦ ¨£8ؾnÅ+Ý)ÄlÚ9ÀT4±Iì(Rðì%À=ÝŽ†ª`½¸jw¼#?±£´1MndJäy¤Þ3r{ÌQ4O/ÞžòÇÊøA
+'A÷fJáÕQHÿ·Ñqž¨žš?Bo±ÒsŒ²ÜboJÿâ¾ÊãúHØZeüp4l :ž±ä‹Ã¡ƒ“h:Ñ–=_´]rGr$ŒgŽaÄFÏõÏc˜ãâ EwùãâLŸJFD afò³ëÚB³¼ÐŽHz´8­²4éxOf” t‰…àõÖ÷9œòxóCåõ͈ßM¿7Ve‚ ½L#†¹aE¥ð*Öæ±5'-ü¶Îäs¦Æ)›W×¹
+c¤²CGªq×qlJ CšÁæÕ[ЂÝ×!óÛl^Šùå)m4v¥ÇíM_îì-—û0¦(›×ãSýÈÁ@G¡¯É0—¶·ˆcÿØ ‹ô†1#1þ’æmM2go#ñx¼áõ6å‡P¬æû@y{«ÇoÛõËÊCiâùk«lO®ß—ÏWO¶(—†M:ß|l.ߘ´4T:Ÿ¡Õ›Ë7&^c0L:_|.ߘ—º8\:Ÿ0jH.Ÿ¨<T:_|.ߘ˜º8L:_|.Ÿ_€"/>—oLL]&/>—oÌŸº8x:_|.gkçóÅçòB"/>—¯¦¿t>
+{2VR$ñ¥^a¡kÀ?Ä'®²9 ñi1ÓJ2tÅÌ©¡ûÍßëƒìÜãÅfCaúÇÝøø®x¤1ÙÆÁç h}C›·`q·Å…‡ó$¦Ýõ_fÀ´»¾-ͽK*åSªQIiwéãK¢I'À&$Äd -…:m¢Xš
+,I){»$
+·;=Ž•E-2í/ôܨ@"DR""­êI {=ü.BžÁ%i%õF©ú°¸‚™R;˜©{×yí†A}LÈôòK˜ Ì´/Ǭ(&äê% è´¬žà¤å´ß»‘gß;ó.HUêsâ$`ÚïÝþlA1l~/àAî™’sô|ss/9 V_Ö›˜9QÅh°*Îz3æÞ8–nZýYo‚j”ßn¼Ò Zo0-jë€i{C[oÔÉÅ™É0MÏGlRj{ý[o¢í{C[o`qÚLLÈHú|¸”Ö›±¸{ (nXë &é‚rи¤½Ö~ns£­7©²ƒ\ÉÔW‚PlàE! H9™^ ©±©éýȘ‹±~2$¿'ld¤æÐÑ¥®]˜)’YS\{¶ïEéFF§ZÜlZ,%{Z8¢î§ †HJcÃ`¿­sÀ¿dŠËtÏ„¿4­±'˜%bÆØéÒ„
+§W¨h \^ŒBÆ ^zâpSG~;q:¡6êhè+
+±Ž¼à84ò>Uˆ5Hé«sÁó¸u[Œ‡!Lq¯‡ºìÖµu¾L'Ýñ’>zú3x‚RдÈPèéÏÔ ®1¢z1,Z¢ot»ÑUÇÔQÒ]8iT\ê¨ÏóÎÖ.Gr/#™£h³I)øSo}] 9°ÙB&`…=KXÖ·Ú-ãσ:¼Ÿ9- Œ4IöÇH“dŒ(IöösI²òxn4I²ÐÑh’d±£á“d±—‘$Éb]òE×ÁØÁÈ428(1WÁ¦Š_ò‡ó ­è=í¡Í`œØyyCÇ
+…%åùØZšX!ÿ2Ój÷ÂÞD*ø#HÊŽ'ÏËûW’ò×=ûJÊ‹6Þ4)Y$¤k”7F7ÃÞÇó–”Üc'’F1áV  鲯ü1É·ß¹¯Ç…lrðâ䯄ã@û u!õmxƉuCå¾A$›ëàÊÉž‰±ÈTyL§Kኻy {xàXT.nrÖu`NûÌýh!†]LJ»zÒü&ÝA2 ø üÌ餙]xû}†¯Écf1>¼þÛ_’³ ¥Óøðú>¼~ž;ß0ðÓ V-fsûºT¸z79sZi¾‹“vìSþ'ôXF˜¨{úÒîN
+’i_\gz²)>1ëO»›yœ<}LöÓfoãÒîîs‘£ÒK䣔›5ìw—v—Õ£GÅ—ÈÝQÕw
+£à–³w1ÏÊ}_?F <¡‡¯sE&ûéosë?æZQ©h×qiw¯R`Ô1ÿ;…w;ÑÉ~ßÞ —Q£VbFÝ–ýRg0·ñuo"rÔìí„qá…Ød¿ñòîT`kñÜæh|úä$~=§ªw<Q DGU?^ɦè²ýõð.Þ6Ž«öDTÏžæbh¾0à±q6çäøÞ^áödê#Ÿ´Ã”\4ÆÞôjEÚ©Â ,Ñoz­‡ÞEÑ\”øDM¯ÿ,Ô:8Üózþ9}üGõ¼^Øö¥5ÛL“œ)ˆ–’_[ñÅƼí|V/…Ù®—õ"W8–ü^ÒC+iV8vÜÀY±©ÞXI ø„ç'ú87ÒËv›
+T¢4úU>O)Yb_˜öѯÍ&Eb_˜–n¶*±/,«/R†<±/ÌŠÈ Ä£Lì Ëê£s3Úľ0ôq}k£Kì‹6w4±/,<E Ð£JìKŒ„Mb_˜Ÿ'‹;LbŸ_YV_ŒceÐľ/î¨ûb2VF™Ø—öŽ®!û„x7«/ܽ:Tb_sb¨‘&ö…ÍIt}(±/,«/Ñ5ŠÄ¾°=tÏÍèûºrœÅ#Lì Ëê ËX2±o` õ—Ø—´%ö…eõõ ´‰}aY}c™^C$ö…ɤcÁ¬ïáûÂhÀ¤G•ØælaºçHûüL%ª¸&ö…íu´ceàÄ>q—ÏL¿0±/B÷Œ„È€‰}8\s,:¡lÐľ°% 7'EÉ«8­!uD/°ØéIš)%Êq‰jÎ$~ï’Ž(ªQƒg_%Ò€È1ŠWü’DŽ½â·ò„_¨È‘T‰o
+ÃàrcÒÇË-zÔí…_—‘£NWgÌ7ÁÐL ÌÇz09j»s±š †a‰ˆëw¹sßÖVmg|úÄ7c¶xóü‘¦Þý×GÃGl"ªŸ÷[Wlj]êoû8ãÄÛ€8*YÌ|ôX`Ê_íhžår¾Ñ™\añ(ý,äÙ…*cå€Ó+))æU>Ÿ8ú¬[Úi¥ øìõ•ùl^9þ¡´Bp)` y˜&µÝég)ñ!à2Týn%¥ÇÍE*`ý¥ÇEE‚Žî N…U}Æ€EG á
+áÓ&
+t«7œ§Ï‹º
+ÃÍ8­jè³£$W³é$Ýj%¾vè†Á ûࡃªá¯ömùàá ·Z ðàaäâFq«•÷àáP1Pé<ŒO
+fuíÌŸŸTÚÙo·óSY´e§ïwÞ²ù•ßóK«ŸöüòÒéõüyí½)mmý.H[¿s‹Ryÿû2‚r³v m·sÒÁîуtðñò*׫oÒÙ¡jK绵Ké¢óö"]Jݺty¿ò%ýÈ]ÎH7 ³ÒÝãø±tõ"=œª]é—z5-ý:œùÞn··
+íÎms©ý%7.a˜ö׃5Ó™6§PN8íb¶ét®ö¼s¼sd¿¬_Þݼf禾]LZKõÍo'gÛ{SoïßÆÇíÂÑÌDýéÛ®fO?þ¾*-Ï9I‰Ù¯…–vô‹¶…Rà`˜ìFùüü›4Y}†â“f(9á{C)¯&¸ds›×šð@&aqq3
+2.ía}é Û¦ *o)‡|:kÉ ¯¯«ðéò“Ô©ð>ž§æê¤ýÑ•¤™|¾"…œáŸ~Wç ÅÎ,ðeúsž›y^²8“ï9þõ@ã}
+Û+sT†Ã`±8úvqÁ«/½½›˜/Ìo»‡Ž&f•»Îï/øáTFú=/שׁ
+ÏŒ³K‡ ×㔎§é•³9¬µ€™Øu¼ÐŸ‰Õ%êC]û±U)?ÌþÜG2™GÚ7Ã^k­vÞ1ì|gŽ“By¼ ”r?ç
+wWîæÍrMC/­M@IQþÎmFŽáHœ6ƒz§™™E¬.ÒBfä­ûçŸ4iyá`iÅ>Ã`` +…ÒÞrS‚Êå¼H?í÷úf}¼Q–s“»oæÍÒÑáE9mû`<Ϲ½>›|¢â)oÝ®Ã
+·Ë9F&§WN?áëAAÒ÷‘F1hÊ;Æ×9îRËw·zèÁ*8"ºvQÞñDºyníÕ\¼;9´7v cþ,onþ:š8¢¯‹SÍÒbi¢º°»õc³Š÷Ù¬¿œËSPA9+ÛújÙž<}.ÞíMì,}½‚HŸ×Ú— Ïm{¸L¦DçjƒbÎIžÁ‘ÁY6&'×·>oÕb _ÇÞ8/ÞßníœÔäõÏÂFi÷£Ö)—êò&G{­Ts¸Î¿FA9RJ˜fLt¶æk7oç—?ÚKU»ýd5ûf~îœlU*Óy ®ão$Á0Ö{ý[ó®ˆ"DÁS;#‡fúMØš(¥|~ùGù¡{'¯/í½Ÿö±`{|~õk*ÛkRE\šÆƒ‡¾÷Áoœ(?Ì“xC³T7-Õ2&NæÕÚæûÌÌ÷´CÃ0lôµ¥Õ©€švè¥ýÉÒmi{{å}㼤~†A±µhÀ+Êæµ¼Ûÿž…iÝ鼶³9í×LÙ½3 ,®Àù^¹æzoÝ–?]ÂêÈÀËSíõËé«ÏõæNûºü°°3±qüº|
+à>ü–k£ÆwƬhPk!›³r÷ÙÙZ}5›k|¿Åæi‹ìZ=Q›`V´iv¿lì°ê^ΕHé•:¥ÆæñÉú]¹¤ë¿6Η~Ï”v{°#3ãëËkå¼k*þôö¡ðö­ÑÆp;¸jwh.CG÷ }Y]¿Ü_Ù…}8Ïný2ŽßR‰W+7!Ñv±kµü§‡¹õ¥Û·‡RþôW»ø²ÒxL+ÙàÀÉbÄB›x‘r$¼ ‡IÉÏ¡*j§#Žçf˜Œ­†­öºðþ)
+©ÀH„ŠxŽÃôOoÿ}…=;w_o¹ÊÛLZœS£ú‚~ïø"—c±êÿ—QºSÞq# 3Ÿðh6º/'óÇÂÑôJ§
+2à-73ÀjêZ9»ðð¼‡_%´'þ`^˜ùïãKÄo¬Üqvö׋•]¸¼ßª*»Áõßâ7ƒ’‡öz:m€öR*É¿ Ó† ^ÊšòoU~m½¯7> ¿`üÓëxVë8ònÛ\øßå7£`uÞ‚Ñ™¸f 6—“¥a 7\èo§‘ÊŸ$ØÀ´ï¥—©Ö
+yÎ["º3Ló¸µÓ¹Ûó‹ß÷©è}*?dáÓâSl‰ß±˜T‡ó:ŠG2óÝ(?¼×çÊõÊïÒ}‚^æËìZõÒÁ4ÏrÚ/ÎMÏkÙŸ³‰ÆÙ¦á§ÜÜÔî‹ÔÚ¼ªt°ÝÝO/r µû´õc<ñÿßÛýôRçP»ï„ÄÿË»ïsý{»O[TàßÝ}¿§ð_Û}ÚzÚ›u÷iëå7éw_ Ñ»Ï¿¡í¼'8ËÝ%Î6´æ›"BQ†ÓÖ0³ã‹]ìÉ  Æ?ú"Î×ý~Ï)½YÆ¢²ñâƸ뫺ô½CÄú˜˜ÿÔBm+ÐÁ|qrmË¡$ *3öµê­ÊÆÇW׶%¶9'î!nüx¹,X¯¤ê¸^tpuu²±-8Vj3BÚa!‹fÄPº­Û¥œ:µôSͬ´ oßçY®"•Á^æYÙ]çƒVo;N¬éC× ·`{§‹‰O;¹/Ýy¸1¿ôt|ˆ“ã§XB†³¤·¹õsá…#÷hÃ0³3k?ï`ªÚ6ü&û©Û|ÃÙ›¯¬½ŸÕ:?§œã9{…?L8yG"6]/4< mÎîÏ;oóìÜåÇ_Ðc[a„<ͧS÷ Ïžbe@(uÎ\ ÜŠ@øúyL@`y4#ó~¶ÕG‹²|¥èÞ‚ÿ­_f;
+pX+~Š§ŠÝjŠØÇGå±m‰‚/
+†èœ/ÌõE(Øôö1,±YXtÀ4é¾vd!1 Zˆ“{$›…|ŠQ׿ÏÌð>*kÇþ
+aøÍ€–z!Ò€‡lÌ{ÖmANŒ˜3² 8Þ!ëŒoïƒ@+ÌyU'êÒ‰óÐއ⯗K¼u1 ¦UX6nA,0--¶Ò`I`=@ E”~"…A“-õB%@¦”!Ï~AMŤw´•Ãâ<룽ª«¾>”¡cÒÊB20â'E€ø$~ %?$Z(ŸOz "¦¤!@Lš”2нÖ;,±Ð}}ÒÑšÌ0¥ÁËPܺ_\æCÇÕOF»zÏ);Ï Üüc¹Q˜ …Íó<êb<Oý:©Jð oÞ
+º6K_y&¾H “Ó<H_ϱ¯wê}B…}ryùK­z¹_uÒ‚öÅ©.H_îb–åBñÛ£ûÂøÃ…üìþ@T@øíuåÅýM~ä<‘~µ}0^qËæ…Ê U¹É†G9ú†á¿µq/Ü AL|ÂÏã@E%#0Ì~I…“õ97ûêî²2Áf`Xݤ=DßB“ˆméý›ÂÉqí. t|½©Kê-œüT ‡gïxÄÏç…ìÑç©<¨Î×^2í/g2ÜäJ…ÊòÔâkcoK(/oi¿1Í»¾H9°LûžŽâ{óßA ùŒ³{ÖwÛÚ.¯OWÏK»Ï+Yn¹¾’ÝPEL­?Lp\¾®hî2+l7 ùñ˜Pq`hÞ>^xvôã•$?ìΧŸ2».¥ðx¯¬Ú»
+ìÍcEu>=kÔßÈ÷Sê^tã”\xó÷Ÿ’óéÞËI~T¦×VùtÞŸUá‡û¬ú@'BùuøùÍIý0<ó&ùoîg_ŠoFùx³nMXB¨æ/Rú%[’÷‡]&ç\ÿ&ºW^îßÇî½$oËë3ð©‚žBç˳âUåǹû[Ll:z÷²<7»ºd^æÆË¿¿ÙASƒÉÊ5¹ð(¡}ëvƒÈÔœsnÎZ¼"øz݆…h8™<™0Ø™Æ×N>1sYf®cr&f®Ï³´õëfÞ±r(ÓëÙ;NqŠd.9YPî¾–w µ«nžÝ=V[Xœ'šªN.mí…]ȧ®]í Œ?\°aPdº¦­®Ì;“Þç‰á@«p5û@-ÌËâ¯÷g_†ûääOî éÅ´7›Ÿìùë1’˜9Z$e^2òÏ6y»¸ÀÊ*ã»-–ÍNÉ™›W׿YªçN®ŒœòH蜥´3ÓÆÿ œÚ´L;C
+§_õjû¸]{­52À'–Æþ(lìÊòEã¹YnW«çÕ¿»¥æÓ×GµÑÍ,f
+gÅÝ]K/UŸšÏÕ ×eyÈ°ÀçÉÑW¼œÄÂÇ’ÅK/ööûÎÄéJ¥ô"]¯üfÕ ð;c®/3GØÂ[í ãøòÙù¯Å3t•²9éP!ì »Ip$Ü7˹_å¦ùC•žE3$ dåqc¡u´·¾owV­åùróF»ÜjßÞH¥›òõyyecå‰ö¿÷‚•;jÁ|Iswed,xÆC<üq•ÉUÆÝ„è%Ì€>…Oœx6lz“ÛºëÙ…¼ üü«2ùqËÐôʵÎd€Í«B¤œ“HÛÁ¯.‹Ã#È?Í0Tí¼Ó5^j4eJ3 ’bžR©ónË‚›ð 竵émF¸K³½Tgá„ Íê:#\![_ʳx¯
+Ñ<‘=€´‹Ü“Ýœ'úãEìÈœä™ 0½rÕ¯§HV2üyƯW¬_87<¿2b2?ËùÜõ.íæ¼xÆõqÞçDKÍb‚äÑc1ק…°þ`˜Á»¼„ãy±²Xܸ˜ZúU|3÷[çLˆØü9wMh<ûtUs„µsÕ»UBÜäÇï
+熧y&&lÝ–fÙ§Êø%¼0™cóFÝ¡dâ$ô‰ïïã«Nç†{pÞ/ò(Ê°sÖ4ýಽœxíÈ{EDäcn†ÿû«æ^¡»«ytã$°é9Žýá‘üË"RvH €™o̱O[·{óì“0óî«JeÊæõüV`:ÆÍÇN½ôò­ƒþëËkWÚÆþ•4!ÒàˆËwïÇå§wÃTX Úªñ­ød·zE1e´»íÓ«Å»ãæÌÖÍýÍÙzûd½Ð5v6·¤ü¹`fdç]g¢ëq›æ·íðýšu¨ÕI“è«÷yG„¡<ZvÇNmüdʽc§ãÜŠ“gW×qYô%º‹ÜÓ—äÉß«D&=Rˆn‰å¿•_‘ÉÓ¾¡rÃHgøÍê;’{%Ë”p¯*iX(3•+¤Ì([€jÕâ“bJÊ#—ûVwÝ öó¢^Õ*JέËw`ƒ¸4²2ç¬ðhÞ‰c*+,$Çt)¦xµ \‡âRQ•¶íS¡s’¿ãïáí]z¼ÙsquÏ6GžÜº×]¯á÷¯a.ày|²öƒžÇlw¦ãöqÒÓ‡6·MQv‘^Ãv{9w(šÏC<ÆDöÛæ¤>û4ÕÓÇfáгQÈå«mÙ»UƒS<ˆ¸Õ¤P[½Ø"<Gqx•N†Svùé”]· µãƼ§Æ“`ì;A쪮[áF®å¥Sá2®X·ñæÎ"CH˜;‹èŸž/worgyæþ}r˅ýrµrß明zþ™a]ã)]‚¥ˆÃA+xpÀ½ îuº13k‹ï sßX`€
+DõA×[„Z¼ƒûuiØøƒ…é·ïœÇrÑùü.ö!5fÓöÞÝ’Ø ô0:‰(´à±!>`Ì/$ö!N¢§ƒ 9ØR‡{Š;RY>òúPÖeKìãÞLƒZó1ÑtÝÖ0g„$«0H ó9-ÌMîÊ,Þl|{gÓéØ@—ɧPo{ós–×+ÿ– ß´£Ò/±êÁø\"¦Å­kûbF @~LK Œnê ݹEÄÖíW-ˆ(ý[VƒXâ†9¤]ÈÎäz¡ÿsëÇ´\Yj!;Æ…iiÏþÎÚ©’0‰ö*ù@Y;Z7±ìcÒòãý·dÔŠ›Äãëü|ä$\&5ÞGKÀaž&ÍÜPgÿ)·’‡&1éX"öd"@¤ŠëòŒ›þ€-á¨òü»9zý£D6<Ÿ–gj™_=©3cŠc@$k>Ú¢k¾w+#¨É\·†ÑI)ã–0ÝœcFfÍÖW˜„ÛŸmº[ÑiV.¸¾ÑÅ –Ý’ËV³?+þfw]Wß¾èêFäºúösâ÷fÕý¡àW…_ÅaDÓ:X4‹‰~L „®óHôcerý˜GyR†PHÌ$ÇÑòHvLª‘WÑÎäZ&î*ÚÑÜC;öGÂU´£¹‡Ív±WÑŽæZgo"¯¢É=´ Ób®¢Í=´…Ž¼Šv4÷Ð:®ˆÈ«hcï¡Ýô|ç<þÁd‡òÃ,a.SØ÷È´;ïÔºüD ÊãBpFŽŸÃ5ÇqïP&f»›ÛXiù(Ó™ÆoÃ^œù$à2š¶ž£Ð}ÔVnàì]¶Ç¡¹ÌÌV ‚ü }ˆT‹Û „ñ$gŒ¹þ dóŒˆ9“¾ãsµ˜c¦¼»Îã;sÿùˆ˜äù ïšWæã¶dFƒ€tY®’“ ZyN°ˆ(dà ƒÛÇÙPÅ›º™/÷ë ¯¯Þ@âÃVãYô&Bñ7(:«v¿ZTEج¾Ö•ª@hå ûO‚ÿð¯igdÅÊ(º_t,=xûc†jgìÙÌÚ¸
+ín©öÔ­5•ö?™E*»:<¸Ø-e3¬öÔ^ÊÌÀœ¤¨?Í’#“*¡[“5 ömþþ¨7 B®Òí¶k_ÝjÇiºÑnWzë=½ÕêÏíjƒ×’3…ÝF×ûÿtÿiUùÏ™ÂtÛxõWø³Rÿrj̼u»­ÅB¡ÑÉWž›ÕüSó£ðò÷kA‘$«
+°ÀÈ«šabœ— ÃÎ(†™×$êHyY³±ÈÊk¦.C‘fcE¡gVrà ¾¾x%ð/Žî~UeX ¯*ø)¤D±6S*Óò’©â$-;oÙ†žQTf¤áŒ,3¯+2y[—,Òó² +(b[§'qàŸ›åÜnŠ¡K’l ÝX ˆó’¥«
+n”j’‰tg;Š,ÚŽž)„-¬wñ™¨rÏLÝ1ˆ
+E&MØá°Ë4€¯iP€L…e4Cs)ô@Í ˆ/Š,§–mT;kXäo‹7´ §!,Î2ଦ³ùåTIcÐÖ%ï¿
+˜«j6!–¹аTe³Æ"è„*¼%h¢K‡#îÁ™ÚâÌs*b«e±9U§³!˜OØL,5,ÕT„¥ûJ”@+ €¢R+˜1ÍJƒ)œ4Ø!Ð@ÐÓ” @°53 V¤Ãú3t"˸HMãëÖL“%§Áô%œ-¶5u·Tc
+l¦.a[8}´5HÎ߀¨Òñïü¬¸ßØY¾Òi¾ëË©H“é41Q ê²é½ÐlŠp‘yÙóÅ}f„êk*2n† 6Áte ¤ @ÆDTYcÍè$;@Z
+­@x KG̶©Ø:œ é±T@FÕ¹E•
+¼"ÛÆÃÀNºbKl¦BJYD†„"ƒ$,b$ %c·Hfƒ¯ÓÝU’ø,Ä ‹ffÙ¬î
+FLg "‘¡ë|uªg„©’Í`
+Ì…äîL®FÌ$5˜
+7Ý"<n ‰€Æ¨‹ œ:žwäëDmPÚâ:(SìÀA‘¤›«eƒ¬Lò•¡I¼duVÄ¥yèÞ2ySÐKlÕ`…¶Å›ê–ÎZʨDXbšºÆgÁuYUVx!ˆµ*›šA¨‹Rˆâ69+5<ÊRš¬HH:“6aëu7Š:–bP覶+€š Øvø&ÀŸé³PÄ׉²£³% ×s¢ÛÉtaИ¼ ôˆ ¨X„+uÙŠ ÚI®Áj
+3,’¤°"Ž S™ˆÐ¤P)œRÀ^‚%êøTB-TP`4¾L^„MÑJ¤ÐQ£RV“™M†Æ 8:!˜ËNH…ÐœŸ8ûvÈ£6Û ·§?rP,ÑÙwÇ
+×Ë¡Â8!™ñ倕R)¬Ô’A®Ä"[GÞ£#þب੮²n8ʺ«åq%’ q•uÅQÖ݃Kñ”uÕUÖeGYW]e]q”uÍUÖUAYg°ÔGY7\e]bʺW` ʺXÊ•u±ˆ)ën‰!Z Á•uWûsô<Ô*e]”uÓUÖGYW\e]v”uO-—|ʺbj+•‘æ`‘lÛ
++BcEL]—\!E³Sª½Ôõ+e Ñð’.E²Îfm:󓸋¼…
+¶Í"ê É6mV¤™ÔmЦÓD#†Ï!rUç8¦hŠBMÉÞª †,#c)28±ž.·&Øf¸ JeFóqþü iŽÕÊÈ´fxFÐïÙF¦lãå’>²Óhg0ÄÊÝ•Œ1L“&p¢õ‰ÏD– ¢µPv¬Ä’cŠ×4‰Û
+Pö£Á4&Eê̬ ©Ìgß#•hLP¹Œgƒ¨Fä Ø)/ÒlYÉôg.¿êºkŠPš}0+®i¢¤¡Å@ªxÀ• Sâ¸iéÈB%4mQEO"ò˜9:Eñ,8(ƒ4ÄH
+r­n»K—™¾@E²>iŠâªêŽÉE_êi'-¨OrÂãiP
+3¡R„8š®e‹wHœõ K–øîI&ð;”„¸ ª+¾¨è¥¶°› ‹Ù]9`^D6„"Ë…€PŠŒzAIXRHA)Õ)âÌMU= @?²-SEól¬¨1¹‰Ž»ÊÎ…>Í÷ZÉçTŠ˜ B<qC*Ö+gBˆGP)ÖBõ?B9:#ArŒÕ¨n˜™™$PÁ7@¦p¾3YÑùÆeIá+7V»ß=cµŠF"©O:²8´'KTD¶b²9“oè^3 ‰>+^£âÌ€rX–…B¼R‚ô]u]²6#íp&t&þ£å ”A\¹nÊÜS§¢òâ±WÒW ÇŠƒ‹fb©:óÈ’w´~×#ˬâ&2/¹(ÖÛÕq|»
+³eP[%OÆx,4%´á“›Iµ¹#-rXÄW¨)L "Û’îØoPýCû("…–OEa¥,æ
+¹_)QºnûRÉø
+šm(Ù œÀèoW$ìÑæ‰EîÑ”j²¶;ƬÔÔÈ
+¨JŽUY+ ‹L‘Æ"çh1ÃjˆëPª ê¢dH$/;L
+`)s^rMÞ–œ©‚o›t6-.êFdSÔyK ø¸n— ˜¶gu‚R¦
+ Ý•I/6‹}Àï(Òãw>¤iù˜žB[<Zª-96n4Ä“a£$ÝAÛ‹›ÐìÀݬc~gLÈ-¢†ŽÇKÑVº©Ì{BS0J—¦»ÛXÄmªT*qéœ ¦ŠÉÉ!2z•¯mÂ*ñ`„[®¢ºN™/Wæ¬!§8ñdâãwâ²Ù 8ö,B)„JÈœL%Üülyž4"Ò¾ÚÜPçZ<™ó‡¶Gv¤.,r8œ Ý §ˆ=1=Œ á
+úIƒ1áA’X3Ù0NÆ°eÒz¸ÿ‘JRLÒ Èžå3ï“U–®ýIHAÐQaØÜ¢d¦á¨õhôx=Â#!^”P_KÀâ³ õìDy<QˆÉu4q—UÀÅuÕ¯Uˆo+Ü ª¡ÊO§ þ?4çÙ2+âs5Ma—ð4[ÜîL… ¢h?ƒ†m™¬HbÄ‚CŽÚ:u,e¨ŒhB2$sª BBÔ2=JÌv‘ÍFcÖQòKZ$¾˜@lM™ùHÈ®Œ$ÐõÙª³ñNé+ÂåÔÅÉ¢ÌeJt` ˆ‰a|!Š»Ú`Ã!µtþ±ˆ"¢Xãîàä=1†í
+su˜ n±‚ê+º©1¼„”,YGš¢‘hoi¤e9ᥪ^*¹á¥ª^ê:Èlî
+C0vbÝijŠÀ½TV¤[–ME*C[’8@ñ˜©”·k2UÃÍ ÆêÃpi<&
+OQ¤­0ìگ𰚶*@™•£aaÚaþ™R5›1!Š#Á-˜Œ-Ï¡î”nEApJ <Ü%$«<ˆÍD2…Þv# \¹ž"NÐÒ€¥ŒR›¨õ’£YƤ/þ¦rC$æ=š<l
+å.•</6+ ‰ÅÌñ©ª² Ca8ÂEnd- Þç`®óÎ)BŠˆÉ–6‰ônEMæ± è)d<EUœU²T1tßQA°$æ•„MH8QXd8²9æ[0>o8FD…Çr°RÕpbG©±¡ÍŠÐƨ:ÁG̥ƅ'֡‡ÆbSEK!ÅÃ8d4ì+bŒ£ëÙW0‰ÃRYE˜1ìRLÉ™ /
+‹ . A Uìi | 41‹ ©X*‘Ø!qß
+]%3ÅFÊè @J*™Î!D’seòôñh 6yFL“Ù¸1nÔd® ¦Z(¶èõ¹@N$#iÈ2Ö‚¨Â*BÝ!ΑJ‚«ÅóÉôznz¼;HÖ1‰è¶Œþô½À∠ õ ƒ-{YH‘‡â‹ÑÞŒ]Û*3çh<Û#ãt²‰â'€PÛY¨‰-Äf±ëµì…˜ÿDa‘»Ri±6°,™ôm-6}²Ù8¾F2eó©¢›RáíïJÖ,›%]éÌÌ„
+¢²©;¶™1LPSl²”0ó Z Ø
+*ò‚Ô\甄⃩0›%ÙÌdóÿôu%­–cGsßÐÿámzYF:ƒ†¥ý°ÁpÁ^|ûW· ~ݦº±ñ¿·"'I'Cµ{•u]é ™q""µh—ZgÚц
+eä(ãK †"`ÕªE(þD0ˆnÜŠy)ÈX'¡±Ueþo³
+š"?nqg(¹"èÏN”ɹóSvKÒ`’, 5IºijNsx’ì“’€×¤ÈÈ¥M‘ÐÍU~?Εö²KŽ×–ÕBŠ&„ü­ç%#K:¶v9QGJ´‹ÞõXÝg½IšÀQˆ`IpzD¦F‹
+Š…uÛg 5|ªlàÊ_>Bò¶ù ^/ÑmEÕ´
+W*†¦°DBôRµÑâY42< íêgq,aû¦^ ž›îÁ—èÒ,›’ÓD¶Ùò°…G-ž•Åµ{Ÿà\J¥Ã»šÊ%U಼. k‚Ø%€ þÚ;n-òËÝk-²RWÞÔ3+ËI­åÃ9ù%òJÛ^sî—2ÇÌœäï,Í'Õ
+™\}ìÚñ"fDØjü8ÑAlŽ¯ËÒÔto”@±y,•ŽZ@xºÐÜäFB*MÁ<ÿ|bàÙ) ^2û$=2œ~;ž¦AÊíT,6¥ÓJHߧV$ÑKwE
+„(§²ÊD1rÎádØŒœ ~Þq/Õ•K»Zr¬§†:(¹61ÒèŠo·M>~7«‘­êÉiŸ‘Ó4ð~ô-òïwUŠé­BHoCÐÜð9¦×òe¡ø=»³Øpò¨jáù¡Â¼Ûeú-Äéz5[Uûìs|…Åã¤J®-N£v#–uð½ä‚w÷X鳪‰ èÓiÓË)ÌÀëXÇ^wÜóŽ“UáÒu¬·ˆçé÷ZÎwΛÝÇj OÜâ#$…­õø«ž§Ùp‡ÑQ,MxTH¦ðGÑ­²4̬¬2L@WÆvÝ‘Š`AƒŽä]Ÿp}2ò[è_{9/´5?)éS9EÓ w‹'#éøäzsÍ ç7/eSŽÇ<ä0(‘C%vôÄΨÀfª,Ýÿ¬Í³LZ …VmÛØE@u”s«`š¸"ä` )×±òus—}mÞôu»æ$@YLj©v\Í•jBÓW_ –H(,0þK‹…íRÃÀÌEpm$öL•:Vá44W;ëâåDZRÍE.C&6¡ƒ„/p ‚"Ö`àÁH2Âð–„Ê0ä&¡;‰'f3B(#´³Ÿ&Ÿx¥±ùÙÔHu#„8ÊœK;NÂcl=Bë#ä?Î$tBB:LìDÃ>îDÆ—òrºHËA¼•„<çUjg< Å-Øë…·)'ƒE“ĺÉ(<RŽI=_ÅIŸÍa’‹ ñšydæŽ^BôåŒàÕ„á |Q·»õ£ÄÙÕ¥øð—ñüN§âk€¼ŽÛ3Õ&„`.þXPv_{Žâ¿,ä…¼=âC££ð“¨C™ˆ”hM‰"•q’2w‰œŠÐ¥2©*¯7‹¸8Ó+3ÂmŒ±Ë(-Õ£PßAŽ3éÂ!å=±÷(Í/‘9ŽœFõK£dø“IÂfS&âº~¦ôÚ?p•dM×.dBd½D–UñÅU›A¤Dà1È@,}ô"/åŒÂ’,>ᕬd!b—» †ˆf˜´†kp²R‡ˆy²ê‡Èƒ˜ˆˆºÑ³9r‚GŽúPщȣˆX 08Æ6̺W f­;_TJÝØ6ùëÊ£žü·‡é6ÝîÝÊmò[Yü†cÖ>ùCÙ&(þàv{p»"Ú«mÎ5ª´Éˆi´î:PJ ¦ÍSº®—“‹mögyª”àßºÛˆê ˆuíاÓSö<&|ä6;J)@Ÿ’È7£?Iê-I‚øa:þ) ™u«£žnÙ*6Drp>M>ƒcɦËL_uEÐLbWF é­§É—ð$š¦Ëúbнf¹ÈÓ0¢$«V;"Qáéº|±Jr#žs—uYVåí²¢Ûª¼ßö·È˜}ÓØbki¾µ,±-—=¨ûÅBÄ{Ù¬ª‘³ F~î™È»m·HšS›fðf ù&$¯uS<ÿ˜'«Ñ¹êâšòº­ª_µo‡‰È
+šlÒ›ÜnuBÖ$)Æ>íEw.-OkIIOPeã$
+ûÐ%GÁ¢àM\?ŽfZÑ1MÌøãX©×Gb‘ %²ó„å:ƒK…8€; æyÁ½1F b²ÁÝ8ˆmG2÷H Ì$„Y‰0ÏbNB,LˆÑ µCI¦)É]ï½™°àf&-ÄÆ…û½dWbCf² ³«I–6Ìö†™ãpf·ÓßnŽ<Ü·'ûûd æ”=…²ï?õÎÇãäýñ´]15¯
+IÍ‘Âֹ˨Ù
+òájŸäólåM×80/‹ÚZv¥+à` MOú•¸KÁ®ÞhIn»¬BÕ÷{„4¨Nu”–sþ`ÁàÝš?E1æÇØ›f{ÖS1×w!•‹q]Ù@×}iR‘x½„ýËi„MœÇo'™ð–)¹™’  [špªõÚÎÿAÓ•×(—@¯,—A•=:¸Ç·èV‡×)ã芭 KÀ¢IÀ&ð^6Ù©ôïZ[ôÃ<ˆï³”ÌþüjñÝ.=ªö` ó=¾°yñØlé”A`ûûÉh—1y,8dØë¬Ŧ]Œ•Ìés`@ÏL1yÞrf)Õ+ôEò°…ªÆ÷âË
+#VA±:‹d¹r#õ].mûŠÆ—Ö›©ºd%(/UÇ‚–Ô¼¼8&UtªµS=ÎjvVÙ3€`Q ¸G'†‘ÀyïôcÀL2ªÂáÒ‡>"èQB˜
+Å°*j1ôk
+8>T>o™‹ ™…ôˆ Ö¸8œÔ3=ÃhviöÜp[MS ø€2Çõ7íÔß@i¦úãkBüãúÑH·n»°YÅSœèÃQMÏ*ÀÇQ¹ÜR‰
+¿aå¼az_çÛ}õÛ?Ÿ·ß¯ÍÀc„üiN—§
+.­®»œøèÀ˜|`L1‚Î#ïøDuHÍ>Ë.£ÉÇéjã4ì±LØh®>ä§ò6+æsVøìY/³B6$®xÀ3d-ø¬¹ÐݦÕ72kí¬.œ,Újüæªë¢‹pAE¶²ÚëDŒº{ª*!.»u‹•PQåš³BRyÏ.—ÖOân-Ø%*i›„4—XmœßC‘ìÑ‘|µ>ß’¯h¶]íÍO¬Öv{§^‹“jø:*²€ö羓w;Z€|LUusè#Q\Úѵ-–yhï¦âkµ˜?ªO¢P;N»†–È(b™ß—¸º³G<.û%Ë)`Ëtìv ]Cr…‡5+yÔ:’ÜíCcÄT0[^+Å°ßFÃ$¥»žØî@Ó¸"kq<zw<[iäuD?èé©uXLíãH“9ž4†&;$+"éK²h6FÒ6–Ü=e9[$)%Ë=I’JSÙ!çýF~œr锆{ÎMó!ƒòúß‹R2‚”©HI… +vrI”j§÷oÖY÷”K涞>·ÕŒ‘¾êbÙ̽¾Hò$";Õ4¹ÜÓq±w]Ål8o‡…¡x« ‰§¥,/xã‚8,›K,YŽ-šVm²²ó-€í㎒v¶3±ý+íry+¤ûe^m%*V]à[, ýâ!ô:–P÷+ Aó-ºt¿™«‹jדIÚ‡^úŒvóùÀÂ"è12e/š…ÇS–S°Ìƒ§(9•IÙK‰râtO¬®y—%bCzöÒ(Éãî¹O YîH2L–ˆ’|•dµ4ýr…Ô_WÚÝ7&ÿ¢3ÁÏΑ}Çq·ÙÓâ¥Q×I»{D*â1±˜×Ói;pG‰¹ê×øÒ¨ /?¯°¨­ˆbêJHÿ­®ÚY8žÅåYþ T'’ö¬{„÷oÙqdù+½–GOõ¹2ÀÊ\ŠteŸrZšã3D3µ¢]{#HfóxüRØe'=QÚsI>“î}ò
+ñK!®*ƒïJ¹™²$ãK?¯/Ž¤f˜Ñ,&™Ê¼›\ñn@óÒh6ª­l˜áM6Æ!î9Éa‡¹ð0¯fé“œˆ?Ð`#ôþõéõ‡ï¿ûá÷îÿÿÇŸÿöúüß/_?}:?üõóO_þïëçüóË×ï¿ûé×ÏÿþòöùçŸùíóo_þuü×ÛO_¿üúÛ/_¿¼ýú÷_þƒÞoøá‡?þåOß÷?| ¿Ñ
+endstream endobj 7 0 obj [6 0 R 5 0 R] endobj 23 0 obj <</CreationDate(D:20141208091002-04'00')/Creator(Adobe Illustrator CS5)/ModDate(D:20141208091002-05'00')/Producer(Adobe PDF library 9.90)/Title(vector-src)>> endobj xref
+0 24
+0000000000 65535 f
+0000000016 00000 n
+0000000156 00000 n
+0000018299 00000 n
+0000000000 00000 f
+0000031291 00000 n
+0000031361 00000 n
+0000081630 00000 n
+0000018350 00000 n
+0000018693 00000 n
+0000031776 00000 n
+0000031663 00000 n
+0000030040 00000 n
+0000030729 00000 n
+0000030777 00000 n
+0000031547 00000 n
+0000031578 00000 n
+0000031431 00000 n
+0000031462 00000 n
+0000031850 00000 n
+0000032024 00000 n
+0000033054 00000 n
+0000050524 00000 n
+0000081659 00000 n
+trailer
+<</Size 24/Root 1 0 R/Info 23 0 R/ID[<771E40AB13143C44A9191713877B7508><101C0C7488283E45A0F1D9331CA1BD41>]>>
+startxref
+81833
+%%EOF
diff --git a/Graphics/drawables/material-launcher/vector-src.psd b/Graphics/drawables/material-launcher/vector-src.psd
new file mode 100644
index 000000000..6c62f155b
--- /dev/null
+++ b/Graphics/drawables/material-launcher/vector-src.psd
Binary files differ
diff --git a/Graphics/drawables/material-launcher/vector-src.svg b/Graphics/drawables/material-launcher/vector-src.svg
new file mode 100644
index 000000000..a4d255d48
--- /dev/null
+++ b/Graphics/drawables/material-launcher/vector-src.svg
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="626px"
+ height="626px" viewBox="0 0 626 626" enable-background="new 0 0 626 626" xml:space="preserve">
+<g id="Layer_9">
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#94C061" d="M313.25,252H265.3c1.047-0.933,2.105-1.85,3.175-2.75h44.775V252z
+ M313.25,313v18.75h-80.5V292.3c1.324-2.403,2.724-4.778,4.2-7.125V313H313.25z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#658D38" d="M232.75,292.3v39.45h80.5V313h3.7v-61h-3.7v-2.75h-44.775
+ c1.307-1.109,2.632-2.192,3.975-3.25c2.202-1.742,4.435-3.408,6.7-5c4.153-2.919,8.412-5.585,12.775-8
+ c9.974-5.517,20.499-9.717,31.575-12.6c12.134-3.167,24.934-4.75,38.4-4.75c9.199,0,18.083,0.75,26.649,2.25c3,0.5,6,1.117,9,1.85
+ c24.967,6,47.217,18.583,66.75,37.75c0.334,0.333,0.667,0.667,1,1c21.334,21.367,34.717,45.983,40.15,73.85
+ c0.2,1.167,0.416,2.351,0.649,3.551c1.4,8.3,2.101,16.85,2.101,25.649c0,0.134,0,0.283,0,0.45c0,22.934-4.601,43.967-13.8,63.1
+ c-4.601,9.434-10.284,18.417-17.051,26.95c-2,2.4-4.033,4.783-6.1,7.15c-1.934,2.133-3.917,4.217-5.95,6.25
+ c-3.5,3.5-7.066,6.8-10.7,9.899c-4.833,4.034-9.833,7.717-15,11.051c-5.333,3.399-10.833,6.416-16.5,9.05
+ c-0.533,0.2-1.033,0.416-1.5,0.649c-17.466,7.867-36.483,11.967-57.05,12.301c-0.533,0-1.05,0-1.55,0c-0.366,0-0.733,0-1.1,0
+ c-40.434,0-74.934-14.317-103.5-42.95c-0.467-0.467-0.917-0.917-1.35-1.351c-27.7-28.3-41.55-62.333-41.55-102.1
+ c0-0.167,0-0.316,0-0.45c0.042-14.928,2.042-29.053,6-42.375c0.517-1.738,1.067-3.464,1.65-5.175
+ C225.71,306.504,228.91,299.271,232.75,292.3z"/>
+</g>
+<g id="Layer_6">
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#BBD89C" d="M304.3,301.2c-0.614-0.905-1.206-1.821-1.775-2.75
+ c0.907-1.061,1.598-2.144,2.075-3.25c1.167-2.333,1.75-4.9,1.75-7.7c0-1.033-0.083-2.033-0.25-3
+ c-0.368-2.332-1.21-4.482-2.525-6.45c0.112,0.118,0.204,0.209,0.275,0.275L304,278.5c2.9,3.256,4.35,7.09,4.35,11.5
+ c0,1.759-0.233,3.425-0.7,5c-0.266,0.932-0.616,1.833-1.05,2.7C306.085,298.895,305.318,300.062,304.3,301.2z M296.825,306.425
+ c-1.841,0.65-3.816,0.975-5.925,0.975c-2.68,0-5.146-0.533-7.4-1.6c-1.783-0.85-3.433-2.033-4.95-3.55
+ c-0.894-0.895-1.669-1.836-2.325-2.825c0.106,0.106,0.214,0.214,0.325,0.325c3.434,3.433,7.55,5.15,12.35,5.15
+ c2.171,0,4.205-0.35,6.1-1.05C295.588,304.717,296.197,305.575,296.825,306.425z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#7BAD45" d="M333.575,324.85c0.758-1.002,1.6-1.968,2.524-2.899
+ c4.9-4.867,10.801-7.3,17.7-7.3c3.473,0,6.689,0.616,9.65,1.85c-0.393-0.553-0.81-1.095-1.25-1.625
+ c0.193,0.112,0.385,0.229,0.575,0.35c0.349,0.262,0.69,0.537,1.024,0.825c1.32,1.517,2.354,3.133,3.101,4.851
+ c0.1,0.199,0.199,0.383,0.3,0.55c1.1,2.033,1.866,4.184,2.3,6.45c0.063,0.356,0.121,0.715,0.175,1.074
+ c-3.332,0.468-6.757,0.7-10.274,0.7C350.13,329.677,341.521,328.068,333.575,324.85z M436.125,303.05
+ c-0.209-0.221-0.417-0.438-0.625-0.65c-1.628-1.637-3.294-3.195-5-4.675c2.639-5.218,4.613-10.71,5.925-16.475l25.851-25.775
+ c0.342,0.343,0.684,0.685,1.024,1.025c21.334,21.367,34.717,45.983,40.15,73.85c0.2,1.167,0.416,2.351,0.649,3.551
+ c1.4,8.3,2.101,16.85,2.101,25.649c0,0.134,0,0.283,0,0.45c0,22.934-4.601,43.967-13.8,63.1
+ c-4.601,9.434-10.284,18.417-17.051,26.95c-0.075,0.091-0.15,0.183-0.225,0.275l5.975-21.976c0.101-0.399,0.051-0.816-0.149-1.25
+ c-0.167-0.366-0.417-0.683-0.75-0.949c-0.134-0.034-8.167-8.784-24.101-26.25c3.448-7.858,5.157-14.851,5.125-20.976
+ c-0.005-1.372-0.005-2.605,0-3.7c0.547-2.661,0.964-5.245,1.25-7.75c0.469-4.224,0.561-8.232,0.275-12.024
+ c0.033-0.367,0.033-0.783,0-1.25c-0.4-2.634-0.884-5.25-1.45-7.851c-2.666-11.433-7.75-22.116-15.25-32.05
+ c-1.333-1.7-2.7-3.383-4.1-5.05c-1.467-1.7-2.95-3.317-4.45-4.85C437.044,303.941,436.586,303.491,436.125,303.05z M255.05,462.1
+ l46.725-46.574c1.695,2.331,3.52,4.623,5.475,6.875c0.874,0.999,1.757,1.975,2.65,2.925l51.075,81.075c-0.362,0-0.721,0-1.074,0
+ c-40.434,0-74.934-14.317-103.5-42.95C255.947,462.998,255.498,462.548,255.05,462.1z M368.6,340.05
+ c-1.316,3.908-3.649,7.324-7,10.25c-0.066,0.033-0.149,0.117-0.25,0.25c-0.1,0.033-0.149,0.084-0.149,0.15
+ c-0.101,0.033-0.167,0.083-0.2,0.149c-0.434,0.367-0.866,0.733-1.3,1.101c-0.101,0.033-0.2,0.1-0.3,0.2
+ c-2.434,1.8-4.9,3.017-7.4,3.649l-2.85,0.601c-0.267,0-0.517,0.033-0.75,0.1c-1,0.1-2.034,0.15-3.101,0.15c-0.1,0-0.2,0-0.3,0
+ s-0.2,0-0.3,0c-0.101,0-0.2,0-0.3,0c-0.134-0.067-0.284-0.101-0.45-0.101h-0.25c-4.182-0.275-7.89-1.476-11.125-3.6
+ c-2.517-3.904-3.775-8.338-3.775-13.3c0-2.092,0.226-4.092,0.675-6c9.717,4.448,20.358,6.682,31.926,6.699
+ C363.842,340.347,366.242,340.246,368.6,340.05z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#94C061" d="M301.775,415.525L255.05,462.1
+ c-27.7-28.304-41.55-62.337-41.55-102.1c0-0.167,0-0.316,0-0.45c0.089-36.006,11.589-67.339,34.5-94
+ c1.905-2.214,3.888-4.397,5.95-6.55c0.805-0.837,1.622-1.671,2.45-2.5c4.5-4.5,9.184-8.667,14.05-12.5
+ c0.165-0.13,0.332-0.264,0.5-0.4c0.336-0.264,0.669-0.522,1-0.775c0.154-0.119,0.304-0.235,0.45-0.35l13.15-8.95
+ c0.752-0.458,1.511-0.908,2.275-1.35v0.025c0.41-0.238,0.818-0.479,1.225-0.725l1.225-0.675c0.469-0.25,0.935-0.5,1.4-0.75
+ c4.524-2.416,9.158-4.565,13.9-6.45c4.045-1.601,8.171-3.009,12.375-4.225c1.177-0.34,2.36-0.665,3.55-0.975
+ c12.141-3.167,24.94-4.75,38.4-4.75c9.199,0,18.083,0.75,26.649,2.25c3,0.5,6,1.117,9,1.85c7.557,1.815,14.865,4.231,21.925,7.25
+ c6.836,10.689,10.252,22.79,10.25,36.3c0.002,10.708-2.14,20.524-6.425,29.45c-8.328-5.511-17.444-9.411-27.35-11.7
+ c-0.233-0.066-0.45-0.117-0.65-0.15c-1.434-0.333-2.916-0.633-4.45-0.9c-0.199-0.033-0.35-0.05-0.449-0.05
+ c-5.301-0.7-8.25-1.067-8.851-1.1h-0.05c-18.967-1.267-36.134,2.783-51.5,12.15c-4.233,2.567-8.316,5.55-12.25,8.95
+ c-0.1,0.066-0.167,0.15-0.2,0.25c-0.133,0.1-0.283,0.233-0.45,0.4c-0.53,0.462-1.056,0.929-1.574,1.4
+ c-2.051,1.869-3.984,3.803-5.8,5.8c-1.214-1.499-2.355-3.032-3.425-4.6c1.019-1.139,1.785-2.305,2.3-3.5
+ c0.434-0.868,0.784-1.768,1.05-2.7c0.467-1.575,0.7-3.241,0.7-5c0-4.41-1.45-8.244-4.35-11.5l-0.15-0.175
+ c-0.071-0.066-0.163-0.158-0.275-0.275c-0.069-0.076-0.144-0.159-0.225-0.25c-0.051-0.051-0.102-0.101-0.15-0.15
+ c-0.633-0.633-1.317-1.217-2.05-1.75c-2.26-1.695-4.768-2.728-7.525-3.1H293.6c-0.432-0.1-0.898-0.149-1.4-0.15
+ c-0.434-0.066-0.867-0.1-1.3-0.1c-0.333,0-0.65,0.034-0.95,0.1c-0.667,0-1.317,0.05-1.95,0.15h-0.05
+ c-0.256,0.041-0.506,0.091-0.75,0.15l-2.2,0.6c-0.44,0.165-0.874,0.348-1.3,0.55c-0.117,0.05-0.233,0.1-0.35,0.15
+ c-1.731,0.798-3.332,1.931-4.8,3.4c-0.2,0.2-0.383,0.417-0.55,0.65c-0.062,0.066-0.12,0.133-0.175,0.2
+ c-1.904,2.117-3.179,4.5-3.825,7.15c-0.333,1.4-0.5,2.85-0.5,4.35c0,3.525,0.908,6.667,2.725,9.425
+ c0.656,0.989,1.431,1.931,2.325,2.825c1.517,1.517,3.167,2.7,4.95,3.55c2.253,1.067,4.72,1.6,7.4,1.6
+ c2.109,0,4.084-0.325,5.925-0.975c1.599,2.163,3.333,4.271,5.2,6.325c0.039-0.053,0.081-0.103,0.125-0.15
+ c-0.357,0.478-0.708,0.961-1.05,1.45c-0.7,1-1.35,2-1.95,3c-1.6,2.434-3.083,4.967-4.45,7.601c-0.016,0.033-0.033,0.066-0.05,0.1
+ c-1.014,2.101-1.964,4.217-2.85,6.35c-0.633,1.601-1.216,3.233-1.75,4.9c-2.267,6.967-3.683,14.384-4.25,22.25
+ C284.278,379.587,289.603,398.679,301.775,415.525z M462.275,255.475l-25.851,25.775c1.307-5.716,1.966-11.699,1.976-17.95
+ c-0.018-11.181-2.109-21.498-6.275-30.95C442.807,238.525,452.856,246.234,462.275,255.475z M362.2,314.875
+ c-0.057-0.069-0.115-0.136-0.175-0.2c0.254,0.176,0.504,0.359,0.75,0.55C362.585,315.104,362.394,314.987,362.2,314.875z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#6C983D" d="M433,487.2c-3.879,2.285-7.846,4.368-11.9,6.25
+ c-0.533,0.2-1.033,0.416-1.5,0.649c-17.453,7.864-36.47,11.956-57.05,12.275c-0.523,0.01-1.049,0.019-1.575,0.025L309.9,425.325
+ c0.931,0.984,1.873,1.943,2.825,2.875c2.176,2.226,4.417,4.309,6.725,6.25c2.767,2.366,5.684,4.533,8.75,6.5
+ c10.033,6.566,21.25,10.816,33.649,12.75c0.101,0,0.233,0,0.4,0c5.441-0.049,10.25-0.207,14.425-0.476
+ c1.525-0.091,2.968-0.199,4.325-0.324c5.1-0.467,10.3-1.184,15.6-2.15l1.4,1.4v0.699c0.2-0.03,0.399-0.063,0.6-0.1L433,487.2z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#E2E2E2" d="M414.8,207.875c-14.804-14.35-32.604-21.525-53.399-21.525
+ c-21.301,0-39.467,7.5-54.5,22.5c-3.536,3.543-6.652,7.26-9.35,11.15c-2.247,3.233-4.206,6.583-5.875,10.05
+ c-0.465,0.25-0.931,0.5-1.4,0.75l-1.225,0.675c-0.406,0.246-0.815,0.487-1.225,0.725v-0.025
+ c3.759-9.244,9.451-17.686,17.075-25.325c15.042-15.012,33.208-22.521,54.5-22.525c21.259,0.003,39.392,7.512,54.399,22.525
+ C414.137,207.187,414.47,207.528,414.8,207.875z M408.7,213.95c0.331,0.331,0.664,0.665,1,1c3.316,3.316,6.225,6.799,8.725,10.45
+ c7.55,11.081,11.325,23.714,11.325,37.9c0,10.513-2.066,20.171-6.2,28.975c-0.072,0.155-0.147,0.314-0.225,0.475
+ c-0.525,1.09-1.084,2.165-1.675,3.225c-3.098,5.593-7.081,10.818-11.95,15.675c-4.908,4.92-10.191,8.937-15.851,12.05
+ c-5.304,2.91-10.937,5.027-16.899,6.35c-1.729,0.384-3.486,0.7-5.275,0.95c-0.607,0.085-1.216,0.16-1.825,0.225
+ c-2.757,0.317-5.573,0.476-8.449,0.476c-10.305,0-19.788-1.983-28.45-5.95c-2.097-0.97-4.146-2.053-6.15-3.25l-0.325,0.55
+ c-0.111,0.182-0.22,0.365-0.324,0.55c0.322-0.596,0.673-1.18,1.05-1.75c2.078,1.124,4.203,2.124,6.375,3
+ c7.946,3.219,16.555,4.827,25.825,4.825c3.518,0,6.942-0.232,10.274-0.7c0.526-0.073,1.052-0.156,1.575-0.25
+ c1.565-0.254,3.106-0.562,4.625-0.925c11.948-2.813,22.557-8.863,31.825-18.15c5.637-5.626,10.078-11.743,13.325-18.35
+ c0.096-0.186,0.188-0.369,0.274-0.55c4.285-8.926,6.427-18.742,6.425-29.45c0.002-13.51-3.414-25.61-10.25-36.3
+ C414.997,221.133,412.072,217.45,408.7,213.95z M295,303.85c-6.065-8.954-9.948-18.82-11.65-29.6c0.117-0.05,0.233-0.1,0.35-0.15
+ c0.426-0.203,0.859-0.386,1.3-0.55c1.337,10.945,4.862,20.97,10.575,30.075c0.549,0.882,1.115,1.757,1.7,2.625
+ c0.852,1.233,1.744,2.45,2.675,3.65c0.707,0.909,1.44,1.809,2.2,2.7c-0.044,0.047-0.086,0.097-0.125,0.15
+ c-1.867-2.054-3.601-4.163-5.2-6.325C296.197,305.575,295.588,304.717,295,303.85z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#D3D3D3" d="M305.575,223.6c-4.743,1.884-9.376,4.034-13.9,6.45
+ c1.669-3.466,3.628-6.816,5.875-10.05c2.698-3.89,5.814-7.606,9.35-11.15c15.034-15,33.2-22.5,54.5-22.5
+ c20.796,0,38.596,7.175,53.399,21.525c0.335,0.318,0.668,0.643,1,0.975c7.129,7.129,12.571,14.962,16.325,23.5
+ c4.166,9.452,6.258,19.769,6.275,30.95c-0.01,6.251-0.669,12.234-1.976,17.95c-1.312,5.765-3.286,11.257-5.925,16.475
+ c-0.037,0.074-0.07,0.148-0.1,0.225c-3.637,7.117-8.504,13.716-14.601,19.8c-10.662,10.686-22.903,17.577-36.725,20.675
+ c-0.104,0.029-0.203,0.054-0.3,0.075c-2.47,0.547-4.986,0.972-7.551,1.275c-0.869,0.103-1.744,0.194-2.625,0.274
+ c-2.357,0.196-4.758,0.297-7.199,0.3c-11.567-0.018-22.209-2.251-31.926-6.699c-1.929-0.879-3.821-1.846-5.675-2.9
+ c0.047-0.277,0.098-0.552,0.15-0.825c0.015-0.092,0.031-0.184,0.05-0.274c0.173-0.857,0.39-1.69,0.65-2.5
+ c0.388-1.194,0.871-2.336,1.449-3.426l0.051-0.125c0.104-0.185,0.213-0.368,0.324-0.55l0.325-0.55
+ c2.004,1.197,4.054,2.28,6.15,3.25c8.662,3.967,18.146,5.95,28.45,5.95c2.876,0,5.692-0.158,8.449-0.476
+ c0.609-0.064,1.218-0.14,1.825-0.225c1.789-0.25,3.547-0.566,5.275-0.95c5.963-1.322,11.596-3.439,16.899-6.35
+ c5.659-3.113,10.942-7.13,15.851-12.05c4.869-4.857,8.853-10.082,11.95-15.675c0.591-1.061,1.149-2.135,1.675-3.225
+ c0.077-0.161,0.152-0.32,0.225-0.475c4.134-8.804,6.2-18.462,6.2-28.975c0-14.186-3.775-26.819-11.325-37.9
+ c-2.5-3.65-5.408-7.134-8.725-10.45c-0.336-0.335-0.669-0.669-1-1c-13.142-12.666-28.908-18.983-47.3-18.95
+ c-18.9-0.033-35.034,6.617-48.4,19.95C310.24,217.717,307.766,220.6,305.575,223.6z M421.35,435.4l-3.1,2.449
+ c-0.2,0.134-0.366,0.25-0.5,0.351c-0.267,0.2-0.517,0.366-0.75,0.5c-1.134,0.733-2.267,1.467-3.4,2.2
+ c-0.1,0.033-0.183,0.083-0.25,0.149l65.601,65.75c0.133,0.134,0.316,0.316,0.55,0.55l1.1,1.101c1.4,1.366,3.067,2.05,5,2.05
+ c1.634-0.066,3.051-0.55,4.25-1.45c0.301-0.166,0.551-0.383,0.75-0.649c0.233-0.167,1.25,0.399,3.051,1.699
+ c1.767,1.334,5.116,4.817,10.05,10.45c4.866,5.533,11.833,9.533,20.899,12c-5.933,1-14.783,1.7-26.55,2.101
+ c-11.121,0.349-19.721-2.201-25.8-7.65c-1.462-1.316-2.778-2.8-3.95-4.45l-20.1-20.1h0.05L433,487.2l-34.4-34.45l-0.6-0.6l-1.4-1.4
+ c-5.3,0.967-10.5,1.684-15.6,2.15c-1.357,0.125-2.8,0.233-4.325,0.324l33.95-33.925c0.542,0.528,1.075,1.045,1.6,1.55
+ c4.902,4.798,8.96,8.848,12.176,12.15c-0.167,0.066-0.284,0.167-0.351,0.3c-0.899,0.733-1.767,1.45-2.6,2.15L421.35,435.4z
+ M302.15,312.6c-0.759-0.891-1.493-1.791-2.2-2.7c-0.932-1.2-1.823-2.417-2.675-3.65c-0.584-0.868-1.151-1.743-1.7-2.625
+ c-5.713-9.105-9.238-19.13-10.575-30.075l2.2-0.6c0.244-0.06,0.494-0.109,0.75-0.15H288c0.633-0.1,1.283-0.15,1.95-0.15
+ c0.3-0.066,0.617-0.1,0.95-0.1c0.434,0,0.867,0.034,1.3,0.1c0.501,0,0.968,0.05,1.4,0.15h0.025c0.946,7.487,3.054,14.487,6.325,21
+ c0.793,1.581,1.651,3.131,2.575,4.65c0.569,0.929,1.161,1.845,1.775,2.75c1.07,1.567,2.211,3.101,3.425,4.6
+ c-0.236,0.257-0.469,0.515-0.7,0.775L302.15,312.6z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#B6B6B6" d="M309.9,425.325c-0.893-0.95-1.776-1.926-2.65-2.925
+ c-1.955-2.252-3.78-4.544-5.475-6.875c-12.172-16.847-17.497-35.938-15.975-57.275c0.567-7.866,1.983-15.283,4.25-22.25
+ c0.534-1.667,1.117-3.3,1.75-4.9c0.886-2.133,1.836-4.249,2.85-6.35c0.017-0.033,0.034-0.066,0.05-0.1
+ c1.367-2.634,2.85-5.167,4.45-7.601c0.6-1,1.25-2,1.95-3c0.342-0.488,0.692-0.972,1.05-1.45l4.875-6.025
+ c0.231-0.26,0.464-0.519,0.7-0.775c1.816-1.997,3.75-3.931,5.8-5.8c0.519-0.471,1.044-0.938,1.574-1.4
+ c0.167-0.167,0.317-0.3,0.45-0.4c0.033-0.1,0.101-0.184,0.2-0.25c3.934-3.4,8.017-6.383,12.25-8.95
+ c15.366-9.367,32.533-13.417,51.5-12.15h0.05c0.601,0.033,3.55,0.4,8.851,1.1c0.1,0,0.25,0.017,0.449,0.05
+ c1.534,0.267,3.017,0.567,4.45,0.9c0.2,0.033,0.417,0.083,0.65,0.15c9.905,2.289,19.021,6.189,27.35,11.7
+ c-0.087,0.181-0.179,0.364-0.274,0.55c-7.707-4.751-16.065-8.167-25.075-10.25c-0.233-0.066-0.45-0.117-0.65-0.15
+ c-1.434-0.333-2.916-0.633-4.45-0.9c-0.199-0.033-0.35-0.05-0.449-0.05c-5.301-0.7-8.25-1.067-8.851-1.1h-0.05
+ c-18.98-1.281-36.146,2.769-51.5,12.15c-4.22,2.58-8.303,5.563-12.25,8.95c-0.1,0.066-0.167,0.15-0.2,0.25
+ c-0.133,0.1-0.283,0.233-0.45,0.4c-5.433,4.733-10.1,9.883-14,15.45c-0.7,1-1.35,2-1.95,3c-1.6,2.434-3.083,4.967-4.45,7.601
+ c-1.034,2.133-2,4.283-2.9,6.449c-0.634,1.608-1.217,3.242-1.75,4.9c-2.268,6.971-3.685,14.388-4.25,22.25
+ c-1.451,20.351,3.324,38.659,14.325,54.925c2.144,3.148,4.519,6.224,7.125,9.226c0.08,0.091,0.163,0.183,0.25,0.274
+ c1.057,1.209,2.132,2.384,3.225,3.525C311.773,427.269,310.831,426.31,309.9,425.325z M363.8,316.05
+ c0.185,0.165,0.368,0.332,0.55,0.5c2.034,1.934,3.551,4.05,4.551,6.351c0.1,0.199,0.199,0.383,0.3,0.55
+ c0.91,1.683,1.594,3.44,2.05,5.274c-0.523,0.094-1.049,0.177-1.575,0.25c-0.054-0.359-0.112-0.718-0.175-1.074
+ c-0.434-2.267-1.2-4.417-2.3-6.45c-0.101-0.167-0.2-0.351-0.3-0.55C366.153,319.183,365.12,317.566,363.8,316.05z M329.9,350.9
+ c0.853,0.762,1.744,1.445,2.675,2.05c3.235,2.124,6.943,3.324,11.125,3.6h0.25c0.166,0,0.316,0.033,0.45,0.101c0.1,0,0.199,0,0.3,0
+ c0.1,0,0.2,0,0.3,0s0.2,0,0.3,0c1.066,0,2.101-0.051,3.101-0.15c0.233-0.066,0.483-0.1,0.75-0.1L352,355.8
+ c2.5-0.633,4.967-1.85,7.4-3.649c0.1-0.101,0.199-0.167,0.3-0.2c0.434-0.367,0.866-0.733,1.3-1.101
+ c0.033-0.066,0.1-0.116,0.2-0.149c0-0.066,0.05-0.117,0.149-0.15c0.101-0.133,0.184-0.217,0.25-0.25
+ c3.351-2.926,5.684-6.342,7-10.25c0.881-0.08,1.756-0.172,2.625-0.274c-1.101,4.872-3.643,9.047-7.625,12.524
+ c-0.066,0.033-0.149,0.117-0.25,0.25c-0.1,0.033-0.149,0.084-0.149,0.15c-0.101,0.033-0.167,0.083-0.2,0.149
+ c-0.434,0.367-0.866,0.733-1.3,1.101c-0.101,0.033-0.2,0.1-0.3,0.2c-2.434,1.8-4.9,3.017-7.4,3.649l-2.85,0.601
+ c-0.267,0-0.517,0.033-0.75,0.1c-1,0.1-2.034,0.15-3.101,0.15c-0.1,0-0.2,0-0.3,0s-0.2,0-0.3,0c-0.101,0-0.2,0-0.3,0
+ c-0.134-0.067-0.284-0.101-0.45-0.101h-0.25c-5.009-0.33-9.343-1.98-13-4.95C331.72,352.795,330.787,351.895,329.9,350.9z
+ M430.5,297.725c1.706,1.48,3.372,3.038,5,4.675c0.208,0.212,0.416,0.429,0.625,0.65c-1.864-1.801-3.772-3.501-5.725-5.1
+ C430.43,297.874,430.463,297.799,430.5,297.725z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#A3A3A3" d="M462.475,367.475l-51.85,51.825l-33.95,33.925
+ c-4.175,0.269-8.983,0.427-14.425,0.476c-0.167,0-0.3,0-0.4,0c-12.399-1.934-23.616-6.184-33.649-12.75
+ c-3.066-1.967-5.983-4.134-8.75-6.5c-2.308-1.941-4.549-4.024-6.725-6.25c-1.093-1.142-2.168-2.316-3.225-3.525
+ c-0.087-0.092-0.17-0.184-0.25-0.274c-2.606-3.002-4.981-6.077-7.125-9.226c-11.001-16.266-15.776-34.574-14.325-54.925
+ c0.565-7.862,1.982-15.279,4.25-22.25c0.533-1.658,1.116-3.292,1.75-4.9c0.9-2.166,1.867-4.316,2.9-6.449
+ c1.367-2.634,2.85-5.167,4.45-7.601c0.6-1,1.25-2,1.95-3c3.9-5.566,8.566-10.716,14-15.45c0.167-0.167,0.317-0.3,0.45-0.4
+ c0.033-0.1,0.101-0.184,0.2-0.25c3.947-3.387,8.03-6.37,12.25-8.95c15.354-9.381,32.52-13.431,51.5-12.15h0.05
+ c0.601,0.033,3.55,0.4,8.851,1.1c0.1,0,0.25,0.017,0.449,0.05c1.534,0.267,3.017,0.567,4.45,0.9c0.2,0.033,0.417,0.083,0.65,0.15
+ c9.01,2.083,17.368,5.499,25.075,10.25c-3.247,6.607-7.688,12.724-13.325,18.35c-9.269,9.287-19.877,15.336-31.825,18.15
+ c-1.519,0.363-3.06,0.671-4.625,0.925c-0.456-1.834-1.14-3.592-2.05-5.274c-0.101-0.167-0.2-0.351-0.3-0.55
+ c-1-2.301-2.517-4.417-4.551-6.351c-0.182-0.168-0.365-0.335-0.55-0.5c-0.334-0.288-0.676-0.563-1.024-0.825
+ c-0.246-0.19-0.496-0.374-0.75-0.55c-3.474-2.444-7.615-3.87-12.426-4.275c-2.301-0.139-4.501,0.011-6.6,0.45
+ c-3.92,0.822-7.487,2.656-10.7,5.5c-0.233,0.167-0.45,0.351-0.649,0.551c-1.766,1.505-3.249,3.154-4.45,4.949
+ c-0.377,0.57-0.728,1.154-1.05,1.75l-0.051,0.125c-0.578,1.09-1.062,2.231-1.449,3.426c-0.261,0.81-0.478,1.643-0.65,2.5
+ c-0.019,0.091-0.035,0.183-0.05,0.274c-0.053,0.273-0.104,0.548-0.15,0.825c-0.114,0.75-0.198,1.517-0.25,2.3
+ c0,0.033,0,0.084,0,0.15c-0.09,1.646-0.04,3.246,0.15,4.8c0.082,0.744,0.199,1.478,0.35,2.2c0.834,3.666,2.601,7.066,5.3,10.2
+ c0.018,0.016,0.034,0.032,0.051,0.05h0.1c0.133,0.155,0.266,0.306,0.4,0.45c0.887,0.994,1.819,1.895,2.8,2.699
+ c3.657,2.97,7.991,4.62,13,4.95h0.25c0.166,0,0.316,0.033,0.45,0.101c0.1,0,0.199,0,0.3,0c0.1,0,0.2,0,0.3,0s0.2,0,0.3,0
+ c1.066,0,2.101-0.051,3.101-0.15c0.233-0.066,0.483-0.1,0.75-0.1L354,357.8c2.5-0.633,4.967-1.85,7.4-3.649
+ c0.1-0.101,0.199-0.167,0.3-0.2c0.434-0.367,0.866-0.733,1.3-1.101c0.033-0.066,0.1-0.116,0.2-0.149c0-0.066,0.05-0.117,0.149-0.15
+ c0.101-0.133,0.184-0.217,0.25-0.25c3.982-3.478,6.524-7.652,7.625-12.524c2.564-0.304,5.081-0.729,7.551-1.275
+ c0.097-0.021,0.196-0.046,0.3-0.075c13.821-3.098,26.063-9.989,36.725-20.675c6.097-6.083,10.964-12.683,14.601-19.8
+ c1.952,1.598,3.86,3.298,5.725,5.1c0.461,0.441,0.919,0.892,1.375,1.35c1.5,1.533,2.983,3.15,4.45,4.85
+ c1.399,1.667,2.767,3.35,4.1,5.05c7.5,9.934,12.584,20.617,15.25,32.05c0.566,2.601,1.05,5.217,1.45,7.851
+ c0.033,0.467,0.033,0.883,0,1.25C463.035,359.242,462.943,363.251,462.475,367.475z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#8F8F8F" d="M474.175,453.9h-0.024v0.05c-0.367,0.066-0.75,0.033-1.15-0.101
+ c-0.192-0.096-0.359-0.229-0.5-0.399c-0.115-0.131-0.216-0.281-0.3-0.45v-0.15c-0.134-0.333-0.134-0.683,0-1.05l-0.05,0.101
+ l6.949-25.551c0.101-0.399,0.051-0.816-0.149-1.25c-0.167-0.366-0.417-0.683-0.75-0.949c-0.134-0.034-8.167-8.784-24.101-26.25
+ c1.967-3.834,4.051-10.117,6.25-18.851c0.32-1.295,0.612-2.57,0.875-3.825c-0.005,1.095-0.005,2.328,0,3.7
+ c0.032,6.125-1.677,13.117-5.125,20.976c15.934,17.466,23.967,26.216,24.101,26.25c0.333,0.267,0.583,0.583,0.75,0.949
+ c0.2,0.434,0.25,0.851,0.149,1.25l-5.975,21.976l-0.975,3.575l0.05-0.101C474.188,453.832,474.18,453.865,474.175,453.9z
+ M527.95,473.35c6.564,5.904,9.681,14.588,9.35,26.051c-0.467,13.733-1.383,23.517-2.75,29.35c-0.233,1.167-0.767,2.25-1.6,3.25
+ l-0.15,0.3c-0.333,0.233-0.649,0.45-0.95,0.65c-0.8,0.533-1.666,0.866-2.6,1c-0.8,0.2-1.684,0.399-2.65,0.6
+ c-5.933,1-14.783,1.7-26.55,2.101c-12.402,0.389-21.669-2.827-27.8-9.65c6.079,5.449,14.679,7.999,25.8,7.65
+ c11.767-0.4,20.617-1.101,26.55-2.101c0.967-0.2,1.851-0.399,2.65-0.6c0.934-0.134,1.8-0.467,2.6-1
+ c0.301-0.2,0.617-0.417,0.95-0.65l0.15-0.3c0.833-1,1.366-2.083,1.6-3.25c1.367-5.833,2.283-15.616,2.75-29.35
+ C535.596,487.171,533.146,479.154,527.95,473.35z M496.825,476.575c-0.357,0.039-0.698,0.014-1.025-0.075
+ c-0.333-0.2-0.6-0.467-0.8-0.8c-0.066-0.066-0.1-0.15-0.1-0.25c-0.134-0.334-0.15-0.667-0.051-1l0.051-0.05l6.75-25.051
+ c0.1-0.433,0.083-0.85-0.051-1.25c1.423,1.927,2.105,3.01,2.051,3.25L496.9,476.4l-0.051,0.05
+ C496.838,476.489,496.83,476.531,496.825,476.575z M398.6,452.75c-0.2,0.036-0.399,0.069-0.6,0.1v-0.699L398.6,452.75z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#DBDBDB" d="M410.625,419.3l51.85-51.825c-0.286,2.505-0.703,5.089-1.25,7.75
+ c-0.263,1.255-0.555,2.53-0.875,3.825c-2.199,8.733-4.283,15.017-6.25,18.851c15.934,17.466,23.967,26.216,24.101,26.25
+ c0.333,0.267,0.583,0.583,0.75,0.949c0.2,0.434,0.25,0.851,0.149,1.25L472.15,451.9l0.05-0.101c-0.134,0.367-0.134,0.717,0,1.05
+ V453c0.084,0.169,0.185,0.319,0.3,0.45c0.141,0.17,0.308,0.304,0.5,0.399c0.4,0.134,0.783,0.167,1.15,0.101v-0.05h0.024
+ l25.325-6.65c0.434-0.233,0.833-0.217,1.2,0.05c0.333,0.167,0.633,0.434,0.899,0.8c0.134,0.4,0.15,0.817,0.051,1.25L494.9,474.4
+ l-0.051,0.05c-0.1,0.333-0.083,0.666,0.051,1c0,0.1,0.033,0.184,0.1,0.25c0.2,0.333,0.467,0.6,0.8,0.8
+ c0.327,0.089,0.668,0.114,1.025,0.075c0.039-0.01,0.081-0.018,0.125-0.025v0.101l0.1-0.101l26.65-7
+ c1.576,1.142,2.992,2.408,4.25,3.8c5.195,5.805,7.646,13.821,7.35,24.051c-0.467,13.733-1.383,23.517-2.75,29.35
+ c-0.233,1.167-0.767,2.25-1.6,3.25l-0.15,0.3c-0.333,0.233-0.649,0.45-0.95,0.65c-0.8,0.533-1.666,0.866-2.6,1
+ c-0.8,0.2-1.684,0.399-2.65,0.6c-21.5-21.6-32.816-32.934-33.949-34L430.55,438.2c-0.2-0.101-0.366-0.233-0.5-0.4l-5.2-5.25
+ l-0.149,0.15c-0.101,0.066-0.2,0.166-0.3,0.3c-3.216-3.303-7.273-7.353-12.176-12.15C411.7,420.345,411.167,419.828,410.625,419.3z
+ M421.35,435.4l0.101,0.05h-0.101V435.4z"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C8C8" d="M421.35,435.4v0.05h0.101c0.833-0.7,1.7-1.417,2.6-2.15
+ c0.066-0.133,0.184-0.233,0.351-0.3c0.1-0.134,0.199-0.233,0.3-0.3l0.149-0.15l5.2,5.25c0.134,0.167,0.3,0.3,0.5,0.4l60.101,60.35
+ c1.133,1.066,12.449,12.4,33.949,34c-9.066-2.467-16.033-6.467-20.899-12c-4.934-5.633-8.283-9.116-10.05-10.45
+ c-1.801-1.3-2.817-1.866-3.051-1.699c-0.199,0.267-0.449,0.483-0.75,0.649c-1.199,0.9-2.616,1.384-4.25,1.45
+ c-1.933,0-3.6-0.684-5-2.05l-1.1-1.101c-0.233-0.233-0.417-0.416-0.55-0.55l-65.601-65.75c0.067-0.066,0.15-0.116,0.25-0.149
+ c1.134-0.733,2.267-1.467,3.4-2.2c0.233-0.134,0.483-0.3,0.75-0.5c0.134-0.101,0.3-0.217,0.5-0.351L421.35,435.4z"/>
+</g>
+</svg>
diff --git a/Graphics/drawables/material-launcher/vector.psd b/Graphics/drawables/material-launcher/vector.psd
new file mode 100644
index 000000000..71885615b
--- /dev/null
+++ b/Graphics/drawables/material-launcher/vector.psd
Binary files differ
diff --git a/Resources/graphics/originals/gnupg-infographic/README b/Graphics/drawables/originals/gnupg-infographic/README
index f29c0a84a..f29c0a84a 100644
--- a/Resources/graphics/originals/gnupg-infographic/README
+++ b/Graphics/drawables/originals/gnupg-infographic/README
diff --git a/Resources/graphics/originals/gnupg-infographic/gnupg-infographic.png b/Graphics/drawables/originals/gnupg-infographic/gnupg-infographic.png
index 52b8f21ac..52b8f21ac 100644
--- a/Resources/graphics/originals/gnupg-infographic/gnupg-infographic.png
+++ b/Graphics/drawables/originals/gnupg-infographic/gnupg-infographic.png
Binary files differ
diff --git a/Resources/graphics/originals/gnupg-infographic/gnupg-infographic.svg b/Graphics/drawables/originals/gnupg-infographic/gnupg-infographic.svg
index 9a17421e2..9a17421e2 100644
--- a/Resources/graphics/originals/gnupg-infographic/gnupg-infographic.svg
+++ b/Graphics/drawables/originals/gnupg-infographic/gnupg-infographic.svg
diff --git a/Resources/graphics/originals/ic_action_qr_code/ic_menu_qr_code.svg b/Graphics/drawables/originals/ic_action_qr_code/ic_menu_qr_code.svg
index 5cbe9defc..5cbe9defc 100644
--- a/Resources/graphics/originals/ic_action_qr_code/ic_menu_qr_code.svg
+++ b/Graphics/drawables/originals/ic_action_qr_code/ic_menu_qr_code.svg
diff --git a/Graphics/drawables/originals/ic_cloud_24px.svg b/Graphics/drawables/originals/ic_cloud_24px.svg
new file mode 100644
index 000000000..63f946c3e
--- /dev/null
+++ b/Graphics/drawables/originals/ic_cloud_24px.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z"/></svg> \ No newline at end of file
diff --git a/Resources/graphics/originals/ic_launcher/AUTHORS b/Graphics/drawables/originals/ic_launcher-old/AUTHORS
index dbfcfb4fc..dbfcfb4fc 100644
--- a/Resources/graphics/originals/ic_launcher/AUTHORS
+++ b/Graphics/drawables/originals/ic_launcher-old/AUTHORS
diff --git a/Resources/graphics/originals/ic_launcher/COPYING b/Graphics/drawables/originals/ic_launcher-old/COPYING
index 2faa27568..2faa27568 100644
--- a/Resources/graphics/originals/ic_launcher/COPYING
+++ b/Graphics/drawables/originals/ic_launcher-old/COPYING
diff --git a/Resources/graphics/originals/ic_launcher/kgpg_key2_kopete.svgz b/Graphics/drawables/originals/ic_launcher-old/kgpg_key2_kopete.svgz
index 2d43afb83..2d43afb83 100644
--- a/Resources/graphics/originals/ic_launcher/kgpg_key2_kopete.svgz
+++ b/Graphics/drawables/originals/ic_launcher-old/kgpg_key2_kopete.svgz
Binary files differ
diff --git a/Graphics/drawables/originals/ic_search_24px.svg b/Graphics/drawables/originals/ic_search_24px.svg
new file mode 100644
index 000000000..12440059b
--- /dev/null
+++ b/Graphics/drawables/originals/ic_search_24px.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg> \ No newline at end of file
diff --git a/Resources/graphics/originals/modernpgp-icons/README.md b/Graphics/drawables/originals/modernpgp-icons/README.md
index c3cc37e5d..c3cc37e5d 100644
--- a/Resources/graphics/originals/modernpgp-icons/README.md
+++ b/Graphics/drawables/originals/modernpgp-icons/README.md
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed.png
index 0003ce164..0003ce164 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed.svg b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed.svg
index 286e89297..286e89297 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@200.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@200.png
index 693b7c6f7..693b7c6f7 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@300.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@300.png
index 6dea7ba27..6dea7ba27 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@512x.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@512x.png
index 7cc3b343b..7cc3b343b 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-closed@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-closed@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error.png
index e2bd291d2..e2bd291d2 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error.svg b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error.svg
index d3c4e1d1d..d3c4e1d1d 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error@200.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@200.png
index 6a4ddf7ee..6a4ddf7ee 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error@300.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@300.png
index 225a82f43..225a82f43 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error@512x.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@512x.png
index 22c5cb14b..22c5cb14b 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-error@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-error@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open.png
index 30b57db5d..30b57db5d 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open.svg b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open.svg
index 9beb127af..9beb127af 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open@200.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@200.png
index 056e1b64b..056e1b64b 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open@300.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@300.png
index a0a12eada..a0a12eada 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open@512x.png b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@512x.png
index 06a576338..06a576338 100644
--- a/Resources/graphics/originals/modernpgp-icons/encryption/lock-open@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/encryption/lock-open@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint.png b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint.png
index c4b79f295..c4b79f295 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint.png
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint.svg b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint.svg
index a5ad87050..a5ad87050 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@200.png b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@200.png
index 305dac198..305dac198 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@300.png b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@300.png
index eff983359..eff983359 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@512x.png b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@512x.png
index 310b224aa..310b224aa 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-fingerprint@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-fingerprint@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-key.png b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key.png
index 66f4708fc..66f4708fc 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-key.png
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-key.svg b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key.svg
index f584037c6..f584037c6 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-key.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-key@200.png b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key@200.png
index ccd7e10a1..ccd7e10a1 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-key@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-key@300.png b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key@300.png
index 551f2ae69..551f2ae69 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-key@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/keys/icon-key@512x.png b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key@512x.png
index 1a4320ec6..1a4320ec6 100644
--- a/Resources/graphics/originals/modernpgp-icons/keys/icon-key@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/keys/icon-key@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout.png
index 661da48e2..661da48e2 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout.svg
index 61ac8fdd0..61ac8fdd0 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@200.png
index 965888294..965888294 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@300.png
index 8c722274a..8c722274a 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@512x.png
index 6c6038df0..6c6038df0 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired-cutout@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired-cutout@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired.png
index 75a064188..75a064188 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired.svg
index 1d280572f..1d280572f 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@200.png
index 492ac9e80..492ac9e80 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@300.png
index 1ef0ac143..1ef0ac143 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@512x.png
index 6b82cf9ab..6b82cf9ab 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-expired@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-expired@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout.png
index d2bfb07a0..d2bfb07a0 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout.svg
index 61fd2ace0..61fd2ace0 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@200.png
index a46488d2b..a46488d2b 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@300.png
index dbb3f0639..dbb3f0639 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@512x.png
index 7a6966cbf..7a6966cbf 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid-cutout@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid-cutout@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid.png
index 9bd4ee24a..9bd4ee24a 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid.svg
index 3eb204fdd..3eb204fdd 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@200.png
index 1033831aa..1033831aa 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@300.png
index 78b62797a..78b62797a 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@512x.png
index 7de3afefc..7de3afefc 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-invalid@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-invalid@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout.png
index a5ce2e419..a5ce2e419 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout.svg
index 0421286fe..0421286fe 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@200.png
index 7da8f0888..7da8f0888 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@300.png
index 73e769750..73e769750 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@512x.png
index a07fbf223..a07fbf223 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked-cutout@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked-cutout@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked.png
index 66f74079a..66f74079a 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked.svg
index 5b6f7a420..5b6f7a420 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@200.png
index b9f891b97..b9f891b97 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@300.png
index 2c333d4f9..2c333d4f9 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@512x.png
index 4612b19db..4612b19db 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-revoked@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-revoked@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout.png
index 1cef14805..1cef14805 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout.svg
index 402bffcaa..402bffcaa 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@200.png
index fcf3cb4a6..fcf3cb4a6 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@300.png
index 33a093b71..33a093b71 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@512x.png
index 011c503f0..011c503f0 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown-cutout@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown-cutout@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown.png
index 0b04995b8..0b04995b8 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown.svg
index f0494aa33..f0494aa33 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@200.png
index bea9ecaf2..bea9ecaf2 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@300.png
index 2baa3b700..2baa3b700 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@512x.png
index 54dac1caa..54dac1caa 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unknown@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unknown@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout.png
index 51c2ed7eb..51c2ed7eb 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout.svg
index ffa98580a..ffa98580a 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@200.png
index 10d328081..10d328081 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@300.png
index b8fe6a994..b8fe6a994 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@512x.png
index 93e562e3b..93e562e3b 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified-cutout@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified-cutout@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified.png
index 00989a976..00989a976 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified.svg
index 6ce6d14dd..6ce6d14dd 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@200.png
index 2ee36bb15..2ee36bb15 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@300.png
index b1f30b334..b1f30b334 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@512x.png
index 56193245c..56193245c 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-unverified@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-unverified@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout.png
index 9a8c5efcd..9a8c5efcd 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout.svg
index 04356a977..04356a977 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@200.png
index 1adfc7fb6..1adfc7fb6 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@300.png
index 227504e6b..227504e6b 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@512x.png
index cf8ad067d..cf8ad067d 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified-cutout@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified-cutout@512x.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified.png
index e19125e3c..e19125e3c 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified.svg b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified.svg
index 197273c79..197273c79 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified.svg
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified.svg
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@200.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@200.png
index 9c3063010..9c3063010 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@200.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@200.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@300.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@300.png
index 5de04efe1..5de04efe1 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@300.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@300.png
Binary files differ
diff --git a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@512x.png b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@512x.png
index d52221f6c..d52221f6c 100644
--- a/Resources/graphics/originals/modernpgp-icons/signatures/signature-verified@512x.png
+++ b/Graphics/drawables/originals/modernpgp-icons/signatures/signature-verified@512x.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_18dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_18dp.png
new file mode 100644
index 000000000..2f4925ed0
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_24dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_24dp.png
new file mode 100644
index 000000000..684c2cb81
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_36dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_36dp.png
new file mode 100644
index 000000000..f05f51239
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_48dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_48dp.png
new file mode 100644
index 000000000..5789581cc
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_18dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_18dp.png
new file mode 100644
index 000000000..01cc481bf
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_24dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_24dp.png
new file mode 100644
index 000000000..fedf39013
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_36dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_36dp.png
new file mode 100644
index 000000000..e97bebf0e
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_48dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_48dp.png
new file mode 100644
index 000000000..7e8fa6ba2
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_18dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_18dp.png
new file mode 100644
index 000000000..b22411115
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_24dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..1d87415c5
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_36dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_36dp.png
new file mode 100644
index 000000000..1ef58907d
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_48dp.png b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_48dp.png
new file mode 100644
index 000000000..484856b3f
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-hdpi/ic_nfc_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_18dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_18dp.png
new file mode 100644
index 000000000..18b1f33c4
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_24dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_24dp.png
new file mode 100644
index 000000000..21f86d95e
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_36dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_36dp.png
new file mode 100644
index 000000000..684c2cb81
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_48dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_48dp.png
new file mode 100644
index 000000000..c987c1249
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_18dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_18dp.png
new file mode 100644
index 000000000..a2eb50380
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_24dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_24dp.png
new file mode 100644
index 000000000..f8f6c3812
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_36dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_36dp.png
new file mode 100644
index 000000000..fedf39013
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_48dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_48dp.png
new file mode 100644
index 000000000..04e0bf781
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_18dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_18dp.png
new file mode 100644
index 000000000..71e38338d
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_24dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..65ae04b7c
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_36dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_36dp.png
new file mode 100644
index 000000000..1d87415c5
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_48dp.png b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_48dp.png
new file mode 100644
index 000000000..44b9006ab
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-mdpi/ic_nfc_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_18dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_18dp.png
new file mode 100644
index 000000000..684c2cb81
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_24dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_24dp.png
new file mode 100644
index 000000000..c987c1249
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_36dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_36dp.png
new file mode 100644
index 000000000..5789581cc
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_48dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_48dp.png
new file mode 100644
index 000000000..aabd4c0b6
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_18dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_18dp.png
new file mode 100644
index 000000000..fedf39013
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_24dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_24dp.png
new file mode 100644
index 000000000..04e0bf781
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_36dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_36dp.png
new file mode 100644
index 000000000..7e8fa6ba2
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_48dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_48dp.png
new file mode 100644
index 000000000..ee00975dc
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_18dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_18dp.png
new file mode 100644
index 000000000..1d87415c5
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_24dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..44b9006ab
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_36dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_36dp.png
new file mode 100644
index 000000000..484856b3f
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_48dp.png b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_48dp.png
new file mode 100644
index 000000000..c8f25bbf7
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xhdpi/ic_nfc_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_18dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_18dp.png
new file mode 100644
index 000000000..f05f51239
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_24dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_24dp.png
new file mode 100644
index 000000000..5789581cc
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_36dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_36dp.png
new file mode 100644
index 000000000..2f6bc956b
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_48dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_48dp.png
new file mode 100644
index 000000000..e9caeea57
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_18dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_18dp.png
new file mode 100644
index 000000000..e97bebf0e
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_24dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_24dp.png
new file mode 100644
index 000000000..7e8fa6ba2
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_36dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_36dp.png
new file mode 100644
index 000000000..b3bb585a5
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_48dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_48dp.png
new file mode 100644
index 000000000..c31ee82b6
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_18dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_18dp.png
new file mode 100644
index 000000000..1ef58907d
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_24dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..484856b3f
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_36dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_36dp.png
new file mode 100644
index 000000000..adc28d66c
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_48dp.png b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_48dp.png
new file mode 100644
index 000000000..5cd14b5cf
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxhdpi/ic_nfc_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_18dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_18dp.png
new file mode 100644
index 000000000..5789581cc
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_24dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_24dp.png
new file mode 100644
index 000000000..aabd4c0b6
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_36dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_36dp.png
new file mode 100644
index 000000000..e9caeea57
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_48dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_48dp.png
new file mode 100644
index 000000000..841d1a80a
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_18dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_18dp.png
new file mode 100644
index 000000000..7e8fa6ba2
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_24dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_24dp.png
new file mode 100644
index 000000000..ee00975dc
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_36dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_36dp.png
new file mode 100644
index 000000000..c31ee82b6
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_48dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_48dp.png
new file mode 100644
index 000000000..721f42e4b
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_18dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_18dp.png
new file mode 100644
index 000000000..484856b3f
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_24dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..c8f25bbf7
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_36dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_36dp.png
new file mode 100644
index 000000000..5cd14b5cf
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_48dp.png b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_48dp.png
new file mode 100644
index 000000000..4ac095cc3
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable-xxxhdpi/ic_nfc_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/nfc/drawable/nfc.xml b/Graphics/drawables/originals/nfc/drawable/nfc.xml
new file mode 100644
index 000000000..a0ce6f228
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/drawable/nfc.xml
@@ -0,0 +1,8 @@
+<!-- drawable/nfc.xml -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="#000" android:pathData="M10.59,7.66C10.59,7.66 11.19,7.39 11.57,7.82C11.95,8.26 12.92,9.94 12.92,11.62C12.92,13.3 12.5,15.09 12.05,15.68C11.62,16.28 11.19,16.28 10.86,16.06C10.54,15.85 5.5,12 5.23,11.89C4.95,11.78 4.85,12.05 5.12,13.5C5.39,15 4.95,15.41 4.57,15.47C4.2,15.5 3.06,15.2 3,12.16C2.95,9.13 3.76,8.64 4.14,8.64C4.85,8.64 10.27,13.5 10.64,13.46C10.97,13.41 11.13,11.35 10.5,9.72C9.78,7.96 10.59,7.66 10.59,7.66M19.3,4.63C21.12,8.24 21,11.66 21,12C21,12.34 21.12,15.76 19.3,19.37C19.3,19.37 18.83,19.92 18.12,19.59C17.42,19.26 17.66,18.4 17.66,18.4C17.66,18.4 19.14,15.55 19.1,12.05V12C19.14,8.5 17.66,5.6 17.66,5.6C17.66,5.6 17.42,4.74 18.12,4.41C18.83,4.08 19.3,4.63 19.3,4.63M15.77,6.25C17.26,8.96 17.16,11.66 17.14,12C17.16,12.34 17.26,14.92 15.77,17.85C15.77,17.85 15.3,18.4 14.59,18.07C13.89,17.74 14.13,16.88 14.13,16.88C14.13,16.88 15.09,15.5 15.24,12.05V12C15.14,8.53 14.13,7.23 14.13,7.23C14.13,7.23 13.89,6.36 14.59,6.04C15.3,5.71 15.77,6.25 15.77,6.25Z" />
+</vector> \ No newline at end of file
diff --git a/Graphics/drawables/originals/nfc/readme.txt b/Graphics/drawables/originals/nfc/readme.txt
new file mode 100644
index 000000000..cc9018452
--- /dev/null
+++ b/Graphics/drawables/originals/nfc/readme.txt
@@ -0,0 +1,5 @@
+Thanks for visiting MaterialDesignIcons.com
+Check back often for new icons and follow @MaterialIcons for updates.
+
+Icon: nfc
+By: Austin Andrews \ No newline at end of file
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_18dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_18dp.png
new file mode 100644
index 000000000..d5e2bffeb
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_24dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_24dp.png
new file mode 100644
index 000000000..75231c4c4
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_36dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_36dp.png
new file mode 100644
index 000000000..0e59ee75a
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_48dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_48dp.png
new file mode 100644
index 000000000..063776cb6
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_18dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_18dp.png
new file mode 100644
index 000000000..97a120be1
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_24dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_24dp.png
new file mode 100644
index 000000000..956eb886c
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_36dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_36dp.png
new file mode 100644
index 000000000..b171b7142
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_48dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_48dp.png
new file mode 100644
index 000000000..1a2d6ed75
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_18dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_18dp.png
new file mode 100644
index 000000000..667202070
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_24dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..261f4a5ab
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_36dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_36dp.png
new file mode 100644
index 000000000..2b1fea929
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_48dp.png b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_48dp.png
new file mode 100644
index 000000000..c4f2f57c9
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-hdpi/ic_qrcode_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_18dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_18dp.png
new file mode 100644
index 000000000..b9dfb309c
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_24dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_24dp.png
new file mode 100644
index 000000000..f2e6ad3e7
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_36dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_36dp.png
new file mode 100644
index 000000000..75231c4c4
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_48dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_48dp.png
new file mode 100644
index 000000000..593aa8f2a
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_18dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_18dp.png
new file mode 100644
index 000000000..7ecef0044
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_24dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_24dp.png
new file mode 100644
index 000000000..af36e585c
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_36dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_36dp.png
new file mode 100644
index 000000000..956eb886c
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_48dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_48dp.png
new file mode 100644
index 000000000..347b0378a
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_18dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_18dp.png
new file mode 100644
index 000000000..be2f80974
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_24dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..5cf552b13
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_36dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_36dp.png
new file mode 100644
index 000000000..261f4a5ab
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_48dp.png b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_48dp.png
new file mode 100644
index 000000000..a2c6ade61
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-mdpi/ic_qrcode_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_18dp.png
new file mode 100644
index 000000000..75231c4c4
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_24dp.png
new file mode 100644
index 000000000..593aa8f2a
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_36dp.png
new file mode 100644
index 000000000..063776cb6
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_48dp.png
new file mode 100644
index 000000000..43daf96e6
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_18dp.png
new file mode 100644
index 000000000..956eb886c
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_24dp.png
new file mode 100644
index 000000000..347b0378a
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_36dp.png
new file mode 100644
index 000000000..1a2d6ed75
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_48dp.png
new file mode 100644
index 000000000..bd6700d03
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_18dp.png
new file mode 100644
index 000000000..261f4a5ab
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..a2c6ade61
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_36dp.png
new file mode 100644
index 000000000..c4f2f57c9
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_48dp.png
new file mode 100644
index 000000000..e795f80a5
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xhdpi/ic_qrcode_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_18dp.png
new file mode 100644
index 000000000..0e59ee75a
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_24dp.png
new file mode 100644
index 000000000..063776cb6
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_36dp.png
new file mode 100644
index 000000000..f87c96984
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_48dp.png
new file mode 100644
index 000000000..d52c08b40
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_18dp.png
new file mode 100644
index 000000000..b171b7142
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_24dp.png
new file mode 100644
index 000000000..1a2d6ed75
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_36dp.png
new file mode 100644
index 000000000..59cb56370
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_48dp.png
new file mode 100644
index 000000000..8ff5607c4
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_18dp.png
new file mode 100644
index 000000000..2b1fea929
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..c4f2f57c9
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_36dp.png
new file mode 100644
index 000000000..f138dfa61
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_48dp.png
new file mode 100644
index 000000000..3b15d3fcc
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxhdpi/ic_qrcode_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_18dp.png
new file mode 100644
index 000000000..063776cb6
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_24dp.png
new file mode 100644
index 000000000..43daf96e6
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_36dp.png
new file mode 100644
index 000000000..d52c08b40
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_48dp.png
new file mode 100644
index 000000000..0ac5a7987
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_black_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_18dp.png
new file mode 100644
index 000000000..1a2d6ed75
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_24dp.png
new file mode 100644
index 000000000..bd6700d03
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_36dp.png
new file mode 100644
index 000000000..8ff5607c4
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_48dp.png
new file mode 100644
index 000000000..9412036dd
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_grey600_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_18dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_18dp.png
new file mode 100644
index 000000000..c4f2f57c9
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_18dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_24dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..e795f80a5
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_36dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_36dp.png
new file mode 100644
index 000000000..3b15d3fcc
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_36dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_48dp.png b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_48dp.png
new file mode 100644
index 000000000..5de99e5c4
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable-xxxhdpi/ic_qrcode_white_48dp.png
Binary files differ
diff --git a/Graphics/drawables/originals/qrcode/drawable/qrcode.xml b/Graphics/drawables/originals/qrcode/drawable/qrcode.xml
new file mode 100644
index 000000000..7d59b50e9
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/drawable/qrcode.xml
@@ -0,0 +1,8 @@
+<!-- drawable/qrcode.xml -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="#000" android:pathData="M5,5H7V7H5V5M1,1H11V11H1V1M3,3V9H9V3H3M5,17H7V19H5V17M1,13H11V23H1V13M3,15V21H9V15H3M17,5H19V7H17V5M13,1H23V11H13V1M15,3V9H21V3H15M13,13H17V15H19V13H23V15H19V17H23V23H19V21H15V23H13V21H15V19H13V13M21,21V19H19V21H21M19,17H17V15H15V19H19V17Z" />
+</vector> \ No newline at end of file
diff --git a/Graphics/drawables/originals/qrcode/readme.txt b/Graphics/drawables/originals/qrcode/readme.txt
new file mode 100644
index 000000000..cc545383e
--- /dev/null
+++ b/Graphics/drawables/originals/qrcode/readme.txt
@@ -0,0 +1,5 @@
+Thanks for visiting MaterialDesignIcons.com
+Check back often for new icons and follow @MaterialIcons for updates.
+
+Icon: qrcode
+By: Austin Andrews \ No newline at end of file
diff --git a/Resources/graphics/originals/tango or oxygen/1270234450.svg b/Graphics/drawables/originals/tango or oxygen/1270234450.svg
index d27c83313..d27c83313 100644
--- a/Resources/graphics/originals/tango or oxygen/1270234450.svg
+++ b/Graphics/drawables/originals/tango or oxygen/1270234450.svg
diff --git a/Resources/graphics/originals/tango or oxygen/application-pgp-signature.svg b/Graphics/drawables/originals/tango or oxygen/application-pgp-signature.svg
index 1d4d7639a..1d4d7639a 100644
--- a/Resources/graphics/originals/tango or oxygen/application-pgp-signature.svg
+++ b/Graphics/drawables/originals/tango or oxygen/application-pgp-signature.svg
diff --git a/Resources/graphics/originals/tango or oxygen/application-pkcs7-signature.svg b/Graphics/drawables/originals/tango or oxygen/application-pkcs7-signature.svg
index 1d4d7639a..1d4d7639a 100644
--- a/Resources/graphics/originals/tango or oxygen/application-pkcs7-signature.svg
+++ b/Graphics/drawables/originals/tango or oxygen/application-pkcs7-signature.svg
diff --git a/Resources/graphics/originals/tango or oxygen/osa_id_card.svg b/Graphics/drawables/originals/tango or oxygen/osa_id_card.svg
index c31482615..c31482615 100644
--- a/Resources/graphics/originals/tango or oxygen/osa_id_card.svg
+++ b/Graphics/drawables/originals/tango or oxygen/osa_id_card.svg
diff --git a/Resources/graphics/originals/tango or oxygen/osa_padlock.svg b/Graphics/drawables/originals/tango or oxygen/osa_padlock.svg
index 652d905c1..652d905c1 100644
--- a/Resources/graphics/originals/tango or oxygen/osa_padlock.svg
+++ b/Graphics/drawables/originals/tango or oxygen/osa_padlock.svg
diff --git a/Resources/graphics/originals/tango or oxygen/tango-style-pen.svg b/Graphics/drawables/originals/tango or oxygen/tango-style-pen.svg
index 4f3486dd1..4f3486dd1 100644
--- a/Resources/graphics/originals/tango or oxygen/tango-style-pen.svg
+++ b/Graphics/drawables/originals/tango or oxygen/tango-style-pen.svg
diff --git a/Resources/graphics/status_lock_closed.svg b/Graphics/drawables/status_lock_closed.svg
index 286e89297..286e89297 100644
--- a/Resources/graphics/status_lock_closed.svg
+++ b/Graphics/drawables/status_lock_closed.svg
diff --git a/Resources/graphics/status_lock_error.svg b/Graphics/drawables/status_lock_error.svg
index d3c4e1d1d..d3c4e1d1d 100644
--- a/Resources/graphics/status_lock_error.svg
+++ b/Graphics/drawables/status_lock_error.svg
diff --git a/Resources/graphics/status_lock_open.svg b/Graphics/drawables/status_lock_open.svg
index 9beb127af..9beb127af 100644
--- a/Resources/graphics/status_lock_open.svg
+++ b/Graphics/drawables/status_lock_open.svg
diff --git a/Resources/graphics/status_signature_expired.svg b/Graphics/drawables/status_signature_expired.svg
index 1d280572f..1d280572f 100644
--- a/Resources/graphics/status_signature_expired.svg
+++ b/Graphics/drawables/status_signature_expired.svg
diff --git a/Resources/graphics/status_signature_expired_cutout.svg b/Graphics/drawables/status_signature_expired_cutout.svg
index 61ac8fdd0..61ac8fdd0 100644
--- a/Resources/graphics/status_signature_expired_cutout.svg
+++ b/Graphics/drawables/status_signature_expired_cutout.svg
diff --git a/Resources/graphics/status_signature_invalid.svg b/Graphics/drawables/status_signature_invalid.svg
index 3eb204fdd..3eb204fdd 100644
--- a/Resources/graphics/status_signature_invalid.svg
+++ b/Graphics/drawables/status_signature_invalid.svg
diff --git a/Resources/graphics/status_signature_invalid_cutout.svg b/Graphics/drawables/status_signature_invalid_cutout.svg
index 61fd2ace0..61fd2ace0 100644
--- a/Resources/graphics/status_signature_invalid_cutout.svg
+++ b/Graphics/drawables/status_signature_invalid_cutout.svg
diff --git a/Resources/graphics/status_signature_revoked.svg b/Graphics/drawables/status_signature_revoked.svg
index 5b6f7a420..5b6f7a420 100644
--- a/Resources/graphics/status_signature_revoked.svg
+++ b/Graphics/drawables/status_signature_revoked.svg
diff --git a/Resources/graphics/status_signature_revoked_cutout.svg b/Graphics/drawables/status_signature_revoked_cutout.svg
index 0421286fe..0421286fe 100644
--- a/Resources/graphics/status_signature_revoked_cutout.svg
+++ b/Graphics/drawables/status_signature_revoked_cutout.svg
diff --git a/Resources/graphics/status_signature_unknown.svg b/Graphics/drawables/status_signature_unknown.svg
index f0494aa33..f0494aa33 100644
--- a/Resources/graphics/status_signature_unknown.svg
+++ b/Graphics/drawables/status_signature_unknown.svg
diff --git a/Resources/graphics/status_signature_unknown_cutout.svg b/Graphics/drawables/status_signature_unknown_cutout.svg
index 402bffcaa..402bffcaa 100644
--- a/Resources/graphics/status_signature_unknown_cutout.svg
+++ b/Graphics/drawables/status_signature_unknown_cutout.svg
diff --git a/Resources/graphics/status_signature_unverified.svg b/Graphics/drawables/status_signature_unverified.svg
index 6ce6d14dd..6ce6d14dd 100644
--- a/Resources/graphics/status_signature_unverified.svg
+++ b/Graphics/drawables/status_signature_unverified.svg
diff --git a/Resources/graphics/status_signature_unverified_cutout.svg b/Graphics/drawables/status_signature_unverified_cutout.svg
index ffa98580a..ffa98580a 100644
--- a/Resources/graphics/status_signature_unverified_cutout.svg
+++ b/Graphics/drawables/status_signature_unverified_cutout.svg
diff --git a/Resources/graphics/status_signature_verified.svg b/Graphics/drawables/status_signature_verified.svg
index 197273c79..197273c79 100644
--- a/Resources/graphics/status_signature_verified.svg
+++ b/Graphics/drawables/status_signature_verified.svg
diff --git a/Resources/graphics/status_signature_verified_cutout.svg b/Graphics/drawables/status_signature_verified_cutout.svg
index 04356a977..04356a977 100644
--- a/Resources/graphics/status_signature_verified_cutout.svg
+++ b/Graphics/drawables/status_signature_verified_cutout.svg
diff --git a/Graphics/get-material-icons.sh b/Graphics/get-material-icons.sh
new file mode 100755
index 000000000..f24735642
--- /dev/null
+++ b/Graphics/get-material-icons.sh
@@ -0,0 +1,28 @@
+# https://google.github.io/material-design-icons/
+cd ./android-icon-copier/
+python copy OpenKeychain action white search 24
+python copy OpenKeychain navigation white arrow_back 24
+python copy OpenKeychain navigation white close 24
+python copy OpenKeychain navigation white check 24
+python copy OpenKeychain navigation black expand_less 24
+python copy OpenKeychain navigation black expand_more 24
+python copy OpenKeychain navigation white refresh 24
+python copy OpenKeychain av white repeat 24
+python copy OpenKeychain av grey repeat 24
+python copy OpenKeychain editor white mode_edit 24
+
+# navigation drawer sections
+python copy OpenKeychain communication black vpn_key 24
+python copy OpenKeychain action black lock 24
+python copy OpenKeychain navigation black apps 24
+python copy OpenKeychain action black help 24
+python copy OpenKeychain action black settings 24
+
+# floating action button
+python copy OpenKeychain av white play_arrow 24
+
+# small floating action button
+python copy OpenKeychain file white folder 24
+
+# multi select
+python copy OpenKeychain action white lock 24 \ No newline at end of file
diff --git a/Graphics/screenshots/device-2015-02-20-110958-device.png b/Graphics/screenshots/device-2015-02-20-110958-device.png
new file mode 100644
index 000000000..092744127
--- /dev/null
+++ b/Graphics/screenshots/device-2015-02-20-110958-device.png
Binary files differ
diff --git a/Graphics/screenshots/device-2015-02-20-110958.png b/Graphics/screenshots/device-2015-02-20-110958.png
new file mode 100644
index 000000000..cc522b7a4
--- /dev/null
+++ b/Graphics/screenshots/device-2015-02-20-110958.png
Binary files differ
diff --git a/Graphics/update-drawables.sh b/Graphics/update-drawables.sh
new file mode 100755
index 000000000..2e73641f5
--- /dev/null
+++ b/Graphics/update-drawables.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+APP_DIR=../OpenKeychain/src/main
+DRAWABLE_DIR=$APP_DIR/res/drawable
+MDPI_DIR=$APP_DIR/res/drawable-mdpi
+HDPI_DIR=$APP_DIR/res/drawable-hdpi
+XDPI_DIR=$APP_DIR/res/drawable-xhdpi
+XXDPI_DIR=$APP_DIR/res/drawable-xxhdpi
+XXXDPI_DIR=$APP_DIR/res/drawable-xxxhdpi
+PLAY_DIR=./drawables/
+SRC_DIR=./drawables/
+
+
+
+# Launcher Icon:
+# -----------------------
+# mdpi: 48x48
+# hdpi: 72x72
+# xhdpi: 96x96
+# xxhdpi: 144x144.
+# xxxhdpi 192x192.
+# google play: 512x512
+
+# Adobe Illustrator (.ai) exports by Tha Phlash are way better than the Inkscape exports (.svg)
+
+#NAME="ic_launcher"
+
+#inkscape -w 48 -h 48 -e "$MDPI_DIR/$NAME.png" $NAME.svg
+#inkscape -w 72 -h 72 -e "$HDPI_DIR/$NAME.png" $NAME.svg
+#inkscape -w 96 -h 96 -e "$XDPI_DIR/$NAME.png" $NAME.svg
+#inkscape -w 144 -h 144 -e "$XXDPI_DIR/$NAME.png" $NAME.svg
+#inkscape -w 192 -h 192 -e "$XXXDPI_DIR/$NAME.png" $NAME.svg
+#inkscape -w 512 -h 512 -e "$PLAY_DIR/$NAME.png" $NAME.svg
+
+# Actionbar Icons
+# -----------------------
+# mdpi: 32x32
+# hdpi: 48x48
+# xhdpi: 64x64
+# xxhdpi: 96x96
+
+for NAME in "ic_action_search_cloud" "ic_cloud_search_24px" "ic_action_encrypt_file" "ic_action_encrypt_text" "ic_action_verified_cutout"
+do
+echo $NAME
+inkscape -w 32 -h 32 -e "$MDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 48 -h 48 -e "$HDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 64 -h 64 -e "$XDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 96 -h 96 -e "$XXDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+done
+
+for NAME in "status_lock_closed" "status_lock_error" "status_lock_open" "status_signature_expired_cutout" "status_signature_invalid_cutout" "status_signature_revoked_cutout" "status_signature_unknown_cutout" "status_signature_unverified_cutout" "status_signature_verified_cutout" "key_flag_authenticate" "key_flag_certify" "key_flag_encrypt" "key_flag_sign"
+do
+echo $NAME
+inkscape -w 24 -h 24 -e "$MDPI_DIR/${NAME}_24px.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 32 -h 32 -e "$HDPI_DIR/${NAME}_24px.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 48 -h 48 -e "$XDPI_DIR/${NAME}_24px.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 64 -h 64 -e "$XXDPI_DIR/${NAME}_24px.png" "$SRC_DIR/$NAME.svg"
+done
+
+for NAME in "status_signature_expired_cutout" "status_signature_invalid_cutout" "status_signature_revoked_cutout" "status_signature_unknown_cutout" "status_signature_unverified_cutout" "status_signature_verified_cutout"
+do
+echo $NAME
+inkscape -w 96 -h 96 -e "$MDPI_DIR/${NAME}_96px.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 128 -h 128 -e "$HDPI_DIR/${NAME}_96px.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 192 -h 192 -e "$XDPI_DIR/${NAME}_96px.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 256 -h 256 -e "$XXDPI_DIR/${NAME}_96px.png" "$SRC_DIR/$NAME.svg"
+done
+
+for NAME in "create_key_robot"
+do
+echo $NAME
+inkscape -w 48 -h 48 -e "$MDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 64 -h 64 -e "$HDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 96 -h 96 -e "$XDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+inkscape -w 128 -h 128 -e "$XXDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+done
+
+for NAME in "drawer_header"
+do
+echo $NAME
+inkscape -w 512 -h 288 -e "$DRAWABLE_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+done
+
+for NAME in "first_time_1"
+do
+echo $NAME
+inkscape -w 512 -h 512 -e "$DRAWABLE_DIR/$NAME.png" "$SRC_DIR/$NAME.svg"
+done \ No newline at end of file
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java
new file mode 100644
index 000000000..c05f4a029
--- /dev/null
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.operations;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.ShadowLog;
+import org.spongycastle.bcpg.sig.KeyFlags;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.sufficientlysecure.keychain.operations.results.CertifyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.ExportResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
+import org.sufficientlysecure.keychain.pgp.WrappedSignature;
+import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
+import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
+import org.sufficientlysecure.keychain.util.InputData;
+import org.sufficientlysecure.keychain.util.ProgressScaler;
+import org.sufficientlysecure.keychain.util.TestingUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.security.Security;
+import java.util.Iterator;
+
+@RunWith(RobolectricTestRunner.class)
+@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19
+public class CertifyOperationTest {
+
+ static String mPassphrase = TestingUtils.genPassphrase(true);
+
+ static UncachedKeyRing mStaticRing1, mStaticRing2;
+ static String mKeyPhrase1 = TestingUtils.genPassphrase(true);
+ static String mKeyPhrase2 = TestingUtils.genPassphrase(true);
+
+ static PrintStream oldShadowStream;
+
+ @BeforeClass
+ public static void setUpOnce() throws Exception {
+ Security.insertProviderAt(new BouncyCastleProvider(), 1);
+ oldShadowStream = ShadowLog.stream;
+ // ShadowLog.stream = System.out;
+
+ PgpKeyOperation op = new PgpKeyOperation(null);
+
+ {
+ SaveKeyringParcel parcel = new SaveKeyringParcel();
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
+ parcel.mAddUserIds.add("derp");
+ parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1);
+
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
+ Assert.assertTrue("initial test key creation must succeed", result.success());
+ Assert.assertNotNull("initial test key creation must succeed", result.getRing());
+
+ mStaticRing1 = result.getRing();
+ }
+
+ {
+ SaveKeyringParcel parcel = new SaveKeyringParcel();
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
+ parcel.mAddUserIds.add("ditz");
+ parcel.mNewUnlock = new ChangeUnlockParcel(null, "1234");
+
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
+ Assert.assertTrue("initial test key creation must succeed", result.success());
+ Assert.assertNotNull("initial test key creation must succeed", result.getRing());
+
+ mStaticRing2 = result.getRing();
+ }
+
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ ProviderHelper providerHelper = new ProviderHelper(Robolectric.application);
+
+ // don't log verbosely here, we're not here to test imports
+ ShadowLog.stream = oldShadowStream;
+
+ providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler());
+ providerHelper.savePublicKeyRing(mStaticRing2.extractPublicKeyRing(), new ProgressScaler());
+
+ // ok NOW log verbosely!
+ ShadowLog.stream = System.out;
+ }
+
+ @Test
+ public void testSelfCertifyFlag() throws Exception {
+
+ CanonicalizedPublicKeyRing ring = new ProviderHelper(Robolectric.application)
+ .getCanonicalizedPublicKeyRing(mStaticRing1.getMasterKeyId());
+ Assert.assertEquals("secret key must be marked self-certified in database",
+ // TODO this should be more correctly be VERIFIED_SELF at some point!
+ Certs.VERIFIED_SECRET, ring.getVerified());
+
+ }
+
+ @Test
+ public void testCertify() throws Exception {
+ CertifyOperation op = operationWithFakePassphraseCache(
+ mStaticRing1.getMasterKeyId(), mStaticRing1.getMasterKeyId(), mKeyPhrase1);
+
+ {
+ CanonicalizedPublicKeyRing ring = new ProviderHelper(Robolectric.application)
+ .getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
+ Assert.assertEquals("public key must not be marked verified prior to certification",
+ Certs.UNVERIFIED, ring.getVerified());
+ }
+
+ CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId());
+ actions.add(new CertifyAction(mStaticRing2.getMasterKeyId()));
+ CertifyResult result = op.certify(actions, null);
+
+ Assert.assertTrue("certification must succeed", result.success());
+
+ {
+ CanonicalizedPublicKeyRing ring = new ProviderHelper(Robolectric.application)
+ .getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
+ Assert.assertEquals("new key must be verified now",
+ Certs.VERIFIED_SECRET, ring.getVerified());
+ }
+
+ }
+
+ @Test
+ public void testCertifySelf() throws Exception {
+ CertifyOperation op = operationWithFakePassphraseCache(
+ mStaticRing1.getMasterKeyId(), mStaticRing1.getMasterKeyId(), mKeyPhrase1);
+
+ CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId());
+ actions.add(new CertifyAction(mStaticRing1.getMasterKeyId()));
+
+ CertifyResult result = op.certify(actions, null);
+
+ Assert.assertFalse("certification with itself must fail!", result.success());
+ Assert.assertTrue("error msg must be about self certification",
+ result.getLog().containsType(LogType.MSG_CRT_ERROR_SELF));
+ }
+
+ @Test
+ public void testCertifyNonexistent() throws Exception {
+
+ CertifyOperation op = operationWithFakePassphraseCache(null, null, mKeyPhrase1);
+
+ {
+ CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId());
+ actions.add(new CertifyAction(1234L));
+
+ CertifyResult result = op.certify(actions, null);
+
+ Assert.assertFalse("certification of nonexistent key must fail", result.success());
+ Assert.assertTrue("must contain error msg about not found",
+ result.getLog().containsType(LogType.MSG_CRT_WARN_NOT_FOUND));
+ }
+
+ {
+ CertifyActionsParcel actions = new CertifyActionsParcel(1234L);
+ actions.add(new CertifyAction(mStaticRing1.getMasterKeyId()));
+
+ CertifyResult result = op.certify(actions, null);
+
+ Assert.assertFalse("certification of nonexistent key must fail", result.success());
+ Assert.assertTrue("must contain error msg about not found",
+ result.getLog().containsType(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND));
+ }
+
+ }
+
+ private CertifyOperation operationWithFakePassphraseCache(
+ final Long checkMasterKeyId, final Long checkSubKeyId, final String passphrase) {
+
+ return new CertifyOperation(Robolectric.application,
+ new ProviderHelper(Robolectric.application),
+ null, null) {
+ @Override
+ public String getCachedPassphrase(long masterKeyId, long subKeyId)
+ throws NoSecretKeyException {
+ if (checkMasterKeyId != null) {
+ Assert.assertEquals("requested passphrase should be for expected master key id",
+ (long) checkMasterKeyId, masterKeyId);
+ }
+ if (checkSubKeyId != null) {
+ Assert.assertEquals("requested passphrase should be for expected sub key id",
+ (long) checkSubKeyId, subKeyId);
+ }
+ if (passphrase == null) {
+ return null;
+ }
+ return passphrase;
+ }
+ };
+ }
+
+}
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java
new file mode 100644
index 000000000..b6fdbfc6c
--- /dev/null
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.operations;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.ShadowLog;
+import org.spongycastle.bcpg.sig.KeyFlags;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.ExportResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
+import org.sufficientlysecure.keychain.pgp.WrappedSignature;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
+import org.sufficientlysecure.keychain.util.ProgressScaler;
+import org.sufficientlysecure.keychain.util.TestingUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.security.Security;
+import java.util.Iterator;
+
+@RunWith(RobolectricTestRunner.class)
+@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19
+public class ExportTest {
+
+ static String mPassphrase = TestingUtils.genPassphrase(true);
+
+ static UncachedKeyRing mStaticRing1, mStaticRing2;
+ static String mKeyPhrase1 = TestingUtils.genPassphrase(true);
+ static String mKeyPhrase2 = TestingUtils.genPassphrase(true);
+
+ static PrintStream oldShadowStream;
+
+ @BeforeClass
+ public static void setUpOnce() throws Exception {
+ Security.insertProviderAt(new BouncyCastleProvider(), 1);
+ oldShadowStream = ShadowLog.stream;
+ // ShadowLog.stream = System.out;
+
+ PgpKeyOperation op = new PgpKeyOperation(null);
+
+ {
+ SaveKeyringParcel parcel = new SaveKeyringParcel();
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
+ parcel.mAddUserIds.add("snips");
+ parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1);
+
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
+ Assert.assertTrue("initial test key creation must succeed", result.success());
+ Assert.assertNotNull("initial test key creation must succeed", result.getRing());
+
+ mStaticRing1 = result.getRing();
+ }
+
+ {
+ SaveKeyringParcel parcel = new SaveKeyringParcel();
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
+ parcel.mAddUserIds.add("snails");
+ parcel.mNewUnlock = new ChangeUnlockParcel(null, "1234");
+
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
+ Assert.assertTrue("initial test key creation must succeed", result.success());
+ Assert.assertNotNull("initial test key creation must succeed", result.getRing());
+
+ mStaticRing2 = result.getRing();
+ }
+
+ }
+
+ @Before
+ public void setUp() {
+ ProviderHelper providerHelper = new ProviderHelper(Robolectric.application);
+
+ // don't log verbosely here, we're not here to test imports
+ ShadowLog.stream = oldShadowStream;
+
+ providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler());
+ providerHelper.saveSecretKeyRing(mStaticRing2, new ProgressScaler());
+
+ // ok NOW log verbosely!
+ ShadowLog.stream = System.out;
+ }
+
+ @Test
+ public void testExportAll() throws Exception {
+ ImportExportOperation op = new ImportExportOperation(Robolectric.application,
+ new ProviderHelper(Robolectric.application), null);
+
+ // make sure there is a local cert (so the later checks that there are none are meaningful)
+ Assert.assertTrue("second keyring has local certification", checkForLocal(mStaticRing2));
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ExportResult result = op.exportKeyRings(new OperationLog(), null, false, out);
+
+ Assert.assertTrue("export must be a success", result.success());
+
+ long masterKeyId1, masterKeyId2;
+ if (mStaticRing1.getMasterKeyId() < mStaticRing2.getMasterKeyId()) {
+ masterKeyId1 = mStaticRing1.getMasterKeyId();
+ masterKeyId2 = mStaticRing2.getMasterKeyId();
+ } else {
+ masterKeyId2 = mStaticRing1.getMasterKeyId();
+ masterKeyId1 = mStaticRing2.getMasterKeyId();
+ }
+
+ IteratorWithIOThrow<UncachedKeyRing> unc =
+ UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray()));
+
+ {
+ Assert.assertTrue("export must have two keys (1/2)", unc.hasNext());
+ UncachedKeyRing ring = unc.next();
+ Assert.assertEquals("first exported key has correct masterkeyid",
+ masterKeyId1, ring.getMasterKeyId());
+ Assert.assertFalse("first exported key must not be secret", ring.isSecret());
+ Assert.assertFalse("there must be no local signatures in an exported keyring",
+ checkForLocal(ring));
+ }
+
+ {
+ Assert.assertTrue("export must have two keys (2/2)", unc.hasNext());
+ UncachedKeyRing ring = unc.next();
+ Assert.assertEquals("second exported key has correct masterkeyid",
+ masterKeyId2, ring.getMasterKeyId());
+ Assert.assertFalse("second exported key must not be secret", ring.isSecret());
+ Assert.assertFalse("there must be no local signatures in an exported keyring",
+ checkForLocal(ring));
+ }
+
+ out = new ByteArrayOutputStream();
+ result = op.exportKeyRings(new OperationLog(), null, true, out);
+
+ Assert.assertTrue("export must be a success", result.success());
+
+ unc = UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray()));
+
+ {
+ Assert.assertTrue("export must have four keys (1/4)", unc.hasNext());
+ UncachedKeyRing ring = unc.next();
+ Assert.assertEquals("1/4 exported key has correct masterkeyid",
+ masterKeyId1, ring.getMasterKeyId());
+ Assert.assertFalse("1/4 exported key must not be public", ring.isSecret());
+ Assert.assertFalse("there must be no local signatures in an exported keyring",
+ checkForLocal(ring));
+
+ Assert.assertTrue("export must have four keys (2/4)", unc.hasNext());
+ ring = unc.next();
+ Assert.assertEquals("2/4 exported key has correct masterkeyid",
+ masterKeyId1, ring.getMasterKeyId());
+ Assert.assertTrue("2/4 exported key must be public", ring.isSecret());
+ Assert.assertFalse("there must be no local signatures in an exported keyring",
+ checkForLocal(ring));
+ }
+
+ {
+ Assert.assertTrue("export must have four keys (3/4)", unc.hasNext());
+ UncachedKeyRing ring = unc.next();
+ Assert.assertEquals("3/4 exported key has correct masterkeyid",
+ masterKeyId2, ring.getMasterKeyId());
+ Assert.assertFalse("3/4 exported key must not be public", ring.isSecret());
+ Assert.assertFalse("there must be no local signatures in an exported keyring",
+ checkForLocal(ring));
+
+ Assert.assertTrue("export must have four keys (4/4)", unc.hasNext());
+ ring = unc.next();
+ Assert.assertEquals("4/4 exported key has correct masterkeyid",
+ masterKeyId2, ring.getMasterKeyId());
+ Assert.assertTrue("4/4 exported key must be public", ring.isSecret());
+ Assert.assertFalse("there must be no local signatures in an exported keyring",
+ checkForLocal(ring));
+ }
+
+ }
+
+ /** This function checks whether or not there are any local signatures in a keyring. */
+ private boolean checkForLocal(UncachedKeyRing ring) {
+ Iterator<WrappedSignature> sigs = ring.getPublicKey().getSignatures();
+ while (sigs.hasNext()) {
+ if (sigs.next().isLocal()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java
new file mode 100644
index 000000000..40ade064b
--- /dev/null
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.operations;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.ShadowLog;
+import org.spongycastle.bcpg.sig.KeyFlags;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
+import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
+import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
+import org.sufficientlysecure.keychain.util.ProgressScaler;
+import org.sufficientlysecure.keychain.util.TestingUtils;
+
+import java.io.PrintStream;
+import java.security.Security;
+import java.util.Iterator;
+
+@RunWith(RobolectricTestRunner.class)
+@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19
+public class PromoteKeyOperationTest {
+
+ static UncachedKeyRing mStaticRing;
+ static String mKeyPhrase1 = TestingUtils.genPassphrase(true);
+
+ static PrintStream oldShadowStream;
+
+ @BeforeClass
+ public static void setUpOnce() throws Exception {
+ Security.insertProviderAt(new BouncyCastleProvider(), 1);
+ oldShadowStream = ShadowLog.stream;
+ // ShadowLog.stream = System.out;
+
+ PgpKeyOperation op = new PgpKeyOperation(null);
+
+ {
+ SaveKeyringParcel parcel = new SaveKeyringParcel();
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
+ Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
+ parcel.mAddUserIds.add("derp");
+ parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1);
+
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
+ Assert.assertTrue("initial test key creation must succeed", result.success());
+ Assert.assertNotNull("initial test key creation must succeed", result.getRing());
+
+ mStaticRing = result.getRing();
+ }
+
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ ProviderHelper providerHelper = new ProviderHelper(Robolectric.application);
+
+ // don't log verbosely here, we're not here to test imports
+ ShadowLog.stream = oldShadowStream;
+
+ providerHelper.savePublicKeyRing(mStaticRing.extractPublicKeyRing(), new ProgressScaler());
+
+ // ok NOW log verbosely!
+ ShadowLog.stream = System.out;
+ }
+
+ @Test
+ public void testPromote() throws Exception {
+ PromoteKeyOperation op = new PromoteKeyOperation(Robolectric.application,
+ new ProviderHelper(Robolectric.application), null, null);
+
+ PromoteKeyResult result = op.execute(mStaticRing.getMasterKeyId());
+
+ Assert.assertTrue("promotion must succeed", result.success());
+
+ {
+ CachedPublicKeyRing ring = new ProviderHelper(Robolectric.application)
+ .getCachedPublicKeyRing(mStaticRing.getMasterKeyId());
+ Assert.assertTrue("key must have a secret now", ring.hasAnySecret());
+
+ Iterator<UncachedPublicKey> it = mStaticRing.getPublicKeys();
+ while (it.hasNext()) {
+ long keyId = it.next().getKeyId();
+ Assert.assertEquals("all subkeys must be divert-to-card",
+ SecretKeyType.GNU_DUMMY, ring.getSecretKeyType(keyId));
+ }
+ }
+
+ // second attempt should fail
+ result = op.execute(mStaticRing.getMasterKeyId());
+ Assert.assertFalse("promotion of secret key must fail", result.success());
+
+ }
+
+}
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java
index 9dc8f8934..d782230c7 100644
--- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java
@@ -22,25 +22,32 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.openintents.openpgp.OpenPgpMetadata;
+import org.openintents.openpgp.OpenPgpSignatureResult;
import org.robolectric.*;
import org.robolectric.shadows.ShadowLog;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.openpgp.PGPEncryptedData;
-import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt.Builder;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
-import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
-import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
+import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import org.sufficientlysecure.keychain.util.TestingUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
import java.security.Security;
+import java.util.HashSet;
@RunWith(RobolectricTestRunner.class)
@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19
@@ -52,10 +59,13 @@ public class PgpEncryptDecryptTest {
static String mKeyPhrase1 = TestingUtils.genPassphrase(true);
static String mKeyPhrase2 = TestingUtils.genPassphrase(true);
+ static PrintStream oldShadowStream;
+
@BeforeClass
public static void setUpOnce() throws Exception {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
- ShadowLog.stream = System.out;
+ oldShadowStream = ShadowLog.stream;
+ // ShadowLog.stream = System.out;
PgpKeyOperation op = new PgpKeyOperation(null);
@@ -68,9 +78,9 @@ public class PgpEncryptDecryptTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
parcel.mAddUserIds.add("bloom");
- parcel.mNewPassphrase = mKeyPhrase1;
+ parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1);
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue("initial test key creation must succeed", result.success());
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
@@ -86,9 +96,9 @@ public class PgpEncryptDecryptTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
parcel.mAddUserIds.add("belle");
- parcel.mNewPassphrase = mKeyPhrase2;
+ parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase2);
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue("initial test key creation must succeed", result.success());
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
@@ -101,8 +111,14 @@ public class PgpEncryptDecryptTest {
public void setUp() {
ProviderHelper providerHelper = new ProviderHelper(Robolectric.application);
+ // don't log verbosely here, we're not here to test imports
+ ShadowLog.stream = oldShadowStream;
+
providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler());
- providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler());
+ providerHelper.saveSecretKeyRing(mStaticRing2, new ProgressScaler());
+
+ // ok NOW log verbosely!
+ ShadowLog.stream = System.out;
}
@Test
@@ -115,15 +131,17 @@ public class PgpEncryptDecryptTest {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
+ PgpSignEncryptOperation op = new PgpSignEncryptOperation(Robolectric.application,
+ new ProviderHelper(Robolectric.application), null);
+
InputData data = new InputData(in, in.available());
- Builder b = new PgpSignEncrypt.Builder(Robolectric.application,
- new ProviderHelper(Robolectric.application),
- null, // new DummyPassphraseCache(mPassphrase, 0L)
- data, out);
+ PgpSignEncryptInput b = new PgpSignEncryptInput();
b.setSymmetricPassphrase(mPassphrase);
b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
- SignEncryptResult result = b.build().execute();
+
+ PgpSignEncryptResult result = op.execute(b, data, out);
+
Assert.assertTrue("encryption must succeed", result.success());
ciphertext = out.toByteArray();
@@ -145,6 +163,10 @@ public class PgpEncryptDecryptTest {
Assert.assertArrayEquals("decrypted ciphertext should equal plaintext",
out.toByteArray(), plaintext.getBytes());
Assert.assertNull("signature should be an error", result.getSignatureResult());
+
+ OpenPgpMetadata metadata = result.getDecryptMetadata();
+ Assert.assertEquals("filesize must be correct",
+ out.toByteArray().length, metadata.getOriginalSize());
}
{ // decryption with a bad passphrase should fail
@@ -194,16 +216,15 @@ public class PgpEncryptDecryptTest {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
+ PgpSignEncryptOperation op = new PgpSignEncryptOperation(Robolectric.application,
+ new ProviderHelper(Robolectric.application), null);
+
InputData data = new InputData(in, in.available());
- Builder b = new PgpSignEncrypt.Builder(
- Robolectric.application,
- new ProviderHelper(Robolectric.application),
- null, // new DummyPassphraseCache(mPassphrase, 0L),
- data, out);
+ PgpSignEncryptInput b = new PgpSignEncryptInput();
b.setEncryptionMasterKeyIds(new long[]{ mStaticRing1.getMasterKeyId() });
b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
- SignEncryptResult result = b.build().execute();
+ PgpSignEncryptResult result = op.execute(b, data, out);
Assert.assertTrue("encryption must succeed", result.success());
ciphertext = out.toByteArray();
@@ -215,89 +236,308 @@ public class PgpEncryptDecryptTest {
ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
InputData data = new InputData(in, in.available());
- PgpDecryptVerify.Builder b = new PgpDecryptVerify.Builder(
- Robolectric.application,
- new ProviderHelper(Robolectric.application),
- null, // new DummyPassphraseCache(null, null),
- data, out);
+
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, null, null, null);
b.setPassphrase(mKeyPhrase1);
DecryptVerifyResult result = b.build().execute();
Assert.assertTrue("decryption with provided passphrase must succeed", result.success());
Assert.assertArrayEquals("decrypted ciphertext with provided passphrase should equal plaintext",
out.toByteArray(), plaintext.getBytes());
Assert.assertNull("signature be empty", result.getSignatureResult());
+
+ OpenPgpMetadata metadata = result.getDecryptMetadata();
+ Assert.assertEquals("filesize must be correct",
+ out.toByteArray().length, metadata.getOriginalSize());
+
}
// TODO how to test passphrase cache?
- /*{ // decryption with passphrase cached should succeed
+ { // decryption with passphrase cached should succeed
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
InputData data = new InputData(in, in.available());
- PassphraseCacheService.addCachedPassphrase(
- Robolectric.application, mStaticRing1.getMasterKeyId(),
- mStaticRing1.getMasterKeyId(), mKeyPhrase1, "dummy");
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
+ mKeyPhrase1, mStaticRing1.getMasterKeyId(), null);
- PgpDecryptVerify.Builder b = new PgpDecryptVerify.Builder(
- Robolectric.application,
- new ProviderHelper(Robolectric.application),
- null, // new DummyPassphraseCache(mKeyPhrase1, null),
- data, out);
DecryptVerifyResult result = b.build().execute();
Assert.assertTrue("decryption with cached passphrase must succeed", result.success());
Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
out.toByteArray(), plaintext.getBytes());
Assert.assertNull("signature should be empty", result.getSignatureResult());
- }*/
+ }
- /*{ // decryption with no passphrase provided should return status pending
+ { // decryption with no passphrase provided should return status pending
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
InputData data = new InputData(in, in.available());
- PgpDecryptVerify.Builder b = new PgpDecryptVerify.Builder(
- Robolectric.application,
- new ProviderHelper(Robolectric.application),
- null, // new DummyPassphraseCache(null, null),
- data, out);
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
+ null, mStaticRing1.getMasterKeyId(), null);
DecryptVerifyResult result = b.build().execute();
Assert.assertFalse("decryption with no passphrase must return pending", result.success());
Assert.assertTrue("decryption with no passphrase should return pending", result.isPending());
Assert.assertEquals("decryption with no passphrase should return pending passphrase",
DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE, result.getResult());
- }*/
+ }
}
- static class DummyPassphraseCache implements PassphraseCacheInterface {
+ @Test
+ public void testMultiAsymmetricEncryptDecrypt() {
+
+ String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true);
+ byte[] ciphertext;
+
+ { // encrypt data with a given passphrase
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
+
+ PgpSignEncryptOperation op = new PgpSignEncryptOperation(Robolectric.application,
+ new ProviderHelper(Robolectric.application), null);
- String mPassphrase;
- Long mExpectedId;
- public DummyPassphraseCache(String passphrase, Long expectedId) {
- mPassphrase = passphrase;
- mExpectedId = expectedId;
+ InputData data = new InputData(in, in.available());
+
+ PgpSignEncryptInput b = new PgpSignEncryptInput();
+ b.setEncryptionMasterKeyIds(new long[] {
+ mStaticRing1.getMasterKeyId(),
+ mStaticRing2.getMasterKeyId()
+ });
+ b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
+
+ PgpSignEncryptResult result = op.execute(b, data, out);
+ Assert.assertTrue("encryption must succeed", result.success());
+
+ ciphertext = out.toByteArray();
}
- @Override
- public String getCachedPassphrase(long masterKeyId, long subKeyId) throws NoSecretKeyException {
- if (mExpectedId != null){
- Assert.assertEquals("requested passphrase must be for expected id",
- (long) mExpectedId, subKeyId);
- }
- return mPassphrase;
+ { // decryption with passphrase cached should succeed for the first key
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
+ InputData data = new InputData(in, in.available());
+
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
+ mKeyPhrase1, mStaticRing1.getMasterKeyId(), null);
+
+ DecryptVerifyResult result = b.build().execute();
+ Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success());
+ Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
+ out.toByteArray(), plaintext.getBytes());
+ Assert.assertNull("signature should be empty", result.getSignatureResult());
+
+ OpenPgpMetadata metadata = result.getDecryptMetadata();
+ Assert.assertEquals("filesize must be correct",
+ out.toByteArray().length, metadata.getOriginalSize());
}
- @Override
- public String getCachedPassphrase(long subKeyId) throws NoSecretKeyException {
- if (mExpectedId != null){
- Assert.assertEquals("requested passphrase must be for expected id",
- (long) mExpectedId, subKeyId);
- }
- return mPassphrase;
+ { // decryption with passphrase cached should succeed for the first key
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
+ InputData data = new InputData(in, in.available());
+
+ // allow only the second to decrypt
+ HashSet<Long> allowed = new HashSet<Long>();
+ allowed.add(mStaticRing2.getMasterKeyId());
+
+ // provide passphrase for the second, and check that the first is never asked for!
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
+ mKeyPhrase2, mStaticRing2.getMasterKeyId(), null);
+ b.setAllowedKeyIds(allowed);
+
+ DecryptVerifyResult result = b.build().execute();
+ Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success());
+ Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
+ out.toByteArray(), plaintext.getBytes());
+ Assert.assertNull("signature should be empty", result.getSignatureResult());
}
+
+ { // decryption with passphrase cached should succeed for the other key if first is gone
+
+ // delete first key from database
+ new ProviderHelper(Robolectric.application).getContentResolver().delete(
+ KeyRingData.buildPublicKeyRingUri(mStaticRing1.getMasterKeyId()), null, null
+ );
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
+ InputData data = new InputData(in, in.available());
+
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
+ mKeyPhrase2, mStaticRing2.getMasterKeyId(), null);
+
+ DecryptVerifyResult result = b.build().execute();
+ Assert.assertTrue("decryption with cached passphrase must succeed", result.success());
+ Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
+ out.toByteArray(), plaintext.getBytes());
+ Assert.assertNull("signature should be empty", result.getSignatureResult());
+ }
+
+ }
+
+ @Test
+ public void testMultiAsymmetricSignEncryptDecryptVerify() {
+
+ String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true);
+ byte[] ciphertext;
+
+ { // encrypt data with a given passphrase
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes());
+
+ PgpSignEncryptOperation op = new PgpSignEncryptOperation(Robolectric.application,
+ new ProviderHelper(Robolectric.application), null);
+
+ InputData data = new InputData(in, in.available());
+ PgpSignEncryptInput b = new PgpSignEncryptInput();
+
+ b.setEncryptionMasterKeyIds(new long[] {
+ mStaticRing1.getMasterKeyId(),
+ mStaticRing2.getMasterKeyId()
+ });
+ b.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId());
+ b.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1));
+ b.setSignaturePassphrase(mKeyPhrase1);
+ b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
+
+ PgpSignEncryptResult result = op.execute(b, data, out);
+ Assert.assertTrue("encryption must succeed", result.success());
+
+ ciphertext = out.toByteArray();
+ }
+
+ { // decryption with passphrase cached should succeed for the first key
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
+ InputData data = new InputData(in, in.available());
+
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
+ mKeyPhrase1, mStaticRing1.getMasterKeyId(), null);
+
+ DecryptVerifyResult result = b.build().execute();
+ Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success());
+ Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
+ out.toByteArray(), plaintext.getBytes());
+ Assert.assertEquals("signature should be verified and certified",
+ OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED, result.getSignatureResult().getStatus());
+
+ OpenPgpMetadata metadata = result.getDecryptMetadata();
+ Assert.assertEquals("filesize must be correct",
+ out.toByteArray().length, metadata.getOriginalSize());
+ }
+
+ { // decryption with passphrase cached should succeed for the other key if first is gone
+
+ // delete first key from database
+ new ProviderHelper(Robolectric.application).getContentResolver().delete(
+ KeyRingData.buildPublicKeyRingUri(mStaticRing1.getMasterKeyId()), null, null
+ );
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
+ InputData data = new InputData(in, in.available());
+
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
+ mKeyPhrase2, mStaticRing2.getMasterKeyId(), null);
+
+ DecryptVerifyResult result = b.build().execute();
+ Assert.assertTrue("decryption with cached passphrase must succeed", result.success());
+ Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
+ out.toByteArray(), plaintext.getBytes());
+ Assert.assertEquals("signature key should be missing",
+ OpenPgpSignatureResult.SIGNATURE_KEY_MISSING,
+ result.getSignatureResult().getStatus());
+ }
+
+ }
+
+ @Test
+ public void testForeignEncoding () throws Exception {
+ String plaintext = "ウィキペディア";
+ byte[] plaindata = plaintext.getBytes("iso-2022-jp");
+
+ { // some quick sanity checks
+ Assert.assertEquals(plaintext, new String(plaindata, "iso-2022-jp"));
+ Assert.assertNotEquals(plaintext, new String(plaindata, "utf-8"));
+ }
+
+ byte[] ciphertext;
+ { // encrypt data with a given passphrase
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(plaindata);
+
+ PgpSignEncryptOperation op = new PgpSignEncryptOperation(Robolectric.application,
+ new ProviderHelper(Robolectric.application), null);
+
+ InputData data = new InputData(in, in.available());
+ PgpSignEncryptInput b = new PgpSignEncryptInput();
+
+ b.setEncryptionMasterKeyIds(new long[]{ mStaticRing1.getMasterKeyId() });
+ b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
+ // this only works with ascii armored output!
+ b.setEnableAsciiArmorOutput(true);
+ b.setCharset("iso-2022-jp");
+ PgpSignEncryptResult result = op.execute(b, data, out);
+ Assert.assertTrue("encryption must succeed", result.success());
+
+ ciphertext = out.toByteArray();
+ }
+
+ { // decryption with provided passphrase should yield the same result
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
+ InputData data = new InputData(in, in.available());
+
+ PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, null, null, null);
+ b.setPassphrase(mKeyPhrase1);
+ DecryptVerifyResult result = b.build().execute();
+ Assert.assertTrue("decryption with provided passphrase must succeed", result.success());
+ Assert.assertArrayEquals("decrypted ciphertext should equal plaintext bytes",
+ out.toByteArray(), plaindata);
+ Assert.assertEquals("charset should be read correctly",
+ "iso-2022-jp", result.getCharset());
+ Assert.assertEquals("decrypted ciphertext should equal plaintext",
+ new String(out.toByteArray(), result.getCharset()), plaintext);
+ Assert.assertNull("signature be empty", result.getSignatureResult());
+ }
+
+ }
+
+ private PgpDecryptVerify.Builder builderWithFakePassphraseCache (
+ InputData data, OutputStream out,
+ final String passphrase, final Long checkMasterKeyId, final Long checkSubKeyId) {
+
+ return new PgpDecryptVerify.Builder(Robolectric.application,
+ new ProviderHelper(Robolectric.application),
+ null,
+ data, out) {
+ public PgpDecryptVerify build() {
+ return new PgpDecryptVerify(this) {
+ @Override
+ public String getCachedPassphrase(long masterKeyId, long subKeyId)
+ throws NoSecretKeyException {
+ if (checkMasterKeyId != null) {
+ Assert.assertEquals("requested passphrase should be for expected master key id",
+ (long) checkMasterKeyId, masterKeyId);
+ }
+ if (checkSubKeyId != null) {
+ Assert.assertEquals("requested passphrase should be for expected sub key id",
+ (long) checkSubKeyId, subKeyId);
+ }
+ if (passphrase == null) {
+ return null;
+ }
+ return passphrase;
+ }
+ };
+ }
+ };
}
}
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java
index abe39b894..dd2feb825 100644
--- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java
@@ -34,15 +34,19 @@ import org.spongycastle.bcpg.S2K;
import org.spongycastle.bcpg.SecretKeyPacket;
import org.spongycastle.bcpg.SecretSubkeyPacket;
import org.spongycastle.bcpg.SignaturePacket;
+import org.spongycastle.bcpg.UserAttributePacket;
+import org.spongycastle.bcpg.UserAttributeSubpacket;
import org.spongycastle.bcpg.UserIDPacket;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.openpgp.PGPSignature;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
-import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
import org.sufficientlysecure.keychain.support.KeyringBuilder;
@@ -91,14 +95,15 @@ public class PgpKeyOperationTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
PgpKeyOperation op = new PgpKeyOperation(null);
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue("initial test key creation must succeed", result.success());
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
staticRing = result.getRing();
+ staticRing = staticRing.canonicalize(new OperationLog(), 0).getUncachedKeyRing();
// we sleep here for a second, to make sure all new certificates have different timestamps
Thread.sleep(1000);
@@ -127,7 +132,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, new Random().nextInt(256)+255, null, KeyFlags.CERTIFY_OTHER, 0L));
parcel.mAddUserIds.add("shy");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with < 512 bytes keysize should fail", parcel,
LogType.MSG_CR_ERROR_KEYSIZE_512);
@@ -138,7 +143,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.ELGAMAL, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
parcel.mAddUserIds.add("shy");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with ElGamal master key should fail", parcel,
LogType.MSG_CR_ERROR_FLAGS_ELGAMAL);
@@ -149,7 +154,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, null));
parcel.mAddUserIds.add("lotus");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating master key with null expiry should fail", parcel,
LogType.MSG_CR_ERROR_NULL_EXPIRY);
@@ -160,7 +165,7 @@ public class PgpKeyOperationTest {
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
parcel.mAddUserIds.add("shy");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with non-certifying master key should fail", parcel,
LogType.MSG_CR_ERROR_NO_CERTIFY);
@@ -170,7 +175,7 @@ public class PgpKeyOperationTest {
parcel.reset();
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring without user ids should fail", parcel,
LogType.MSG_CR_ERROR_NO_USER_ID);
@@ -179,7 +184,7 @@ public class PgpKeyOperationTest {
{
parcel.reset();
parcel.mAddUserIds.add("shy");
- parcel.mNewPassphrase = passphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(passphrase);
assertFailure("creating ring with no master key should fail", parcel,
LogType.MSG_CR_ERROR_NO_MASTER);
@@ -226,7 +231,7 @@ public class PgpKeyOperationTest {
ring.getPublicKey().getCreationTime().after(new Date(new Date().getTime()-1000*120)));
Assert.assertNull("key ring should not expire",
- ring.getPublicKey().getExpiryTime());
+ ring.getPublicKey().getUnsafeExpiryTimeForTesting());
Assert.assertEquals("first (master) key can certify",
KeyFlags.CERTIFY_OTHER, (long) subkeys.get(0).getKeyUsage());
@@ -337,9 +342,9 @@ public class PgpKeyOperationTest {
Assert.assertNotNull("new key is not null", newKey);
Assert.assertNotNull("added key must have an expiry date",
- newKey.getExpiryTime());
+ newKey.getUnsafeExpiryTimeForTesting());
Assert.assertEquals("added key must have expected expiry date",
- expiry, newKey.getExpiryTime().getTime()/1000);
+ expiry, newKey.getUnsafeExpiryTimeForTesting().getTime()/1000);
Assert.assertEquals("added key must have expected flags",
flags, (long) newKey.getKeyUsage());
Assert.assertEquals("added key must have expected bitsize",
@@ -398,9 +403,9 @@ public class PgpKeyOperationTest {
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
Assert.assertNotNull("modified key must have an expiry date",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("modified key must have expected expiry date",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime()/1000);
Assert.assertEquals("modified key must have same flags as before",
ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage());
}
@@ -412,9 +417,9 @@ public class PgpKeyOperationTest {
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
Assert.assertNotNull("modified key must have an expiry date",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("modified key must have expected expiry date",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime()/1000);
Assert.assertEquals("modified key must have same flags as before",
ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage());
}
@@ -438,9 +443,9 @@ public class PgpKeyOperationTest {
Assert.assertEquals("modified key must have expected flags",
flags, (long) modified.getPublicKey(keyId).getKeyUsage());
Assert.assertNotNull("key must retain its expiry",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("key expiry must be unchanged",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime()/1000);
}
{ // expiry of 0 should be "no expiry"
@@ -458,7 +463,7 @@ public class PgpKeyOperationTest {
Assert.assertEquals("signature must have been created by master key",
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
- Assert.assertNull("key must not expire anymore", modified.getPublicKey(keyId).getExpiryTime());
+ Assert.assertNull("key must not expire anymore", modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
}
{ // a past expiry should fail
@@ -512,9 +517,9 @@ public class PgpKeyOperationTest {
PacketTags.SIGNATURE, onlyB.get(1).tag);
Assert.assertNotNull("modified key must have an expiry date",
- modified.getPublicKey().getExpiryTime());
+ modified.getPublicKey().getUnsafeExpiryTimeForTesting());
Assert.assertEquals("modified key must have expected expiry date",
- expiry, modified.getPublicKey().getExpiryTime().getTime() / 1000);
+ expiry, modified.getPublicKey().getUnsafeExpiryTimeForTesting().getTime() / 1000);
Assert.assertEquals("modified key must have same flags as before",
ring.getPublicKey().getKeyUsage(), modified.getPublicKey().getKeyUsage());
}
@@ -526,9 +531,9 @@ public class PgpKeyOperationTest {
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
Assert.assertNotNull("modified key must have an expiry date",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("modified key must have expected expiry date",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime() / 1000);
Assert.assertEquals("modified key must have same flags as before",
ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage());
}
@@ -542,17 +547,29 @@ public class PgpKeyOperationTest {
Assert.assertEquals("modified key must have expected flags",
flags, (long) modified.getPublicKey(keyId).getKeyUsage());
Assert.assertNotNull("key must retain its expiry",
- modified.getPublicKey(keyId).getExpiryTime());
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
Assert.assertEquals("key expiry must be unchanged",
- expiry, modified.getPublicKey(keyId).getExpiryTime().getTime()/1000);
+ expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime()/1000);
}
{ // expiry of 0 should be "no expiry"
+
+ // even if there is a non-expiring user id while all others are revoked, it doesn't count!
+ // for this purpose we revoke one while they still have expiry times
+ parcel.reset();
+ parcel.mRevokeUserIds.add("aloe");
+ modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
+
parcel.reset();
parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, 0L));
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
- Assert.assertNull("key must not expire anymore", modified.getPublicKey(keyId).getExpiryTime());
+ // for this check, it is relevant that we DON'T use the unsafe one!
+ Assert.assertNull("key must not expire anymore",
+ modified.canonicalize(new OperationLog(), 0).getPublicKey().getExpiryTime());
+ // make sure the unsafe one behaves incorrectly as expected
+ Assert.assertNotNull("unsafe expiry must yield wrong result from revoked user id",
+ modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
}
{ // if we revoke everything, nothing is left to properly sign...
@@ -604,7 +621,7 @@ public class PgpKeyOperationTest {
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
Assert.assertTrue("subkey must actually be revoked",
- modified.getPublicKey().isRevoked());
+ modified.getPublicKey().isMaybeRevoked());
}
@@ -648,13 +665,14 @@ public class PgpKeyOperationTest {
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
Assert.assertTrue("subkey must actually be revoked",
- modified.getPublicKey(keyId).isRevoked());
+ modified.getPublicKey(keyId).isMaybeRevoked());
}
{ // re-add second subkey
parcel.reset();
- parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, null));
+ // re-certify the revoked subkey
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true));
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
@@ -685,7 +703,7 @@ public class PgpKeyOperationTest {
ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID());
Assert.assertFalse("subkey must no longer be revoked",
- modified.getPublicKey(keyId).isRevoked());
+ modified.getPublicKey(keyId).isMaybeRevoked());
Assert.assertEquals("subkey must have the same usage flags as before",
flags, (long) modified.getPublicKey(keyId).getKeyUsage());
@@ -696,7 +714,7 @@ public class PgpKeyOperationTest {
public void testSubkeyStrip() throws Exception {
long keyId = KeyringTestingHelper.getSubkeyId(ring, 1);
- parcel.mStripSubKeys.add(keyId);
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, null));
applyModificationWithChecks(parcel, ring, onlyA, onlyB);
Assert.assertEquals("one extra packet in original", 1, onlyA.size());
@@ -722,7 +740,7 @@ public class PgpKeyOperationTest {
public void testMasterStrip() throws Exception {
long keyId = ring.getMasterKeyId();
- parcel.mStripSubKeys.add(keyId);
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, null));
applyModificationWithChecks(parcel, ring, onlyA, onlyB);
Assert.assertEquals("one extra packet in original", 1, onlyA.size());
@@ -741,6 +759,44 @@ public class PgpKeyOperationTest {
Assert.assertEquals("new packet secret key data should have length zero",
0, ((SecretKeyPacket) p).getSecretKeyData().length);
Assert.assertNull("new packet should have no iv data", ((SecretKeyPacket) p).getIV());
+ }
+
+ @Test
+ public void testRestrictedStrip() throws Exception {
+
+ long keyId = KeyringTestingHelper.getSubkeyId(ring, 1);
+ UncachedKeyRing modified;
+
+ { // we should be able to change the stripped/divert status of subkeys without passphrase
+ parcel.reset();
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, null));
+ modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, null);
+ Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
+ Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
+ Assert.assertEquals("new packet should have GNU_DUMMY S2K type",
+ S2K.GNU_DUMMY_S2K, ((SecretKeyPacket) p).getS2K().getType());
+ Assert.assertEquals("new packet should have GNU_DUMMY protection mode stripped",
+ S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY, ((SecretKeyPacket) p).getS2K().getProtectionMode());
+ }
+
+ { // and again, changing to divert-to-card
+ parcel.reset();
+ byte[] serial = new byte[] {
+ 0x6a, 0x6f, 0x6c, 0x6f, 0x73, 0x77, 0x61, 0x67,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+ parcel.mChangeSubKeys.add(new SubkeyChange(keyId, false, serial));
+ modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, null);
+ Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
+ Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
+ Assert.assertEquals("new packet should have GNU_DUMMY S2K type",
+ S2K.GNU_DUMMY_S2K, ((SecretKeyPacket) p).getS2K().getType());
+ Assert.assertEquals("new packet should have GNU_DUMMY protection mode divert-to-card",
+ S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD, ((SecretKeyPacket) p).getS2K().getProtectionMode());
+ Assert.assertArrayEquals("new packet should have correct serial number as iv",
+ serial, ((SecretKeyPacket) p).getIV());
+
+ }
}
@@ -862,6 +918,70 @@ public class PgpKeyOperationTest {
}
@Test
+ public void testUserAttributeAdd() throws Exception {
+
+ {
+ parcel.mAddUserAttribute.add(WrappedUserAttribute.fromData(new byte[0]));
+ assertModifyFailure("adding an empty user attribute should fail", ring, parcel,
+ LogType.MSG_MF_UAT_ERROR_EMPTY);
+ }
+
+ parcel.reset();
+
+ Random r = new Random();
+ int type = r.nextInt(110)+1;
+ byte[] data = new byte[r.nextInt(2000)];
+ new Random().nextBytes(data);
+
+ WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data);
+ parcel.mAddUserAttribute.add(uat);
+
+ UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
+
+ Assert.assertEquals("no extra packets in original", 0, onlyA.size());
+ Assert.assertEquals("exactly two extra packets in modified", 2, onlyB.size());
+
+ Assert.assertTrue("keyring must contain added user attribute",
+ modified.getPublicKey().getUnorderedUserAttributes().contains(uat));
+
+ Packet p;
+
+ p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
+ Assert.assertTrue("first new packet must be user attribute", p instanceof UserAttributePacket);
+ {
+ UserAttributeSubpacket[] subpackets = ((UserAttributePacket) p).getSubpackets();
+ Assert.assertEquals("user attribute packet must contain one subpacket",
+ 1, subpackets.length);
+ Assert.assertEquals("user attribute subpacket type must be as specified above",
+ type, subpackets[0].getType());
+ Assert.assertArrayEquals("user attribute subpacket data must be as specified above",
+ data, subpackets[0].getData());
+ }
+
+ p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(1).buf)).readPacket();
+ Assert.assertTrue("second new packet must be signature", p instanceof SignaturePacket);
+ Assert.assertEquals("signature type must be positive certification",
+ PGPSignature.POSITIVE_CERTIFICATION, ((SignaturePacket) p).getSignatureType());
+
+ // make sure packets can be distinguished by timestamp
+ Thread.sleep(1000);
+
+ // applying the same modification AGAIN should not add more certifications but drop those
+ // as duplicates
+ modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, passphrase, true, false);
+
+ Assert.assertEquals("duplicate modification: one extra packet in original", 1, onlyA.size());
+ Assert.assertEquals("duplicate modification: one extra packet in modified", 1, onlyB.size());
+
+ p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(0).buf)).readPacket();
+ Assert.assertTrue("lost packet must be signature", p instanceof SignaturePacket);
+ p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
+ Assert.assertTrue("new packet must be signature", p instanceof SignaturePacket);
+
+ }
+
+
+ @Test
public void testUserIdPrimary() throws Exception {
UncachedKeyRing modified = ring;
@@ -910,8 +1030,10 @@ public class PgpKeyOperationTest {
public void testPassphraseChange() throws Exception {
// change passphrase to empty
- parcel.mNewPassphrase = "";
- UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
+ // note that canonicalization here necessarily strips the empty notation packet
+ UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB,
+ passphrase);
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
3, onlyB.size());
@@ -923,7 +1045,7 @@ public class PgpKeyOperationTest {
// modify keyring, change to non-empty passphrase
String otherPassphrase = TestingUtils.genPassphrase(true);
- parcel.mNewPassphrase = otherPassphrase;
+ parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase);
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, "");
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
@@ -948,7 +1070,7 @@ public class PgpKeyOperationTest {
PacketTags.SECRET_SUBKEY, sKeyNoPassphrase.tag);
String otherPassphrase2 = TestingUtils.genPassphrase(true);
- parcel.mNewPassphrase = otherPassphrase2;
+ parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase2);
{
// if we replace a secret key with one without passphrase
modified = KeyringTestingHelper.removePacket(modified, sKeyNoPassphrase.position);
@@ -957,7 +1079,7 @@ public class PgpKeyOperationTest {
// we should still be able to modify it (and change its passphrase) without errors
PgpKeyOperation op = new PgpKeyOperation(null);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase);
Assert.assertTrue("key modification must succeed", result.success());
Assert.assertFalse("log must not contain a warning",
result.getLog().containsWarnings());
@@ -973,7 +1095,7 @@ public class PgpKeyOperationTest {
PgpKeyOperation op = new PgpKeyOperation(null);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase2);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase2);
Assert.assertTrue("key modification must succeed", result.success());
Assert.assertTrue("log must contain a failed passphrase change warning",
result.getLog().containsType(LogType.MSG_MF_PASSPHRASE_FAIL));
@@ -981,6 +1103,57 @@ public class PgpKeyOperationTest {
}
+ @Test
+ public void testUnlockPin() throws Exception {
+
+ String pin = "5235125";
+
+ // change passphrase to a pin type
+ parcel.mNewUnlock = new ChangeUnlockParcel(null, pin);
+ UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
+
+ Assert.assertEquals("exactly three packets should have been added (the secret keys + notation packet)",
+ 3, onlyA.size());
+ Assert.assertEquals("exactly four packets should have been added (the secret keys + notation packet)",
+ 4, onlyB.size());
+
+ RawPacket dkSig = onlyB.get(1);
+ Assert.assertEquals("second modified packet should be notation data",
+ PacketTags.SIGNATURE, dkSig.tag);
+
+ // check that notation data contains pin
+ CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(
+ modified.getEncoded(), false, 0);
+ Assert.assertEquals("secret key type should be 'pin' after this",
+ SecretKeyType.PIN,
+ secretRing.getSecretKey().getSecretKeyType());
+
+ // need to sleep for a sec, so the timestamp changes for notation data
+ Thread.sleep(1000);
+
+ {
+ parcel.mNewUnlock = new ChangeUnlockParcel("phrayse", null);
+ applyModificationWithChecks(parcel, modified, onlyA, onlyB, pin, true, false);
+
+ Assert.assertEquals("exactly four packets should have been removed (the secret keys + notation packet)",
+ 4, onlyA.size());
+ Assert.assertEquals("exactly three packets should have been added (no more notation packet)",
+ 3, onlyB.size());
+ }
+
+ }
+
+ @Test
+ public void testRestricted () throws Exception {
+
+ CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
+
+ parcel.mAddUserIds.add("discord");
+ PgpKeyOperation op = new PgpKeyOperation(null);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, null);
+ Assert.assertFalse("non-restricted operations should fail without passphrase", result.success());
+ }
+
private static UncachedKeyRing applyModificationWithChecks(SaveKeyringParcel parcel,
UncachedKeyRing ring,
ArrayList<RawPacket> onlyA,
@@ -1011,7 +1184,7 @@ public class PgpKeyOperationTest {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
PgpKeyOperation op = new PgpKeyOperation(null);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
Assert.assertTrue("key modification must succeed", result.success());
UncachedKeyRing rawModified = result.getRing();
Assert.assertNotNull("key modification must not return null", rawModified);
@@ -1068,7 +1241,7 @@ public class PgpKeyOperationTest {
private void assertFailure(String reason, SaveKeyringParcel parcel, LogType expected) {
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertFalse(reason, result.success());
Assert.assertNull(reason, result.getRing());
@@ -1082,7 +1255,7 @@ public class PgpKeyOperationTest {
throws Exception {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
Assert.assertFalse(reason, result.success());
Assert.assertNull(reason, result.getRing());
@@ -1096,7 +1269,7 @@ public class PgpKeyOperationTest {
throws Exception {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
- EditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
+ PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
Assert.assertFalse(reason, result.success());
Assert.assertNull(reason, result.getRing());
@@ -1107,7 +1280,7 @@ public class PgpKeyOperationTest {
private UncachedKeyRing assertCreateSuccess(String reason, SaveKeyringParcel parcel) {
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue(reason, result.success());
Assert.assertNotNull(reason, result.getRing());
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java
index e66026246..f9e0d52c3 100644
--- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java
@@ -53,17 +53,19 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
import org.spongycastle.util.Strings;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket;
import java.io.ByteArrayInputStream;
import java.security.Security;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
@@ -102,17 +104,25 @@ public class UncachedKeyringCanonicalizeTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
+ {
+ WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(100,
+ "sunshine, sunshine, ladybugs awake~".getBytes());
+ parcel.mAddUserAttribute.add(uat);
+ }
+
// passphrase is tested in PgpKeyOperationTest, just use empty here
- parcel.mNewPassphrase = "";
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
PgpKeyOperation op = new PgpKeyOperation(null);
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
Assert.assertTrue("initial test key creation must succeed", result.success());
staticRing = result.getRing();
Assert.assertNotNull("initial test key creation must succeed", staticRing);
+ staticRing = staticRing.canonicalize(new OperationLog(), 0).getUncachedKeyRing();
+
// just for later reference
- totalPackets = 9;
+ totalPackets = 11;
// we sleep here for a second, to make sure all new certificates have different timestamps
Thread.sleep(1000);
@@ -146,8 +156,8 @@ public class UncachedKeyringCanonicalizeTest {
Assert.assertEquals("packet #4 should be signature",
PacketTags.SIGNATURE, it.next().tag);
- Assert.assertEquals("packet #5 should be secret subkey",
- PacketTags.SECRET_SUBKEY, it.next().tag);
+ Assert.assertEquals("packet #5 should be user id",
+ PacketTags.USER_ATTRIBUTE, it.next().tag);
Assert.assertEquals("packet #6 should be signature",
PacketTags.SIGNATURE, it.next().tag);
@@ -156,7 +166,12 @@ public class UncachedKeyringCanonicalizeTest {
Assert.assertEquals("packet #8 should be signature",
PacketTags.SIGNATURE, it.next().tag);
- Assert.assertFalse("exactly 9 packets total", it.hasNext());
+ Assert.assertEquals("packet #9 should be secret subkey",
+ PacketTags.SECRET_SUBKEY, it.next().tag);
+ Assert.assertEquals("packet #10 should be signature",
+ PacketTags.SIGNATURE, it.next().tag);
+
+ Assert.assertFalse("exactly 11 packets total", it.hasNext());
Assert.assertArrayEquals("created keyring should be constant through canonicalization",
ring.getEncoded(), ring.canonicalize(log, 0).getEncoded());
@@ -355,18 +370,18 @@ public class UncachedKeyringCanonicalizeTest {
@Test public void testSignatureFuture() throws Exception {
- // generate future
- subHashedPacketsGen.setSignatureCreationTime(false, new Date(new Date().getTime() + 1000 * 1000));
+ // generate future timestamp (we allow up to one day future timestamps)
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.DAY_OF_YEAR, 2);
+ subHashedPacketsGen.setSignatureCreationTime(false, cal.getTime());
injectEverytype(secretKey, ring, subHashedPacketsGen);
-
}
@Test public void testSignatureLocal() throws Exception {
- // generate future
- subHashedPacketsGen.setSignatureCreationTime(false, new Date());
+ // make key local only
subHashedPacketsGen.setExportable(false, false);
injectEverytype(secretKey, ring, subHashedPacketsGen);
@@ -376,7 +391,7 @@ public class UncachedKeyringCanonicalizeTest {
@Test public void testSubkeyDestroy() throws Exception {
// signature for second key (first subkey)
- UncachedKeyRing modified = KeyringTestingHelper.removePacket(ring, 6);
+ UncachedKeyRing modified = KeyringTestingHelper.removePacket(ring, 8);
// canonicalization should fail, because there are no valid uids left
CanonicalizedKeyRing canonicalized = modified.canonicalize(log, 0);
@@ -420,7 +435,7 @@ public class UncachedKeyringCanonicalizeTest {
secretKey.getPublicKey(), pKey.getPublicKey());
// inject in the right position
- UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig.getEncoded(), 6);
+ UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig.getEncoded(), 8);
// canonicalize, and check if we lose the bad signature
CanonicalizedKeyRing canonicalized = modified.canonicalize(log, 0);
@@ -445,7 +460,7 @@ public class UncachedKeyringCanonicalizeTest {
secretKey.getPublicKey(), pKey.getPublicKey());
// inject in the right position
- UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig.getEncoded(), 6);
+ UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig.getEncoded(), 8);
// canonicalize, and check if we lose the bad signature
CanonicalizedKeyRing canonicalized = modified.canonicalize(log, 0);
@@ -477,10 +492,10 @@ public class UncachedKeyringCanonicalizeTest {
secretKey, PGPSignature.SUBKEY_BINDING, subHashedPacketsGen,
secretKey.getPublicKey(), pKey.getPublicKey());
- UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig1.getEncoded(), 8);
- modified = KeyringTestingHelper.injectPacket(modified, sig2.getEncoded(), 9);
- modified = KeyringTestingHelper.injectPacket(modified, sig1.getEncoded(), 10);
- modified = KeyringTestingHelper.injectPacket(modified, sig3.getEncoded(), 11);
+ UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig1.getEncoded(), 10);
+ modified = KeyringTestingHelper.injectPacket(modified, sig2.getEncoded(), 11);
+ modified = KeyringTestingHelper.injectPacket(modified, sig1.getEncoded(), 12);
+ modified = KeyringTestingHelper.injectPacket(modified, sig3.getEncoded(), 13);
// canonicalize, and check if we lose the bad signature
CanonicalizedKeyRing canonicalized = modified.canonicalize(log, 0);
@@ -508,13 +523,13 @@ public class UncachedKeyringCanonicalizeTest {
// get subkey packets
Iterator<RawPacket> it = KeyringTestingHelper.parseKeyring(ring.getEncoded());
- RawPacket subKey = KeyringTestingHelper.getNth(it, 5);
+ RawPacket subKey = KeyringTestingHelper.getNth(it, 7);
RawPacket subSig = it.next();
// inject at a second position
UncachedKeyRing modified = ring;
- modified = KeyringTestingHelper.injectPacket(modified, subKey.buf, 7);
- modified = KeyringTestingHelper.injectPacket(modified, subSig.buf, 8);
+ modified = KeyringTestingHelper.injectPacket(modified, subKey.buf, 9);
+ modified = KeyringTestingHelper.injectPacket(modified, subSig.buf, 10);
// canonicalize, and check if we lose the bad signature
OperationLog log = new OperationLog();
@@ -553,7 +568,7 @@ public class UncachedKeyringCanonicalizeTest {
sKey = new PGPSecretKey(masterSecretKey.getPrivateKey(), subPubKey, sha1Calc, false, keyEncryptor);
}
- UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sKey.getEncoded(), 5);
+ UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sKey.getEncoded(), 7);
// canonicalize, and check if we lose the bad signature
OperationLog log = new OperationLog();
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java
index 3e43cd4b4..ccd47d0ee 100644
--- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java
@@ -33,9 +33,11 @@ import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.util.Strings;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket;
import org.sufficientlysecure.keychain.util.ProgressScaler;
@@ -44,6 +46,7 @@ import java.io.ByteArrayInputStream;
import java.security.Security;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.Random;
/** Tests for the UncachedKeyring.merge method.
*
@@ -95,14 +98,21 @@ public class UncachedKeyringMergeTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
+ {
+ WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(100,
+ "sunshine, sunshine, ladybugs awake~".getBytes());
+ parcel.mAddUserAttribute.add(uat);
+ }
+
// passphrase is tested in PgpKeyOperationTest, just use empty here
- parcel.mNewPassphrase = "";
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
PgpKeyOperation op = new PgpKeyOperation(null);
OperationResult.OperationLog log = new OperationResult.OperationLog();
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
staticRingA = result.getRing();
+ staticRingA = staticRingA.canonicalize(new OperationLog(), 0).getUncachedKeyRing();
}
{
@@ -112,12 +122,13 @@ public class UncachedKeyringMergeTest {
parcel.mAddUserIds.add("shy");
// passphrase is tested in PgpKeyOperationTest, just use empty here
- parcel.mNewPassphrase = "";
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
PgpKeyOperation op = new PgpKeyOperation(null);
OperationResult.OperationLog log = new OperationResult.OperationLog();
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
staticRingB = result.getRing();
+ staticRingB = staticRingB.canonicalize(new OperationLog(), 0).getUncachedKeyRing();
}
Assert.assertNotNull("initial test key creation must succeed", staticRingA);
@@ -335,6 +346,36 @@ public class UncachedKeyringMergeTest {
}
}
+ @Test
+ public void testAddedUserAttributeSignature() throws Exception {
+
+ final UncachedKeyRing modified; {
+ parcel.reset();
+
+ Random r = new Random();
+ int type = r.nextInt(110)+1;
+ byte[] data = new byte[r.nextInt(2000)];
+ new Random().nextBytes(data);
+
+ WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data);
+ parcel.mAddUserAttribute.add(uat);
+
+ CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(
+ ringA.getEncoded(), false, 0);
+ modified = op.modifySecretKeyRing(secretRing, parcel, "").getRing();
+ }
+
+ {
+ UncachedKeyRing merged = ringA.merge(modified, log, 0);
+ Assert.assertNotNull("merge must succeed", merged);
+ Assert.assertFalse(
+ "merging keyring with extra user attribute into its base should yield that same keyring",
+ KeyringTestingHelper.diffKeyrings(merged.getEncoded(), modified.getEncoded(), onlyA, onlyB)
+ );
+ }
+
+ }
+
private UncachedKeyRing mergeWithChecks(UncachedKeyRing a, UncachedKeyRing b)
throws Exception {
return mergeWithChecks(a, b, a);
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java
index 6ed37bbbb..65395f1ab 100644
--- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java
@@ -26,16 +26,18 @@ import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowLog;
import org.spongycastle.bcpg.sig.KeyFlags;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
-import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
+import java.io.IOException;
import java.util.Iterator;
+import java.util.Random;
@RunWith(RobolectricTestRunner.class)
@org.robolectric.annotation.Config(emulateSdk = 18) // Robolectric doesn't yet support 19
@@ -43,10 +45,6 @@ public class UncachedKeyringTest {
static UncachedKeyRing staticRing, staticPubRing;
UncachedKeyRing ring, pubRing;
- ArrayList<RawPacket> onlyA = new ArrayList<RawPacket>();
- ArrayList<RawPacket> onlyB = new ArrayList<RawPacket>();
- PgpKeyOperation op;
- SaveKeyringParcel parcel;
@BeforeClass
public static void setUpOnce() throws Exception {
@@ -62,11 +60,20 @@ public class UncachedKeyringTest {
parcel.mAddUserIds.add("twi");
parcel.mAddUserIds.add("pink");
+ {
+ Random r = new Random();
+ int type = r.nextInt(110)+1;
+ byte[] data = new byte[r.nextInt(2000)];
+ new Random().nextBytes(data);
+
+ WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data);
+ parcel.mAddUserAttribute.add(uat);
+ }
// passphrase is tested in PgpKeyOperationTest, just use empty here
- parcel.mNewPassphrase = "";
+ parcel.mNewUnlock = new ChangeUnlockParcel("");
PgpKeyOperation op = new PgpKeyOperation(null);
- EditKeyResult result = op.createSecretKeyRing(parcel);
+ PgpEditKeyResult result = op.createSecretKeyRing(parcel);
staticRing = result.getRing();
staticPubRing = staticRing.extractPublicKeyRing();
@@ -114,7 +121,7 @@ public class UncachedKeyringTest {
ring.encodeArmored(out, "OpenKeychain");
pubRing.encodeArmored(out, "OpenKeychain");
- Iterator<UncachedKeyRing> it =
+ IteratorWithIOThrow<UncachedKeyRing> it =
UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray()));
Assert.assertTrue("there should be two rings in the stream", it.hasNext());
Assert.assertArrayEquals("first ring should be the first we put in",
@@ -134,4 +141,16 @@ public class UncachedKeyringTest {
pubRing.extractPublicKeyRing();
}
+ @Test(expected = IOException.class)
+ public void testBrokenVersionCert() throws Throwable {
+ // this is a test for one of the patches we use on top of stock bouncycastle, which
+ // returns an IOException rather than a RuntimeException in case of a bad certificate
+ // version byte
+ readRingFromResource("/test-keys/broken_cert_version.asc");
+ }
+
+ UncachedKeyRing readRingFromResource(String name) throws Throwable {
+ return UncachedKeyRing.fromStream(UncachedKeyringTest.class.getResourceAsStream(name)).next();
+ }
+
}
diff --git a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java
index e4a1d62ae..171ecc377 100644
--- a/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java
+++ b/OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/provider/ProviderHelperSaveTest.java
@@ -106,8 +106,8 @@ public class ProviderHelperSaveTest {
UncachedKeyRing pub = readRingFromResource("/test-keys/mailvelope_07_no_key_flags.asc");
long keyId = pub.getMasterKeyId();
- Assert.assertNull("key flags should be null",
- pub.canonicalize(new OperationLog(), 0).getPublicKey().getKeyUsage());
+ Assert.assertEquals("key flags should be zero",
+ 0, (long) pub.canonicalize(new OperationLog(), 0).getPublicKey().getKeyUsage());
mProviderHelper.savePublicKeyRing(pub);
@@ -117,7 +117,8 @@ public class ProviderHelperSaveTest {
Assert.assertEquals("master key should be encryption key", keyId, pubRing.getEncryptId());
Assert.assertEquals("master key should be encryption key (cached)", keyId, cachedRing.getEncryptId());
- Assert.assertNull("canonicalized key flags should be null", pubRing.getPublicKey().getKeyUsage());
+ Assert.assertEquals("canonicalized key flags should be zero",
+ 0, (long) pubRing.getPublicKey().getKeyUsage());
Assert.assertTrue("master key should be able to certify", pubRing.getPublicKey().canCertify());
Assert.assertTrue("master key should be allowed to sign", pubRing.getPublicKey().canSign());
Assert.assertTrue("master key should be able to encrypt", pubRing.getPublicKey().canEncrypt());
diff --git a/OpenKeychain-Test/src/test/resources/test-keys/broken_cert_version.asc b/OpenKeychain-Test/src/test/resources/test-keys/broken_cert_version.asc
new file mode 100644
index 000000000..e2d2abd8e
--- /dev/null
+++ b/OpenKeychain-Test/src/test/resources/test-keys/broken_cert_version.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBFSl5DIBCADqsGJJ8RhV4Uw6a3Q48QyTMrUtvZquOTlLVaqOdEFZNL5/OBal
+prft9LNkcOkIVA89Hdn715WwkmG2OJiJoQ/ZAKwal1CPGm4Q8kZIM7k57ISJL6J5
+300e7UIznc74XbG7eFNxNcjCM9wG12vW2rFwc+ogJtkBSf0IXukPwtUkRK+H5ufO
+lpqS5NNZfiGbNQCrb+YsGZNRk4QTGR6WGyaIRHlcG8G00VPGNSauTqe/11MO9MoF
+BvPgFeur3nefWunCQ+uDmzIEs8r94gaHu3LWbctd5w5x/o/PDfTSSiO+U8zzXrKC
+4ZpEl5bk7t7jH1hYMLWyO6nn0vWTOMO1EYLBABEBAAG0GGJyb2tlbiBzaWduYXR1
+cmUgdmVyc2lvbokBOMATAQIAIgUCVKXkMgIbAwYLCQgHAwIGFQgCCQoLBBYCAwEC
+HgECF4AACgkQDe00lH/2SnprLggAh64TsdHDfIhTNc1DeJLCuvuHsitAcUdEEnue
+yJjodxboKNSplIwnmb5CpM3P8f736dNaW77Yd6aO4IeAy6cBlxT1tSRkJMsp+cBt
+kBa3lRr+GnWZlLZs3coL2g0t5RbuyYKyQxm2qvgFJGi/7Qfty5nJOW5U1ElT3VT8
+jISNdQdDAIaBsCE+TuyW3VsP3PqnJ7x14K7VhkFuCyvYB9paLcJBnan93R0Ja0Ip
+Cv1pbrNxXp0UELf0RYc2X5C1m6otZ9LKf3PmzxlEkApkb1TZUEBak2Za5p99koZT
++pg/XpZPyawi+gZeYkBAohxRGmzG/a4L+YacAZHbchfN0eG7lg==
+=mxTR
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle
index 6bea6954e..3d852621c 100644
--- a/OpenKeychain/build.gradle
+++ b/OpenKeychain/build.gradle
@@ -3,14 +3,14 @@ apply plugin: 'com.android.application'
dependencies {
// NOTE: Always use fixed version codes not dynamic ones, e.g. 0.7.3 instead of 0.7.+, see README for more information
- compile 'com.android.support:support-v4:21.0.2'
- compile 'com.android.support:appcompat-v7:21.0.2'
+ compile 'com.android.support:support-v4:21.0.3'
+ compile 'com.android.support:appcompat-v7:21.0.3'
+ compile 'com.android.support:recyclerview-v7:21.0.3'
+ compile 'com.android.support:cardview-v7:21.0.3'
compile project(':extern:openpgp-api-lib')
compile project(':extern:openkeychain-api-lib')
compile project(':extern:html-textview')
compile project(':extern:StickyListHeaders:library')
- compile project(':extern:zxing-qr-code')
- compile project(':extern:zxing-android-integration')
compile project(':extern:spongycastle:core')
compile project(':extern:spongycastle:pg')
compile project(':extern:spongycastle:pkix')
@@ -20,17 +20,32 @@ dependencies {
compile project(':extern:KeybaseLib:Lib')
compile project(':extern:TokenAutoComplete:library')
compile project(':extern:safeslinger-exchange')
+
+ // TODO: Pin!
+ compile 'com.eftimoff:android-patternview:1.0.0@aar'
+ compile 'com.journeyapps:zxing-android-embedded:2.0.1@aar'
+ compile 'com.journeyapps:zxing-android-integration:2.0.1@aar'
+ compile 'com.google.zxing:core:3.0.1'
+ compile 'com.jpardogo.materialtabstrip:library:1.0.9'
+ compile 'it.neokree:MaterialNavigationDrawer:1.3.1'
+ compile 'com.nispok:snackbar:2.7.4'
+ compile 'com.getbase:floatingactionbutton:1.8.0'
}
android {
compileSdkVersion 21
- buildToolsVersion '21.1.1'
+ buildToolsVersion '21.1.2'
defaultConfig {
- minSdkVersion 9
+ minSdkVersion 15
targetSdkVersion 21
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
/*
* To sign release build, create file gradle.properties in ~/.gradle/ with this content:
*
diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml
index 100f584c1..29b748410 100644
--- a/OpenKeychain/src/main/AndroidManifest.xml
+++ b/OpenKeychain/src/main/AndroidManifest.xml
@@ -31,10 +31,7 @@
For OI Filemanager it makes no difference, gpg files can't be associated
-->
- <!-- Specified in build.gradle -->
- <!--<uses-sdk-->
- <!--android:minSdkVersion="9"-->
- <!--android:targetSdkVersion="19" />-->
+ <!-- SDK levels are specified in build.gradle -->
<uses-feature
android:name="android.hardware.wifi"
@@ -70,15 +67,17 @@
<uses-permission android:name="android.permission.READ_PROFILE" />
<!-- android:allowBackup="false": Don't allow backup over adb backup or other apps! -->
+ <!-- tools:replace="android:allowBackup" is a workaround for https://github.com/geftimov/android-patternview/pull/2 -->
<application
android:name=".KeychainApplication"
+ tools:replace="android:allowBackup"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
android:theme="@style/KeychainTheme"
android:label="@string/app_name">
<activity
- android:name=".ui.KeyListActivity"
+ android:name=".ui.MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/app_name"
android:launchMode="singleTop">
@@ -98,10 +97,10 @@
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:windowSoftInputMode="stateHidden"
android:label="@string/title_create_key"
- android:parentActivityName=".ui.KeyListActivity">
+ android:parentActivityName=".ui.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value=".ui.KeyListActivity" />
+ android:value=".ui.MainActivity" />
</activity>
<activity
android:name=".ui.EditKeyActivity"
@@ -115,10 +114,10 @@
android:name=".ui.ViewKeyActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_key_details"
- android:parentActivityName=".ui.KeyListActivity">
+ android:parentActivityName=".ui.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value=".ui.KeyListActivity" />
+ android:value=".ui.MainActivity" />
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@@ -139,21 +138,20 @@
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_exchange_keys"
android:windowSoftInputMode="stateHidden"
- android:parentActivityName=".ui.KeyListActivity">
+ android:parentActivityName=".ui.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value=".ui.KeyListActivity" />
+ android:value=".ui.MainActivity" />
</activity>
<activity
- android:name=".ui.SelectPublicKeyActivity"
- android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
- android:label="@string/title_select_recipients"
- android:launchMode="singleTop" />
- <activity
android:name=".ui.EncryptFilesActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_encrypt_files"
- android:windowSoftInputMode="stateHidden">
+ android:windowSoftInputMode="stateHidden"
+ android:parentActivityName=".ui.MainActivity">
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".ui.MainActivity" />
<!-- Keychain's own Actions -->
<!-- ENCRYPT with data Uri -->
@@ -182,7 +180,11 @@
android:name=".ui.EncryptTextActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_encrypt_text"
- android:windowSoftInputMode="stateHidden">
+ android:windowSoftInputMode="stateHidden"
+ android:parentActivityName=".ui.MainActivity">
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".ui.MainActivity" />
<!-- Keychain's own Actions -->
<!-- ENCRYPT with text as extra -->
@@ -202,19 +204,14 @@
</intent-filter>
</activity>
<activity
- android:name=".ui.DecryptActivity"
- android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
- android:label="@string/title_decrypt"
- android:windowSoftInputMode="stateHidden" />
- <activity
android:name=".ui.DecryptTextActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_decrypt"
android:windowSoftInputMode="stateHidden"
- android:parentActivityName=".ui.DecryptActivity">
+ android:parentActivityName=".ui.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value=".ui.DecryptActivity" />
+ android:value=".ui.MainActivity" />
<!-- Keychain's own Actions -->
<!-- DECRYPT with text as extra -->
@@ -238,10 +235,10 @@
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_decrypt"
android:windowSoftInputMode="stateHidden"
- android:parentActivityName=".ui.DecryptActivity">
+ android:parentActivityName=".ui.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value=".ui.DecryptActivity" />
+ android:value=".ui.MainActivity" />
<!-- VIEW with mimeType application/octet-stream, application/pgp and text/pgp -->
<intent-filter android:label="@string/intent_send_decrypt">
@@ -416,12 +413,11 @@
android:value=".ui.ViewKeyActivity" />
</activity>
<activity
- android:name=".ui.ViewKeyAdvancedActivity"
+ android:name=".ui.ViewKeyAdvActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
- android:label="@string/title_advanced_key_info">
- </activity>
+ android:label="@string/title_advanced_key_info"/>
<activity
- android:name=".ui.PreferencesActivity"
+ android:name=".ui.SettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_preferences">
<intent-filter>
@@ -434,7 +430,7 @@
</intent-filter>
</activity>
<activity
- android:name=".ui.PreferencesKeyServerActivity"
+ android:name=".ui.SettingsKeyServerActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_key_server_preference"
android:windowSoftInputMode="stateHidden" />
@@ -444,7 +440,15 @@
android:label="@string/title_certify_key">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value=".ui.KeyListActivity" />
+ android:value=".ui.MainActivity" />
+ </activity>
+ <activity
+ android:name=".ui.CertifyFingerprintActivity"
+ android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
+ android:label="@string/title_certify_key">
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".ui.MainActivity" />
</activity>
<activity
android:name=".ui.QrCodeScanActivity"
@@ -651,7 +655,7 @@
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value=".ui.KeyListActivity" />
+ android:value=".ui.MainActivity" />
</activity>
<activity
android:name=".ui.ConsolidateDialogActivity"
@@ -659,6 +663,7 @@
<activity
android:name=".ui.PassphraseDialogActivity"
android:theme="@android:style/Theme.NoDisplay" />
+ <activity android:name=".ui.PassphraseWizardActivity" />
<!--
NOTE: singleTop is set to get NFC foreground dispatch to work.
Then, all NFC intents will be broadcasted to onNewIntent() of this activity!
@@ -709,18 +714,13 @@
android:launchMode="singleTop"
android:process=":remote_api" />
<activity
- android:name=".remote.ui.AppsListActivity"
- android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
- android:exported="false"
- android:label="@string/title_api_registered_apps" />
- <activity
android:name=".remote.ui.AppSettingsActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:exported="false">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
- android:value=".remote.ui.AppsListActivity" />
+ android:value=".ui.MainActivity" />
</activity>
<activity
android:name=".remote.ui.AccountSettingsActivity"
diff --git a/OpenKeychain/src/main/java/android/support/v4/widget/FixedDrawerLayout.java b/OpenKeychain/src/main/java/android/support/v4/widget/FixedDrawerLayout.java
deleted file mode 100644
index 6924e0b06..000000000
--- a/OpenKeychain/src/main/java/android/support/v4/widget/FixedDrawerLayout.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-
-/**
- * Fix for NullPointerException at android.support.v4.widget.DrawerLayout.isContentView(DrawerLayout.java:840)
- * <p/>
- * http://stackoverflow.com/a/18107942
- */
-public class FixedDrawerLayout extends DrawerLayout {
- public FixedDrawerLayout(Context context) {
- super(context);
- }
-
- public FixedDrawerLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public FixedDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- boolean isContentView(View child) {
- if (child == null) {
- return false;
- }
- return ((LayoutParams) child.getLayoutParams()).gravity == Gravity.NO_GRAVITY;
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
index 04a932658..67fa30a44 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
@@ -20,11 +20,6 @@ package org.sufficientlysecure.keychain;
import android.os.Environment;
import org.spongycastle.jce.provider.BouncyCastleProvider;
-import org.sufficientlysecure.keychain.remote.ui.AppsListActivity;
-import org.sufficientlysecure.keychain.ui.DecryptActivity;
-import org.sufficientlysecure.keychain.ui.EncryptFilesActivity;
-import org.sufficientlysecure.keychain.ui.EncryptTextActivity;
-import org.sufficientlysecure.keychain.ui.KeyListActivity;
import java.io.File;
@@ -91,21 +86,6 @@ public final class Constants {
public static final int PREF_VERSION = 4;
}
- public static final class DrawerItems {
- public static final Class KEY_LIST = KeyListActivity.class;
- public static final Class ENCRYPT_TEXT = EncryptTextActivity.class;
- public static final Class ENCRYPT_FILE = EncryptFilesActivity.class;
- public static final Class DECRYPT = DecryptActivity.class;
- public static final Class REGISTERED_APPS_LIST = AppsListActivity.class;
- public static final Class[] ARRAY = new Class[]{
- KEY_LIST,
- ENCRYPT_TEXT,
- ENCRYPT_FILE,
- DECRYPT,
- REGISTERED_APPS_LIST
- };
- }
-
public static final class key {
public static final int none = 0;
public static final int symmetric = -1;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java
index 446699a81..01f6735ea 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java
@@ -32,12 +32,12 @@ import android.provider.ContactsContract;
import android.widget.Toast;
import org.spongycastle.jce.provider.BouncyCastleProvider;
-import org.sufficientlysecure.keychain.util.Preferences;
-import org.sufficientlysecure.keychain.util.TlsHelper;
import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PRNGFixes;
+import org.sufficientlysecure.keychain.util.Preferences;
+import org.sufficientlysecure.keychain.util.TlsHelper;
import java.security.Security;
@@ -86,7 +86,7 @@ public class KeychainApplication extends Application {
}
brandGlowEffect(getApplicationContext(),
- getApplicationContext().getResources().getColor(R.color.emphasis));
+ getApplicationContext().getResources().getColor(R.color.primary));
setupAccountAsNeeded(this);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java
index 255ca1cde..c0221fad3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java
@@ -17,8 +17,8 @@
package org.sufficientlysecure.keychain.keyimport;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
import java.util.ArrayList;
import java.util.Vector;
@@ -32,10 +32,10 @@ public class CloudSearch {
public static ArrayList<ImportKeysListEntry> search(final String query, Preferences.CloudSearchPrefs cloudPrefs)
throws Keyserver.CloudSearchFailureException {
- final ArrayList<Keyserver> servers = new ArrayList<Keyserver>();
+ final ArrayList<Keyserver> servers = new ArrayList<>();
// it's a Vector for sync, multiple threads might report problems
- final Vector<Keyserver.CloudSearchFailureException> problems = new Vector<Keyserver.CloudSearchFailureException>();
+ final Vector<Keyserver.CloudSearchFailureException> problems = new Vector<>();
if (cloudPrefs.searchKeyserver) {
servers.add(new HkpKeyserver(cloudPrefs.keyserver));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java
index 7f07b8162..480319081 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java
@@ -19,10 +19,10 @@
package org.sufficientlysecure.keychain.keyimport;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.util.TlsHelper;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.TlsHelper;
import java.io.BufferedWriter;
import java.io.IOException;
@@ -234,7 +234,7 @@ public class HkpKeyserver extends Keyserver {
@Override
public ArrayList<ImportKeysListEntry> search(String query) throws QueryFailedException,
QueryNeedsRepairException {
- ArrayList<ImportKeysListEntry> results = new ArrayList<ImportKeysListEntry>();
+ ArrayList<ImportKeysListEntry> results = new ArrayList<>();
if (query.length() < 3) {
throw new QueryTooShortException();
@@ -305,7 +305,7 @@ public class HkpKeyserver extends Keyserver {
entry.setRevoked(matcher.group(6).contains("r"));
entry.setExpired(matcher.group(6).contains("e"));
- ArrayList<String> userIds = new ArrayList<String>();
+ ArrayList<String> userIds = new ArrayList<>();
final String uidLines = matcher.group(7);
final Matcher uidMatcher = UID_LINE.matcher(uidLines);
while (uidMatcher.find()) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java
index 854a90713..79065604a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java
@@ -21,10 +21,11 @@ import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
+import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.io.Serializable;
import java.util.ArrayList;
@@ -88,7 +89,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
public ImportKeysListEntry createFromParcel(final Parcel source) {
ImportKeysListEntry vr = new ImportKeysListEntry();
vr.mPrimaryUserId = source.readString();
- vr.mUserIds = new ArrayList<String>();
+ vr.mUserIds = new ArrayList<>();
source.readStringList(vr.mUserIds);
vr.mMergedUserIds = (HashMap<String, HashSet<String>>) source.readSerializable();
vr.mKeyId = source.readLong();
@@ -102,7 +103,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
vr.mSecretKey = source.readByte() == 1;
vr.mSelected = source.readByte() == 1;
vr.mExtraData = source.readString();
- vr.mOrigins = new ArrayList<String>();
+ vr.mOrigins = new ArrayList<>();
source.readStringList(vr.mOrigins);
return vr;
@@ -264,8 +265,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
mSecretKey = false;
// do not select by default
mSelected = false;
- mUserIds = new ArrayList<String>();
- mOrigins = new ArrayList<String>();
+ mUserIds = new ArrayList<>();
+ mOrigins = new ArrayList<>();
}
/**
@@ -287,14 +288,14 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
// if there was no user id flagged as primary, use the first one
if (mPrimaryUserId == null) {
- mPrimaryUserId = mUserIds.get(0);
+ mPrimaryUserId = context.getString(R.string.user_id_none);
}
mKeyId = key.getKeyId();
mKeyIdHex = KeyFormattingUtils.convertKeyIdToHex(mKeyId);
- mRevoked = key.isRevoked();
- mExpired = key.isExpired();
+ mRevoked = key.isMaybeRevoked();
+ mExpired = key.isMaybeExpired();
mFingerprintHex = KeyFormattingUtils.convertFingerprintToHex(key.getFingerprint());
mBitStrength = key.getBitStrength();
mCurveOid = key.getCurveOid();
@@ -303,7 +304,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
}
public void updateMergedUserIds() {
- mMergedUserIds = new HashMap<String, HashSet<String>>();
+ mMergedUserIds = new HashMap<>();
for (String userId : mUserIds) {
String[] userIdSplit = KeyRing.splitUserId(userId);
@@ -314,7 +315,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
// email
if (userIdSplit[1] != null) {
if (!mMergedUserIds.containsKey(userIdSplit[0])) {
- HashSet<String> emails = new HashSet<String>();
+ HashSet<String> emails = new HashSet<>();
emails.add(userIdSplit[1]);
mMergedUserIds.put(userIdSplit[0], emails);
} else {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java
index 2363a40b3..e310e9a3f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java
@@ -36,7 +36,7 @@ public class KeybaseKeyserver extends Keyserver {
@Override
public ArrayList<ImportKeysListEntry> search(String query) throws QueryFailedException,
QueryNeedsRepairException {
- ArrayList<ImportKeysListEntry> results = new ArrayList<ImportKeysListEntry>();
+ ArrayList<ImportKeysListEntry> results = new ArrayList<>();
if (query.startsWith("0x")) {
// cut off "0x" if a user is searching for a key id
@@ -81,7 +81,7 @@ public class KeybaseKeyserver extends Keyserver {
final int algorithmId = match.getAlgorithmId();
entry.setAlgorithm(KeyFormattingUtils.getAlgorithmInfo(algorithmId, bitStrength, null));
- ArrayList<String> userIds = new ArrayList<String>();
+ ArrayList<String> userIds = new ArrayList<>();
String name = "<keybase.io/" + username + ">";
if (fullName != null) {
name = fullName + " " + name;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java
index c400eb813..e796bdc91 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java
@@ -77,6 +77,12 @@ public abstract class BaseOperation implements PassphraseCacheInterface {
return mCancelled != null && mCancelled.get();
}
+ protected void setPreventCancel () {
+ if (mProgressable != null) {
+ mProgressable.setPreventCancel();
+ }
+ }
+
@Override
public String getCachedPassphrase(long subKeyId) throws NoSecretKeyException {
try {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java
index 3bd412c36..025f45f7f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java
@@ -5,6 +5,10 @@ import android.content.Context;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException;
+import org.sufficientlysecure.keychain.operations.results.CertifyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
@@ -16,10 +20,6 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
-import org.sufficientlysecure.keychain.operations.results.CertifyResult;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
-import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log;
@@ -50,9 +50,6 @@ public class CertifyOperation extends BaseOperation {
CanonicalizedSecretKey certificationKey;
try {
- // certification is always with the master key id, so use that one
- String passphrase = getCachedPassphrase(parcel.mMasterKeyId, parcel.mMasterKeyId);
-
log.add(LogType.MSG_CRT_MASTER_FETCH, 1);
CanonicalizedSecretKeyRing secretKeyRing =
mProviderHelper.getCanonicalizedSecretKeyRing(parcel.mMasterKeyId);
@@ -62,6 +59,10 @@ public class CertifyOperation extends BaseOperation {
log.add(LogType.MSG_CRT_ERROR_DIVERT, 2);
return new CertifyResult(CertifyResult.RESULT_ERROR, log);
}
+
+ // certification is always with the master key id, so use that one
+ String passphrase = getCachedPassphrase(parcel.mMasterKeyId, parcel.mMasterKeyId);
+
if (!certificationKey.unlock(passphrase)) {
log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2);
return new CertifyResult(CertifyResult.RESULT_ERROR, log);
@@ -77,7 +78,7 @@ public class CertifyOperation extends BaseOperation {
return new CertifyResult(CertifyResult.RESULT_ERROR, log);
}
- ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<UncachedKeyRing>();
+ ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<>();
log.add(LogType.MSG_CRT_CERTIFYING, 1);
@@ -94,6 +95,12 @@ public class CertifyOperation extends BaseOperation {
try {
+ if (action.mMasterKeyId == parcel.mMasterKeyId) {
+ log.add(LogType.MSG_CRT_ERROR_SELF, 2);
+ certifyError += 1;
+ continue;
+ }
+
if (action.mUserIds == null) {
log.add(LogType.MSG_CRT_CERTIFY_ALL, 2,
KeyFormattingUtils.convertKeyIdToHex(action.mMasterKeyId));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java
new file mode 100644
index 000000000..7f14b08d9
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java
@@ -0,0 +1,131 @@
+package org.sufficientlysecure.keychain.operations;
+
+import android.content.Context;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
+import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
+import org.sufficientlysecure.keychain.pgp.Progressable;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
+import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
+import org.sufficientlysecure.keychain.service.PassphraseCacheService;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.ProgressScaler;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/** An operation which implements a high level key edit operation.
+ *
+ * This operation provides a higher level interface to the edit and
+ * create key operations in PgpKeyOperation. It takes care of fetching
+ * and saving the key before and after the operation.
+ *
+ * @see SaveKeyringParcel
+ *
+ */
+public class EditKeyOperation extends BaseOperation {
+
+ public EditKeyOperation(Context context, ProviderHelper providerHelper,
+ Progressable progressable, AtomicBoolean cancelled) {
+ super(context, providerHelper, progressable, cancelled);
+ }
+
+ public EditKeyResult execute(SaveKeyringParcel saveParcel, String passphrase) {
+
+ OperationLog log = new OperationLog();
+ log.add(LogType.MSG_ED, 0);
+
+ if (saveParcel == null) {
+ log.add(LogType.MSG_ED_ERROR_NO_PARCEL, 1);
+ return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ }
+
+ // Perform actual modification (or creation)
+ PgpEditKeyResult modifyResult;
+ {
+ PgpKeyOperation keyOperations =
+ new PgpKeyOperation(new ProgressScaler(mProgressable, 10, 60, 100), mCancelled);
+
+ // If a key id is specified, fetch and edit
+ if (saveParcel.mMasterKeyId != null) {
+ try {
+
+ log.add(LogType.MSG_ED_FETCHING, 1,
+ KeyFormattingUtils.convertKeyIdToHex(saveParcel.mMasterKeyId));
+ CanonicalizedSecretKeyRing secRing =
+ mProviderHelper.getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
+
+ modifyResult = keyOperations.modifySecretKeyRing(secRing, saveParcel, passphrase);
+
+ } catch (NotFoundException e) {
+ log.add(LogType.MSG_ED_ERROR_KEY_NOT_FOUND, 2);
+ return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ }
+ } else {
+ // otherwise, create new one
+ modifyResult = keyOperations.createSecretKeyRing(saveParcel);
+ }
+ }
+
+ // Add the result to the log
+ log.add(modifyResult, 1);
+
+ // Check if the action was cancelled
+ if (checkCancelled()) {
+ log.add(LogType.MSG_OPERATION_CANCELLED, 0);
+ return new EditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null);
+ }
+
+ // If the edit operation didn't succeed, exit here
+ if (!modifyResult.success()) {
+ // error is already logged by modification
+ return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ }
+
+ // Cannot cancel from here on out!
+ mProgressable.setPreventCancel();
+
+ // It's a success, so this must be non-null now
+ UncachedKeyRing ring = modifyResult.getRing();
+
+ // Save the new keyring.
+ SaveKeyringResult saveResult = mProviderHelper
+ .saveSecretKeyRing(ring, new ProgressScaler(mProgressable, 60, 95, 100));
+ log.add(saveResult, 1);
+
+ // If the save operation didn't succeed, exit here
+ if (!saveResult.success()) {
+ return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ }
+
+ // There is a new passphrase - cache it
+ if (saveParcel.mNewUnlock != null) {
+ log.add(LogType.MSG_ED_CACHING_NEW, 1);
+ PassphraseCacheService.addCachedPassphrase(mContext,
+ ring.getMasterKeyId(),
+ ring.getMasterKeyId(),
+ saveParcel.mNewUnlock.mNewPassphrase != null
+ ? saveParcel.mNewUnlock.mNewPassphrase
+ : saveParcel.mNewUnlock.mNewPin,
+ ring.getPublicKey().getPrimaryUserIdWithFallback());
+ }
+
+ updateProgress(R.string.progress_done, 100, 100);
+
+ // make sure new data is synced into contacts
+ ContactSyncAdapterService.requestSync();
+
+ log.add(LogType.MSG_ED_SUCCESS, 0);
+ return new EditKeyResult(EditKeyResult.RESULT_OK, log, ring.getMasterKeyId());
+
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
index da532d2dc..8f10377cd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
@@ -30,7 +30,13 @@ import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver;
import org.sufficientlysecure.keychain.keyimport.Keyserver;
import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
+import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.operations.results.ExportResult;
+import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.Progressable;
@@ -39,13 +45,12 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
-import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
-import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
+import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.ParcelableFileCache;
+import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import java.io.BufferedOutputStream;
@@ -57,6 +62,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/** An operation class which implements high level import and export
@@ -122,6 +128,35 @@ public class ImportExportOperation extends BaseOperation {
}
}
+ public ImportKeyResult importKeyRings(List<ParcelableKeyRing> entries, String keyServerUri) {
+
+ Iterator<ParcelableKeyRing> it = entries.iterator();
+ int numEntries = entries.size();
+
+ return importKeyRings(it, numEntries, keyServerUri);
+
+ }
+
+ public ImportKeyResult importKeyRings(ParcelableFileCache<ParcelableKeyRing> cache, String keyServerUri) {
+
+ // get entries from cached file
+ try {
+ IteratorWithSize<ParcelableKeyRing> it = cache.readCache();
+ int numEntries = it.getSize();
+
+ return importKeyRings(it, numEntries, keyServerUri);
+ } catch (IOException e) {
+
+ // Special treatment here, we need a lot
+ OperationLog log = new OperationLog();
+ log.add(LogType.MSG_IMPORT, 0, 0);
+ log.add(LogType.MSG_IMPORT_ERROR_IO, 0, 0);
+
+ return new ImportKeyResult(ImportKeyResult.RESULT_ERROR, log);
+ }
+
+ }
+
public ImportKeyResult importKeyRings(Iterator<ParcelableKeyRing> entries, int num, String keyServerUri) {
updateProgress(R.string.progress_importing, 0, 100);
@@ -130,13 +165,11 @@ public class ImportExportOperation extends BaseOperation {
// If there aren't even any keys, do nothing here.
if (entries == null || !entries.hasNext()) {
- return new ImportKeyResult(
- ImportKeyResult.RESULT_FAIL_NOTHING, log, 0, 0, 0, 0,
- new long[]{});
+ return new ImportKeyResult(ImportKeyResult.RESULT_FAIL_NOTHING, log);
}
int newKeys = 0, oldKeys = 0, badKeys = 0, secret = 0;
- ArrayList<Long> importedMasterKeyIds = new ArrayList<Long>();
+ ArrayList<Long> importedMasterKeyIds = new ArrayList<>();
boolean cancelled = false;
int position = 0;
@@ -292,6 +325,16 @@ public class ImportExportOperation extends BaseOperation {
position++;
}
+ // Special: consolidate on secret key import (cannot be cancelled!)
+ if (secret > 0) {
+ setPreventCancel();
+ ConsolidateResult result = mProviderHelper.consolidateDatabaseStep1(mProgressable);
+ log.add(result, 1);
+ }
+
+ // Special: make sure new data is synced into contacts
+ ContactSyncAdapterService.requestSync();
+
// convert to long array
long[] importedMasterKeyIdsArray = new long[importedMasterKeyIds.size()];
for (int i = 0; i < importedMasterKeyIds.size(); ++i) {
@@ -399,7 +442,7 @@ public class ImportExportOperation extends BaseOperation {
}
- private ExportResult exportKeyRings(OperationLog log, long[] masterKeyIds, boolean exportSecret,
+ ExportResult exportKeyRings(OperationLog log, long[] masterKeyIds, boolean exportSecret,
OutputStream outStream) {
/* TODO isn't this checked above, with the isStorageMounted call?
@@ -469,12 +512,16 @@ public class ImportExportOperation extends BaseOperation {
log.add(LogType.MSG_EXPORT_PUBLIC, 1, KeyFormattingUtils.beautifyKeyId(keyId));
- { // export public key part
- byte[] data = cursor.getBlob(1);
- arOutStream.write(data);
+ byte[] data = cursor.getBlob(1);
+ CanonicalizedKeyRing ring =
+ UncachedKeyRing.decodeFromData(data).canonicalize(log, 2, true);
+ ring.encode(arOutStream);
- okPublic += 1;
- }
+ okPublic += 1;
+ } catch (PgpGeneralException e) {
+ log.add(LogType.MSG_EXPORT_ERROR_KEY, 2);
+ updateProgress(progress++, numKeys);
+ continue;
} finally {
// make sure this is closed
if (arOutStream != null) {
@@ -491,12 +538,18 @@ public class ImportExportOperation extends BaseOperation {
arOutStream.setHeader("Version", version);
}
- // export secret key part
+ // export secret key part
log.add(LogType.MSG_EXPORT_SECRET, 2, KeyFormattingUtils.beautifyKeyId(keyId));
byte[] data = cursor.getBlob(2);
- arOutStream.write(data);
+ CanonicalizedKeyRing ring =
+ UncachedKeyRing.decodeFromData(data).canonicalize(log, 2, true);
+ ring.encode(arOutStream);
okSecret += 1;
+ } catch (PgpGeneralException e) {
+ log.add(LogType.MSG_EXPORT_ERROR_KEY, 2);
+ updateProgress(progress++, numKeys);
+ continue;
} finally {
// make sure this is closed
if (arOutStream != null) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java
new file mode 100644
index 000000000..783b32477
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java
@@ -0,0 +1,103 @@
+package org.sufficientlysecure.keychain.operations;
+
+import android.content.Context;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
+import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
+import org.sufficientlysecure.keychain.pgp.Progressable;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.ProgressScaler;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/** An operation which promotes a public key ring to a secret one.
+ *
+ * This operation can only be applied to public key rings where no secret key
+ * is available. Doing this "promotes" the public key ring to a secret one
+ * without secret key material, using a GNU_DUMMY s2k type.
+ *
+ */
+public class PromoteKeyOperation extends BaseOperation {
+
+ public PromoteKeyOperation(Context context, ProviderHelper providerHelper,
+ Progressable progressable, AtomicBoolean cancelled) {
+ super(context, providerHelper, progressable, cancelled);
+ }
+
+ public PromoteKeyResult execute(long masterKeyId) {
+
+ OperationLog log = new OperationLog();
+ log.add(LogType.MSG_PR, 0);
+
+ // Perform actual type change
+ UncachedKeyRing promotedRing;
+ {
+
+ try {
+
+ // This operation is only allowed for pure public keys
+ // TODO delete secret keys if they are stripped, or have been moved to the card?
+ if (mProviderHelper.getCachedPublicKeyRing(masterKeyId).hasAnySecret()) {
+ log.add(LogType.MSG_PR_ERROR_ALREADY_SECRET, 2);
+ return new PromoteKeyResult(PromoteKeyResult.RESULT_ERROR, log, null);
+ }
+
+ log.add(LogType.MSG_PR_FETCHING, 1,
+ KeyFormattingUtils.convertKeyIdToHex(masterKeyId));
+ CanonicalizedPublicKeyRing pubRing =
+ mProviderHelper.getCanonicalizedPublicKeyRing(masterKeyId);
+
+ // create divert-to-card secret key from public key
+ promotedRing = pubRing.createDummySecretRing();
+
+ } catch (PgpKeyNotFoundException e) {
+ log.add(LogType.MSG_PR_ERROR_KEY_NOT_FOUND, 2);
+ return new PromoteKeyResult(PromoteKeyResult.RESULT_ERROR, log, null);
+ } catch (NotFoundException e) {
+ log.add(LogType.MSG_PR_ERROR_KEY_NOT_FOUND, 2);
+ return new PromoteKeyResult(PromoteKeyResult.RESULT_ERROR, log, null);
+ }
+ }
+
+ // If the edit operation didn't succeed, exit here
+ if (promotedRing == null) {
+ // error is already logged by modification
+ return new PromoteKeyResult(PromoteKeyResult.RESULT_ERROR, log, null);
+ }
+
+ // Check if the action was cancelled
+ if (checkCancelled()) {
+ log.add(LogType.MSG_OPERATION_CANCELLED, 0);
+ return new PromoteKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null);
+ }
+
+ // Cannot cancel from here on out!
+ setPreventCancel();
+
+ // Save the new keyring.
+ SaveKeyringResult saveResult = mProviderHelper
+ .saveSecretKeyRing(promotedRing, new ProgressScaler(mProgressable, 60, 95, 100));
+ log.add(saveResult, 1);
+
+ // If the save operation didn't succeed, exit here
+ if (!saveResult.success()) {
+ return new PromoteKeyResult(PromoteKeyResult.RESULT_ERROR, log, null);
+ }
+
+ updateProgress(R.string.progress_done, 100, 100);
+
+ log.add(LogType.MSG_PR_SUCCESS, 0);
+ return new PromoteKeyResult(PromoteKeyResult.RESULT_OK, log, promotedRing.getMasterKeyId());
+
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java
new file mode 100644
index 000000000..e98f6b150
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java
@@ -0,0 +1,136 @@
+package org.sufficientlysecure.keychain.operations;
+
+import android.content.Context;
+import android.net.Uri;
+
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
+import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
+import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;
+import org.sufficientlysecure.keychain.pgp.Progressable;
+import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.util.FileHelper;
+import org.sufficientlysecure.keychain.util.InputData;
+import org.sufficientlysecure.keychain.util.ProgressScaler;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/** This is a high-level operation, which encapsulates one or more sign/encrypt
+ * operations, using URIs or byte arrays as input and output.
+ *
+ * This operation is fail-fast: If any sign/encrypt sub-operation fails or returns
+ * a pending result, it will terminate.
+ *
+ */
+public class SignEncryptOperation extends BaseOperation {
+
+ public SignEncryptOperation(Context context, ProviderHelper providerHelper,
+ Progressable progressable, AtomicBoolean cancelled) {
+ super(context, providerHelper, progressable, cancelled);
+ }
+
+ public SignEncryptResult execute(SignEncryptParcel input) {
+
+ OperationLog log = new OperationLog();
+ log.add(LogType.MSG_SE, 0);
+
+ ArrayDeque<Uri> inputUris = new ArrayDeque<>(input.getInputUris());
+ ArrayDeque<Uri> outputUris = new ArrayDeque<>(input.getOutputUris());
+ byte[] inputBytes = input.getBytes();
+ byte[] outputBytes = null;
+
+ ArrayList<PgpSignEncryptResult> results = new ArrayList<>();
+
+ do {
+
+ if (checkCancelled()) {
+ log.add(LogType.MSG_OPERATION_CANCELLED, 0);
+ return new SignEncryptResult(SignEncryptResult.RESULT_CANCELLED, log, results);
+ }
+
+ InputData inputData;
+ {
+ if (inputBytes != null) {
+ log.add(LogType.MSG_SE_INPUT_BYTES, 1);
+ InputStream is = new ByteArrayInputStream(inputBytes);
+ inputData = new InputData(is, inputBytes.length);
+ inputBytes = null;
+ } else {
+ if (inputUris.isEmpty()) {
+ log.add(LogType.MSG_SE_ERROR_NO_INPUT, 1);
+ return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
+ }
+
+ log.add(LogType.MSG_SE_INPUT_URI, 1);
+ Uri uri = inputUris.removeFirst();
+ try {
+ InputStream is = mContext.getContentResolver().openInputStream(uri);
+ long fileSize = FileHelper.getFileSize(mContext, uri, 0);
+ String filename = FileHelper.getFilename(mContext, uri);
+ inputData = new InputData(is, fileSize, filename);
+ } catch (FileNotFoundException e) {
+ log.add(LogType.MSG_SE_ERROR_INPUT_URI_NOT_FOUND, 1);
+ return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
+ }
+ }
+ }
+
+ OutputStream outStream;
+ {
+ if (!outputUris.isEmpty()) {
+ try {
+ Uri outputUri = outputUris.removeFirst();
+ outStream = mContext.getContentResolver().openOutputStream(outputUri);
+ } catch (FileNotFoundException e) {
+ log.add(LogType.MSG_SE_ERROR_OUTPUT_URI_NOT_FOUND, 1);
+ return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
+ }
+ } else {
+ if (outputBytes != null) {
+ log.add(LogType.MSG_SE_ERROR_TOO_MANY_INPUTS, 1);
+ return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
+ }
+ outStream = new ByteArrayOutputStream();
+ }
+ }
+
+ PgpSignEncryptOperation op = new PgpSignEncryptOperation(mContext, mProviderHelper,
+ new ProgressScaler(), mCancelled);
+ PgpSignEncryptResult result = op.execute(input, inputData, outStream);
+ results.add(result);
+ log.add(result, 2);
+
+ if (result.isPending()) {
+ return new SignEncryptResult(SignEncryptResult.RESULT_PENDING, log, results);
+ }
+
+ if (!result.success()) {
+ return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
+ }
+
+ if (outStream instanceof ByteArrayOutputStream) {
+ outputBytes = ((ByteArrayOutputStream) outStream).toByteArray();
+ }
+
+ } while (!inputUris.isEmpty());
+
+ if (!outputUris.isEmpty()) {
+ // Any output URIs left are indicative of a programming error
+ log.add(LogType.MSG_SE_WARN_OUTPUT_LEFT, 1);
+ }
+
+ log.add(LogType.MSG_SE_SUCCESS, 1);
+ return new SignEncryptResult(SignEncryptResult.RESULT_OK, log, results, outputBytes);
+
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
index 7b38cd244..94684851a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
@@ -21,18 +21,14 @@ package org.sufficientlysecure.keychain.operations.results;
import android.app.Activity;
import android.content.Intent;
import android.os.Parcel;
-import android.os.Parcelable;
-import android.view.View;
-
-import com.github.johnpersano.supertoasts.SuperCardToast;
-import com.github.johnpersano.supertoasts.SuperToast;
-import com.github.johnpersano.supertoasts.SuperToast.Duration;
-import com.github.johnpersano.supertoasts.util.OnClickWrapper;
-import com.github.johnpersano.supertoasts.util.Style;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
+import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
+import org.sufficientlysecure.keychain.ui.util.Notify.Showable;
+import org.sufficientlysecure.keychain.ui.util.Notify.Style;
public class CertifyResult extends OperationResult {
@@ -78,30 +74,31 @@ public class CertifyResult extends OperationResult {
}
};
- public SuperCardToast createNotify(final Activity activity) {
+ public Showable createNotify(final Activity activity) {
int resultType = getResult();
String str;
- int duration, color;
+ int duration;
+ Style style;
// Not an overall failure
if ((resultType & OperationResult.RESULT_ERROR) == 0) {
String withWarnings;
- duration = Duration.EXTRA_LONG;
- color = Style.GREEN;
+ duration = Notify.LENGTH_LONG;
+ style = Style.OK;
withWarnings = "";
// Any warnings?
if ((resultType & ImportKeyResult.RESULT_WARNINGS) > 0) {
duration = 0;
- color = Style.ORANGE;
+ style = Style.WARN;
withWarnings += activity.getString(R.string.with_warnings);
}
if ((resultType & ImportKeyResult.RESULT_CANCELLED) > 0) {
duration = 0;
- color = Style.ORANGE;
+ style = Style.WARN;
withWarnings += activity.getString(R.string.with_cancelled);
}
@@ -111,46 +108,27 @@ public class CertifyResult extends OperationResult {
if (mCertifyError > 0) {
// definitely switch to warning-style message in this case!
duration = 0;
- color = Style.RED;
+ style = Style.ERROR;
str += " " + activity.getResources().getQuantityString(
R.plurals.certify_keys_with_errors, mCertifyError, mCertifyError);
}
} else {
duration = 0;
- color = Style.RED;
+ style = Style.ERROR;
str = activity.getResources().getQuantityString(R.plurals.certify_error,
mCertifyError, mCertifyError);
}
- boolean button = getLog() != null && !getLog().isEmpty();
- SuperCardToast toast = new SuperCardToast(activity,
- button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
- Style.getStyle(color, SuperToast.Animations.POPUP));
- toast.setText(str);
- toast.setDuration(duration);
- toast.setIndeterminate(duration == 0);
- toast.setSwipeToDismiss(true);
- // If we have a log and it's non-empty, show a View Log button
- if (button) {
- toast.setButtonIcon(R.drawable.ic_action_view_as_list,
- activity.getResources().getString(R.string.view_log));
- toast.setButtonTextColor(activity.getResources().getColor(R.color.black));
- toast.setTextColor(activity.getResources().getColor(R.color.black));
- toast.setOnClickWrapper(new OnClickWrapper("supercardtoast",
- new SuperToast.OnClickListener() {
- @Override
- public void onClick(View view, Parcelable token) {
- Intent intent = new Intent(
- activity, LogDisplayActivity.class);
- intent.putExtra(LogDisplayFragment.EXTRA_RESULT, CertifyResult.this);
- activity.startActivity(intent);
- }
- }
- ));
- }
-
- return toast;
+ return Notify.createNotify(activity, str, duration, style, new ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intent = new Intent(
+ activity, LogDisplayActivity.class);
+ intent.putExtra(LogDisplayFragment.EXTRA_RESULT, CertifyResult.this);
+ activity.startActivity(intent);
+ }
+ }, R.string.view_log);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
index d81577102..86b37fea6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
@@ -41,6 +41,9 @@ public class DecryptVerifyResult extends OperationResult {
OpenPgpSignatureResult mSignatureResult;
OpenPgpMetadata mDecryptMetadata;
+ // This holds the charset which was specified in the ascii armor, if specified
+ // https://tools.ietf.org/html/rfc4880#page56
+ String mCharset;
public long getKeyIdPassphraseNeeded() {
return mKeyIdPassphraseNeeded;
@@ -84,6 +87,14 @@ public class DecryptVerifyResult extends OperationResult {
mDecryptMetadata = decryptMetadata;
}
+ public String getCharset () {
+ return mCharset;
+ }
+
+ public void setCharset(String charset) {
+ mCharset = charset;
+ }
+
public boolean isPending() {
return (mResult & RESULT_PENDING) == RESULT_PENDING;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java
index 1ca5ad20a..62197541a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java
@@ -21,18 +21,14 @@ package org.sufficientlysecure.keychain.operations.results;
import android.app.Activity;
import android.content.Intent;
import android.os.Parcel;
-import android.os.Parcelable;
-import android.view.View;
-
-import com.github.johnpersano.supertoasts.SuperCardToast;
-import com.github.johnpersano.supertoasts.SuperToast;
-import com.github.johnpersano.supertoasts.SuperToast.Duration;
-import com.github.johnpersano.supertoasts.util.OnClickWrapper;
-import com.github.johnpersano.supertoasts.util.Style;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
+import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
+import org.sufficientlysecure.keychain.ui.util.Notify.Showable;
+import org.sufficientlysecure.keychain.ui.util.Notify.Style;
public class DeleteResult extends OperationResult {
@@ -68,31 +64,32 @@ public class DeleteResult extends OperationResult {
}
};
- public SuperCardToast createNotify(final Activity activity) {
+ public Showable createNotify(final Activity activity) {
int resultType = getResult();
String str;
- int duration, color;
+ int duration;
+ Style style;
// Not an overall failure
if ((resultType & OperationResult.RESULT_ERROR) == 0) {
String untilCancelled;
- duration = Duration.EXTRA_LONG;
- color = Style.GREEN;
+ duration = Notify.LENGTH_LONG;
+ style = Style.OK;
untilCancelled = "";
// Any warnings?
if ((resultType & ImportKeyResult.RESULT_CANCELLED) > 0) {
duration = 0;
- color = Style.ORANGE;
+ style = Style.WARN;
untilCancelled += activity.getString(R.string.with_cancelled);
}
// New and updated keys
if (mOk > 0 && mFail > 0) {
- color = Style.ORANGE;
+ style = Style.WARN;
duration = 0;
str = activity.getResources().getQuantityString(
R.plurals.delete_ok_but_fail_1, mOk, mOk);
@@ -105,13 +102,13 @@ public class DeleteResult extends OperationResult {
str = activity.getString(R.string.delete_cancelled);
} else {
duration = 0;
- color = Style.RED;
+ style = Style.ERROR;
str = "internal error";
}
} else {
duration = 0;
- color = Style.RED;
+ style = Style.ERROR;
if (mFail == 0) {
str = activity.getString(R.string.delete_nothing);
} else {
@@ -119,34 +116,15 @@ public class DeleteResult extends OperationResult {
}
}
- boolean button = getLog() != null && !getLog().isEmpty();
- SuperCardToast toast = new SuperCardToast(activity,
- button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
- Style.getStyle(color, SuperToast.Animations.POPUP));
- toast.setText(str);
- toast.setDuration(duration);
- toast.setIndeterminate(duration == 0);
- toast.setSwipeToDismiss(true);
- // If we have a log and it's non-empty, show a View Log button
- if (button) {
- toast.setButtonIcon(R.drawable.ic_action_view_as_list,
- activity.getResources().getString(R.string.view_log));
- toast.setButtonTextColor(activity.getResources().getColor(R.color.black));
- toast.setTextColor(activity.getResources().getColor(R.color.black));
- toast.setOnClickWrapper(new OnClickWrapper("supercardtoast",
- new SuperToast.OnClickListener() {
- @Override
- public void onClick(View view, Parcelable token) {
- Intent intent = new Intent(
- activity, LogDisplayActivity.class);
- intent.putExtra(LogDisplayFragment.EXTRA_RESULT, DeleteResult.this);
- activity.startActivity(intent);
- }
- }
- ));
- }
-
- return toast;
+ return Notify.createNotify(activity, str, duration, style, new ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intent = new Intent(
+ activity, LogDisplayActivity.class);
+ intent.putExtra(LogDisplayFragment.EXTRA_RESULT, DeleteResult.this);
+ activity.startActivity(intent);
+ }
+ }, R.string.view_log);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java
index f2acfef1e..abcf575af 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java
@@ -20,34 +20,24 @@ package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
-
public class EditKeyResult extends OperationResult {
- private transient UncachedKeyRing mRing;
- public final long mRingMasterKeyId;
+ public final Long mMasterKeyId;
- public EditKeyResult(int result, OperationLog log,
- UncachedKeyRing ring) {
+ public EditKeyResult(int result, OperationLog log, Long masterKeyId) {
super(result, log);
- mRing = ring;
- mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : Constants.key.none;
- }
-
- public UncachedKeyRing getRing() {
- return mRing;
+ mMasterKeyId = masterKeyId;
}
public EditKeyResult(Parcel source) {
super(source);
- mRingMasterKeyId = source.readLong();
+ mMasterKeyId = source.readLong();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- dest.writeLong(mRingMasterKeyId);
+ dest.writeLong(mMasterKeyId);
}
public static Creator<EditKeyResult> CREATOR = new Creator<EditKeyResult>() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java
index 1dd038a23..2d533ed16 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java
@@ -21,18 +21,14 @@ package org.sufficientlysecure.keychain.operations.results;
import android.app.Activity;
import android.content.Intent;
import android.os.Parcel;
-import android.os.Parcelable;
-import android.view.View;
-
-import com.github.johnpersano.supertoasts.SuperCardToast;
-import com.github.johnpersano.supertoasts.SuperToast;
-import com.github.johnpersano.supertoasts.SuperToast.Duration;
-import com.github.johnpersano.supertoasts.util.OnClickWrapper;
-import com.github.johnpersano.supertoasts.util.Style;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
+import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
+import org.sufficientlysecure.keychain.ui.util.Notify.Showable;
+import org.sufficientlysecure.keychain.ui.util.Notify.Style;
public class ImportKeyResult extends OperationResult {
@@ -83,6 +79,10 @@ public class ImportKeyResult extends OperationResult {
mImportedMasterKeyIds = source.createLongArray();
}
+ public ImportKeyResult(int result, OperationLog log) {
+ this(result, log, 0, 0, 0, 0, new long[] { });
+ }
+
public ImportKeyResult(int result, OperationLog log,
int newKeys, int updatedKeys, int badKeys, int secret,
long[] importedMasterKeyIds) {
@@ -114,30 +114,31 @@ public class ImportKeyResult extends OperationResult {
}
};
- public SuperCardToast createNotify(final Activity activity) {
+ public Showable createNotify(final Activity activity) {
int resultType = getResult();
String str;
- int duration, color;
+ int duration;
+ Style style;
// Not an overall failure
if ((resultType & OperationResult.RESULT_ERROR) == 0) {
String withWarnings;
- duration = Duration.EXTRA_LONG;
- color = Style.GREEN;
+ duration = Notify.LENGTH_LONG;
+ style = Style.OK;
withWarnings = "";
// Any warnings?
if ((resultType & ImportKeyResult.RESULT_WARNINGS) > 0) {
duration = 0;
- color = Style.ORANGE;
+ style = Style.WARN;
withWarnings += activity.getString(R.string.with_warnings);
}
if ((resultType & ImportKeyResult.RESULT_CANCELLED) > 0) {
duration = 0;
- color = Style.ORANGE;
+ style = Style.WARN;
withWarnings += activity.getString(R.string.with_cancelled);
}
@@ -155,20 +156,20 @@ public class ImportKeyResult extends OperationResult {
R.plurals.import_keys_added, mNewKeys, mNewKeys, withWarnings);
} else {
duration = 0;
- color = Style.RED;
+ style = Style.ERROR;
str = "internal error";
}
if (isOkWithErrors()) {
// definitely switch to warning-style message in this case!
duration = 0;
- color = Style.RED;
+ style = Style.ERROR;
str += " " + activity.getResources().getQuantityString(
R.plurals.import_keys_with_errors, mBadKeys, mBadKeys);
}
} else {
duration = 0;
- color = Style.RED;
+ style = Style.ERROR;
if (isFailNothing()) {
str = activity.getString((resultType & ImportKeyResult.RESULT_CANCELLED) > 0
? R.string.import_error_nothing_cancelled
@@ -178,34 +179,15 @@ public class ImportKeyResult extends OperationResult {
}
}
- boolean button = getLog() != null && !getLog().isEmpty();
- SuperCardToast toast = new SuperCardToast(activity,
- button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
- Style.getStyle(color, SuperToast.Animations.POPUP));
- toast.setText(str);
- toast.setDuration(duration);
- toast.setIndeterminate(duration == 0);
- toast.setSwipeToDismiss(true);
- // If we have a log and it's non-empty, show a View Log button
- if (button) {
- toast.setButtonIcon(R.drawable.ic_action_view_as_list,
- activity.getResources().getString(R.string.view_log));
- toast.setButtonTextColor(activity.getResources().getColor(R.color.black));
- toast.setTextColor(activity.getResources().getColor(R.color.black));
- toast.setOnClickWrapper(new OnClickWrapper("supercardtoast",
- new SuperToast.OnClickListener() {
- @Override
- public void onClick(View view, Parcelable token) {
- Intent intent = new Intent(
- activity, LogDisplayActivity.class);
- intent.putExtra(LogDisplayFragment.EXTRA_RESULT, ImportKeyResult.this);
- activity.startActivity(intent);
- }
- }
- ));
- }
-
- return toast;
+ return Notify.createNotify(activity, str, duration, style, new ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intent = new Intent(
+ activity, LogDisplayActivity.class);
+ intent.putExtra(LogDisplayFragment.EXTRA_RESULT, ImportKeyResult.this);
+ activity.startActivity(intent);
+ }
+ }, R.string.view_log);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
index 70d999242..f79900aab 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
@@ -22,17 +22,15 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
-import android.view.View;
-
-import com.github.johnpersano.supertoasts.SuperCardToast;
-import com.github.johnpersano.supertoasts.SuperToast;
-import com.github.johnpersano.supertoasts.util.OnClickWrapper;
-import com.github.johnpersano.supertoasts.util.Style;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
+import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
+import org.sufficientlysecure.keychain.ui.util.Notify.Showable;
+import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
@@ -195,58 +193,44 @@ public abstract class OperationResult implements Parcelable {
}
- public SuperCardToast createNotify(final Activity activity) {
-
- int color;
+ public Showable createNotify(final Activity activity) {
Log.d(Constants.TAG, "mLog.getLast()"+mLog.getLast());
Log.d(Constants.TAG, "mLog.getLast().mType"+mLog.getLast().mType);
Log.d(Constants.TAG, "mLog.getLast().mType.getMsgId()"+mLog.getLast().mType.getMsgId());
// Take the last message as string
- String str = activity.getString(mLog.getLast().mType.getMsgId());
+ int msgId = mLog.getLast().mType.getMsgId();
+
+ Style style;
// Not an overall failure
if (cancelled()) {
- color = Style.RED;
+ style = Style.ERROR;
} else if (success()) {
if (getLog().containsWarnings()) {
- color = Style.ORANGE;
+ style = Style.WARN;
} else {
- color = Style.GREEN;
+ style = Style.OK;
}
} else {
- color = Style.RED;
+ style = Style.ERROR;
}
- boolean button = getLog() != null && !getLog().isEmpty();
- SuperCardToast toast = new SuperCardToast(activity,
- button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
- Style.getStyle(color, SuperToast.Animations.POPUP));
- toast.setText(str);
- toast.setDuration(SuperToast.Duration.EXTRA_LONG);
- toast.setIndeterminate(false);
- toast.setSwipeToDismiss(true);
- // If we have a log and it's non-empty, show a View Log button
- if (button) {
- toast.setButtonIcon(R.drawable.ic_action_view_as_list,
- activity.getResources().getString(R.string.view_log));
- toast.setButtonTextColor(activity.getResources().getColor(R.color.black));
- toast.setTextColor(activity.getResources().getColor(R.color.black));
- toast.setOnClickWrapper(new OnClickWrapper("supercardtoast",
- new SuperToast.OnClickListener() {
- @Override
- public void onClick(View view, Parcelable token) {
- Intent intent = new Intent(
- activity, LogDisplayActivity.class);
- intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResult.this);
- activity.startActivity(intent);
- }
- }
- ));
+ if (getLog() == null || getLog().isEmpty()) {
+ return Notify.createNotify(activity, msgId, Notify.LENGTH_LONG, style);
}
- return toast;
+ return Notify.createNotify(activity, msgId, Notify.LENGTH_LONG, style,
+ new ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intent = new Intent(
+ activity, LogDisplayActivity.class);
+ intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResult.this);
+ activity.startActivity(intent);
+ }
+ }, R.string.view_log);
}
@@ -343,6 +327,18 @@ public abstract class OperationResult implements Parcelable {
MSG_IP_UID_REORDER(LogLevel.DEBUG, R.string.msg_ip_uid_reorder),
MSG_IP_UID_PROCESSING (LogLevel.DEBUG, R.string.msg_ip_uid_processing),
MSG_IP_UID_REVOKED (LogLevel.DEBUG, R.string.msg_ip_uid_revoked),
+ MSG_IP_UAT_CLASSIFYING (LogLevel.DEBUG, R.string.msg_ip_uat_classifying),
+ MSG_IP_UAT_PROCESSING_IMAGE (LogLevel.DEBUG, R.string.msg_ip_uat_processing_image),
+ MSG_IP_UAT_PROCESSING_UNKNOWN (LogLevel.DEBUG, R.string.msg_ip_uat_processing_unknown),
+ MSG_IP_UAT_REVOKED (LogLevel.DEBUG, R.string.msg_ip_uat_revoked),
+ MSG_IP_UAT_CERT_BAD (LogLevel.WARN, R.string.msg_ip_uat_cert_bad),
+ MSG_IP_UAT_CERT_OLD (LogLevel.DEBUG, R.string.msg_ip_uat_cert_old),
+ MSG_IP_UAT_CERT_NONREVOKE (LogLevel.DEBUG, R.string.msg_ip_uat_cert_nonrevoke),
+ MSG_IP_UAT_CERT_NEW (LogLevel.DEBUG, R.string.msg_ip_uat_cert_new),
+ MSG_IP_UAT_CERT_ERROR (LogLevel.WARN, R.string.msg_ip_uat_cert_error),
+ MSG_IP_UAT_CERTS_UNKNOWN (LogLevel.DEBUG, R.plurals.msg_ip_uat_certs_unknown),
+ MSG_IP_UAT_CERT_GOOD_REVOKE (LogLevel.DEBUG, R.string.msg_ip_uat_cert_good_revoke),
+ MSG_IP_UAT_CERT_GOOD (LogLevel.DEBUG, R.string.msg_ip_uat_cert_good),
// import secret
MSG_IS(LogLevel.START, R.string.msg_is),
@@ -359,6 +355,7 @@ public abstract class OperationResult implements Parcelable {
MSG_IS_SUBKEY_STRIPPED (LogLevel.DEBUG, R.string.msg_is_subkey_stripped),
MSG_IS_SUBKEY_DIVERT (LogLevel.DEBUG, R.string.msg_is_subkey_divert),
MSG_IS_SUBKEY_EMPTY (LogLevel.DEBUG, R.string.msg_is_subkey_empty),
+ MSG_IS_SUBKEY_PIN (LogLevel.DEBUG, R.string.msg_is_subkey_pin),
MSG_IS_SUCCESS_IDENTICAL (LogLevel.OK, R.string.msg_is_success_identical),
MSG_IS_SUCCESS (LogLevel.OK, R.string.msg_is_success),
@@ -370,13 +367,16 @@ public abstract class OperationResult implements Parcelable {
MSG_KC_ERROR_MASTER_ALGO (LogLevel.ERROR, R.string.msg_kc_error_master_algo),
MSG_KC_ERROR_DUP_KEY (LogLevel.ERROR, R.string.msg_kc_error_dup_key),
MSG_KC_MASTER (LogLevel.DEBUG, R.string.msg_kc_master),
- MSG_KC_REVOKE_BAD_ERR (LogLevel.WARN, R.string.msg_kc_revoke_bad_err),
- MSG_KC_REVOKE_BAD_LOCAL (LogLevel.WARN, R.string.msg_kc_revoke_bad_local),
- MSG_KC_REVOKE_BAD_TIME (LogLevel.WARN, R.string.msg_kc_revoke_bad_time),
- MSG_KC_REVOKE_BAD_TYPE (LogLevel.WARN, R.string.msg_kc_revoke_bad_type),
- MSG_KC_REVOKE_BAD_TYPE_UID (LogLevel.WARN, R.string.msg_kc_revoke_bad_type_uid),
- MSG_KC_REVOKE_BAD (LogLevel.WARN, R.string.msg_kc_revoke_bad),
+ MSG_KC_MASTER_BAD_TYPE(LogLevel.WARN, R.string.msg_kc_master_bad_type),
+ MSG_KC_MASTER_BAD_LOCAL(LogLevel.WARN, R.string.msg_kc_master_bad_local),
+ MSG_KC_MASTER_BAD_ERR(LogLevel.WARN, R.string.msg_kc_master_bad_err),
+ MSG_KC_MASTER_BAD_TIME(LogLevel.WARN, R.string.msg_kc_master_bad_time),
+ MSG_KC_MASTER_BAD_TYPE_UID(LogLevel.WARN, R.string.msg_kc_master_bad_type_uid),
+ MSG_KC_MASTER_BAD(LogLevel.WARN, R.string.msg_kc_master_bad),
+ MSG_KC_MASTER_LOCAL(LogLevel.WARN, R.string.msg_kc_master_local),
MSG_KC_REVOKE_DUP (LogLevel.DEBUG, R.string.msg_kc_revoke_dup),
+ MSG_KC_NOTATION_DUP (LogLevel.DEBUG, R.string.msg_kc_notation_dup),
+ MSG_KC_NOTATION_EMPTY (LogLevel.DEBUG, R.string.msg_kc_notation_empty),
MSG_KC_SUB (LogLevel.DEBUG, R.string.msg_kc_sub),
MSG_KC_SUB_BAD(LogLevel.WARN, R.string.msg_kc_sub_bad),
MSG_KC_SUB_BAD_ERR(LogLevel.WARN, R.string.msg_kc_sub_bad_err),
@@ -412,6 +412,21 @@ public abstract class OperationResult implements Parcelable {
MSG_KC_UID_REVOKE_OLD (LogLevel.DEBUG, R.string.msg_kc_uid_revoke_old),
MSG_KC_UID_REMOVE (LogLevel.DEBUG, R.string.msg_kc_uid_remove),
MSG_KC_UID_WARN_ENCODING (LogLevel.WARN, R.string.msg_kc_uid_warn_encoding),
+ MSG_KC_UAT_JPEG (LogLevel.DEBUG, R.string.msg_kc_uat_jpeg),
+ MSG_KC_UAT_UNKNOWN (LogLevel.DEBUG, R.string.msg_kc_uat_unknown),
+ MSG_KC_UAT_BAD_ERR (LogLevel.WARN, R.string.msg_kc_uat_bad_err),
+ MSG_KC_UAT_BAD_LOCAL (LogLevel.WARN, R.string.msg_kc_uat_bad_local),
+ MSG_KC_UAT_BAD_TIME (LogLevel.WARN, R.string.msg_kc_uat_bad_time),
+ MSG_KC_UAT_BAD_TYPE (LogLevel.WARN, R.string.msg_kc_uat_bad_type),
+ MSG_KC_UAT_BAD (LogLevel.WARN, R.string.msg_kc_uat_bad),
+ MSG_KC_UAT_CERT_DUP (LogLevel.DEBUG, R.string.msg_kc_uat_cert_dup),
+ MSG_KC_UAT_DUP (LogLevel.DEBUG, R.string.msg_kc_uat_dup),
+ MSG_KC_UAT_FOREIGN (LogLevel.DEBUG, R.string.msg_kc_uat_foreign),
+ MSG_KC_UAT_NO_CERT (LogLevel.DEBUG, R.string.msg_kc_uat_no_cert),
+ MSG_KC_UAT_REVOKE_DUP (LogLevel.DEBUG, R.string.msg_kc_uat_revoke_dup),
+ MSG_KC_UAT_REVOKE_OLD (LogLevel.DEBUG, R.string.msg_kc_uat_revoke_old),
+ MSG_KC_UAT_REMOVE (LogLevel.DEBUG, R.string.msg_kc_uat_remove),
+ MSG_KC_UAT_WARN_ENCODING (LogLevel.WARN, R.string.msg_kc_uat_warn_encoding),
// keyring consolidation
@@ -442,6 +457,7 @@ public abstract class OperationResult implements Parcelable {
// secret key modify
MSG_MF (LogLevel.START, R.string.msg_mr),
+ MSG_MF_ERROR_DIVERT_SERIAL (LogLevel.ERROR, R.string.msg_mf_error_divert_serial),
MSG_MF_ERROR_ENCODE (LogLevel.ERROR, R.string.msg_mf_error_encode),
MSG_MF_ERROR_FINGERPRINT (LogLevel.ERROR, R.string.msg_mf_error_fingerprint),
MSG_MF_ERROR_KEYID (LogLevel.ERROR, R.string.msg_mf_error_keyid),
@@ -454,10 +470,13 @@ public abstract class OperationResult implements Parcelable {
MSG_MF_ERROR_PASSPHRASE_MASTER(LogLevel.ERROR, R.string.msg_mf_error_passphrase_master),
MSG_MF_ERROR_PAST_EXPIRY(LogLevel.ERROR, R.string.msg_mf_error_past_expiry),
MSG_MF_ERROR_PGP (LogLevel.ERROR, R.string.msg_mf_error_pgp),
+ MSG_MF_ERROR_RESTRICTED(LogLevel.ERROR, R.string.msg_mf_error_restricted),
MSG_MF_ERROR_REVOKED_PRIMARY (LogLevel.ERROR, R.string.msg_mf_error_revoked_primary),
MSG_MF_ERROR_SIG (LogLevel.ERROR, R.string.msg_mf_error_sig),
MSG_MF_ERROR_SUBKEY_MISSING(LogLevel.ERROR, R.string.msg_mf_error_subkey_missing),
MSG_MF_MASTER (LogLevel.DEBUG, R.string.msg_mf_master),
+ MSG_MF_NOTATION_PIN (LogLevel.DEBUG, R.string.msg_mf_notation_pin),
+ MSG_MF_NOTATION_EMPTY (LogLevel.DEBUG, R.string.msg_mf_notation_empty),
MSG_MF_PASSPHRASE (LogLevel.INFO, R.string.msg_mf_passphrase),
MSG_MF_PASSPHRASE_KEY (LogLevel.DEBUG, R.string.msg_mf_passphrase_key),
MSG_MF_PASSPHRASE_EMPTY_RETRY (LogLevel.DEBUG, R.string.msg_mf_passphrase_empty_retry),
@@ -474,6 +493,9 @@ public abstract class OperationResult implements Parcelable {
MSG_MF_UID_PRIMARY (LogLevel.INFO, R.string.msg_mf_uid_primary),
MSG_MF_UID_REVOKE (LogLevel.INFO, R.string.msg_mf_uid_revoke),
MSG_MF_UID_ERROR_EMPTY (LogLevel.ERROR, R.string.msg_mf_uid_error_empty),
+ MSG_MF_UAT_ERROR_EMPTY (LogLevel.ERROR, R.string.msg_mf_uat_error_empty),
+ MSG_MF_UAT_ADD_IMAGE (LogLevel.INFO, R.string.msg_mf_uat_add_image),
+ MSG_MF_UAT_ADD_UNKNOWN (LogLevel.INFO, R.string.msg_mf_uat_add_unknown),
MSG_MF_UNLOCK_ERROR (LogLevel.ERROR, R.string.msg_mf_unlock_error),
MSG_MF_UNLOCK (LogLevel.DEBUG, R.string.msg_mf_unlock),
@@ -491,6 +513,7 @@ public abstract class OperationResult implements Parcelable {
MSG_CON_ERROR_PUBLIC (LogLevel.ERROR, R.string.msg_con_error_public),
MSG_CON_ERROR_SECRET (LogLevel.ERROR, R.string.msg_con_error_secret),
MSG_CON_RECOVER (LogLevel.DEBUG, R.string.msg_con_recover),
+ MSG_CON_RECURSIVE (LogLevel.OK, R.string.msg_con_recursive),
MSG_CON_REIMPORT_PUBLIC (LogLevel.DEBUG, R.plurals.msg_con_reimport_public),
MSG_CON_REIMPORT_PUBLIC_SKIP (LogLevel.DEBUG, R.string.msg_con_reimport_public_skip),
MSG_CON_REIMPORT_SECRET (LogLevel.DEBUG, R.plurals.msg_con_reimport_secret),
@@ -502,6 +525,21 @@ public abstract class OperationResult implements Parcelable {
MSG_CON_WARN_DELETE_PUBLIC (LogLevel.WARN, R.string.msg_con_warn_delete_public),
MSG_CON_WARN_DELETE_SECRET (LogLevel.WARN, R.string.msg_con_warn_delete_secret),
+ // edit key (higher level operation than modify)
+ MSG_ED (LogLevel.START, R.string.msg_ed),
+ MSG_ED_CACHING_NEW (LogLevel.DEBUG, R.string.msg_ed_caching_new),
+ MSG_ED_ERROR_NO_PARCEL (LogLevel.ERROR, R.string.msg_ed_error_no_parcel),
+ MSG_ED_ERROR_KEY_NOT_FOUND (LogLevel.ERROR, R.string.msg_ed_error_key_not_found),
+ MSG_ED_FETCHING (LogLevel.DEBUG, R.string.msg_ed_fetching),
+ MSG_ED_SUCCESS (LogLevel.OK, R.string.msg_ed_success),
+
+ // promote key
+ MSG_PR (LogLevel.START, R.string.msg_pr),
+ MSG_PR_ERROR_ALREADY_SECRET (LogLevel.ERROR, R.string.msg_pr_error_already_secret),
+ MSG_PR_ERROR_KEY_NOT_FOUND (LogLevel.ERROR, R.string.msg_pr_error_key_not_found),
+ MSG_PR_FETCHING (LogLevel.DEBUG, R.string.msg_pr_fetching),
+ MSG_PR_SUCCESS (LogLevel.OK, R.string.msg_pr_success),
+
// messages used in UI code
MSG_EK_ERROR_DIVERT (LogLevel.ERROR, R.string.msg_ek_error_divert),
MSG_EK_ERROR_DUMMY (LogLevel.ERROR, R.string.msg_ek_error_dummy),
@@ -511,11 +549,13 @@ public abstract class OperationResult implements Parcelable {
MSG_DC_ASKIP_NO_KEY (LogLevel.DEBUG, R.string.msg_dc_askip_no_key),
MSG_DC_ASKIP_NOT_ALLOWED (LogLevel.DEBUG, R.string.msg_dc_askip_not_allowed),
MSG_DC_ASYM (LogLevel.DEBUG, R.string.msg_dc_asym),
+ MSG_DC_CHARSET (LogLevel.DEBUG, R.string.msg_dc_charset),
MSG_DC_CLEAR_DATA (LogLevel.DEBUG, R.string.msg_dc_clear_data),
MSG_DC_CLEAR_DECOMPRESS (LogLevel.DEBUG, R.string.msg_dc_clear_decompress),
MSG_DC_CLEAR_META_FILE (LogLevel.DEBUG, R.string.msg_dc_clear_meta_file),
MSG_DC_CLEAR_META_MIME (LogLevel.DEBUG, R.string.msg_dc_clear_meta_mime),
MSG_DC_CLEAR_META_SIZE (LogLevel.DEBUG, R.string.msg_dc_clear_meta_size),
+ MSG_DC_CLEAR_META_SIZE_UNKNOWN (LogLevel.DEBUG, R.string.msg_dc_clear_meta_size_unknown),
MSG_DC_CLEAR_META_TIME (LogLevel.DEBUG, R.string.msg_dc_clear_meta_time),
MSG_DC_CLEAR (LogLevel.DEBUG, R.string.msg_dc_clear),
MSG_DC_CLEAR_SIGNATURE_BAD (LogLevel.WARN, R.string.msg_dc_clear_signature_bad),
@@ -525,6 +565,7 @@ public abstract class OperationResult implements Parcelable {
MSG_DC_ERROR_BAD_PASSPHRASE (LogLevel.ERROR, R.string.msg_dc_error_bad_passphrase),
MSG_DC_ERROR_EXTRACT_KEY (LogLevel.ERROR, R.string.msg_dc_error_extract_key),
MSG_DC_ERROR_INTEGRITY_CHECK (LogLevel.ERROR, R.string.msg_dc_error_integrity_check),
+ MSG_DC_ERROR_INTEGRITY_MISSING (LogLevel.ERROR, R.string.msg_dc_error_integrity_missing),
MSG_DC_ERROR_INVALID_SIGLIST(LogLevel.ERROR, R.string.msg_dc_error_invalid_siglist),
MSG_DC_ERROR_IO (LogLevel.ERROR, R.string.msg_dc_error_io),
MSG_DC_ERROR_NO_DATA (LogLevel.ERROR, R.string.msg_dc_error_no_data),
@@ -555,32 +596,47 @@ public abstract class OperationResult implements Parcelable {
MSG_VL_OK (LogLevel.OK, R.string.msg_vl_ok),
// signencrypt
- MSG_SE_ASYMMETRIC (LogLevel.INFO, R.string.msg_se_asymmetric),
- MSG_SE_CLEARSIGN_ONLY (LogLevel.DEBUG, R.string.msg_se_clearsign_only),
- MSG_SE_COMPRESSING (LogLevel.DEBUG, R.string.msg_se_compressing),
- MSG_SE_ENCRYPTING (LogLevel.DEBUG, R.string.msg_se_encrypting),
- MSG_SE_ERROR_BAD_PASSPHRASE (LogLevel.ERROR, R.string.msg_se_error_bad_passphrase),
- MSG_SE_ERROR_IO (LogLevel.ERROR, R.string.msg_se_error_io),
- MSG_SE_ERROR_SIGN_KEY(LogLevel.ERROR, R.string.msg_se_error_sign_key),
- MSG_SE_ERROR_KEY_SIGN (LogLevel.ERROR, R.string.msg_se_error_key_sign),
- MSG_SE_ERROR_NFC (LogLevel.ERROR, R.string.msg_se_error_nfc),
- MSG_SE_ERROR_PGP (LogLevel.ERROR, R.string.msg_se_error_pgp),
- MSG_SE_ERROR_SIG (LogLevel.ERROR, R.string.msg_se_error_sig),
- MSG_SE_ERROR_UNLOCK (LogLevel.ERROR, R.string.msg_se_error_unlock),
- MSG_SE_KEY_OK (LogLevel.OK, R.string.msg_se_key_ok),
- MSG_SE_KEY_UNKNOWN (LogLevel.DEBUG, R.string.msg_se_key_unknown),
- MSG_SE_KEY_WARN (LogLevel.WARN, R.string.msg_se_key_warn),
- MSG_SE_OK (LogLevel.OK, R.string.msg_se_ok),
- MSG_SE_PENDING_NFC (LogLevel.INFO, R.string.msg_se_pending_nfc),
- MSG_SE_PENDING_PASSPHRASE (LogLevel.INFO, R.string.msg_se_pending_passphrase),
- MSG_SE (LogLevel.DEBUG, R.string.msg_se),
- MSG_SE_SIGNING (LogLevel.DEBUG, R.string.msg_se_signing),
- MSG_SE_SIGCRYPTING (LogLevel.DEBUG, R.string.msg_se_sigcrypting),
- MSG_SE_SYMMETRIC (LogLevel.INFO, R.string.msg_se_symmetric),
+ MSG_SE (LogLevel.START, R.string.msg_se),
+ MSG_SE_INPUT_BYTES (LogLevel.INFO, R.string.msg_se_input_bytes),
+ MSG_SE_INPUT_URI (LogLevel.INFO, R.string.msg_se_input_uri),
+ MSG_SE_ERROR_NO_INPUT (LogLevel.DEBUG, R.string.msg_se_error_no_input),
+ MSG_SE_ERROR_INPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_input_uri_not_found),
+ MSG_SE_ERROR_OUTPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_output_uri_not_found),
+ MSG_SE_ERROR_TOO_MANY_INPUTS (LogLevel.ERROR, R.string.msg_se_error_too_many_inputs),
+ MSG_SE_WARN_OUTPUT_LEFT (LogLevel.WARN, R.string.msg_se_warn_output_left),
+ MSG_SE_SUCCESS (LogLevel.OK, R.string.msg_se_success),
+
+ // pgpsignencrypt
+ MSG_PSE_ASYMMETRIC (LogLevel.INFO, R.string.msg_pse_asymmetric),
+ MSG_PSE_CLEARSIGN_ONLY (LogLevel.DEBUG, R.string.msg_pse_clearsign_only),
+ MSG_PSE_COMPRESSING (LogLevel.DEBUG, R.string.msg_pse_compressing),
+ MSG_PSE_ENCRYPTING (LogLevel.DEBUG, R.string.msg_pse_encrypting),
+ MSG_PSE_ERROR_BAD_PASSPHRASE (LogLevel.ERROR, R.string.msg_pse_error_bad_passphrase),
+ MSG_PSE_ERROR_HASH_ALGO (LogLevel.ERROR, R.string.msg_pse_error_hash_algo),
+ MSG_PSE_ERROR_IO (LogLevel.ERROR, R.string.msg_pse_error_io),
+ MSG_PSE_ERROR_SIGN_KEY(LogLevel.ERROR, R.string.msg_pse_error_sign_key),
+ MSG_PSE_ERROR_KEY_SIGN (LogLevel.ERROR, R.string.msg_pse_error_key_sign),
+ MSG_PSE_ERROR_NFC (LogLevel.ERROR, R.string.msg_pse_error_nfc),
+ MSG_PSE_ERROR_PGP (LogLevel.ERROR, R.string.msg_pse_error_pgp),
+ MSG_PSE_ERROR_SIG (LogLevel.ERROR, R.string.msg_pse_error_sig),
+ MSG_PSE_ERROR_UNLOCK (LogLevel.ERROR, R.string.msg_pse_error_unlock),
+ MSG_PSE_KEY_OK (LogLevel.OK, R.string.msg_pse_key_ok),
+ MSG_PSE_KEY_UNKNOWN (LogLevel.DEBUG, R.string.msg_pse_key_unknown),
+ MSG_PSE_KEY_WARN (LogLevel.WARN, R.string.msg_pse_key_warn),
+ MSG_PSE_OK (LogLevel.OK, R.string.msg_pse_ok),
+ MSG_PSE_PENDING_NFC (LogLevel.INFO, R.string.msg_pse_pending_nfc),
+ MSG_PSE_PENDING_PASSPHRASE (LogLevel.INFO, R.string.msg_pse_pending_passphrase),
+ MSG_PSE (LogLevel.DEBUG, R.string.msg_pse),
+ MSG_PSE_SIGNING (LogLevel.DEBUG, R.string.msg_pse_signing),
+ MSG_PSE_SIGNING_CLEARTEXT (LogLevel.DEBUG, R.string.msg_pse_signing_cleartext),
+ MSG_PSE_SIGNING_DETACHED (LogLevel.DEBUG, R.string.msg_pse_signing_detached),
+ MSG_PSE_SIGCRYPTING (LogLevel.DEBUG, R.string.msg_pse_sigcrypting),
+ MSG_PSE_SYMMETRIC (LogLevel.INFO, R.string.msg_pse_symmetric),
MSG_CRT_CERTIFYING (LogLevel.DEBUG, R.string.msg_crt_certifying),
MSG_CRT_CERTIFY_ALL (LogLevel.DEBUG, R.string.msg_crt_certify_all),
MSG_CRT_CERTIFY_SOME (LogLevel.DEBUG, R.plurals.msg_crt_certify_some),
+ MSG_CRT_ERROR_SELF (LogLevel.ERROR, R.string.msg_crt_error_self),
MSG_CRT_ERROR_MASTER_NOT_FOUND (LogLevel.ERROR, R.string.msg_crt_error_master_not_found),
MSG_CRT_ERROR_NOTHING (LogLevel.ERROR, R.string.msg_crt_error_nothing),
MSG_CRT_ERROR_UNLOCK (LogLevel.ERROR, R.string.msg_crt_error_unlock),
@@ -608,6 +664,7 @@ public abstract class OperationResult implements Parcelable {
MSG_IMPORT_FINGERPRINT_ERROR (LogLevel.ERROR, R.string.msg_import_fingerprint_error),
MSG_IMPORT_FINGERPRINT_OK (LogLevel.DEBUG, R.string.msg_import_fingerprint_ok),
MSG_IMPORT_ERROR (LogLevel.ERROR, R.string.msg_import_error),
+ MSG_IMPORT_ERROR_IO (LogLevel.ERROR, R.string.msg_import_error_io),
MSG_IMPORT_PARTIAL (LogLevel.ERROR, R.string.msg_import_partial),
MSG_IMPORT_SUCCESS (LogLevel.OK, R.string.msg_import_success),
@@ -622,6 +679,7 @@ public abstract class OperationResult implements Parcelable {
MSG_EXPORT_ERROR_STORAGE (LogLevel.ERROR, R.string.msg_export_error_storage),
MSG_EXPORT_ERROR_DB (LogLevel.ERROR, R.string.msg_export_error_db),
MSG_EXPORT_ERROR_IO (LogLevel.ERROR, R.string.msg_export_error_io),
+ MSG_EXPORT_ERROR_KEY (LogLevel.ERROR, R.string.msg_export_error_key),
MSG_EXPORT_SUCCESS (LogLevel.OK, R.string.msg_export_success),
MSG_CRT_UPLOAD_SUCCESS (LogLevel.OK, R.string.msg_crt_upload_success),
@@ -688,7 +746,7 @@ public abstract class OperationResult implements Parcelable {
public static class OperationLog implements Iterable<LogEntryParcel> {
- private final List<LogEntryParcel> mParcels = new ArrayList<LogEntryParcel>();
+ private final List<LogEntryParcel> mParcels = new ArrayList<>();
/// Simple convenience method
public void add(LogType type, int indent, Object... parameters) {
@@ -713,7 +771,7 @@ public abstract class OperationResult implements Parcelable {
}
public boolean containsType(LogType type) {
- for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(mParcels.iterator())) {
+ for(LogEntryParcel entry : new IterableIterator<>(mParcels.iterator())) {
if (entry.mType == type) {
return true;
}
@@ -722,7 +780,7 @@ public abstract class OperationResult implements Parcelable {
}
public boolean containsWarnings() {
- for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(mParcels.iterator())) {
+ for(LogEntryParcel entry : new IterableIterator<>(mParcels.iterator())) {
if (entry.mType.mLevel == LogLevel.WARN || entry.mType.mLevel == LogLevel.ERROR) {
return true;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java
new file mode 100644
index 000000000..611353ac9
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.operations.results;
+
+import android.os.Parcel;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+
+public class PgpEditKeyResult extends OperationResult {
+
+ private transient UncachedKeyRing mRing;
+ public final long mRingMasterKeyId;
+
+ public PgpEditKeyResult(int result, OperationLog log,
+ UncachedKeyRing ring) {
+ super(result, log);
+ mRing = ring;
+ mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : Constants.key.none;
+ }
+
+ public UncachedKeyRing getRing() {
+ return mRing;
+ }
+
+ public PgpEditKeyResult(Parcel source) {
+ super(source);
+ mRingMasterKeyId = source.readLong();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeLong(mRingMasterKeyId);
+ }
+
+ public static Creator<PgpEditKeyResult> CREATOR = new Creator<PgpEditKeyResult>() {
+ public PgpEditKeyResult createFromParcel(final Parcel source) {
+ return new PgpEditKeyResult(source);
+ }
+
+ public PgpEditKeyResult[] newArray(final int size) {
+ return new PgpEditKeyResult[size];
+ }
+ };
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java
new file mode 100644
index 000000000..de2f64404
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.operations.results;
+
+import android.os.Parcel;
+
+import java.util.Date;
+
+public class PgpSignEncryptResult extends OperationResult {
+
+ // the fourth bit indicates a "data pending" result! (it's also a form of non-success)
+ public static final int RESULT_PENDING = RESULT_ERROR + 8;
+
+ // fifth to sixth bit in addition indicate specific type of pending
+ public static final int RESULT_PENDING_PASSPHRASE = RESULT_PENDING + 16;
+ public static final int RESULT_PENDING_NFC = RESULT_PENDING + 32;
+
+ long mKeyIdPassphraseNeeded;
+
+ long mNfcKeyId;
+ byte[] mNfcHash;
+ int mNfcAlgo;
+ Date mNfcTimestamp;
+ String mNfcPassphrase;
+ byte[] mDetachedSignature;
+
+ public long getKeyIdPassphraseNeeded() {
+ return mKeyIdPassphraseNeeded;
+ }
+
+ public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) {
+ mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
+ }
+
+ public void setNfcData(long nfcKeyId, byte[] nfcHash, int nfcAlgo, Date nfcTimestamp, String passphrase) {
+ mNfcKeyId = nfcKeyId;
+ mNfcHash = nfcHash;
+ mNfcAlgo = nfcAlgo;
+ mNfcTimestamp = nfcTimestamp;
+ mNfcPassphrase = passphrase;
+ }
+
+ public void setDetachedSignature(byte[] detachedSignature) {
+ mDetachedSignature = detachedSignature;
+ }
+
+ public long getNfcKeyId() {
+ return mNfcKeyId;
+ }
+
+ public byte[] getNfcHash() {
+ return mNfcHash;
+ }
+
+ public int getNfcAlgo() {
+ return mNfcAlgo;
+ }
+
+ public Date getNfcTimestamp() {
+ return mNfcTimestamp;
+ }
+
+ public String getNfcPassphrase() {
+ return mNfcPassphrase;
+ }
+
+ public byte[] getDetachedSignature() {
+ return mDetachedSignature;
+ }
+
+ public boolean isPending() {
+ return (mResult & RESULT_PENDING) == RESULT_PENDING;
+ }
+
+ public PgpSignEncryptResult(int result, OperationLog log) {
+ super(result, log);
+ }
+
+ public PgpSignEncryptResult(Parcel source) {
+ super(source);
+ mNfcHash = source.readInt() != 0 ? source.createByteArray() : null;
+ mNfcAlgo = source.readInt();
+ mNfcTimestamp = source.readInt() != 0 ? new Date(source.readLong()) : null;
+ mDetachedSignature = source.readInt() != 0 ? source.createByteArray() : null;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ if (mNfcHash != null) {
+ dest.writeInt(1);
+ dest.writeByteArray(mNfcHash);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeInt(mNfcAlgo);
+ if (mNfcTimestamp != null) {
+ dest.writeInt(1);
+ dest.writeLong(mNfcTimestamp.getTime());
+ } else {
+ dest.writeInt(0);
+ }
+ if (mDetachedSignature != null) {
+ dest.writeInt(1);
+ dest.writeByteArray(mDetachedSignature);
+ } else {
+ dest.writeInt(0);
+ }
+ }
+
+ public static final Creator<PgpSignEncryptResult> CREATOR = new Creator<PgpSignEncryptResult>() {
+ public PgpSignEncryptResult createFromParcel(final Parcel source) {
+ return new PgpSignEncryptResult(source);
+ }
+
+ public PgpSignEncryptResult[] newArray(final int size) {
+ return new PgpSignEncryptResult[size];
+ }
+ };
+
+} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java
new file mode 100644
index 000000000..af9aff84a
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.operations.results;
+
+import android.os.Parcel;
+
+public class PromoteKeyResult extends OperationResult {
+
+ public final Long mMasterKeyId;
+
+ public PromoteKeyResult(int result, OperationLog log, Long masterKeyId) {
+ super(result, log);
+ mMasterKeyId = masterKeyId;
+ }
+
+ public PromoteKeyResult(Parcel source) {
+ super(source);
+ mMasterKeyId = source.readLong();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeLong(mMasterKeyId);
+ }
+
+ public static Creator<PromoteKeyResult> CREATOR = new Creator<PromoteKeyResult>() {
+ public PromoteKeyResult createFromParcel(final Parcel source) {
+ return new PromoteKeyResult(source);
+ }
+
+ public PromoteKeyResult[] newArray(final int size) {
+ return new PromoteKeyResult[size];
+ }
+ };
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java
index 57daf3430..ed0de65b0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java
@@ -19,74 +19,42 @@ package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel;
-import java.util.Date;
+import java.util.ArrayList;
public class SignEncryptResult extends OperationResult {
- // the fourth bit indicates a "data pending" result! (it's also a form of non-success)
- public static final int RESULT_PENDING = RESULT_ERROR + 8;
-
- // fifth to sixth bit in addition indicate specific type of pending
- public static final int RESULT_PENDING_PASSPHRASE = RESULT_PENDING + 16;
- public static final int RESULT_PENDING_NFC = RESULT_PENDING + 32;
-
- long mKeyIdPassphraseNeeded;
-
- long mNfcKeyId;
- byte[] mNfcHash;
- int mNfcAlgo;
- Date mNfcTimestamp;
- String mNfcPassphrase;
-
- public long getKeyIdPassphraseNeeded() {
- return mKeyIdPassphraseNeeded;
- }
-
- public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) {
- mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
- }
-
- public void setNfcData(long nfcKeyId, byte[] nfcHash, int nfcAlgo, Date nfcTimestamp, String passphrase) {
- mNfcKeyId = nfcKeyId;
- mNfcHash = nfcHash;
- mNfcAlgo = nfcAlgo;
- mNfcTimestamp = nfcTimestamp;
- mNfcPassphrase = passphrase;
- }
-
- public long getNfcKeyId() {
- return mNfcKeyId;
- }
+ ArrayList<PgpSignEncryptResult> mResults;
+ byte[] mResultBytes;
- public byte[] getNfcHash() {
- return mNfcHash;
- }
-
- public int getNfcAlgo() {
- return mNfcAlgo;
- }
-
- public Date getNfcTimestamp() {
- return mNfcTimestamp;
- }
+ public static final int RESULT_PENDING = RESULT_ERROR + 8;
- public String getNfcPassphrase() {
- return mNfcPassphrase;
+ public PgpSignEncryptResult getPending() {
+ for (PgpSignEncryptResult sub : mResults) {
+ if (sub.isPending()) {
+ return sub;
+ }
+ }
+ return null;
}
- public boolean isPending() {
- return (mResult & RESULT_PENDING) == RESULT_PENDING;
+ public SignEncryptResult(int result, OperationLog log, ArrayList<PgpSignEncryptResult> results) {
+ super(result, log);
+ mResults = results;
}
- public SignEncryptResult(int result, OperationLog log) {
+ public SignEncryptResult(int result, OperationLog log, ArrayList<PgpSignEncryptResult> results, byte[] resultBytes) {
super(result, log);
+ mResults = results;
+ mResultBytes = resultBytes;
}
public SignEncryptResult(Parcel source) {
super(source);
- mNfcHash = source.readInt() != 0 ? source.createByteArray() : null;
- mNfcAlgo = source.readInt();
- mNfcTimestamp = source.readInt() != 0 ? new Date(source.readLong()) : null;
+ mResults = source.createTypedArrayList(PgpSignEncryptResult.CREATOR);
+ }
+
+ public byte[] getResultBytes() {
+ return mResultBytes;
}
public int describeContents() {
@@ -95,19 +63,7 @@ public class SignEncryptResult extends OperationResult {
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- if (mNfcHash != null) {
- dest.writeInt(1);
- dest.writeByteArray(mNfcHash);
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(mNfcAlgo);
- if (mNfcTimestamp != null) {
- dest.writeInt(1);
- dest.writeLong(mNfcTimestamp.getTime());
- } else {
- dest.writeInt(0);
- }
+ dest.writeTypedList(mResults);
}
public static final Creator<SignEncryptResult> CREATOR = new Creator<SignEncryptResult>() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SingletonResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SingletonResult.java
index 43cc85522..04cb241f9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SingletonResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SingletonResult.java
@@ -18,13 +18,8 @@
package org.sufficientlysecure.keychain.operations.results;
-import android.app.Activity;
import android.os.Parcel;
-import com.github.johnpersano.supertoasts.SuperCardToast;
-import com.github.johnpersano.supertoasts.SuperToast;
-import com.github.johnpersano.supertoasts.util.Style;
-
/** This is a simple subclass meant to contain only a single log message. This log
* message is also shown without a log button in the createNotify SuperToast. */
public class SingletonResult extends OperationResult {
@@ -41,35 +36,6 @@ public class SingletonResult extends OperationResult {
}
@Override
- public SuperCardToast createNotify(final Activity activity) {
-
- // there is exactly one error msg - use that one
- String str = activity.getString(mLog.iterator().next().mType.getMsgId());
- int color;
-
- // Determine color by result type
- if (cancelled()) {
- color = Style.RED;
- } else if (success()) {
- if (getLog().containsWarnings()) {
- color = Style.ORANGE;
- } else {
- color = Style.GREEN;
- }
- } else {
- color = Style.RED;
- }
-
- SuperCardToast toast = new SuperCardToast(activity, SuperToast.Type.STANDARD,
- Style.getStyle(color, SuperToast.Animations.POPUP));
- toast.setText(str);
- toast.setDuration(SuperToast.Duration.EXTRA_LONG);
- toast.setIndeterminate(false);
- toast.setSwipeToDismiss(true);
- return toast;
- }
-
- @Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java
index db0a9b137..4adacaf23 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java
@@ -19,7 +19,6 @@
package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.openpgp.PGPKeyRing;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.util.IterableIterator;
@@ -80,9 +79,8 @@ public abstract class CanonicalizedKeyRing extends KeyRing {
public boolean isExpired() {
// Is the master key expired?
- Date creationDate = getRing().getPublicKey().getCreationTime();
- Date expiryDate = getRing().getPublicKey().getValidSeconds() > 0
- ? new Date(creationDate.getTime() + getRing().getPublicKey().getValidSeconds() * 1000) : null;
+ Date creationDate = getPublicKey().getCreationTime();
+ Date expiryDate = getPublicKey().getExpiryTime();
Date now = new Date();
return creationDate.after(now) || (expiryDate != null && expiryDate.before(now));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java
index 3539a4ceb..303070333 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java
@@ -20,8 +20,16 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.openpgp.PGPPublicKey;
+import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.util.IterableIterator;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
/** Wrapper for a PGPPublicKey.
*
@@ -53,7 +61,7 @@ public class CanonicalizedPublicKey extends UncachedPublicKey {
public boolean canSign() {
// if key flags subpacket is available, honor it!
- if (getKeyUsage() != null) {
+ if (getKeyUsage() != 0) {
return (getKeyUsage() & KeyFlags.SIGN_DATA) != 0;
}
@@ -66,7 +74,7 @@ public class CanonicalizedPublicKey extends UncachedPublicKey {
public boolean canCertify() {
// if key flags subpacket is available, honor it!
- if (getKeyUsage() != null) {
+ if (getKeyUsage() != 0) {
return (getKeyUsage() & KeyFlags.CERTIFY_OTHER) != 0;
}
@@ -79,7 +87,7 @@ public class CanonicalizedPublicKey extends UncachedPublicKey {
public boolean canEncrypt() {
// if key flags subpacket is available, honor it!
- if (getKeyUsage() != null) {
+ if (getKeyUsage() != 0) {
return (getKeyUsage() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0;
}
@@ -93,13 +101,79 @@ public class CanonicalizedPublicKey extends UncachedPublicKey {
public boolean canAuthenticate() {
// if key flags subpacket is available, honor it!
- if (getKeyUsage() != null) {
+ if (getKeyUsage() != 0) {
return (getKeyUsage() & KeyFlags.AUTHENTICATION) != 0;
}
return false;
}
+ public boolean isRevoked() {
+ return mPublicKey.getSignaturesOfType(isMasterKey()
+ ? PGPSignature.KEY_REVOCATION
+ : PGPSignature.SUBKEY_REVOCATION).hasNext();
+ }
+
+ public boolean isExpired () {
+ Date expiry = getExpiryTime();
+ return expiry != null && expiry.before(new Date());
+ }
+
+ public long getValidSeconds() {
+
+ long seconds;
+
+ // the getValidSeconds method is unreliable for master keys. we need to iterate all
+ // user ids, then use the most recent certification from a non-revoked user id
+ if (isMasterKey()) {
+ Date latestCreation = null;
+ seconds = 0;
+
+ for (byte[] rawUserId : getUnorderedRawUserIds()) {
+ Iterator<WrappedSignature> sigs = getSignaturesForRawId(rawUserId);
+
+ // there is always a certification, so this call is safe
+ WrappedSignature sig = sigs.next();
+
+ // we know a user id has at most two sigs: one certification, one revocation.
+ // if the sig is a revocation, or there is another sig (which is a revocation),
+ // the data in this uid is not relevant
+ if (sig.isRevocation() || sigs.hasNext()) {
+ continue;
+ }
+
+ // this is our revocation, UNLESS there is a newer certificate!
+ if (latestCreation == null || latestCreation.before(sig.getCreationTime())) {
+ latestCreation = sig.getCreationTime();
+ seconds = sig.getKeyExpirySeconds();
+ }
+ }
+ } else {
+ seconds = mPublicKey.getValidSeconds();
+ }
+
+ return seconds;
+ }
+
+ public Date getExpiryTime() {
+ long seconds = getValidSeconds();
+
+ if (seconds > Integer.MAX_VALUE) {
+ Log.e(Constants.TAG, "error, expiry time too large");
+ return null;
+ }
+ if (seconds == 0) {
+ // no expiry
+ return null;
+ }
+ Date creationDate = getCreationTime();
+ Calendar calendar = GregorianCalendar.getInstance();
+ calendar.setTime(creationDate);
+ calendar.add(Calendar.SECOND, (int) seconds);
+
+ return calendar.getTime();
+ }
+
/** Same method as superclass, but we make it public. */
public Integer getKeyUsage() {
return super.getKeyUsage();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java
index 85ef3eaa4..c2506685d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java
@@ -18,9 +18,11 @@
package org.sufficientlysecure.keychain.pgp;
+import org.spongycastle.bcpg.S2K;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing;
+import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.util.IterableIterator;
@@ -76,7 +78,7 @@ public class CanonicalizedPublicKeyRing extends CanonicalizedKeyRing {
public IterableIterator<CanonicalizedPublicKey> publicKeyIterator() {
@SuppressWarnings("unchecked")
final Iterator<PGPPublicKey> it = getRing().getPublicKeys();
- return new IterableIterator<CanonicalizedPublicKey>(new Iterator<CanonicalizedPublicKey>() {
+ return new IterableIterator<>(new Iterator<CanonicalizedPublicKey>() {
@Override
public boolean hasNext() {
return it.hasNext();
@@ -94,4 +96,13 @@ public class CanonicalizedPublicKeyRing extends CanonicalizedKeyRing {
});
}
+ /** Create a dummy secret ring from this key */
+ public UncachedKeyRing createDummySecretRing () {
+
+ PGPSecretKeyRing secRing = PGPSecretKeyRing.constructDummyFromPublic(getRing(),
+ S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY);
+ return new UncachedKeyRing(secRing);
+
+ }
+
} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
index f9fa41528..40f2f48ad 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
@@ -36,19 +36,16 @@ import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
-import org.spongycastle.openpgp.operator.jcajce.NfcSyncPublicKeyDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder;
+import org.spongycastle.openpgp.operator.jcajce.NfcSyncPublicKeyDataDecryptorFactoryBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SignatureException;
import java.util.Date;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -83,7 +80,8 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
}
public enum SecretKeyType {
- UNAVAILABLE(0), GNU_DUMMY(1), PASSPHRASE(2), PASSPHRASE_EMPTY(3), DIVERT_TO_CARD(4);
+ UNAVAILABLE(0), GNU_DUMMY(1), PASSPHRASE(2), PASSPHRASE_EMPTY(3), DIVERT_TO_CARD(4), PIN(5),
+ PATTERN(6);
final int mNum;
@@ -101,6 +99,10 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
return PASSPHRASE_EMPTY;
case 4:
return DIVERT_TO_CARD;
+ case 5:
+ return PIN;
+ case 6:
+ return PATTERN;
// if this case happens, it's probably a check from a database value
default:
return UNAVAILABLE;
@@ -135,6 +137,11 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
// It means the passphrase is empty
return SecretKeyType.PASSPHRASE_EMPTY;
} catch (PGPException e) {
+ HashMap<String,String> notation = getRing().getLocalNotationData();
+ if (notation.containsKey("unlock.pin@sufficientlysecure.org")
+ && "1".equals(notation.get("unlock.pin@sufficientlysecure.org"))) {
+ return SecretKeyType.PIN;
+ }
// Otherwise, it's just a regular ol' passphrase
return SecretKeyType.PASSPHRASE;
}
@@ -175,7 +182,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
* @return
*/
public LinkedList<Integer> getSupportedHashAlgorithms() {
- LinkedList<Integer> supported = new LinkedList<Integer>();
+ LinkedList<Integer> supported = new LinkedList<>();
if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) {
// No support for MD5
@@ -240,7 +247,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
int signatureType;
if (cleartext) {
- // for sign-only ascii text
+ // for sign-only ascii text (cleartext signature)
signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT;
} else {
signatureType = PGPSignature.BINARY_DOCUMENT;
@@ -255,11 +262,9 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
spGen.setSignatureCreationTime(false, nfcCreationTimestamp);
signatureGenerator.setHashedSubpackets(spGen.generate());
return signatureGenerator;
- } catch (PgpKeyNotFoundException e) {
+ } catch (PgpKeyNotFoundException | PGPException e) {
// TODO: simply throw PGPException!
throw new PgpGeneralException("Error initializing signature!", e);
- } catch (PGPException e) {
- throw new PgpGeneralException("Error initializing signature!", e);
}
}
@@ -289,6 +294,12 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {
throw new PrivateKeyNotUnlockedException();
}
+ if (!isMasterKey()) {
+ throw new AssertionError("tried to certify with non-master key, this is a programming error!");
+ }
+ if (publicKeyRing.getMasterKeyId() == getKeyId()) {
+ throw new AssertionError("key tried to self-certify, this is a programming error!");
+ }
// create a signatureGenerator from the supplied masterKeyId and passphrase
PGPSignatureGenerator signatureGenerator;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java
index e20155cc6..b5f6a5b09 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKeyRing.java
@@ -18,25 +18,19 @@
package org.sufficientlysecure.keychain.pgp;
-import org.spongycastle.bcpg.S2K;
-import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
+import org.spongycastle.openpgp.PGPSignature;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.Iterator;
public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing {
@@ -92,7 +86,7 @@ public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing {
public IterableIterator<CanonicalizedSecretKey> secretKeyIterator() {
final Iterator<PGPSecretKey> it = mRing.getSecretKeys();
- return new IterableIterator<CanonicalizedSecretKey>(new Iterator<CanonicalizedSecretKey>() {
+ return new IterableIterator<>(new Iterator<CanonicalizedSecretKey>() {
@Override
public boolean hasNext() {
return it.hasNext();
@@ -112,7 +106,7 @@ public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing {
public IterableIterator<CanonicalizedPublicKey> publicKeyIterator() {
final Iterator<PGPPublicKey> it = getRing().getPublicKeys();
- return new IterableIterator<CanonicalizedPublicKey>(new Iterator<CanonicalizedPublicKey>() {
+ return new IterableIterator<>(new Iterator<CanonicalizedPublicKey>() {
@Override
public boolean hasNext() {
return it.hasNext();
@@ -130,4 +124,16 @@ public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing {
});
}
+ public HashMap<String,String> getLocalNotationData() {
+ HashMap<String,String> result = new HashMap<>();
+ Iterator<PGPSignature> it = getRing().getPublicKey().getKeySignatures();
+ while (it.hasNext()) {
+ WrappedSignature sig = new WrappedSignature(it.next());
+ if (sig.isLocal()) {
+ result.putAll(sig.getNotation());
+ }
+ }
+ return result;
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java
index fc5064e79..46defebf7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java
@@ -19,7 +19,6 @@ package org.sufficientlysecure.keychain.pgp;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.util.Log;
@@ -33,7 +32,7 @@ public class OpenPgpSignatureResultBuilder {
// OpenPgpSignatureResult
private boolean mSignatureOnly = false;
private String mPrimaryUserId;
- private ArrayList<String> mUserIds = new ArrayList<String>();
+ private ArrayList<String> mUserIds = new ArrayList<>();
private long mKeyId;
// builder
@@ -84,6 +83,10 @@ public class OpenPgpSignatureResultBuilder {
this.mUserIds = userIds;
}
+ public boolean isValidSignature() {
+ return mValidSignature;
+ }
+
public void initValid(CanonicalizedPublicKeyRing signingRing,
CanonicalizedPublicKey signingKey) {
setSignatureAvailable(true);
@@ -101,8 +104,8 @@ public class OpenPgpSignatureResultBuilder {
setUserIds(signingRing.getUnorderedUserIds());
// either master key is expired/revoked or this specific subkey is expired/revoked
- setKeyExpired(signingRing.isExpired() || signingKey.isExpired());
- setKeyRevoked(signingRing.isRevoked() || signingKey.isRevoked());
+ setKeyExpired(signingRing.isExpired() || signingKey.isMaybeExpired());
+ setKeyRevoked(signingRing.isRevoked() || signingKey.isMaybeRevoked());
}
public OpenPgpSignatureResult build() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
index 5589a3521..2ba0b6231 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -29,7 +29,6 @@ import org.spongycastle.openpgp.PGPEncryptedData;
import org.spongycastle.openpgp.PGPEncryptedDataList;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPLiteralData;
-import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPOnePassSignature;
import org.spongycastle.openpgp.PGPOnePassSignatureList;
import org.spongycastle.openpgp.PGPPBEEncryptedData;
@@ -37,10 +36,10 @@ import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureList;
import org.spongycastle.openpgp.PGPUtil;
+import org.spongycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory;
import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
-import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;
@@ -55,6 +54,9 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -85,10 +87,11 @@ public class PgpDecryptVerify extends BaseOperation {
private Set<Long> mAllowedKeyIds;
private boolean mDecryptMetadataOnly;
private byte[] mDecryptedSessionKey;
+ private byte[] mDetachedSignature;
private String mRequiredSignerFingerprint;
private boolean mSignedLiteralData;
- private PgpDecryptVerify(Builder builder) {
+ protected PgpDecryptVerify(Builder builder) {
super(builder.mContext, builder.mProviderHelper, builder.mProgressable);
// private Constructor can only be called from Builder
@@ -100,6 +103,7 @@ public class PgpDecryptVerify extends BaseOperation {
this.mAllowedKeyIds = builder.mAllowedKeyIds;
this.mDecryptMetadataOnly = builder.mDecryptMetadataOnly;
this.mDecryptedSessionKey = builder.mDecryptedSessionKey;
+ this.mDetachedSignature = builder.mDetachedSignature;
this.mSignedLiteralData = builder.mSignedLiteralData;
this.mRequiredSignerFingerprint = builder.mRequiredSignerFingerprint;
}
@@ -109,15 +113,16 @@ public class PgpDecryptVerify extends BaseOperation {
private Context mContext;
private ProviderHelper mProviderHelper;
private InputData mData;
- private OutputStream mOutStream;
// optional
+ private OutputStream mOutStream = null;
private Progressable mProgressable = null;
private boolean mAllowSymmetricDecryption = true;
private String mPassphrase = null;
private Set<Long> mAllowedKeyIds = null;
private boolean mDecryptMetadataOnly = false;
private byte[] mDecryptedSessionKey = null;
+ private byte[] mDetachedSignature = null;
private String mRequiredSignerFingerprint = null;
private boolean mSignedLiteralData = false;
@@ -182,6 +187,14 @@ public class PgpDecryptVerify extends BaseOperation {
return this;
}
+ /**
+ * If detachedSignature != null, it will be used exclusively to verify the signature
+ */
+ public Builder setDetachedSignature(byte[] detachedSignature) {
+ mDetachedSignature = detachedSignature;
+ return this;
+ }
+
public PgpDecryptVerify build() {
return new PgpDecryptVerify(this);
}
@@ -192,24 +205,32 @@ public class PgpDecryptVerify extends BaseOperation {
*/
public DecryptVerifyResult execute() {
try {
- // automatically works with ascii armor input and binary
- InputStream in = PGPUtil.getDecoderStream(mData.getInputStream());
-
- if (in instanceof ArmoredInputStream) {
- ArmoredInputStream aIn = (ArmoredInputStream) in;
- // it is ascii armored
- Log.d(Constants.TAG, "ASCII Armor Header Line: " + aIn.getArmorHeaderLine());
-
- if (mSignedLiteralData) {
- return verifySignedLiteralData(aIn, 0);
- } else if (aIn.isClearText()) {
- // a cleartext signature, verify it with the other method
- return verifyCleartextSignature(aIn, 0);
+ if (mDetachedSignature != null) {
+ Log.d(Constants.TAG, "Detached signature present, verifying with this signature only");
+
+ return verifyDetachedSignature(mData.getInputStream(), 0);
+ } else {
+ // automatically works with PGP ascii armor and PGP binary
+ InputStream in = PGPUtil.getDecoderStream(mData.getInputStream());
+
+ if (in instanceof ArmoredInputStream) {
+ ArmoredInputStream aIn = (ArmoredInputStream) in;
+ // it is ascii armored
+ Log.d(Constants.TAG, "ASCII Armor Header Line: " + aIn.getArmorHeaderLine());
+
+ if (mSignedLiteralData) {
+ return verifySignedLiteralData(aIn, 0);
+ } else if (aIn.isClearText()) {
+ // a cleartext signature, verify it with the other method
+ return verifyCleartextSignature(aIn, 0);
+ } else {
+ // else: ascii armored encryption! go on...
+ return decryptVerify(in, 0);
+ }
+ } else {
+ return decryptVerify(in, 0);
}
- // else: ascii armored encryption! go on...
}
-
- return decryptVerify(in, 0);
} catch (PGPException e) {
Log.d(Constants.TAG, "PGPException", e);
OperationLog log = new OperationLog();
@@ -233,12 +254,12 @@ public class PgpDecryptVerify extends BaseOperation {
// thinking that the proof-fetching operation is going to take most of the time
updateProgress(R.string.progress_reading_data, 75, 100);
- PGPObjectFactory pgpF = new PGPObjectFactory(in, new JcaKeyFingerprintCalculator());
+ JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
Object o = pgpF.nextObject();
if (o instanceof PGPCompressedData) {
log.add(LogType.MSG_DC_CLEAR_DECOMPRESS, indent + 1);
- pgpF = new PGPObjectFactory(((PGPCompressedData) o).getDataStream(), new JcaKeyFingerprintCalculator());
+ pgpF = new JcaPGPObjectFactory(((PGPCompressedData) o).getDataStream());
o = pgpF.nextObject();
updateProgress(R.string.progress_decompressing_data, 80, 100);
}
@@ -363,7 +384,7 @@ public class PgpDecryptVerify extends BaseOperation {
log.add(LogType.MSG_DC, indent);
indent += 1;
- PGPObjectFactory pgpF = new PGPObjectFactory(in, new JcaKeyFingerprintCalculator());
+ JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
@@ -392,6 +413,25 @@ public class PgpDecryptVerify extends BaseOperation {
boolean symmetricPacketFound = false;
boolean anyPacketFound = false;
+ // If the input stream is armored, and there is a charset specified, take a note for later
+ // https://tools.ietf.org/html/rfc4880#page56
+ String charset = null;
+ if (in instanceof ArmoredInputStream) {
+ ArmoredInputStream aIn = (ArmoredInputStream) in;
+ if (aIn.getArmorHeaders() != null) {
+ for (String header : aIn.getArmorHeaders()) {
+ String[] pieces = header.split(":", 2);
+ if (pieces.length == 2 && "charset".equalsIgnoreCase(pieces[0])) {
+ charset = pieces[1].trim();
+ break;
+ }
+ }
+ if (charset != null) {
+ log.add(LogType.MSG_DC_CHARSET, indent, charset);
+ }
+ }
+ }
+
// go through all objects and find one we can decrypt
while (it.hasNext()) {
Object obj = it.next();
@@ -415,19 +455,19 @@ public class PgpDecryptVerify extends BaseOperation {
);
} catch (ProviderHelper.NotFoundException e) {
// continue with the next packet in the while loop
- log.add(LogType.MSG_DC_ASKIP_NO_KEY, indent +1);
+ log.add(LogType.MSG_DC_ASKIP_NO_KEY, indent + 1);
continue;
}
if (secretKeyRing == null) {
// continue with the next packet in the while loop
- log.add(LogType.MSG_DC_ASKIP_NO_KEY, indent +1);
+ log.add(LogType.MSG_DC_ASKIP_NO_KEY, indent + 1);
continue;
}
// get subkey which has been used for this encryption packet
secretEncryptionKey = secretKeyRing.getSecretKey(subKeyId);
if (secretEncryptionKey == null) {
// should actually never happen, so no need to be more specific.
- log.add(LogType.MSG_DC_ASKIP_NO_KEY, indent +1);
+ log.add(LogType.MSG_DC_ASKIP_NO_KEY, indent + 1);
continue;
}
@@ -441,7 +481,7 @@ public class PgpDecryptVerify extends BaseOperation {
if (!mAllowedKeyIds.contains(masterKeyId)) {
// this key is in our db, but NOT allowed!
// continue with the next packet in the while loop
- log.add(LogType.MSG_DC_ASKIP_NOT_ALLOWED, indent +1);
+ log.add(LogType.MSG_DC_ASKIP_NOT_ALLOWED, indent + 1);
continue;
}
}
@@ -456,15 +496,15 @@ public class PgpDecryptVerify extends BaseOperation {
try {
// returns "" if key has no passphrase
mPassphrase = getCachedPassphrase(subKeyId);
- log.add(LogType.MSG_DC_PASS_CACHED, indent +1);
+ log.add(LogType.MSG_DC_PASS_CACHED, indent + 1);
} catch (PassphraseCacheInterface.NoSecretKeyException e) {
- log.add(LogType.MSG_DC_ERROR_NO_KEY, indent +1);
+ log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
// if passphrase was not cached, return here indicating that a passphrase is missing!
if (mPassphrase == null) {
- log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent +1);
+ log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1);
DecryptVerifyResult result =
new DecryptVerifyResult(DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE, log);
result.setKeyIdPassphraseNeeded(subKeyId);
@@ -480,8 +520,8 @@ public class PgpDecryptVerify extends BaseOperation {
log.add(LogType.MSG_DC_SYM, indent);
- if (! mAllowSymmetricDecryption) {
- log.add(LogType.MSG_DC_SYM_SKIP, indent +1);
+ if (!mAllowSymmetricDecryption) {
+ log.add(LogType.MSG_DC_SYM_SKIP, indent + 1);
continue;
}
@@ -496,7 +536,7 @@ public class PgpDecryptVerify extends BaseOperation {
// if no passphrase is given, return here
// indicating that a passphrase is missing!
if (mPassphrase == null) {
- log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent +1);
+ log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE, log);
}
@@ -541,13 +581,13 @@ public class PgpDecryptVerify extends BaseOperation {
updateProgress(R.string.progress_extracting_key, currentProgress, 100);
try {
- log.add(LogType.MSG_DC_UNLOCKING, indent +1);
+ log.add(LogType.MSG_DC_UNLOCKING, indent + 1);
if (!secretEncryptionKey.unlock(mPassphrase)) {
- log.add(LogType.MSG_DC_ERROR_BAD_PASSPHRASE, indent +1);
+ log.add(LogType.MSG_DC_ERROR_BAD_PASSPHRASE, indent + 1);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
} catch (PgpGeneralException e) {
- log.add(LogType.MSG_DC_ERROR_EXTRACT_KEY, indent +1);
+ log.add(LogType.MSG_DC_ERROR_EXTRACT_KEY, indent + 1);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
@@ -559,7 +599,7 @@ public class PgpDecryptVerify extends BaseOperation {
= secretEncryptionKey.getDecryptorFactory(mDecryptedSessionKey);
clear = encryptedDataAsymmetric.getDataStream(decryptorFactory);
} catch (NfcSyncPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) {
- log.add(LogType.MSG_DC_PENDING_NFC, indent +1);
+ log.add(LogType.MSG_DC_PENDING_NFC, indent + 1);
DecryptVerifyResult result =
new DecryptVerifyResult(DecryptVerifyResult.RESULT_PENDING_NFC, log);
result.setNfcState(secretEncryptionKey.getKeyId(), e.encryptedSessionKey, mPassphrase);
@@ -570,11 +610,11 @@ public class PgpDecryptVerify extends BaseOperation {
// If we didn't find any useful data, error out
// no packet has been found where we have the corresponding secret key in our db
log.add(
- anyPacketFound ? LogType.MSG_DC_ERROR_NO_KEY : LogType.MSG_DC_ERROR_NO_DATA, indent +1);
+ anyPacketFound ? LogType.MSG_DC_ERROR_NO_KEY : LogType.MSG_DC_ERROR_NO_DATA, indent + 1);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
- PGPObjectFactory plainFact = new PGPObjectFactory(clear, new JcaKeyFingerprintCalculator());
+ JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
Object dataChunk = plainFact.nextObject();
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
int signatureIndex = -1;
@@ -585,25 +625,27 @@ public class PgpDecryptVerify extends BaseOperation {
indent += 1;
if (dataChunk instanceof PGPCompressedData) {
- log.add(LogType.MSG_DC_CLEAR_DECOMPRESS, indent +1);
+ log.add(LogType.MSG_DC_CLEAR_DECOMPRESS, indent + 1);
currentProgress += 2;
updateProgress(R.string.progress_decompressing_data, currentProgress, 100);
PGPCompressedData compressedData = (PGPCompressedData) dataChunk;
- PGPObjectFactory fact = new PGPObjectFactory(compressedData.getDataStream(), new JcaKeyFingerprintCalculator());
+ JcaPGPObjectFactory fact = new JcaPGPObjectFactory(compressedData.getDataStream());
dataChunk = fact.nextObject();
plainFact = fact;
}
PGPOnePassSignature signature = null;
if (dataChunk instanceof PGPOnePassSignatureList) {
- log.add(LogType.MSG_DC_CLEAR_SIGNATURE, indent +1);
+ log.add(LogType.MSG_DC_CLEAR_SIGNATURE, indent + 1);
currentProgress += 2;
updateProgress(R.string.progress_processing_signature, currentProgress, 100);
PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
+ // NOTE: following code is similar to processSignature, but for PGPOnePassSignature
+
// go through all signatures
// and find out for which signature we have a key in our database
for (int i = 0; i < sigList.size(); ++i) {
@@ -649,19 +691,15 @@ public class PgpDecryptVerify extends BaseOperation {
OpenPgpMetadata metadata;
if (dataChunk instanceof PGPLiteralData) {
- log.add(LogType.MSG_DC_CLEAR_DATA, indent +1);
+ log.add(LogType.MSG_DC_CLEAR_DATA, indent + 1);
indent += 2;
currentProgress += 4;
updateProgress(R.string.progress_decrypting, currentProgress, 100);
PGPLiteralData literalData = (PGPLiteralData) dataChunk;
- // TODO: how to get the real original size?
- // this is the encrypted size so if we enable compression this value is wrong!
- long originalSize = mData.getSize() - mData.getStreamPosition();
- if (originalSize < 0) {
- originalSize = 0;
- }
+ // reported size may be null if partial packets are involved (highly unlikely though)
+ Long originalSize = literalData.getDataLengthIfAvailable();
String originalFilename = literalData.getFileName();
String mimeType = null;
@@ -689,18 +727,20 @@ public class PgpDecryptVerify extends BaseOperation {
originalFilename,
mimeType,
literalData.getModificationTime().getTime(),
- originalSize);
+ originalSize == null ? 0 : originalSize);
- if ( ! originalFilename.equals("")) {
+ if (!"".equals(originalFilename)) {
log.add(LogType.MSG_DC_CLEAR_META_FILE, indent + 1, originalFilename);
}
- log.add(LogType.MSG_DC_CLEAR_META_MIME, indent +1,
+ log.add(LogType.MSG_DC_CLEAR_META_MIME, indent + 1,
mimeType);
- log.add(LogType.MSG_DC_CLEAR_META_TIME, indent +1,
+ log.add(LogType.MSG_DC_CLEAR_META_TIME, indent + 1,
new Date(literalData.getModificationTime().getTime()).toString());
- if (originalSize != 0) {
+ if (originalSize != null) {
log.add(LogType.MSG_DC_CLEAR_META_SIZE, indent + 1,
Long.toString(originalSize));
+ } else {
+ log.add(LogType.MSG_DC_CLEAR_META_SIZE_UNKNOWN, indent + 1);
}
// return here if we want to decrypt the metadata only
@@ -708,6 +748,7 @@ public class PgpDecryptVerify extends BaseOperation {
log.add(LogType.MSG_DC_OK_META_ONLY, indent);
DecryptVerifyResult result =
new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
+ result.setCharset(charset);
result.setDecryptMetadata(metadata);
return result;
}
@@ -730,7 +771,10 @@ public class PgpDecryptVerify extends BaseOperation {
int length;
byte[] buffer = new byte[1 << 16];
while ((length = dataIn.read(buffer)) > 0) {
- mOutStream.write(buffer, 0, length);
+ Log.d(Constants.TAG, "read bytes: " + length);
+ if (mOutStream != null) {
+ mOutStream.write(buffer, 0, length);
+ }
// update signature buffer if signature is also present
if (signature != null) {
@@ -745,9 +789,8 @@ public class PgpDecryptVerify extends BaseOperation {
progress = 100;
}
progressScaler.setProgress((int) progress, 100);
- } else {
- // TODO: slow annealing to fake a progress?
}
+ // TODO: slow annealing to fake a progress?
}
if (signature != null) {
@@ -764,9 +807,9 @@ public class PgpDecryptVerify extends BaseOperation {
// Verify signature and check binding signatures
boolean validSignature = signature.verify(messageSignature);
if (validSignature) {
- log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent +1);
+ log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent + 1);
} else {
- log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent +1);
+ log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1);
}
signatureResultBuilder.setValidSignature(validSignature);
}
@@ -777,8 +820,6 @@ public class PgpDecryptVerify extends BaseOperation {
metadata = null;
}
- OpenPgpSignatureResult signatureResult = signatureResultBuilder.build();
-
if (encryptedData.isIntegrityProtected()) {
updateProgress(R.string.progress_verifying_integrity, 95, 100);
@@ -792,9 +833,9 @@ public class PgpDecryptVerify extends BaseOperation {
// If no valid signature is present:
// Handle missing integrity protection like failed integrity protection!
// The MDC packet can be stripped by an attacker!
- if (signatureResult.getStatus() != OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED
- && signatureResult.getStatus() != OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED) {
- log.add(LogType.MSG_DC_ERROR_INTEGRITY_CHECK, indent);
+ Log.d(Constants.TAG, "MDC fail");
+ if (!signatureResultBuilder.isValidSignature()) {
+ log.add(LogType.MSG_DC_ERROR_INTEGRITY_MISSING, indent);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
}
@@ -807,7 +848,8 @@ public class PgpDecryptVerify extends BaseOperation {
DecryptVerifyResult result =
new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
result.setDecryptMetadata(metadata);
- result.setSignatureResult(signatureResult);
+ result.setSignatureResult(signatureResultBuilder.build());
+ result.setCharset(charset);
return result;
}
@@ -830,7 +872,7 @@ public class PgpDecryptVerify extends BaseOperation {
ByteArrayOutputStream out = new ByteArrayOutputStream();
- updateProgress(R.string.progress_done, 0, 100);
+ updateProgress(R.string.progress_reading_data, 0, 100);
ByteArrayOutputStream lineOut = new ByteArrayOutputStream();
int lookAhead = readInputLine(lineOut, aIn);
@@ -850,10 +892,12 @@ public class PgpDecryptVerify extends BaseOperation {
out.close();
byte[] clearText = out.toByteArray();
- mOutStream.write(clearText);
+ if (mOutStream != null) {
+ mOutStream.write(clearText);
+ }
updateProgress(R.string.progress_processing_signature, 60, 100);
- PGPObjectFactory pgpFact = new PGPObjectFactory(aIn, new JcaKeyFingerprintCalculator());
+ JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(aIn);
PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
if (sigList == null) {
@@ -861,45 +905,7 @@ public class PgpDecryptVerify extends BaseOperation {
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
- CanonicalizedPublicKeyRing signingRing = null;
- CanonicalizedPublicKey signingKey = null;
- int signatureIndex = -1;
-
- // go through all signatures
- // and find out for which signature we have a key in our database
- for (int i = 0; i < sigList.size(); ++i) {
- try {
- long sigKeyId = sigList.get(i).getKeyID();
- signingRing = mProviderHelper.getCanonicalizedPublicKeyRing(
- KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(sigKeyId)
- );
- signingKey = signingRing.getPublicKey(sigKeyId);
- signatureIndex = i;
- } catch (ProviderHelper.NotFoundException e) {
- Log.d(Constants.TAG, "key not found, trying next signature...");
- }
- }
-
- PGPSignature signature = null;
-
- if (signingKey != null) {
- // key found in our database!
- signature = sigList.get(signatureIndex);
-
- signatureResultBuilder.initValid(signingRing, signingKey);
-
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
- new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- signature.init(contentVerifierBuilderProvider, signingKey.getPublicKey());
- } else {
- // no key in our database -> return "unknown pub key" status including the first key id
- if (!sigList.isEmpty()) {
- signatureResultBuilder.setSignatureAvailable(true);
- signatureResultBuilder.setKnownKey(false);
- signatureResultBuilder.setKeyId(sigList.get(0).getKeyID());
- }
- }
+ PGPSignature signature = processPGPSignatureList(sigList, signatureResultBuilder);
if (signature != null) {
try {
@@ -947,6 +953,133 @@ public class PgpDecryptVerify extends BaseOperation {
return result;
}
+ private DecryptVerifyResult verifyDetachedSignature(InputStream in, int indent)
+ throws IOException, PGPException {
+
+ OperationLog log = new OperationLog();
+
+ OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
+ // detached signatures are never encrypted
+ signatureResultBuilder.setSignatureOnly(true);
+
+ updateProgress(R.string.progress_processing_signature, 0, 100);
+ InputStream detachedSigIn = new ByteArrayInputStream(mDetachedSignature);
+ detachedSigIn = PGPUtil.getDecoderStream(detachedSigIn);
+
+ JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(detachedSigIn);
+
+ PGPSignatureList sigList;
+ Object o = pgpFact.nextObject();
+ if (o instanceof PGPCompressedData) {
+ PGPCompressedData c1 = (PGPCompressedData) o;
+ pgpFact = new JcaPGPObjectFactory(c1.getDataStream());
+ sigList = (PGPSignatureList) pgpFact.nextObject();
+ } else if (o instanceof PGPSignatureList) {
+ sigList = (PGPSignatureList) o;
+ } else {
+ log.add(LogType.MSG_DC_ERROR_INVALID_SIGLIST, 0);
+ return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
+ }
+
+ PGPSignature signature = processPGPSignatureList(sigList, signatureResultBuilder);
+
+ if (signature != null) {
+ updateProgress(R.string.progress_reading_data, 60, 100);
+
+ ProgressScaler progressScaler = new ProgressScaler(mProgressable, 60, 90, 100);
+ long alreadyWritten = 0;
+ long wholeSize = mData.getSize() - mData.getStreamPosition();
+ int length;
+ byte[] buffer = new byte[1 << 16];
+ while ((length = in.read(buffer)) > 0) {
+ if (mOutStream != null) {
+ mOutStream.write(buffer, 0, length);
+ }
+
+ // update signature buffer if signature is also present
+ signature.update(buffer, 0, length);
+
+ alreadyWritten += length;
+ if (wholeSize > 0) {
+ long progress = 100 * alreadyWritten / wholeSize;
+ // stop at 100% for wrong file sizes...
+ if (progress > 100) {
+ progress = 100;
+ }
+ progressScaler.setProgress((int) progress, 100);
+ }
+ // TODO: slow annealing to fake a progress?
+ }
+
+ updateProgress(R.string.progress_verifying_signature, 90, 100);
+ log.add(LogType.MSG_DC_CLEAR_SIGNATURE_CHECK, indent);
+
+ // these are not cleartext signatures!
+ signatureResultBuilder.setSignatureOnly(false);
+
+ // Verify signature and check binding signatures
+ boolean validSignature = signature.verify();
+ if (validSignature) {
+ log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent + 1);
+ } else {
+ log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1);
+ }
+ signatureResultBuilder.setValidSignature(validSignature);
+ }
+
+ updateProgress(R.string.progress_done, 100, 100);
+
+ log.add(LogType.MSG_DC_OK, indent);
+
+ DecryptVerifyResult result = new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
+ result.setSignatureResult(signatureResultBuilder.build());
+ return result;
+ }
+
+ private PGPSignature processPGPSignatureList(PGPSignatureList sigList, OpenPgpSignatureResultBuilder signatureResultBuilder) throws PGPException {
+ CanonicalizedPublicKeyRing signingRing = null;
+ CanonicalizedPublicKey signingKey = null;
+ int signatureIndex = -1;
+
+ // go through all signatures
+ // and find out for which signature we have a key in our database
+ for (int i = 0; i < sigList.size(); ++i) {
+ try {
+ long sigKeyId = sigList.get(i).getKeyID();
+ signingRing = mProviderHelper.getCanonicalizedPublicKeyRing(
+ KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(sigKeyId)
+ );
+ signingKey = signingRing.getPublicKey(sigKeyId);
+ signatureIndex = i;
+ } catch (ProviderHelper.NotFoundException e) {
+ Log.d(Constants.TAG, "key not found, trying next signature...");
+ }
+ }
+
+ PGPSignature signature = null;
+
+ if (signingKey != null) {
+ // key found in our database!
+ signature = sigList.get(signatureIndex);
+
+ signatureResultBuilder.initValid(signingRing, signingKey);
+
+ JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
+ new JcaPGPContentVerifierBuilderProvider()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ signature.init(contentVerifierBuilderProvider, signingKey.getPublicKey());
+ } else {
+ // no key in our database -> return "unknown pub key" status including the first key id
+ if (!sigList.isEmpty()) {
+ signatureResultBuilder.setSignatureAvailable(true);
+ signatureResultBuilder.setKnownKey(false);
+ signatureResultBuilder.setKeyId(sigList.get(0).getKeyID());
+ }
+ }
+
+ return signature;
+ }
+
/**
* Mostly taken from ClearSignedFileProcessor in Bouncy Castle
*/
@@ -968,7 +1101,7 @@ public class PgpDecryptVerify extends BaseOperation {
while ((ch = fIn.read()) >= 0) {
bOut.write(ch);
if (ch == '\r' || ch == '\n') {
- lookAhead = readPassedEOL(bOut, ch, fIn);
+ lookAhead = readPastEOL(bOut, ch, fIn);
break;
}
}
@@ -985,7 +1118,7 @@ public class PgpDecryptVerify extends BaseOperation {
do {
bOut.write(ch);
if (ch == '\r' || ch == '\n') {
- lookAhead = readPassedEOL(bOut, ch, fIn);
+ lookAhead = readPastEOL(bOut, ch, fIn);
break;
}
} while ((ch = fIn.read()) >= 0);
@@ -997,7 +1130,7 @@ public class PgpDecryptVerify extends BaseOperation {
return lookAhead;
}
- private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn)
+ private static int readPastEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn)
throws IOException {
int lookAhead = fIn.read();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
index 0a15fd98f..12de2f637 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
@@ -24,8 +24,8 @@ import android.content.pm.PackageManager.NameNotFoundException;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
import java.io.File;
import java.io.IOException;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
index 6e45fab99..1a251eb79 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -34,6 +34,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
+import org.spongycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
@@ -49,9 +50,10 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
-import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
@@ -133,7 +135,7 @@ public class PgpKeyOperation {
public PgpKeyOperation(Progressable progress) {
super();
if (progress != null) {
- mProgress = new Stack<Progressable>();
+ mProgress = new Stack<>();
mProgress.push(progress);
}
}
@@ -286,13 +288,11 @@ public class PgpKeyOperation {
// build new key pair
return new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
- } catch(NoSuchProviderException e) {
+ } catch(NoSuchProviderException | InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
} catch(NoSuchAlgorithmException e) {
log.add(LogType.MSG_CR_ERROR_UNKNOWN_ALGO, indent);
return null;
- } catch(InvalidAlgorithmParameterException e) {
- throw new RuntimeException(e);
} catch(PGPException e) {
Log.e(Constants.TAG, "internal pgp error", e);
log.add(LogType.MSG_CR_ERROR_INTERNAL_PGP, indent);
@@ -300,7 +300,7 @@ public class PgpKeyOperation {
}
}
- public EditKeyResult createSecretKeyRing(SaveKeyringParcel saveParcel) {
+ public PgpEditKeyResult createSecretKeyRing(SaveKeyringParcel saveParcel) {
OperationLog log = new OperationLog();
int indent = 0;
@@ -313,23 +313,23 @@ public class PgpKeyOperation {
if (saveParcel.mAddSubKeys.isEmpty()) {
log.add(LogType.MSG_CR_ERROR_NO_MASTER, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (saveParcel.mAddUserIds.isEmpty()) {
log.add(LogType.MSG_CR_ERROR_NO_USER_ID, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
SubkeyAdd add = saveParcel.mAddSubKeys.remove(0);
if ((add.mFlags & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) {
log.add(LogType.MSG_CR_ERROR_NO_CERTIFY, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (add.mExpiry == null) {
log.add(LogType.MSG_CR_ERROR_NULL_EXPIRY, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
subProgressPush(10, 30);
@@ -338,7 +338,7 @@ public class PgpKeyOperation {
// return null if this failed (an error will already have been logged by createKey)
if (keyPair == null) {
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
progress(R.string.progress_building_master_key, 40);
@@ -365,10 +365,10 @@ public class PgpKeyOperation {
} catch (PGPException e) {
log.add(LogType.MSG_CR_ERROR_INTERNAL_PGP, indent);
Log.e(Constants.TAG, "pgp error encoding key", e);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
} catch (IOException e) {
Log.e(Constants.TAG, "io error encoding key", e);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
}
@@ -387,8 +387,11 @@ public class PgpKeyOperation {
* with a passphrase fails, the operation will fail with an unlocking error. More specific
* handling of errors should be done in UI code!
*
+ * If the passphrase is null, only a restricted subset of operations will be available,
+ * namely stripping of subkeys and changing the protection mode of dummy keys.
+ *
*/
- public EditKeyResult modifySecretKeyRing(CanonicalizedSecretKeyRing wsKR, SaveKeyringParcel saveParcel,
+ public PgpEditKeyResult modifySecretKeyRing(CanonicalizedSecretKeyRing wsKR, SaveKeyringParcel saveParcel,
String passphrase) {
OperationLog log = new OperationLog();
@@ -413,7 +416,7 @@ public class PgpKeyOperation {
// Make sure this is called with a proper SaveKeyringParcel
if (saveParcel.mMasterKeyId == null || saveParcel.mMasterKeyId != wsKR.getMasterKeyId()) {
log.add(LogType.MSG_MF_ERROR_KEYID, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// We work on bouncycastle object level here
@@ -424,21 +427,26 @@ public class PgpKeyOperation {
if (saveParcel.mFingerprint == null || !Arrays.equals(saveParcel.mFingerprint,
masterSecretKey.getPublicKey().getFingerprint())) {
log.add(LogType.MSG_MF_ERROR_FINGERPRINT, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
+ }
+
+ // If we have no passphrase, only allow restricted operation
+ if (passphrase == null) {
+ return internalRestricted(sKR, saveParcel, log);
}
// read masterKeyFlags, and use the same as before.
// since this is the master key, this contains at least CERTIFY_OTHER
PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey();
int masterKeyFlags = readKeyFlags(masterPublicKey) | KeyFlags.CERTIFY_OTHER;
- long masterKeyExpiry = masterPublicKey.getValidSeconds() == 0L ? 0L :
- masterPublicKey.getCreationTime().getTime() / 1000 + masterPublicKey.getValidSeconds();
+ Date expiryTime = wsKR.getPublicKey().getExpiryTime();
+ long masterKeyExpiry = expiryTime != null ? expiryTime.getTime() / 1000 : 0L;
return internal(sKR, masterSecretKey, masterKeyFlags, masterKeyExpiry, saveParcel, passphrase, log);
}
- private EditKeyResult internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey,
+ private PgpEditKeyResult internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey,
int masterKeyFlags, long masterKeyExpiry,
SaveKeyringParcel saveParcel, String passphrase,
OperationLog log) {
@@ -460,7 +468,7 @@ public class PgpKeyOperation {
masterPrivateKey = masterSecretKey.extractPrivateKey(keyDecryptor);
} catch (PGPException e) {
log.add(LogType.MSG_MF_UNLOCK_ERROR, indent + 1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
}
@@ -469,7 +477,7 @@ public class PgpKeyOperation {
// Check if we were cancelled
if (checkCancelled()) {
log.add(LogType.MSG_OPERATION_CANCELLED, indent);
- return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null);
}
{ // work on master secret key
@@ -477,7 +485,7 @@ public class PgpKeyOperation {
PGPPublicKey modifiedPublicKey = masterPublicKey;
// 2a. Add certificates for new user ids
- subProgressPush(15, 25);
+ subProgressPush(15, 23);
for (int i = 0; i < saveParcel.mAddUserIds.size(); i++) {
progress(R.string.progress_modify_adduid, (i - 1) * (100 / saveParcel.mAddUserIds.size()));
@@ -486,7 +494,7 @@ public class PgpKeyOperation {
if (userId.equals("")) {
log.add(LogType.MSG_MF_UID_ERROR_EMPTY, indent + 1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// this operation supersedes all previous binding and revocation certificates,
@@ -494,11 +502,11 @@ public class PgpKeyOperation {
@SuppressWarnings("unchecked")
Iterator<PGPSignature> it = modifiedPublicKey.getSignaturesForID(userId);
if (it != null) {
- for (PGPSignature cert : new IterableIterator<PGPSignature>(it)) {
+ for (PGPSignature cert : new IterableIterator<>(it)) {
if (cert.getKeyID() != masterPublicKey.getKeyID()) {
// foreign certificate?! error error error
log.add(LogType.MSG_MF_ERROR_INTEGRITY, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION
|| cert.getSignatureType() == PGPSignature.NO_CERTIFICATION
@@ -521,8 +529,37 @@ public class PgpKeyOperation {
}
subProgressPop();
- // 2b. Add revocations for revoked user ids
- subProgressPush(25, 40);
+ // 2b. Add certificates for new user ids
+ subProgressPush(23, 32);
+ for (int i = 0; i < saveParcel.mAddUserAttribute.size(); i++) {
+
+ progress(R.string.progress_modify_adduat, (i - 1) * (100 / saveParcel.mAddUserAttribute.size()));
+ WrappedUserAttribute attribute = saveParcel.mAddUserAttribute.get(i);
+
+ switch (attribute.getType()) {
+ // the 'none' type must not succeed
+ case WrappedUserAttribute.UAT_NONE:
+ log.add(LogType.MSG_MF_UAT_ERROR_EMPTY, indent);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
+ case WrappedUserAttribute.UAT_IMAGE:
+ log.add(LogType.MSG_MF_UAT_ADD_IMAGE, indent);
+ break;
+ default:
+ log.add(LogType.MSG_MF_UAT_ADD_UNKNOWN, indent);
+ break;
+ }
+
+ PGPUserAttributeSubpacketVector vector = attribute.getVector();
+
+ // generate and add new certificate
+ PGPSignature cert = generateUserAttributeSignature(masterPrivateKey,
+ masterPublicKey, vector);
+ modifiedPublicKey = PGPPublicKey.addCertification(modifiedPublicKey, vector, cert);
+ }
+ subProgressPop();
+
+ // 2c. Add revocations for revoked user ids
+ subProgressPush(32, 40);
for (int i = 0; i < saveParcel.mRevokeUserIds.size(); i++) {
progress(R.string.progress_modify_revokeuid, (i - 1) * (100 / saveParcel.mRevokeUserIds.size()));
@@ -540,7 +577,7 @@ public class PgpKeyOperation {
}
if (!exists) {
log.add(LogType.MSG_MF_ERROR_NOEXIST_REVOKE, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// a duplicate revocation will be removed during canonicalization, so no need to
@@ -571,7 +608,7 @@ public class PgpKeyOperation {
if (cert.getKeyID() != masterPublicKey.getKeyID()) {
// foreign certificate?! error error error
log.add(LogType.MSG_MF_ERROR_INTEGRITY, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// we know from canonicalization that if there is any revocation here, it
// is valid and not superseded by a newer certification.
@@ -592,7 +629,7 @@ public class PgpKeyOperation {
if (currentCert == null) {
// no certificate found?! error error error
log.add(LogType.MSG_MF_ERROR_INTEGRITY, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// we definitely should not update certifications of revoked keys, so just leave it.
@@ -600,7 +637,7 @@ public class PgpKeyOperation {
// revoked user ids cannot be primary!
if (userId.equals(saveParcel.mChangePrimaryUserId)) {
log.add(LogType.MSG_MF_ERROR_REVOKED_PRIMARY, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
continue;
}
@@ -649,7 +686,7 @@ public class PgpKeyOperation {
if (!ok) {
log.add(LogType.MSG_MF_ERROR_NOEXIST_PRIMARY, indent);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
}
@@ -665,7 +702,7 @@ public class PgpKeyOperation {
// Check if we were cancelled - again
if (checkCancelled()) {
log.add(LogType.MSG_OPERATION_CANCELLED, indent);
- return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null);
}
// 4a. For each subkey change, generate new subkey binding certificate
@@ -681,7 +718,28 @@ public class PgpKeyOperation {
if (sKey == null) {
log.add(LogType.MSG_MF_ERROR_SUBKEY_MISSING,
indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId));
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
+ }
+
+ if (change.mDummyStrip || change.mDummyDivert != null) {
+ // IT'S DANGEROUS~
+ // no really, it is. this operation irrevocably removes the private key data from the key
+ if (change.mDummyStrip) {
+ sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey());
+ } else {
+ // the serial number must be 16 bytes in length
+ if (change.mDummyDivert.length != 16) {
+ log.add(LogType.MSG_MF_ERROR_DIVERT_SERIAL,
+ indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId));
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
+ }
+ }
+ sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
+ }
+
+ // This doesn't concern us any further
+ if (!change.mRecertify && (change.mExpiry == null && change.mFlags == null)) {
+ continue;
}
// expiry must not be in the past
@@ -689,7 +747,7 @@ public class PgpKeyOperation {
new Date(change.mExpiry*1000).before(new Date())) {
log.add(LogType.MSG_MF_ERROR_PAST_EXPIRY,
indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId));
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// if this is the master key, update uid certificates instead
@@ -699,7 +757,7 @@ public class PgpKeyOperation {
if ((flags & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) {
log.add(LogType.MSG_MF_ERROR_NO_CERTIFY, indent + 1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
PGPPublicKey pKey =
@@ -707,7 +765,7 @@ public class PgpKeyOperation {
flags, expiry, indent, log);
if (pKey == null) {
// error log entry has already been added by updateMasterCertificates itself
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
masterSecretKey = PGPSecretKey.replacePublicKey(sKey, pKey);
masterPublicKey = pKey;
@@ -762,7 +820,7 @@ public class PgpKeyOperation {
if (sKey == null) {
log.add(LogType.MSG_MF_ERROR_SUBKEY_MISSING,
indent+1, KeyFormattingUtils.convertKeyIdToHex(revocation));
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
PGPPublicKey pKey = sKey.getPublicKey();
@@ -774,30 +832,6 @@ public class PgpKeyOperation {
}
subProgressPop();
- // 4c. For each subkey to be stripped... do so
- subProgressPush(65, 70);
- for (int i = 0; i < saveParcel.mStripSubKeys.size(); i++) {
-
- progress(R.string.progress_modify_subkeystrip, (i-1) * (100 / saveParcel.mStripSubKeys.size()));
- long strip = saveParcel.mStripSubKeys.get(i);
- log.add(LogType.MSG_MF_SUBKEY_STRIP,
- indent, KeyFormattingUtils.convertKeyIdToHex(strip));
-
- PGPSecretKey sKey = sKR.getSecretKey(strip);
- if (sKey == null) {
- log.add(LogType.MSG_MF_ERROR_SUBKEY_MISSING,
- indent+1, KeyFormattingUtils.convertKeyIdToHex(strip));
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
- }
-
- // IT'S DANGEROUS~
- // no really, it is. this operation irrevocably removes the private key data from the key
- sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey());
- sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
-
- }
- subProgressPop();
-
// 5. Generate and add new subkeys
subProgressPush(70, 90);
for (int i = 0; i < saveParcel.mAddSubKeys.size(); i++) {
@@ -805,7 +839,7 @@ public class PgpKeyOperation {
// Check if we were cancelled - again. This operation is expensive so we do it each loop.
if (checkCancelled()) {
log.add(LogType.MSG_OPERATION_CANCELLED, indent);
- return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null);
}
progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size()));
@@ -815,12 +849,12 @@ public class PgpKeyOperation {
if (add.mExpiry == null) {
log.add(LogType.MSG_MF_ERROR_NULL_EXPIRY, indent +1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (add.mExpiry > 0L && new Date(add.mExpiry*1000).before(new Date())) {
log.add(LogType.MSG_MF_ERROR_PAST_EXPIRY, indent +1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// generate a new secret key (privkey only for now)
@@ -832,7 +866,7 @@ public class PgpKeyOperation {
subProgressPop();
if (keyPair == null) {
log.add(LogType.MSG_MF_ERROR_PGP, indent +1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// add subkey binding signature (making this a sub rather than master key)
@@ -867,67 +901,20 @@ public class PgpKeyOperation {
// Check if we were cancelled - again. This operation is expensive so we do it each loop.
if (checkCancelled()) {
log.add(LogType.MSG_OPERATION_CANCELLED, indent);
- return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null);
}
// 6. If requested, change passphrase
- if (saveParcel.mNewPassphrase != null) {
+ if (saveParcel.mNewUnlock != null) {
progress(R.string.progress_modify_passphrase, 90);
log.add(LogType.MSG_MF_PASSPHRASE, indent);
indent += 1;
- PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder().build()
- .get(SECRET_KEY_ENCRYPTOR_HASH_ALGO);
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
- // Build key encryptor based on new passphrase
- PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder(
- SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, SECRET_KEY_ENCRYPTOR_S2K_COUNT)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- saveParcel.mNewPassphrase.toCharArray());
-
- // noinspection unchecked
- for (PGPSecretKey sKey : new IterableIterator<PGPSecretKey>(sKR.getSecretKeys())) {
- log.add(LogType.MSG_MF_PASSPHRASE_KEY, indent,
- KeyFormattingUtils.convertKeyIdToHex(sKey.getKeyID()));
-
- boolean ok = false;
-
- try {
- // try to set new passphrase
- sKey = PGPSecretKey.copyWithNewPassword(sKey, keyDecryptor, keyEncryptorNew);
- ok = true;
- } catch (PGPException e) {
-
- // if this is the master key, error!
- if (sKey.getKeyID() == masterPublicKey.getKeyID()) {
- log.add(LogType.MSG_MF_ERROR_PASSPHRASE_MASTER, indent+1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
- }
-
- // being in here means decrypt failed, likely due to a bad passphrase try
- // again with an empty passphrase, maybe we can salvage this
- try {
- log.add(LogType.MSG_MF_PASSPHRASE_EMPTY_RETRY, indent+1);
- PBESecretKeyDecryptor emptyDecryptor =
- new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());
- sKey = PGPSecretKey.copyWithNewPassword(sKey, emptyDecryptor, keyEncryptorNew);
- ok = true;
- } catch (PGPException e2) {
- // non-fatal but not ok, handled below
- }
- }
-
- if (!ok) {
- // for a subkey, it's merely a warning
- log.add(LogType.MSG_MF_PASSPHRASE_FAIL, indent+1,
- KeyFormattingUtils.convertKeyIdToHex(sKey.getKeyID()));
- continue;
- }
-
- sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
-
+ sKR = applyNewUnlock(sKR, masterPublicKey, masterPrivateKey,
+ passphrase, saveParcel.mNewUnlock, log, indent);
+ if (sKR == null) {
+ // The error has been logged above, just return a bad state
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
indent -= 1;
@@ -936,20 +923,235 @@ public class PgpKeyOperation {
} catch (IOException e) {
Log.e(Constants.TAG, "encountered IOException while modifying key", e);
log.add(LogType.MSG_MF_ERROR_ENCODE, indent+1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
} catch (PGPException e) {
Log.e(Constants.TAG, "encountered pgp error while modifying key", e);
log.add(LogType.MSG_MF_ERROR_PGP, indent+1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
} catch (SignatureException e) {
Log.e(Constants.TAG, "encountered SignatureException while modifying key", e);
log.add(LogType.MSG_MF_ERROR_SIG, indent+1);
- return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
progress(R.string.progress_done, 100);
log.add(LogType.MSG_MF_SUCCESS, indent);
- return new EditKeyResult(OperationResult.RESULT_OK, log, new UncachedKeyRing(sKR));
+ return new PgpEditKeyResult(OperationResult.RESULT_OK, log, new UncachedKeyRing(sKR));
+
+ }
+
+ /** This method does the actual modifications in a keyring just like internal, except it
+ * supports only the subset of operations which require no passphrase, and will error
+ * otherwise.
+ */
+ private PgpEditKeyResult internalRestricted(PGPSecretKeyRing sKR, SaveKeyringParcel saveParcel,
+ OperationLog log) {
+
+ int indent = 1;
+
+ progress(R.string.progress_modify, 0);
+
+ // Make sure the saveParcel includes only operations available without passphrae!
+ if (!saveParcel.isRestrictedOnly()) {
+ log.add(LogType.MSG_MF_ERROR_RESTRICTED, indent);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
+ }
+
+ // Check if we were cancelled
+ if (checkCancelled()) {
+ log.add(LogType.MSG_OPERATION_CANCELLED, indent);
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null);
+ }
+
+ // The only operation we can do here:
+ // 4a. Strip secret keys, or change their protection mode (stripped/divert-to-card)
+ subProgressPush(50, 60);
+ for (int i = 0; i < saveParcel.mChangeSubKeys.size(); i++) {
+
+ progress(R.string.progress_modify_subkeychange, (i - 1) * (100 / saveParcel.mChangeSubKeys.size()));
+ SaveKeyringParcel.SubkeyChange change = saveParcel.mChangeSubKeys.get(i);
+ log.add(LogType.MSG_MF_SUBKEY_CHANGE,
+ indent, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId));
+
+ PGPSecretKey sKey = sKR.getSecretKey(change.mKeyId);
+ if (sKey == null) {
+ log.add(LogType.MSG_MF_ERROR_SUBKEY_MISSING,
+ indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId));
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
+ }
+
+ if (change.mDummyStrip || change.mDummyDivert != null) {
+ // IT'S DANGEROUS~
+ // no really, it is. this operation irrevocably removes the private key data from the key
+ if (change.mDummyStrip) {
+ sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey());
+ } else {
+ // the serial number must be 16 bytes in length
+ if (change.mDummyDivert.length != 16) {
+ log.add(LogType.MSG_MF_ERROR_DIVERT_SERIAL,
+ indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId));
+ return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
+ }
+ sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey(), change.mDummyDivert);
+ }
+ sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
+ }
+
+ }
+
+ // And we're done!
+ progress(R.string.progress_done, 100);
+ log.add(LogType.MSG_MF_SUCCESS, indent);
+ return new PgpEditKeyResult(OperationResult.RESULT_OK, log, new UncachedKeyRing(sKR));
+
+ }
+
+
+ private static PGPSecretKeyRing applyNewUnlock(
+ PGPSecretKeyRing sKR,
+ PGPPublicKey masterPublicKey,
+ PGPPrivateKey masterPrivateKey,
+ String passphrase,
+ ChangeUnlockParcel newUnlock,
+ OperationLog log, int indent) throws PGPException {
+
+ if (newUnlock.mNewPassphrase != null) {
+ sKR = applyNewPassphrase(sKR, masterPublicKey, passphrase, newUnlock.mNewPassphrase, log, indent);
+
+ // if there is any old packet with notation data
+ if (hasNotationData(sKR)) {
+
+ log.add(LogType.MSG_MF_NOTATION_EMPTY, indent);
+
+ // add packet with EMPTY notation data (updates old one, but will be stripped later)
+ PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
+ { // set subpackets
+ PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
+ hashedPacketsGen.setExportable(false, false);
+ sGen.setHashedSubpackets(hashedPacketsGen.generate());
+ }
+ sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey);
+ PGPSignature emptySig = sGen.generateCertification(masterPublicKey);
+
+ masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, emptySig);
+ sKR = PGPSecretKeyRing.insertSecretKey(sKR,
+ PGPSecretKey.replacePublicKey(sKR.getSecretKey(), masterPublicKey));
+ }
+
+ return sKR;
+ }
+
+ if (newUnlock.mNewPin != null) {
+ sKR = applyNewPassphrase(sKR, masterPublicKey, passphrase, newUnlock.mNewPin, log, indent);
+
+ log.add(LogType.MSG_MF_NOTATION_PIN, indent);
+
+ // add packet with "pin" notation data
+ PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
+ { // set subpackets
+ PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
+ hashedPacketsGen.setExportable(false, false);
+ hashedPacketsGen.setNotationData(false, true, "unlock.pin@sufficientlysecure.org", "1");
+ sGen.setHashedSubpackets(hashedPacketsGen.generate());
+ }
+ sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey);
+ PGPSignature emptySig = sGen.generateCertification(masterPublicKey);
+
+ masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, emptySig);
+ sKR = PGPSecretKeyRing.insertSecretKey(sKR,
+ PGPSecretKey.replacePublicKey(sKR.getSecretKey(), masterPublicKey));
+
+ return sKR;
+ }
+
+ throw new UnsupportedOperationException("PIN passphrases not yet implemented!");
+
+ }
+
+ /** This method returns true iff the provided keyring has a local direct key signature
+ * with notation data.
+ */
+ private static boolean hasNotationData(PGPSecretKeyRing sKR) {
+ // noinspection unchecked
+ Iterator<PGPSignature> sigs = sKR.getPublicKey().getKeySignatures();
+ while (sigs.hasNext()) {
+ WrappedSignature sig = new WrappedSignature(sigs.next());
+ if (sig.getSignatureType() == PGPSignature.DIRECT_KEY
+ && sig.isLocal() && !sig.getNotation().isEmpty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static PGPSecretKeyRing applyNewPassphrase(
+ PGPSecretKeyRing sKR,
+ PGPPublicKey masterPublicKey,
+ String passphrase,
+ String newPassphrase,
+ OperationLog log, int indent) throws PGPException {
+
+ PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder().build()
+ .get(SECRET_KEY_ENCRYPTOR_HASH_ALGO);
+ PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
+ // Build key encryptor based on new passphrase
+ PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder(
+ SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc, SECRET_KEY_ENCRYPTOR_S2K_COUNT)
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
+ newPassphrase.toCharArray());
+
+ // noinspection unchecked
+ for (PGPSecretKey sKey : new IterableIterator<PGPSecretKey>(sKR.getSecretKeys())) {
+ log.add(LogType.MSG_MF_PASSPHRASE_KEY, indent,
+ KeyFormattingUtils.convertKeyIdToHex(sKey.getKeyID()));
+
+ boolean ok = false;
+
+ try {
+ // try to set new passphrase
+ sKey = PGPSecretKey.copyWithNewPassword(sKey, keyDecryptor, keyEncryptorNew);
+ ok = true;
+ } catch (PGPException e) {
+
+ // if this is the master key, error!
+ if (sKey.getKeyID() == masterPublicKey.getKeyID()) {
+ log.add(LogType.MSG_MF_ERROR_PASSPHRASE_MASTER, indent+1);
+ return null;
+ }
+
+ // being in here means decrypt failed, likely due to a bad passphrase try
+ // again with an empty passphrase, maybe we can salvage this
+ try {
+ log.add(LogType.MSG_MF_PASSPHRASE_EMPTY_RETRY, indent+1);
+ PBESecretKeyDecryptor emptyDecryptor =
+ new JcePBESecretKeyDecryptorBuilder().setProvider(
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());
+ sKey = PGPSecretKey.copyWithNewPassword(sKey, emptyDecryptor, keyEncryptorNew);
+ ok = true;
+ } catch (PGPException e2) {
+ // non-fatal but not ok, handled below
+ }
+ }
+
+ if (!ok) {
+ // for a subkey, it's merely a warning
+ log.add(LogType.MSG_MF_PASSPHRASE_FAIL, indent+1,
+ KeyFormattingUtils.convertKeyIdToHex(sKey.getKeyID()));
+ continue;
+ }
+
+ sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
+
+ }
+
+ return sKR;
}
@@ -1072,6 +1274,26 @@ public class PgpKeyOperation {
return sGen.generateCertification(userId, pKey);
}
+ private static PGPSignature generateUserAttributeSignature(
+ PGPPrivateKey masterPrivateKey, PGPPublicKey pKey,
+ PGPUserAttributeSubpacketVector vector)
+ throws IOException, PGPException, SignatureException {
+ PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
+ masterPrivateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512)
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
+
+ PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
+ {
+ /* critical subpackets: we consider those important for a modern pgp implementation */
+ hashedPacketsGen.setSignatureCreationTime(true, new Date());
+ }
+
+ sGen.setHashedSubpackets(hashedPacketsGen.generate());
+ sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
+ return sGen.generateCertification(vector, pKey);
+ }
+
private static PGPSignature generateRevocationSignature(
PGPPrivateKey masterPrivateKey, PGPPublicKey pKey, String userId)
throws IOException, PGPException, SignatureException {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java
deleted file mode 100644
index f89027a19..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
- * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import android.content.Context;
-
-import org.spongycastle.bcpg.ArmoredOutputStream;
-import org.spongycastle.bcpg.BCPGOutputStream;
-import org.spongycastle.bcpg.CompressionAlgorithmTags;
-import org.spongycastle.openpgp.PGPCompressedDataGenerator;
-import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPLiteralData;
-import org.spongycastle.openpgp.PGPLiteralDataGenerator;
-import org.spongycastle.openpgp.PGPSignatureGenerator;
-import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator;
-import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
-import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder;
-import org.spongycastle.util.encoders.Hex;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.operations.BaseOperation;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
-import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.util.InputData;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.ProgressScaler;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.security.SignatureException;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.LinkedList;
-
-/**
- * This class uses a Builder pattern!
- */
-public class PgpSignEncrypt extends BaseOperation {
- private String mVersionHeader;
- private InputData mData;
- private OutputStream mOutStream;
-
- private boolean mEnableAsciiArmorOutput;
- private int mCompressionId;
- private long[] mEncryptionMasterKeyIds;
- private String mSymmetricPassphrase;
- private int mSymmetricEncryptionAlgorithm;
- private long mSignatureMasterKeyId;
- private Long mSignatureSubKeyId;
- private int mSignatureHashAlgorithm;
- private String mSignaturePassphrase;
- private long mAdditionalEncryptId;
- private boolean mCleartextInput;
- private String mOriginalFilename;
- private boolean mFailOnMissingEncryptionKeyIds;
-
- private byte[] mNfcSignedHash = null;
- private Date mNfcCreationTimestamp = null;
-
- private static byte[] NEW_LINE;
-
- static {
- try {
- NEW_LINE = "\r\n".getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- Log.e(Constants.TAG, "UnsupportedEncodingException", e);
- }
- }
-
- private PgpSignEncrypt(Builder builder) {
- super(builder.mContext, builder.mProviderHelper, builder.mProgressable);
-
- // private Constructor can only be called from Builder
- this.mVersionHeader = builder.mVersionHeader;
- this.mData = builder.mData;
- this.mOutStream = builder.mOutStream;
-
- this.mEnableAsciiArmorOutput = builder.mEnableAsciiArmorOutput;
- this.mCompressionId = builder.mCompressionId;
- this.mEncryptionMasterKeyIds = builder.mEncryptionMasterKeyIds;
- this.mSymmetricPassphrase = builder.mSymmetricPassphrase;
- this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm;
- this.mSignatureMasterKeyId = builder.mSignatureMasterKeyId;
- this.mSignatureSubKeyId = builder.mSignatureSubKeyId;
- this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm;
- this.mSignaturePassphrase = builder.mSignaturePassphrase;
- this.mAdditionalEncryptId = builder.mAdditionalEncryptId;
- this.mCleartextInput = builder.mCleartextInput;
- this.mNfcSignedHash = builder.mNfcSignedHash;
- this.mNfcCreationTimestamp = builder.mNfcCreationTimestamp;
- this.mOriginalFilename = builder.mOriginalFilename;
- this.mFailOnMissingEncryptionKeyIds = builder.mFailOnMissingEncryptionKeyIds;
- }
-
- public static class Builder {
- // mandatory parameter
- private Context mContext;
- private ProviderHelper mProviderHelper;
- private Progressable mProgressable;
- private InputData mData;
- private OutputStream mOutStream;
-
- // optional
- private String mVersionHeader = null;
- private boolean mEnableAsciiArmorOutput = false;
- private int mCompressionId = CompressionAlgorithmTags.UNCOMPRESSED;
- private long[] mEncryptionMasterKeyIds = null;
- private String mSymmetricPassphrase = null;
- private int mSymmetricEncryptionAlgorithm = 0;
- private long mSignatureMasterKeyId = Constants.key.none;
- private Long mSignatureSubKeyId = null;
- private int mSignatureHashAlgorithm = 0;
- private String mSignaturePassphrase = null;
- private long mAdditionalEncryptId = Constants.key.none;
- private boolean mCleartextInput = false;
- private String mOriginalFilename = "";
- private byte[] mNfcSignedHash = null;
- private Date mNfcCreationTimestamp = null;
- private boolean mFailOnMissingEncryptionKeyIds = false;
-
- public Builder(Context context, ProviderHelper providerHelper, Progressable progressable,
- InputData data, OutputStream outStream) {
- mContext = context;
- mProviderHelper = providerHelper;
- mProgressable = progressable;
-
- mData = data;
- mOutStream = outStream;
- }
-
- public Builder setVersionHeader(String versionHeader) {
- mVersionHeader = versionHeader;
- return this;
- }
-
- public Builder setEnableAsciiArmorOutput(boolean enableAsciiArmorOutput) {
- mEnableAsciiArmorOutput = enableAsciiArmorOutput;
- return this;
- }
-
- public Builder setCompressionId(int compressionId) {
- mCompressionId = compressionId;
- return this;
- }
-
- public Builder setEncryptionMasterKeyIds(long[] encryptionMasterKeyIds) {
- mEncryptionMasterKeyIds = encryptionMasterKeyIds;
- return this;
- }
-
- public Builder setSymmetricPassphrase(String symmetricPassphrase) {
- mSymmetricPassphrase = symmetricPassphrase;
- return this;
- }
-
- public Builder setSymmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) {
- mSymmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm;
- return this;
- }
-
- public Builder setSignatureMasterKeyId(long signatureMasterKeyId) {
- mSignatureMasterKeyId = signatureMasterKeyId;
- return this;
- }
-
- public Builder setSignatureSubKeyId(long signatureSubKeyId) {
- mSignatureSubKeyId = signatureSubKeyId;
- return this;
- }
-
- public Builder setSignatureHashAlgorithm(int signatureHashAlgorithm) {
- mSignatureHashAlgorithm = signatureHashAlgorithm;
- return this;
- }
-
- public Builder setSignaturePassphrase(String signaturePassphrase) {
- mSignaturePassphrase = signaturePassphrase;
- return this;
- }
-
- public Builder setFailOnMissingEncryptionKeyIds(boolean failOnMissingEncryptionKeyIds) {
- mFailOnMissingEncryptionKeyIds = failOnMissingEncryptionKeyIds;
- return this;
- }
-
- /**
- * Also encrypt with the signing keyring
- *
- * @param additionalEncryptId
- * @return
- */
- public Builder setAdditionalEncryptId(long additionalEncryptId) {
- mAdditionalEncryptId = additionalEncryptId;
- return this;
- }
-
- /**
- * TODO: test this option!
- *
- * @param cleartextInput
- * @return
- */
- public Builder setCleartextInput(boolean cleartextInput) {
- mCleartextInput = cleartextInput;
- return this;
- }
-
- public Builder setOriginalFilename(String originalFilename) {
- mOriginalFilename = originalFilename;
- return this;
- }
-
- public Builder setNfcState(byte[] signedHash, Date creationTimestamp) {
- mNfcSignedHash = signedHash;
- mNfcCreationTimestamp = creationTimestamp;
- return this;
- }
-
- public PgpSignEncrypt build() {
- return new PgpSignEncrypt(this);
- }
- }
-
- /**
- * Signs and/or encrypts data based on parameters of class
- */
- public SignEncryptResult execute() {
-
- int indent = 0;
- OperationLog log = new OperationLog();
-
- log.add(LogType.MSG_SE, indent);
- indent += 1;
-
- boolean enableSignature = mSignatureMasterKeyId != Constants.key.none;
- boolean enableEncryption = ((mEncryptionMasterKeyIds != null && mEncryptionMasterKeyIds.length > 0)
- || mSymmetricPassphrase != null);
- boolean enableCompression = (mCompressionId != CompressionAlgorithmTags.UNCOMPRESSED);
-
- Log.d(Constants.TAG, "enableSignature:" + enableSignature
- + "\nenableEncryption:" + enableEncryption
- + "\nenableCompression:" + enableCompression
- + "\nenableAsciiArmorOutput:" + mEnableAsciiArmorOutput);
-
- // add additional key id to encryption ids (mostly to do self-encryption)
- if (enableEncryption && mAdditionalEncryptId != Constants.key.none) {
- mEncryptionMasterKeyIds = Arrays.copyOf(mEncryptionMasterKeyIds, mEncryptionMasterKeyIds.length + 1);
- mEncryptionMasterKeyIds[mEncryptionMasterKeyIds.length - 1] = mAdditionalEncryptId;
- }
-
- ArmoredOutputStream armorOut = null;
- OutputStream out;
- if (mEnableAsciiArmorOutput) {
- armorOut = new ArmoredOutputStream(mOutStream);
- if (mVersionHeader != null) {
- armorOut.setHeader("Version", mVersionHeader);
- }
- out = armorOut;
- } else {
- out = mOutStream;
- }
-
- /* Get keys for signature generation for later usage */
- CanonicalizedSecretKey signingKey = null;
- long signKeyId;
- if (enableSignature) {
-
- try {
- // fetch the indicated master key id (the one whose name we sign in)
- CanonicalizedSecretKeyRing signingKeyRing =
- mProviderHelper.getCanonicalizedSecretKeyRing(mSignatureMasterKeyId);
- // fetch the specific subkey to sign with, or just use the master key if none specified
- signKeyId = mSignatureSubKeyId != null ? mSignatureSubKeyId : mSignatureMasterKeyId;
- signingKey = signingKeyRing.getSecretKey(signKeyId);
- // make sure it's a signing key alright!
- } catch (ProviderHelper.NotFoundException e) {
- log.add(LogType.MSG_SE_ERROR_SIGN_KEY, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
-
- // Make sure we are allowed to sign here!
- if (!signingKey.canSign()) {
- log.add(LogType.MSG_SE_ERROR_KEY_SIGN, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
-
- // if no passphrase was explicitly set try to get it from the cache service
- if (mSignaturePassphrase == null) {
- try {
- // returns "" if key has no passphrase
- mSignaturePassphrase = getCachedPassphrase(signKeyId);
- // TODO
-// log.add(LogType.MSG_DC_PASS_CACHED, indent + 1);
- } catch (PassphraseCacheInterface.NoSecretKeyException e) {
- // TODO
-// log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
-
- // if passphrase was not cached, return here indicating that a passphrase is missing!
- if (mSignaturePassphrase == null) {
- log.add(LogType.MSG_SE_PENDING_PASSPHRASE, indent + 1);
- SignEncryptResult result = new SignEncryptResult(SignEncryptResult.RESULT_PENDING_PASSPHRASE, log);
- result.setKeyIdPassphraseNeeded(signKeyId);
- return result;
- }
- }
-
- updateProgress(R.string.progress_extracting_signature_key, 0, 100);
-
- try {
- if (!signingKey.unlock(mSignaturePassphrase)) {
- log.add(LogType.MSG_SE_ERROR_BAD_PASSPHRASE, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
- } catch (PgpGeneralException e) {
- log.add(LogType.MSG_SE_ERROR_UNLOCK, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
-
- // check if hash algo is supported
- LinkedList<Integer> supported = signingKey.getSupportedHashAlgorithms();
- if (!supported.contains(mSignatureHashAlgorithm)) {
- // get most preferred
- mSignatureHashAlgorithm = supported.getLast();
- }
- }
- updateProgress(R.string.progress_preparing_streams, 2, 100);
-
- /* Initialize PGPEncryptedDataGenerator for later usage */
- PGPEncryptedDataGenerator cPk = null;
- if (enableEncryption) {
- // has Integrity packet enabled!
- JcePGPDataEncryptorBuilder encryptorBuilder =
- new JcePGPDataEncryptorBuilder(mSymmetricEncryptionAlgorithm)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME)
- .setWithIntegrityPacket(true);
-
- cPk = new PGPEncryptedDataGenerator(encryptorBuilder);
-
- if (mSymmetricPassphrase != null) {
- // Symmetric encryption
- log.add(LogType.MSG_SE_SYMMETRIC, indent);
-
- JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator =
- new JcePBEKeyEncryptionMethodGenerator(mSymmetricPassphrase.toCharArray());
- cPk.addMethod(symmetricEncryptionGenerator);
- } else {
- log.add(LogType.MSG_SE_ASYMMETRIC, indent);
-
- // Asymmetric encryption
- for (long id : mEncryptionMasterKeyIds) {
- try {
- CanonicalizedPublicKeyRing keyRing = mProviderHelper.getCanonicalizedPublicKeyRing(
- KeyRings.buildUnifiedKeyRingUri(id));
- CanonicalizedPublicKey key = keyRing.getEncryptionSubKey();
- cPk.addMethod(key.getPubKeyEncryptionGenerator());
- log.add(LogType.MSG_SE_KEY_OK, indent + 1,
- KeyFormattingUtils.convertKeyIdToHex(id));
- } catch (PgpKeyNotFoundException e) {
- log.add(LogType.MSG_SE_KEY_WARN, indent + 1,
- KeyFormattingUtils.convertKeyIdToHex(id));
- if (mFailOnMissingEncryptionKeyIds) {
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
- } catch (ProviderHelper.NotFoundException e) {
- log.add(LogType.MSG_SE_KEY_UNKNOWN, indent + 1,
- KeyFormattingUtils.convertKeyIdToHex(id));
- if (mFailOnMissingEncryptionKeyIds) {
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
- }
- }
- }
- }
-
- /* Initialize signature generator object for later usage */
- PGPSignatureGenerator signatureGenerator = null;
- if (enableSignature) {
- updateProgress(R.string.progress_preparing_signature, 4, 100);
-
- try {
- boolean cleartext = mCleartextInput && mEnableAsciiArmorOutput && !enableEncryption;
- signatureGenerator = signingKey.getSignatureGenerator(
- mSignatureHashAlgorithm, cleartext, mNfcSignedHash, mNfcCreationTimestamp);
- } catch (PgpGeneralException e) {
- log.add(LogType.MSG_SE_ERROR_NFC, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
- }
-
- ProgressScaler progressScaler =
- new ProgressScaler(mProgressable, 8, 95, 100);
- PGPCompressedDataGenerator compressGen = null;
- OutputStream pOut;
- OutputStream encryptionOut = null;
- BCPGOutputStream bcpgOut;
-
- try {
-
- if (enableEncryption) {
- /* actual encryption */
- updateProgress(R.string.progress_encrypting, 8, 100);
- log.add(enableSignature
- ? LogType.MSG_SE_SIGCRYPTING
- : LogType.MSG_SE_ENCRYPTING,
- indent
- );
- indent += 1;
-
- encryptionOut = cPk.open(out, new byte[1 << 16]);
-
- if (enableCompression) {
- log.add(LogType.MSG_SE_COMPRESSING, indent);
- compressGen = new PGPCompressedDataGenerator(mCompressionId);
- bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
- } else {
- bcpgOut = new BCPGOutputStream(encryptionOut);
- }
-
- if (enableSignature) {
- signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
- }
-
- PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
- char literalDataFormatTag;
- if (mCleartextInput) {
- literalDataFormatTag = PGPLiteralData.UTF8;
- } else {
- literalDataFormatTag = PGPLiteralData.BINARY;
- }
- pOut = literalGen.open(bcpgOut, literalDataFormatTag, mOriginalFilename, new Date(),
- new byte[1 << 16]);
-
- long alreadyWritten = 0;
- int length;
- byte[] buffer = new byte[1 << 16];
- InputStream in = mData.getInputStream();
- while ((length = in.read(buffer)) > 0) {
- pOut.write(buffer, 0, length);
-
- // update signature buffer if signature is requested
- if (enableSignature) {
- signatureGenerator.update(buffer, 0, length);
- }
-
- alreadyWritten += length;
- if (mData.getSize() > 0) {
- long progress = 100 * alreadyWritten / mData.getSize();
- progressScaler.setProgress((int) progress, 100);
- }
- }
-
- literalGen.close();
- indent -= 1;
-
- } else if (enableSignature && mCleartextInput && mEnableAsciiArmorOutput) {
- /* cleartext signature: sign-only of ascii text */
-
- updateProgress(R.string.progress_signing, 8, 100);
- log.add(LogType.MSG_SE_SIGNING, indent);
-
- // write -----BEGIN PGP SIGNED MESSAGE-----
- armorOut.beginClearText(mSignatureHashAlgorithm);
-
- InputStream in = mData.getInputStream();
- final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-
- // update signature buffer with first line
- processLine(reader.readLine(), armorOut, signatureGenerator);
-
- // TODO: progress: fake annealing?
- while (true) {
- String line = reader.readLine();
-
- // end cleartext signature with newline, see http://tools.ietf.org/html/rfc4880#section-7
- if (line == null) {
- armorOut.write(NEW_LINE);
- break;
- }
-
- armorOut.write(NEW_LINE);
-
- // update signature buffer with input line
- signatureGenerator.update(NEW_LINE);
- processLine(line, armorOut, signatureGenerator);
- }
-
- armorOut.endClearText();
-
- pOut = new BCPGOutputStream(armorOut);
- } else if (enableSignature && !mCleartextInput) {
- /* sign-only binary (files/data stream) */
-
- updateProgress(R.string.progress_signing, 8, 100);
- log.add(LogType.MSG_SE_ENCRYPTING, indent);
-
- InputStream in = mData.getInputStream();
-
- if (enableCompression) {
- compressGen = new PGPCompressedDataGenerator(mCompressionId);
- bcpgOut = new BCPGOutputStream(compressGen.open(out));
- } else {
- bcpgOut = new BCPGOutputStream(out);
- }
-
- signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
-
- PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
- pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, mOriginalFilename, new Date(),
- new byte[1 << 16]);
-
- long alreadyWritten = 0;
- int length;
- byte[] buffer = new byte[1 << 16];
- while ((length = in.read(buffer)) > 0) {
- pOut.write(buffer, 0, length);
-
- signatureGenerator.update(buffer, 0, length);
-
- alreadyWritten += length;
- if (mData.getSize() > 0) {
- long progress = 100 * alreadyWritten / mData.getSize();
- progressScaler.setProgress((int) progress, 100);
- }
- }
-
- literalGen.close();
- } else {
- pOut = null;
- log.add(LogType.MSG_SE_CLEARSIGN_ONLY, indent);
- }
-
- if (enableSignature) {
- updateProgress(R.string.progress_generating_signature, 95, 100);
- try {
- signatureGenerator.generate().encode(pOut);
- } catch (NfcSyncPGPContentSignerBuilder.NfcInteractionNeeded e) {
- // this secret key diverts to a OpenPGP card, throw exception with hash that will be signed
- log.add(LogType.MSG_SE_PENDING_NFC, indent);
- SignEncryptResult result =
- new SignEncryptResult(SignEncryptResult.RESULT_PENDING_NFC, log);
- // Note that the checked key here is the master key, not the signing key
- // (although these are always the same on Yubikeys)
- result.setNfcData(mSignatureSubKeyId, e.hashToSign, e.hashAlgo, e.creationTimestamp, mSignaturePassphrase);
- Log.d(Constants.TAG, "e.hashToSign"+ Hex.toHexString(e.hashToSign));
- return result;
- }
- }
-
- // closing outputs
- // NOTE: closing needs to be done in the correct order!
- // TODO: closing bcpgOut and pOut???
- if (enableEncryption) {
- if (enableCompression) {
- compressGen.close();
- }
-
- encryptionOut.close();
- }
- if (mEnableAsciiArmorOutput) {
- armorOut.close();
- }
-
- out.close();
- mOutStream.close();
-
- } catch (SignatureException e) {
- log.add(LogType.MSG_SE_ERROR_SIG, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- } catch (PGPException e) {
- log.add(LogType.MSG_SE_ERROR_PGP, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- } catch (IOException e) {
- log.add(LogType.MSG_SE_ERROR_IO, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
- }
-
- updateProgress(R.string.progress_done, 100, 100);
-
- log.add(LogType.MSG_SE_OK, indent);
- return new SignEncryptResult(SignEncryptResult.RESULT_OK, log);
-
- }
-
- private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
- final PGPSignatureGenerator pSignatureGenerator)
- throws IOException, SignatureException {
-
- if (pLine == null) {
- return;
- }
-
- final char[] chars = pLine.toCharArray();
- int len = chars.length;
-
- while (len > 0) {
- if (!Character.isWhitespace(chars[len - 1])) {
- break;
- }
- len--;
- }
-
- final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
-
- if (pArmoredOutput != null) {
- pArmoredOutput.write(data);
- }
- pSignatureGenerator.update(data);
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java
new file mode 100644
index 000000000..9318be006
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java
@@ -0,0 +1,176 @@
+package org.sufficientlysecure.keychain.pgp;
+
+import org.spongycastle.bcpg.CompressionAlgorithmTags;
+import org.sufficientlysecure.keychain.Constants;
+
+import java.util.Date;
+
+public class PgpSignEncryptInput {
+
+ protected String mVersionHeader = null;
+ protected boolean mEnableAsciiArmorOutput = false;
+ protected int mCompressionId = CompressionAlgorithmTags.UNCOMPRESSED;
+ protected long[] mEncryptionMasterKeyIds = null;
+ protected String mSymmetricPassphrase = null;
+ protected int mSymmetricEncryptionAlgorithm = 0;
+ protected long mSignatureMasterKeyId = Constants.key.none;
+ protected Long mSignatureSubKeyId = null;
+ protected int mSignatureHashAlgorithm = 0;
+ protected String mSignaturePassphrase = null;
+ protected long mAdditionalEncryptId = Constants.key.none;
+ protected byte[] mNfcSignedHash = null;
+ protected Date mNfcCreationTimestamp = null;
+ protected boolean mFailOnMissingEncryptionKeyIds = false;
+ protected String mCharset;
+ protected boolean mCleartextSignature;
+ protected boolean mDetachedSignature;
+
+ public String getCharset() {
+ return mCharset;
+ }
+
+ public void setCharset(String mCharset) {
+ this.mCharset = mCharset;
+ }
+
+ public boolean ismFailOnMissingEncryptionKeyIds() {
+ return mFailOnMissingEncryptionKeyIds;
+ }
+
+ public Date getNfcCreationTimestamp() {
+ return mNfcCreationTimestamp;
+ }
+
+ public byte[] getNfcSignedHash() {
+ return mNfcSignedHash;
+ }
+
+ public long getAdditionalEncryptId() {
+ return mAdditionalEncryptId;
+ }
+
+ public PgpSignEncryptInput setAdditionalEncryptId(long additionalEncryptId) {
+ mAdditionalEncryptId = additionalEncryptId;
+ return this;
+ }
+
+ public String getSignaturePassphrase() {
+ return mSignaturePassphrase;
+ }
+
+ public PgpSignEncryptInput setSignaturePassphrase(String signaturePassphrase) {
+ mSignaturePassphrase = signaturePassphrase;
+ return this;
+ }
+
+ public int getSignatureHashAlgorithm() {
+ return mSignatureHashAlgorithm;
+ }
+
+ public PgpSignEncryptInput setSignatureHashAlgorithm(int signatureHashAlgorithm) {
+ mSignatureHashAlgorithm = signatureHashAlgorithm;
+ return this;
+ }
+
+ public Long getSignatureSubKeyId() {
+ return mSignatureSubKeyId;
+ }
+
+ public PgpSignEncryptInput setSignatureSubKeyId(long signatureSubKeyId) {
+ mSignatureSubKeyId = signatureSubKeyId;
+ return this;
+ }
+
+ public long getSignatureMasterKeyId() {
+ return mSignatureMasterKeyId;
+ }
+
+ public PgpSignEncryptInput setSignatureMasterKeyId(long signatureMasterKeyId) {
+ mSignatureMasterKeyId = signatureMasterKeyId;
+ return this;
+ }
+
+ public int getSymmetricEncryptionAlgorithm() {
+ return mSymmetricEncryptionAlgorithm;
+ }
+
+ public PgpSignEncryptInput setSymmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) {
+ mSymmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm;
+ return this;
+ }
+
+ public String getSymmetricPassphrase() {
+ return mSymmetricPassphrase;
+ }
+
+ public PgpSignEncryptInput setSymmetricPassphrase(String symmetricPassphrase) {
+ mSymmetricPassphrase = symmetricPassphrase;
+ return this;
+ }
+
+ public long[] getEncryptionMasterKeyIds() {
+ return mEncryptionMasterKeyIds;
+ }
+
+ public PgpSignEncryptInput setEncryptionMasterKeyIds(long[] encryptionMasterKeyIds) {
+ mEncryptionMasterKeyIds = encryptionMasterKeyIds;
+ return this;
+ }
+
+ public int getCompressionId() {
+ return mCompressionId;
+ }
+
+ public PgpSignEncryptInput setCompressionId(int compressionId) {
+ mCompressionId = compressionId;
+ return this;
+ }
+
+ public boolean ismEnableAsciiArmorOutput() {
+ return mEnableAsciiArmorOutput;
+ }
+
+ public String getVersionHeader() {
+ return mVersionHeader;
+ }
+
+ public PgpSignEncryptInput setVersionHeader(String versionHeader) {
+ mVersionHeader = versionHeader;
+ return this;
+ }
+
+ public PgpSignEncryptInput setEnableAsciiArmorOutput(boolean enableAsciiArmorOutput) {
+ mEnableAsciiArmorOutput = enableAsciiArmorOutput;
+ return this;
+ }
+
+ public PgpSignEncryptInput setFailOnMissingEncryptionKeyIds(boolean failOnMissingEncryptionKeyIds) {
+ mFailOnMissingEncryptionKeyIds = failOnMissingEncryptionKeyIds;
+ return this;
+ }
+
+ public PgpSignEncryptInput setNfcState(byte[] signedHash, Date creationTimestamp) {
+ mNfcSignedHash = signedHash;
+ mNfcCreationTimestamp = creationTimestamp;
+ return this;
+ }
+
+ public PgpSignEncryptInput setCleartextSignature(boolean cleartextSignature) {
+ this.mCleartextSignature = cleartextSignature;
+ return this;
+ }
+
+ public boolean isCleartextSignature() {
+ return mCleartextSignature;
+ }
+
+ public PgpSignEncryptInput setDetachedSignature(boolean detachedSignature) {
+ this.mDetachedSignature = detachedSignature;
+ return this;
+ }
+
+ public boolean isDetachedSignature() {
+ return mDetachedSignature;
+ }
+}
+
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
new file mode 100644
index 000000000..2fa01d241
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
@@ -0,0 +1,578 @@
+/*
+ * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.pgp;
+
+import android.content.Context;
+
+import org.spongycastle.bcpg.ArmoredOutputStream;
+import org.spongycastle.bcpg.BCPGOutputStream;
+import org.spongycastle.bcpg.CompressionAlgorithmTags;
+import org.spongycastle.openpgp.PGPCompressedDataGenerator;
+import org.spongycastle.openpgp.PGPEncryptedData;
+import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
+import org.spongycastle.openpgp.PGPException;
+import org.spongycastle.openpgp.PGPLiteralData;
+import org.spongycastle.openpgp.PGPLiteralDataGenerator;
+import org.spongycastle.openpgp.PGPSignatureGenerator;
+import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator;
+import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
+import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder;
+import org.spongycastle.util.encoders.Hex;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.BaseOperation;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.InputData;
+import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.ProgressScaler;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.SignatureException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/** This class supports a single, low-level, sign/encrypt operation.
+ *
+ * The operation of this class takes an Input- and OutputStream plus a
+ * PgpSignEncryptInput, and signs and/or encrypts the stream as
+ * parametrized in the PgpSignEncryptInput object. It returns its status
+ * and a possible detached signature as a SignEncryptResult.
+ *
+ * For a high-level operation based on URIs, see SignEncryptOperation.
+ *
+ * @see org.sufficientlysecure.keychain.pgp.PgpSignEncryptInput
+ * @see org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult
+ * @see org.sufficientlysecure.keychain.operations.SignEncryptOperation
+ *
+ */
+public class PgpSignEncryptOperation extends BaseOperation {
+
+ private static byte[] NEW_LINE;
+
+ static {
+ try {
+ NEW_LINE = "\r\n".getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ Log.e(Constants.TAG, "UnsupportedEncodingException", e);
+ }
+ }
+
+ public PgpSignEncryptOperation(Context context, ProviderHelper providerHelper, Progressable progressable, AtomicBoolean cancelled) {
+ super(context, providerHelper, progressable, cancelled);
+ }
+
+ public PgpSignEncryptOperation(Context context, ProviderHelper providerHelper, Progressable progressable) {
+ super(context, providerHelper, progressable);
+ }
+
+ /**
+ * Signs and/or encrypts data based on parameters of class
+ */
+ public PgpSignEncryptResult execute(PgpSignEncryptInput input,
+ InputData inputData, OutputStream outputStream) {
+
+ int indent = 0;
+ OperationLog log = new OperationLog();
+
+ log.add(LogType.MSG_PSE, indent);
+ indent += 1;
+
+ boolean enableSignature = input.getSignatureMasterKeyId() != Constants.key.none;
+ boolean enableEncryption = ((input.getEncryptionMasterKeyIds() != null && input.getEncryptionMasterKeyIds().length > 0)
+ || input.getSymmetricPassphrase() != null);
+ boolean enableCompression = (input.getCompressionId() != CompressionAlgorithmTags.UNCOMPRESSED);
+
+ Log.d(Constants.TAG, "enableSignature:" + enableSignature
+ + "\nenableEncryption:" + enableEncryption
+ + "\nenableCompression:" + enableCompression
+ + "\nenableAsciiArmorOutput:" + input.ismEnableAsciiArmorOutput());
+
+ // add additional key id to encryption ids (mostly to do self-encryption)
+ if (enableEncryption && input.getAdditionalEncryptId() != Constants.key.none) {
+ input.setEncryptionMasterKeyIds(Arrays.copyOf(input.getEncryptionMasterKeyIds(), input.getEncryptionMasterKeyIds().length + 1));
+ input.getEncryptionMasterKeyIds()[input.getEncryptionMasterKeyIds().length - 1] = input.getAdditionalEncryptId();
+ }
+
+ ArmoredOutputStream armorOut = null;
+ OutputStream out;
+ if (input.ismEnableAsciiArmorOutput()) {
+ armorOut = new ArmoredOutputStream(outputStream);
+ if (input.getVersionHeader() != null) {
+ armorOut.setHeader("Version", input.getVersionHeader());
+ }
+ // if we have a charset, put it in the header
+ if (input.getCharset() != null) {
+ armorOut.setHeader("Charset", input.getCharset());
+ }
+ out = armorOut;
+ } else {
+ out = outputStream;
+ }
+
+ /* Get keys for signature generation for later usage */
+ CanonicalizedSecretKey signingKey = null;
+ if (enableSignature) {
+
+ try {
+ // fetch the indicated master key id (the one whose name we sign in)
+ CanonicalizedSecretKeyRing signingKeyRing =
+ mProviderHelper.getCanonicalizedSecretKeyRing(input.getSignatureMasterKeyId());
+
+ long signKeyId;
+ // use specified signing subkey, or find the one to use
+ if (input.getSignatureSubKeyId() == null) {
+ signKeyId = signingKeyRing.getSecretSignId();
+ } else {
+ signKeyId = input.getSignatureSubKeyId();
+ }
+
+ // fetch the specific subkey to sign with, or just use the master key if none specified
+ signingKey = signingKeyRing.getSecretKey(signKeyId);
+
+ } catch (ProviderHelper.NotFoundException | PgpGeneralException e) {
+ log.add(LogType.MSG_PSE_ERROR_SIGN_KEY, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+
+ // Make sure we are allowed to sign here!
+ if (!signingKey.canSign()) {
+ log.add(LogType.MSG_PSE_ERROR_KEY_SIGN, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+
+ // if no passphrase was explicitly set try to get it from the cache service
+ if (input.getSignaturePassphrase() == null) {
+ try {
+ // returns "" if key has no passphrase
+ input.setSignaturePassphrase(getCachedPassphrase(signingKey.getKeyId()));
+ // TODO
+// log.add(LogType.MSG_DC_PASS_CACHED, indent + 1);
+ } catch (PassphraseCacheInterface.NoSecretKeyException e) {
+ // TODO
+// log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+
+ // if passphrase was not cached, return here indicating that a passphrase is missing!
+ if (input.getSignaturePassphrase() == null) {
+ log.add(LogType.MSG_PSE_PENDING_PASSPHRASE, indent + 1);
+ PgpSignEncryptResult result = new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE, log);
+ result.setKeyIdPassphraseNeeded(signingKey.getKeyId());
+ return result;
+ }
+ }
+
+ updateProgress(R.string.progress_extracting_signature_key, 0, 100);
+
+ try {
+ if (!signingKey.unlock(input.getSignaturePassphrase())) {
+ log.add(LogType.MSG_PSE_ERROR_BAD_PASSPHRASE, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+ } catch (PgpGeneralException e) {
+ log.add(LogType.MSG_PSE_ERROR_UNLOCK, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+
+ // check if hash algo is supported
+ int requestedAlgorithm = input.getSignatureHashAlgorithm();
+ LinkedList<Integer> supported = signingKey.getSupportedHashAlgorithms();
+ if (requestedAlgorithm == 0) {
+ // get most preferred
+ input.setSignatureHashAlgorithm(supported.getLast());
+ } else if (!supported.contains(requestedAlgorithm)) {
+ log.add(LogType.MSG_PSE_ERROR_HASH_ALGO, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+ }
+ updateProgress(R.string.progress_preparing_streams, 2, 100);
+
+ /* Initialize PGPEncryptedDataGenerator for later usage */
+ PGPEncryptedDataGenerator cPk = null;
+ if (enableEncryption) {
+ int algo = input.getSymmetricEncryptionAlgorithm();
+ if (algo == 0) {
+ algo = PGPEncryptedData.AES_128;
+ }
+ // has Integrity packet enabled!
+ JcePGPDataEncryptorBuilder encryptorBuilder =
+ new JcePGPDataEncryptorBuilder(algo)
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME)
+ .setWithIntegrityPacket(true);
+
+ cPk = new PGPEncryptedDataGenerator(encryptorBuilder);
+
+ if (input.getSymmetricPassphrase() != null) {
+ // Symmetric encryption
+ log.add(LogType.MSG_PSE_SYMMETRIC, indent);
+
+ JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator =
+ new JcePBEKeyEncryptionMethodGenerator(input.getSymmetricPassphrase().toCharArray());
+ cPk.addMethod(symmetricEncryptionGenerator);
+ } else {
+ log.add(LogType.MSG_PSE_ASYMMETRIC, indent);
+
+ // Asymmetric encryption
+ for (long id : input.getEncryptionMasterKeyIds()) {
+ try {
+ CanonicalizedPublicKeyRing keyRing = mProviderHelper.getCanonicalizedPublicKeyRing(
+ KeyRings.buildUnifiedKeyRingUri(id));
+ CanonicalizedPublicKey key = keyRing.getEncryptionSubKey();
+ cPk.addMethod(key.getPubKeyEncryptionGenerator());
+ log.add(LogType.MSG_PSE_KEY_OK, indent + 1,
+ KeyFormattingUtils.convertKeyIdToHex(id));
+ } catch (PgpKeyNotFoundException e) {
+ log.add(LogType.MSG_PSE_KEY_WARN, indent + 1,
+ KeyFormattingUtils.convertKeyIdToHex(id));
+ if (input.ismFailOnMissingEncryptionKeyIds()) {
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+ } catch (ProviderHelper.NotFoundException e) {
+ log.add(LogType.MSG_PSE_KEY_UNKNOWN, indent + 1,
+ KeyFormattingUtils.convertKeyIdToHex(id));
+ if (input.ismFailOnMissingEncryptionKeyIds()) {
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+ }
+ }
+ }
+ }
+
+ /* Initialize signature generator object for later usage */
+ PGPSignatureGenerator signatureGenerator = null;
+ if (enableSignature) {
+ updateProgress(R.string.progress_preparing_signature, 4, 100);
+
+ try {
+ boolean cleartext = input.isCleartextSignature() && input.ismEnableAsciiArmorOutput() && !enableEncryption;
+ signatureGenerator = signingKey.getSignatureGenerator(
+ input.getSignatureHashAlgorithm(), cleartext, input.getNfcSignedHash(), input.getNfcCreationTimestamp());
+ } catch (PgpGeneralException e) {
+ log.add(LogType.MSG_PSE_ERROR_NFC, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+ }
+
+ ProgressScaler progressScaler =
+ new ProgressScaler(mProgressable, 8, 95, 100);
+ PGPCompressedDataGenerator compressGen = null;
+ OutputStream pOut;
+ OutputStream encryptionOut = null;
+ BCPGOutputStream bcpgOut;
+
+ ByteArrayOutputStream detachedByteOut = null;
+ ArmoredOutputStream detachedArmorOut = null;
+ BCPGOutputStream detachedBcpgOut = null;
+
+ try {
+
+ if (enableEncryption) {
+ /* actual encryption */
+ updateProgress(R.string.progress_encrypting, 8, 100);
+ log.add(enableSignature
+ ? LogType.MSG_PSE_SIGCRYPTING
+ : LogType.MSG_PSE_ENCRYPTING,
+ indent
+ );
+ indent += 1;
+
+ encryptionOut = cPk.open(out, new byte[1 << 16]);
+
+ if (enableCompression) {
+ log.add(LogType.MSG_PSE_COMPRESSING, indent);
+ compressGen = new PGPCompressedDataGenerator(input.getCompressionId());
+ bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
+ } else {
+ bcpgOut = new BCPGOutputStream(encryptionOut);
+ }
+
+ if (enableSignature) {
+ signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
+ }
+
+ PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
+ char literalDataFormatTag;
+ if (input.isCleartextSignature()) {
+ literalDataFormatTag = PGPLiteralData.UTF8;
+ } else {
+ literalDataFormatTag = PGPLiteralData.BINARY;
+ }
+ pOut = literalGen.open(bcpgOut, literalDataFormatTag,
+ inputData.getOriginalFilename(), new Date(), new byte[1 << 16]);
+
+ long alreadyWritten = 0;
+ int length;
+ byte[] buffer = new byte[1 << 16];
+ InputStream in = inputData.getInputStream();
+ while ((length = in.read(buffer)) > 0) {
+ pOut.write(buffer, 0, length);
+
+ // update signature buffer if signature is requested
+ if (enableSignature) {
+ signatureGenerator.update(buffer, 0, length);
+ }
+
+ alreadyWritten += length;
+ if (inputData.getSize() > 0) {
+ long progress = 100 * alreadyWritten / inputData.getSize();
+ progressScaler.setProgress((int) progress, 100);
+ }
+ }
+
+ literalGen.close();
+ indent -= 1;
+
+ } else if (enableSignature && input.isCleartextSignature() && input.ismEnableAsciiArmorOutput()) {
+ /* cleartext signature: sign-only of ascii text */
+
+ updateProgress(R.string.progress_signing, 8, 100);
+ log.add(LogType.MSG_PSE_SIGNING_CLEARTEXT, indent);
+
+ // write -----BEGIN PGP SIGNED MESSAGE-----
+ armorOut.beginClearText(input.getSignatureHashAlgorithm());
+
+ InputStream in = inputData.getInputStream();
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+
+ // update signature buffer with first line
+ processLine(reader.readLine(), armorOut, signatureGenerator);
+
+ // TODO: progress: fake annealing?
+ while (true) {
+ String line = reader.readLine();
+
+ // end cleartext signature with newline, see http://tools.ietf.org/html/rfc4880#section-7
+ if (line == null) {
+ armorOut.write(NEW_LINE);
+ break;
+ }
+
+ armorOut.write(NEW_LINE);
+
+ // update signature buffer with input line
+ signatureGenerator.update(NEW_LINE);
+ processLine(line, armorOut, signatureGenerator);
+ }
+
+ armorOut.endClearText();
+
+ pOut = new BCPGOutputStream(armorOut);
+ } else if (enableSignature && input.isDetachedSignature()) {
+ /* detached signature */
+
+ updateProgress(R.string.progress_signing, 8, 100);
+ log.add(LogType.MSG_PSE_SIGNING_DETACHED, indent);
+
+ InputStream in = inputData.getInputStream();
+
+ // handle output stream separately for detached signatures
+ detachedByteOut = new ByteArrayOutputStream();
+ OutputStream detachedOut = detachedByteOut;
+ if (input.ismEnableAsciiArmorOutput()) {
+ detachedArmorOut = new ArmoredOutputStream(detachedOut);
+ if (input.getVersionHeader() != null) {
+ detachedArmorOut.setHeader("Version", input.getVersionHeader());
+ }
+
+ detachedOut = detachedArmorOut;
+ }
+ detachedBcpgOut = new BCPGOutputStream(detachedOut);
+
+ long alreadyWritten = 0;
+ int length;
+ byte[] buffer = new byte[1 << 16];
+ while ((length = in.read(buffer)) > 0) {
+ // no output stream is written, no changed to original data!
+
+ signatureGenerator.update(buffer, 0, length);
+
+ alreadyWritten += length;
+ if (inputData.getSize() > 0) {
+ long progress = 100 * alreadyWritten / inputData.getSize();
+ progressScaler.setProgress((int) progress, 100);
+ }
+ }
+
+ pOut = null;
+ } else if (enableSignature && !input.isCleartextSignature() && !input.isDetachedSignature()) {
+ /* sign-only binary (files/data stream) */
+
+ updateProgress(R.string.progress_signing, 8, 100);
+ log.add(LogType.MSG_PSE_SIGNING, indent);
+
+ InputStream in = inputData.getInputStream();
+
+ if (enableCompression) {
+ compressGen = new PGPCompressedDataGenerator(input.getCompressionId());
+ bcpgOut = new BCPGOutputStream(compressGen.open(out));
+ } else {
+ bcpgOut = new BCPGOutputStream(out);
+ }
+
+ signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
+
+ PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
+ pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY,
+ inputData.getOriginalFilename(), new Date(),
+ new byte[1 << 16]);
+
+ long alreadyWritten = 0;
+ int length;
+ byte[] buffer = new byte[1 << 16];
+ while ((length = in.read(buffer)) > 0) {
+ pOut.write(buffer, 0, length);
+
+ signatureGenerator.update(buffer, 0, length);
+
+ alreadyWritten += length;
+ if (inputData.getSize() > 0) {
+ long progress = 100 * alreadyWritten / inputData.getSize();
+ progressScaler.setProgress((int) progress, 100);
+ }
+ }
+
+ literalGen.close();
+ } else {
+ pOut = null;
+ // TODO: Is this log right?
+ log.add(LogType.MSG_PSE_CLEARSIGN_ONLY, indent);
+ }
+
+ if (enableSignature) {
+ updateProgress(R.string.progress_generating_signature, 95, 100);
+ try {
+ if (detachedBcpgOut != null) {
+ signatureGenerator.generate().encode(detachedBcpgOut);
+ } else {
+ signatureGenerator.generate().encode(pOut);
+ }
+ } catch (NfcSyncPGPContentSignerBuilder.NfcInteractionNeeded e) {
+ // this secret key diverts to a OpenPGP card, throw exception with hash that will be signed
+ log.add(LogType.MSG_PSE_PENDING_NFC, indent);
+ PgpSignEncryptResult result =
+ new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_PENDING_NFC, log);
+ // Note that the checked key here is the master key, not the signing key
+ // (although these are always the same on Yubikeys)
+ result.setNfcData(input.getSignatureSubKeyId(), e.hashToSign, e.hashAlgo, e.creationTimestamp, input.getSignaturePassphrase());
+ Log.d(Constants.TAG, "e.hashToSign" + Hex.toHexString(e.hashToSign));
+ return result;
+ }
+ }
+
+ // closing outputs
+ // NOTE: closing needs to be done in the correct order!
+ if (encryptionOut != null) {
+ if (compressGen != null) {
+ compressGen.close();
+ }
+
+ encryptionOut.close();
+ }
+ // Note: Closing ArmoredOutputStream does not close the underlying stream
+ if (armorOut != null) {
+ armorOut.close();
+ }
+ // Note: Closing ArmoredOutputStream does not close the underlying stream
+ if (detachedArmorOut != null) {
+ detachedArmorOut.close();
+ }
+ // Also closes detachedBcpgOut
+ if (detachedByteOut != null) {
+ detachedByteOut.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (outputStream != null) {
+ outputStream.close();
+ }
+
+ } catch (SignatureException e) {
+ log.add(LogType.MSG_PSE_ERROR_SIG, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ } catch (PGPException e) {
+ log.add(LogType.MSG_PSE_ERROR_PGP, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ } catch (IOException e) {
+ log.add(LogType.MSG_PSE_ERROR_IO, indent);
+ return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
+ }
+
+ updateProgress(R.string.progress_done, 100, 100);
+
+ log.add(LogType.MSG_PSE_OK, indent);
+ PgpSignEncryptResult result = new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_OK, log);
+ if (detachedByteOut != null) {
+ try {
+ detachedByteOut.flush();
+ detachedByteOut.close();
+ } catch (IOException e) {
+ // silently catch
+ }
+ result.setDetachedSignature(detachedByteOut.toByteArray());
+ }
+ return result;
+ }
+
+ /**
+ * Remove whitespaces on line endings
+ */
+ private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
+ final PGPSignatureGenerator pSignatureGenerator)
+ throws IOException, SignatureException {
+
+ if (pLine == null) {
+ return;
+ }
+
+ final char[] chars = pLine.toCharArray();
+ int len = chars.length;
+
+ while (len > 0) {
+ if (!Character.isWhitespace(chars[len - 1])) {
+ break;
+ }
+ len--;
+ }
+
+ final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
+
+ if (pArmoredOutput != null) {
+ pArmoredOutput.write(data);
+ }
+ pSignatureGenerator.update(data);
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java
new file mode 100644
index 000000000..a4ed33397
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java
@@ -0,0 +1,135 @@
+package org.sufficientlysecure.keychain.pgp;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+/** This parcel stores the input of one or more PgpSignEncrypt operations.
+ * All operations will use the same general paramters, differing only in
+ * input and output. Each input/output set depends on the paramters:
+ *
+ * - Each input uri is individually encrypted/signed
+ * - If a byte array is supplied, it is treated as an input before uris are processed
+ * - The number of output uris must match the number of input uris, plus one more
+ * if there is a byte array present.
+ * - Once the output uris are empty, there must be exactly one input (uri xor bytes)
+ * left, which will be returned in a byte array as part of the result parcel.
+ *
+ */
+public class SignEncryptParcel extends PgpSignEncryptInput implements Parcelable {
+
+ public ArrayList<Uri> mInputUris = new ArrayList<>();
+ public ArrayList<Uri> mOutputUris = new ArrayList<>();
+ public byte[] mBytes;
+
+ public SignEncryptParcel() {
+ super();
+ }
+
+ public SignEncryptParcel(Parcel src) {
+
+ // we do all of those here, so the PgpSignEncryptInput class doesn't have to be parcelable
+ mVersionHeader = src.readString();
+ mEnableAsciiArmorOutput = src.readInt() == 1;
+ mCompressionId = src.readInt();
+ mEncryptionMasterKeyIds = src.createLongArray();
+ mSymmetricPassphrase = src.readString();
+ mSymmetricEncryptionAlgorithm = src.readInt();
+ mSignatureMasterKeyId = src.readLong();
+ mSignatureSubKeyId = src.readInt() == 1 ? src.readLong() : null;
+ mSignatureHashAlgorithm = src.readInt();
+ mSignaturePassphrase = src.readString();
+ mAdditionalEncryptId = src.readLong();
+ mNfcSignedHash = src.createByteArray();
+ mNfcCreationTimestamp = src.readInt() == 1 ? new Date(src.readLong()) : null;
+ mFailOnMissingEncryptionKeyIds = src.readInt() == 1;
+ mCharset = src.readString();
+ mCleartextSignature = src.readInt() == 1;
+ mDetachedSignature = src.readInt() == 1;
+
+ mInputUris = src.createTypedArrayList(Uri.CREATOR);
+ mOutputUris = src.createTypedArrayList(Uri.CREATOR);
+ mBytes = src.createByteArray();
+
+ }
+
+ public byte[] getBytes() {
+ return mBytes;
+ }
+
+ public void setBytes(byte[] bytes) {
+ mBytes = bytes;
+ }
+
+ public List<Uri> getInputUris() {
+ return Collections.unmodifiableList(mInputUris);
+ }
+
+ public void addInputUris(Collection<Uri> inputUris) {
+ mInputUris.addAll(inputUris);
+ }
+
+ public List<Uri> getOutputUris() {
+ return Collections.unmodifiableList(mOutputUris);
+ }
+
+ public void addOutputUris(ArrayList<Uri> outputUris) {
+ mOutputUris.addAll(outputUris);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mVersionHeader);
+ dest.writeInt(mEnableAsciiArmorOutput ? 1 : 0);
+ dest.writeInt(mCompressionId);
+ dest.writeLongArray(mEncryptionMasterKeyIds);
+ dest.writeString(mSymmetricPassphrase);
+ dest.writeInt(mSymmetricEncryptionAlgorithm);
+ dest.writeLong(mSignatureMasterKeyId);
+ if (mSignatureSubKeyId != null) {
+ dest.writeInt(1);
+ dest.writeLong(mSignatureSubKeyId);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeInt(mSignatureHashAlgorithm);
+ dest.writeString(mSignaturePassphrase);
+ dest.writeLong(mAdditionalEncryptId);
+ dest.writeByteArray(mNfcSignedHash);
+ if (mNfcCreationTimestamp != null) {
+ dest.writeInt(1);
+ dest.writeLong(mNfcCreationTimestamp.getTime());
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeInt(mFailOnMissingEncryptionKeyIds ? 1 : 0);
+ dest.writeString(mCharset);
+ dest.writeInt(mCleartextSignature ? 1 : 0);
+ dest.writeInt(mDetachedSignature ? 1 : 0);
+
+ dest.writeTypedList(mInputUris);
+ dest.writeTypedList(mOutputUris);
+ dest.writeByteArray(mBytes);
+ }
+
+ public static final Creator<SignEncryptParcel> CREATOR = new Creator<SignEncryptParcel>() {
+ public SignEncryptParcel createFromParcel(final Parcel source) {
+ return new SignEncryptParcel(source);
+ }
+
+ public SignEncryptParcel[] newArray(final int size) {
+ return new SignEncryptParcel[size];
+ }
+ };
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
index d05ce3d5c..681aff56d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
@@ -21,6 +21,7 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
import org.spongycastle.bcpg.SignatureSubpacketTags;
+import org.spongycastle.bcpg.UserAttributeSubpacketTags;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPObjectFactory;
@@ -30,18 +31,18 @@ import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureList;
+import org.spongycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.spongycastle.openpgp.PGPUtil;
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Utf8Util;
-import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -49,11 +50,13 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
+import java.util.TimeZone;
import java.util.TreeSet;
/** Wrapper around PGPKeyRing class, to be constructed from bytes.
@@ -136,7 +139,7 @@ public class UncachedKeyRing {
public static UncachedKeyRing decodeFromData(byte[] data)
throws PgpGeneralException, IOException {
- Iterator<UncachedKeyRing> parsed = fromStream(new ByteArrayInputStream(data));
+ IteratorWithIOThrow<UncachedKeyRing> parsed = fromStream(new ByteArrayInputStream(data));
if ( ! parsed.hasNext()) {
throw new PgpGeneralException("Object not recognized as PGPKeyRing!");
@@ -152,14 +155,14 @@ public class UncachedKeyRing {
}
- public static Iterator<UncachedKeyRing> fromStream(final InputStream stream) throws IOException {
+ public static IteratorWithIOThrow<UncachedKeyRing> fromStream(final InputStream stream) {
- return new Iterator<UncachedKeyRing>() {
+ return new IteratorWithIOThrow<UncachedKeyRing>() {
UncachedKeyRing mNext = null;
PGPObjectFactory mObjectFactory = null;
- private void cacheNext() {
+ private void cacheNext() throws IOException {
if (mNext != null) {
return;
}
@@ -188,21 +191,19 @@ public class UncachedKeyRing {
// if we are past the while loop, that means the objectFactory had no next
mObjectFactory = null;
}
- } catch (IOException e) {
- Log.e(Constants.TAG, "IOException while processing stream. ArmoredInputStream CRC check failed?", e);
} catch (ArrayIndexOutOfBoundsException e) {
- Log.e(Constants.TAG, "ArmoredInputStream decode failed, symbol is not in decodingTable!", e);
+ throw new IOException(e);
}
}
@Override
- public boolean hasNext() {
+ public boolean hasNext() throws IOException {
cacheNext();
return mNext != null;
}
@Override
- public UncachedKeyRing next() {
+ public UncachedKeyRing next() throws IOException {
try {
cacheNext();
return mNext;
@@ -210,15 +211,15 @@ public class UncachedKeyRing {
mNext = null;
}
}
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
};
}
+ public interface IteratorWithIOThrow<E> {
+ public boolean hasNext() throws IOException;
+ public E next() throws IOException;
+ }
+
public void encodeArmored(OutputStream out, String version) throws IOException {
ArmoredOutputStream aos = new ArmoredOutputStream(out);
if (version != null) {
@@ -265,6 +266,35 @@ public class UncachedKeyRing {
*/
@SuppressWarnings("ConstantConditions")
public CanonicalizedKeyRing canonicalize(OperationLog log, int indent) {
+ return canonicalize(log, indent, false);
+ }
+
+
+ /** "Canonicalizes" a public key, removing inconsistencies in the process.
+ *
+ * More specifically:
+ * - Remove all non-verifying self-certificates
+ * - Remove all "future" self-certificates
+ * - Remove all certificates flagged as "local"
+ * - Remove all certificates which are superseded by a newer one on the same target,
+ * including revocations with later re-certifications.
+ * - Remove all certificates in other positions if not of known type:
+ * - key revocation signatures on the master key
+ * - subkey binding signatures for subkeys
+ * - certifications and certification revocations for user ids
+ * - If a subkey retains no valid subkey binding certificate, remove it
+ * - If a user id retains no valid self certificate, remove it
+ * - If the key is a secret key, remove all certificates by foreign keys
+ * - If no valid user id remains, log an error and return null
+ *
+ * This operation writes an OperationLog which can be used as part of an OperationResultParcel.
+ *
+ * @param forExport if this is true, non-exportable signatures will be removed
+ * @return A canonicalized key, or null on fatal error (log will include a message in this case)
+ *
+ */
+ @SuppressWarnings("ConstantConditions")
+ public CanonicalizedKeyRing canonicalize(OperationLog log, int indent, boolean forExport) {
log.add(isSecret() ? LogType.MSG_KC_SECRET : LogType.MSG_KC_PUBLIC,
indent, KeyFormattingUtils.convertKeyIdToHex(getMasterKeyId()));
@@ -276,7 +306,10 @@ public class UncachedKeyRing {
return null;
}
- final Date now = new Date();
+ Calendar nowCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ // allow for diverging clocks up to one day when checking creation time
+ nowCal.add(Calendar.DAY_OF_YEAR, 1);
+ final Date nowPlusOneDay = nowCal.getTime();
int redundantCerts = 0, badCerts = 0;
@@ -297,6 +330,7 @@ public class UncachedKeyRing {
PGPPublicKey modified = masterKey;
PGPSignature revocation = null;
+ PGPSignature notation = null;
for (PGPSignature zert : new IterableIterator<PGPSignature>(masterKey.getKeySignatures())) {
int type = zert.getSignatureType();
@@ -306,47 +340,80 @@ public class UncachedKeyRing {
|| type == PGPSignature.CASUAL_CERTIFICATION
|| type == PGPSignature.POSITIVE_CERTIFICATION
|| type == PGPSignature.CERTIFICATION_REVOCATION) {
- log.add(LogType.MSG_KC_REVOKE_BAD_TYPE_UID, indent);
+ log.add(LogType.MSG_KC_MASTER_BAD_TYPE_UID, indent);
modified = PGPPublicKey.removeCertification(modified, zert);
badCerts += 1;
continue;
}
WrappedSignature cert = new WrappedSignature(zert);
- if (type != PGPSignature.KEY_REVOCATION) {
+ if (type != PGPSignature.KEY_REVOCATION && type != PGPSignature.DIRECT_KEY) {
// Unknown type, just remove
- log.add(LogType.MSG_KC_REVOKE_BAD_TYPE, indent, "0x" + Integer.toString(type, 16));
+ log.add(LogType.MSG_KC_MASTER_BAD_TYPE, indent, "0x" + Integer.toString(type, 16));
modified = PGPPublicKey.removeCertification(modified, zert);
badCerts += 1;
continue;
}
- if (cert.getCreationTime().after(now)) {
+ if (cert.getCreationTime().after(nowPlusOneDay)) {
// Creation date in the future? No way!
- log.add(LogType.MSG_KC_REVOKE_BAD_TIME, indent);
+ log.add(LogType.MSG_KC_MASTER_BAD_TIME, indent);
modified = PGPPublicKey.removeCertification(modified, zert);
badCerts += 1;
continue;
}
- if (cert.isLocal()) {
- // Remove revocation certs with "local" flag
- log.add(LogType.MSG_KC_REVOKE_BAD_LOCAL, indent);
+ try {
+ cert.init(masterKey);
+ if (!cert.verifySignature(masterKey)) {
+ log.add(LogType.MSG_KC_MASTER_BAD, indent);
+ modified = PGPPublicKey.removeCertification(modified, zert);
+ badCerts += 1;
+ continue;
+ }
+ } catch (PgpGeneralException e) {
+ log.add(LogType.MSG_KC_MASTER_BAD_ERR, indent);
modified = PGPPublicKey.removeCertification(modified, zert);
badCerts += 1;
continue;
}
- try {
- cert.init(masterKey);
- if (!cert.verifySignature(masterKey)) {
- log.add(LogType.MSG_KC_REVOKE_BAD, indent);
+ // if this is for export, we always remove any non-exportable certs
+ if (forExport && cert.isLocal()) {
+ // Remove revocation certs with "local" flag
+ log.add(LogType.MSG_KC_MASTER_LOCAL, indent);
+ modified = PGPPublicKey.removeCertification(modified, zert);
+ continue;
+ }
+
+ // special case: non-exportable, direct key signatures for notations!
+ if (cert.getSignatureType() == PGPSignature.DIRECT_KEY) {
+ // must be local, otherwise strip!
+ if (!cert.isLocal()) {
+ log.add(LogType.MSG_KC_MASTER_BAD_TYPE, indent);
modified = PGPPublicKey.removeCertification(modified, zert);
badCerts += 1;
continue;
}
- } catch (PgpGeneralException e) {
- log.add(LogType.MSG_KC_REVOKE_BAD_ERR, indent);
+
+ // first notation? fine then.
+ if (notation == null) {
+ notation = zert;
+ // more notations? at least one is superfluous, then.
+ } else if (notation.getCreationTime().before(zert.getCreationTime())) {
+ log.add(LogType.MSG_KC_NOTATION_DUP, indent);
+ modified = PGPPublicKey.removeCertification(modified, notation);
+ redundantCerts += 1;
+ notation = zert;
+ } else {
+ log.add(LogType.MSG_KC_NOTATION_DUP, indent);
+ modified = PGPPublicKey.removeCertification(modified, zert);
+ redundantCerts += 1;
+ }
+ continue;
+ } else if (cert.isLocal()) {
+ // Remove revocation certs with "local" flag
+ log.add(LogType.MSG_KC_MASTER_BAD_LOCAL, indent);
modified = PGPPublicKey.removeCertification(modified, zert);
badCerts += 1;
continue;
@@ -368,7 +435,17 @@ public class UncachedKeyRing {
}
}
- ArrayList<String> processedUserIds = new ArrayList<String>();
+ // If we have a notation packet, check if there is even any data in it?
+ if (notation != null) {
+ // If there isn't, might as well strip it
+ if (new WrappedSignature(notation).getNotation().isEmpty()) {
+ log.add(LogType.MSG_KC_NOTATION_EMPTY, indent);
+ modified = PGPPublicKey.removeCertification(modified, notation);
+ redundantCerts += 1;
+ }
+ }
+
+ ArrayList<String> processedUserIds = new ArrayList<>();
for (byte[] rawUserId : new IterableIterator<byte[]>(masterKey.getRawUserIDs())) {
String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId);
@@ -393,7 +470,7 @@ public class UncachedKeyRing {
@SuppressWarnings("unchecked")
Iterator<PGPSignature> signaturesIt = masterKey.getSignaturesForID(rawUserId);
if (signaturesIt != null) {
- for (PGPSignature zert : new IterableIterator<PGPSignature>(signaturesIt)) {
+ for (PGPSignature zert : new IterableIterator<>(signaturesIt)) {
WrappedSignature cert = new WrappedSignature(zert);
long certId = cert.getKeyId();
@@ -410,7 +487,7 @@ public class UncachedKeyRing {
continue;
}
- if (cert.getCreationTime().after(now)) {
+ if (cert.getCreationTime().after(nowPlusOneDay)) {
// Creation date in the future? No way!
log.add(LogType.MSG_KC_UID_BAD_TIME, indent);
modified = PGPPublicKey.removeCertification(modified, rawUserId, zert);
@@ -530,6 +607,170 @@ public class UncachedKeyRing {
return null;
}
+ ArrayList<PGPUserAttributeSubpacketVector> processedUserAttributes = new ArrayList<>();
+ for (PGPUserAttributeSubpacketVector userAttribute :
+ new IterableIterator<PGPUserAttributeSubpacketVector>(masterKey.getUserAttributes())) {
+
+ if (userAttribute.getSubpacket(UserAttributeSubpacketTags.IMAGE_ATTRIBUTE) != null) {
+ log.add(LogType.MSG_KC_UAT_JPEG, indent);
+ } else {
+ log.add(LogType.MSG_KC_UAT_UNKNOWN, indent);
+ }
+
+ try {
+ indent += 1;
+
+ // check for duplicate user attributes
+ if (processedUserAttributes.contains(userAttribute)) {
+ log.add(LogType.MSG_KC_UAT_DUP, indent);
+ // strip out the first found user id with this name
+ modified = PGPPublicKey.removeCertification(modified, userAttribute);
+ }
+ processedUserAttributes.add(userAttribute);
+
+ PGPSignature selfCert = null;
+ revocation = null;
+
+ // look through signatures for this specific user id
+ @SuppressWarnings("unchecked")
+ Iterator<PGPSignature> signaturesIt = masterKey.getSignaturesForUserAttribute(userAttribute);
+ if (signaturesIt != null) {
+ for (PGPSignature zert : new IterableIterator<>(signaturesIt)) {
+ WrappedSignature cert = new WrappedSignature(zert);
+ long certId = cert.getKeyId();
+
+ int type = zert.getSignatureType();
+ if (type != PGPSignature.DEFAULT_CERTIFICATION
+ && type != PGPSignature.NO_CERTIFICATION
+ && type != PGPSignature.CASUAL_CERTIFICATION
+ && type != PGPSignature.POSITIVE_CERTIFICATION
+ && type != PGPSignature.CERTIFICATION_REVOCATION) {
+ log.add(LogType.MSG_KC_UAT_BAD_TYPE,
+ indent, "0x" + Integer.toString(zert.getSignatureType(), 16));
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ badCerts += 1;
+ continue;
+ }
+
+ if (cert.getCreationTime().after(nowPlusOneDay)) {
+ // Creation date in the future? No way!
+ log.add(LogType.MSG_KC_UAT_BAD_TIME, indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ badCerts += 1;
+ continue;
+ }
+
+ if (cert.isLocal()) {
+ // Creation date in the future? No way!
+ log.add(LogType.MSG_KC_UAT_BAD_LOCAL, indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ badCerts += 1;
+ continue;
+ }
+
+ // If this is a foreign signature, ...
+ if (certId != masterKeyId) {
+ // never mind any further for public keys, but remove them from secret ones
+ if (isSecret()) {
+ log.add(LogType.MSG_KC_UAT_FOREIGN,
+ indent, KeyFormattingUtils.convertKeyIdToHex(certId));
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ badCerts += 1;
+ }
+ continue;
+ }
+
+ // Otherwise, first make sure it checks out
+ try {
+ cert.init(masterKey);
+ if (!cert.verifySignature(masterKey, userAttribute)) {
+ log.add(LogType.MSG_KC_UAT_BAD,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ badCerts += 1;
+ continue;
+ }
+ } catch (PgpGeneralException e) {
+ log.add(LogType.MSG_KC_UAT_BAD_ERR,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ badCerts += 1;
+ continue;
+ }
+
+ switch (type) {
+ case PGPSignature.DEFAULT_CERTIFICATION:
+ case PGPSignature.NO_CERTIFICATION:
+ case PGPSignature.CASUAL_CERTIFICATION:
+ case PGPSignature.POSITIVE_CERTIFICATION:
+ if (selfCert == null) {
+ selfCert = zert;
+ } else if (selfCert.getCreationTime().before(cert.getCreationTime())) {
+ log.add(LogType.MSG_KC_UAT_CERT_DUP,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, selfCert);
+ redundantCerts += 1;
+ selfCert = zert;
+ } else {
+ log.add(LogType.MSG_KC_UAT_CERT_DUP,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ redundantCerts += 1;
+ }
+ // If there is a revocation certificate, and it's older than this, drop it
+ if (revocation != null
+ && revocation.getCreationTime().before(selfCert.getCreationTime())) {
+ log.add(LogType.MSG_KC_UAT_REVOKE_OLD,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, revocation);
+ revocation = null;
+ redundantCerts += 1;
+ }
+ break;
+
+ case PGPSignature.CERTIFICATION_REVOCATION:
+ // If this is older than the (latest) self cert, drop it
+ if (selfCert != null && selfCert.getCreationTime().after(zert.getCreationTime())) {
+ log.add(LogType.MSG_KC_UAT_REVOKE_OLD,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ redundantCerts += 1;
+ continue;
+ }
+ // first revocation? remember it.
+ if (revocation == null) {
+ revocation = zert;
+ // more revocations? at least one is superfluous, then.
+ } else if (revocation.getCreationTime().before(cert.getCreationTime())) {
+ log.add(LogType.MSG_KC_UAT_REVOKE_DUP,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, revocation);
+ redundantCerts += 1;
+ revocation = zert;
+ } else {
+ log.add(LogType.MSG_KC_UAT_REVOKE_DUP,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute, zert);
+ redundantCerts += 1;
+ }
+ break;
+ }
+ }
+ }
+
+ // If no valid certificate (if only a revocation) remains, drop it
+ if (selfCert == null && revocation == null) {
+ log.add(LogType.MSG_KC_UAT_REMOVE,
+ indent);
+ modified = PGPPublicKey.removeCertification(modified, userAttribute);
+ }
+
+ } finally {
+ indent -= 1;
+ }
+ }
+
+
// Replace modified key in the keyring
ring = replacePublicKey(ring, modified);
indent -= 1;
@@ -537,7 +778,7 @@ public class UncachedKeyRing {
}
// Keep track of ids we encountered so far
- Set<Long> knownIds = new HashSet<Long>();
+ Set<Long> knownIds = new HashSet<>();
// Process all keys
for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(ring.getPublicKeys())) {
@@ -592,7 +833,7 @@ public class UncachedKeyRing {
continue;
}
- if (cert.getCreationTime().after(now)) {
+ if (cert.getCreationTime().after(nowPlusOneDay)) {
// Creation date in the future? No way!
log.add(LogType.MSG_KC_SUB_BAD_TIME, indent);
badCerts += 1;
@@ -777,8 +1018,8 @@ public class UncachedKeyRing {
/** This operation merges information from a different keyring, returning a combined
* UncachedKeyRing.
*
- * The combined keyring contains the subkeys and user ids of both input keyrings, but it does
- * not necessarily have the canonicalized property.
+ * The combined keyring contains the subkeys, user ids and user attributes of both input
+ * keyrings, but it does not necessarily have the canonicalized property.
*
* @param other The UncachedKeyRing to merge. Must not be empty, and of the same masterKeyId
* @return A consolidated UncachedKeyRing with the data of both input keyrings. Same type as
@@ -801,7 +1042,7 @@ public class UncachedKeyRing {
}
// remember which certs we already added. this is cheaper than semantic deduplication
- Set<byte[]> certs = new TreeSet<byte[]>(new Comparator<byte[]>() {
+ Set<byte[]> certs = new TreeSet<>(new Comparator<byte[]>() {
public int compare(byte[] left, byte[] right) {
// check for length equality
if (left.length != right.length) {
@@ -883,7 +1124,7 @@ public class UncachedKeyRing {
if (signaturesIt == null) {
continue;
}
- for (PGPSignature cert : new IterableIterator<PGPSignature>(signaturesIt)) {
+ for (PGPSignature cert : new IterableIterator<>(signaturesIt)) {
// Don't merge foreign stuff into secret keys
if (cert.getKeyID() != masterKeyId && isSecret()) {
continue;
@@ -898,6 +1139,32 @@ public class UncachedKeyRing {
modified = PGPPublicKey.addCertification(modified, rawUserId, cert);
}
}
+
+ // Copy over all user attribute certificates
+ for (PGPUserAttributeSubpacketVector vector :
+ new IterableIterator<PGPUserAttributeSubpacketVector>(key.getUserAttributes())) {
+ @SuppressWarnings("unchecked")
+ Iterator<PGPSignature> signaturesIt = key.getSignaturesForUserAttribute(vector);
+ // no signatures for this user attribute attribute, skip it
+ if (signaturesIt == null) {
+ continue;
+ }
+ for (PGPSignature cert : new IterableIterator<>(signaturesIt)) {
+ // Don't merge foreign stuff into secret keys
+ if (cert.getKeyID() != masterKeyId && isSecret()) {
+ continue;
+ }
+ byte[] encoded = cert.getEncoded();
+ // Known cert, skip it
+ if (certs.contains(encoded)) {
+ continue;
+ }
+ newCerts += 1;
+ certs.add(encoded);
+ modified = PGPPublicKey.addCertification(modified, vector, cert);
+ }
+ }
+
// If anything changed, save the updated (sub)key
if (modified != resultKey) {
result = replacePublicKey(result, modified);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
index c4cacaca7..9276cba10 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
@@ -20,10 +20,10 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.ECPublicBCPGKey;
import org.spongycastle.bcpg.SignatureSubpacketTags;
-import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
+import org.spongycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.util.IterableIterator;
@@ -50,7 +50,7 @@ public class UncachedPublicKey {
}
/** The revocation signature is NOT checked here, so this may be false! */
- public boolean isRevoked() {
+ public boolean isMaybeRevoked() {
return mPublicKey.getSignaturesOfType(isMasterKey()
? PGPSignature.KEY_REVOCATION
: PGPSignature.SUBKEY_REVOCATION).hasNext();
@@ -60,25 +60,8 @@ public class UncachedPublicKey {
return mPublicKey.getCreationTime();
}
- public Date getExpiryTime() {
- long seconds = mPublicKey.getValidSeconds();
- if (seconds > Integer.MAX_VALUE) {
- Log.e(Constants.TAG, "error, expiry time too large");
- return null;
- }
- if (seconds == 0) {
- // no expiry
- return null;
- }
- Date creationDate = getCreationTime();
- Calendar calendar = GregorianCalendar.getInstance();
- calendar.setTime(creationDate);
- calendar.add(Calendar.SECOND, (int) seconds);
-
- return calendar.getTime();
- }
-
- public boolean isExpired() {
+ /** The revocation signature is NOT checked here, so this may be false! */
+ public boolean isMaybeExpired() {
Date creationDate = mPublicKey.getCreationTime();
Date expiryDate = mPublicKey.getValidSeconds() > 0
? new Date(creationDate.getTime() + mPublicKey.getValidSeconds() * 1000) : null;
@@ -135,7 +118,7 @@ public class UncachedPublicKey {
continue;
}
- for (PGPSignature sig : new IterableIterator<PGPSignature>(signaturesIt)) {
+ for (PGPSignature sig : new IterableIterator<>(signaturesIt)) {
try {
// if this is a revocation, this is not the user id
@@ -186,18 +169,20 @@ public class UncachedPublicKey {
}
/**
- * Returns primary user id if existing. If not, return first encountered user id.
+ * Returns primary user id if existing. If not, return first encountered user id. If there
+ * is no user id, return null (this can only happen for not yet canonicalized keys during import)
*/
public String getPrimaryUserIdWithFallback() {
String userId = getPrimaryUserId();
if (userId == null) {
- userId = (String) mPublicKey.getUserIDs().next();
+ Iterator<String> it = mPublicKey.getUserIDs();
+ userId = it.hasNext() ? it.next() : null;
}
return userId;
}
public ArrayList<String> getUnorderedUserIds() {
- ArrayList<String> userIds = new ArrayList<String>();
+ ArrayList<String> userIds = new ArrayList<>();
for (byte[] rawUserId : new IterableIterator<byte[]>(mPublicKey.getRawUserIDs())) {
// use our decoding method
userIds.add(Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId));
@@ -206,13 +191,22 @@ public class UncachedPublicKey {
}
public ArrayList<byte[]> getUnorderedRawUserIds() {
- ArrayList<byte[]> userIds = new ArrayList<byte[]>();
+ ArrayList<byte[]> userIds = new ArrayList<>();
for (byte[] userId : new IterableIterator<byte[]>(mPublicKey.getRawUserIDs())) {
userIds.add(userId);
}
return userIds;
}
+ public ArrayList<WrappedUserAttribute> getUnorderedUserAttributes() {
+ ArrayList<WrappedUserAttribute> userAttributes = new ArrayList<>();
+ for (PGPUserAttributeSubpacketVector userAttribute :
+ new IterableIterator<PGPUserAttributeSubpacketVector>(mPublicKey.getUserAttributes())) {
+ userAttributes.add(new WrappedUserAttribute(userAttribute));
+ }
+ return userAttributes;
+ }
+
public boolean isElGamalEncrypt() {
return getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT;
}
@@ -268,33 +262,103 @@ public class UncachedPublicKey {
}
}
+ public Iterator<WrappedSignature> getSignaturesForUserAttribute(WrappedUserAttribute attribute) {
+ final Iterator<PGPSignature> it = mPublicKey.getSignaturesForUserAttribute(attribute.getVector());
+ if (it != null) {
+ return new Iterator<WrappedSignature>() {
+ public void remove() {
+ it.remove();
+ }
+ public WrappedSignature next() {
+ return new WrappedSignature(it.next());
+ }
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+ };
+ } else {
+ return null;
+ }
+ }
+
/** Get all key usage flags.
* If at least one key flag subpacket is present return these. If no
* subpacket is present it returns null.
*
* Note that this method has package visiblity because it is used in test
* cases. Certificates of UncachedPublicKey instances can NOT be assumed to
- * be verified, so the result of this method should not be used in other
- * places!
+ * be verified or even by the correct key, so the result of this method
+ * should never be used in other places!
*/
@SuppressWarnings("unchecked")
Integer getKeyUsage() {
if (mCacheUsage == null) {
+ PGPSignature mostRecentSig = null;
for (PGPSignature sig : new IterableIterator<PGPSignature>(mPublicKey.getSignatures())) {
if (mPublicKey.isMasterKey() && sig.getKeyID() != mPublicKey.getKeyID()) {
continue;
}
- PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
+ switch (sig.getSignatureType()) {
+ case PGPSignature.DEFAULT_CERTIFICATION:
+ case PGPSignature.POSITIVE_CERTIFICATION:
+ case PGPSignature.CASUAL_CERTIFICATION:
+ case PGPSignature.NO_CERTIFICATION:
+ case PGPSignature.SUBKEY_BINDING:
+ break;
+ // if this is not one of the above types, don't care
+ default:
+ continue;
+ }
+
+ // If we have no sig yet, take the first we can get
+ if (mostRecentSig == null) {
+ mostRecentSig = sig;
+ continue;
+ }
+
+ // If the new sig is less recent, skip it
+ if (mostRecentSig.getCreationTime().after(sig.getCreationTime())) {
+ continue;
+ }
+
+ // Otherwise, note it down as the new "most recent" one
+ mostRecentSig = sig;
+ }
+
+ // Initialize to 0 as cached but empty value, if there is no sig (can't happen
+ // for canonicalized keyring), or there is no KEY_FLAGS packet in the sig
+ mCacheUsage = 0;
+ if (mostRecentSig != null) {
+ // If a mostRecentSig has been found, (cache and) return its flags
+ PGPSignatureSubpacketVector hashed = mostRecentSig.getHashedSubPackets();
if (hashed != null && hashed.getSubpacket(SignatureSubpacketTags.KEY_FLAGS) != null) {
- // init if at least one key flag subpacket has been found
- if (mCacheUsage == null) {
- mCacheUsage = 0;
- }
- mCacheUsage |= hashed.getKeyFlags();
+ mCacheUsage = hashed.getKeyFlags();
}
}
+
}
return mCacheUsage;
}
+
+ // this method relies on UNSAFE assumptions about the keyring, and should ONLY be used for
+ // TEST CASES!!
+ Date getUnsafeExpiryTimeForTesting () {
+ long valid = mPublicKey.getValidSeconds();
+
+ if (valid > Integer.MAX_VALUE) {
+ Log.e(Constants.TAG, "error, expiry time too large");
+ return null;
+ }
+ if (valid == 0) {
+ // no expiry
+ return null;
+ }
+ Date creationDate = getCreationTime();
+ Calendar calendar = GregorianCalendar.getInstance();
+ calendar.setTime(creationDate);
+ calendar.add(Calendar.SECOND, (int) valid);
+
+ return calendar.getTime();
+ }
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java
index 93afb987a..c6fad1a73 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java
@@ -21,6 +21,7 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.SignatureSubpacket;
import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.bcpg.sig.Exportable;
+import org.spongycastle.bcpg.sig.NotationData;
import org.spongycastle.bcpg.sig.Revocable;
import org.spongycastle.bcpg.sig.RevocationReason;
import org.spongycastle.openpgp.PGPException;
@@ -28,15 +29,16 @@ import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureList;
+import org.spongycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
-import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashMap;
/** OpenKeychain wrapper around PGPSignature objects.
*
@@ -76,8 +78,12 @@ public class WrappedSignature {
return mSig.getCreationTime();
}
+ public long getKeyExpirySeconds() {
+ return mSig.getHashedSubPackets().getKeyExpirationTime();
+ }
+
public ArrayList<WrappedSignature> getEmbeddedSignatures() {
- ArrayList<WrappedSignature> sigs = new ArrayList<WrappedSignature>();
+ ArrayList<WrappedSignature> sigs = new ArrayList<>();
if (!mSig.hasSubpackets()) {
return sigs;
}
@@ -197,12 +203,23 @@ public class WrappedSignature {
}
}
+ boolean verifySignature(PGPPublicKey key, PGPUserAttributeSubpacketVector attribute) throws PgpGeneralException {
+ try {
+ return mSig.verifyCertification(attribute, key);
+ } catch (PGPException e) {
+ throw new PgpGeneralException("Error!", e);
+ }
+ }
+
public boolean verifySignature(UncachedPublicKey key, byte[] rawUserId) throws PgpGeneralException {
return verifySignature(key.getPublicKey(), rawUserId);
}
public boolean verifySignature(CanonicalizedPublicKey key, String uid) throws PgpGeneralException {
return verifySignature(key.getPublicKey(), uid);
}
+ public boolean verifySignature(UncachedPublicKey key, WrappedUserAttribute attribute) throws PgpGeneralException {
+ return verifySignature(key.getPublicKey(), attribute.getVector());
+ }
public static WrappedSignature fromBytes(byte[] data) {
PGPObjectFactory factory = new PGPObjectFactory(data);
@@ -239,4 +256,20 @@ public class WrappedSignature {
SignatureSubpacket p = mSig.getHashedSubPackets().getSubpacket(SignatureSubpacketTags.EXPORTABLE);
return ! ((Exportable) p).isExportable();
}
+
+ public HashMap<String,String> getNotation() {
+ HashMap<String,String> result = new HashMap<>();
+
+ // If there is any notation data
+ if (mSig.getHashedSubPackets() != null
+ && mSig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.NOTATION_DATA)) {
+ // Iterate over notation data
+ for (NotationData data : mSig.getHashedSubPackets().getNotationDataOccurrences()) {
+ result.put(data.getNotationName(), data.getNotationValue());
+ }
+ }
+
+ return result;
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java
new file mode 100644
index 000000000..8e23d36d9
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.pgp;
+
+import org.spongycastle.bcpg.BCPGInputStream;
+import org.spongycastle.bcpg.BCPGOutputStream;
+import org.spongycastle.bcpg.Packet;
+import org.spongycastle.bcpg.UserAttributePacket;
+import org.spongycastle.bcpg.UserAttributeSubpacket;
+import org.spongycastle.bcpg.UserAttributeSubpacketInputStream;
+import org.spongycastle.bcpg.UserAttributeSubpacketTags;
+import org.spongycastle.openpgp.PGPUserAttributeSubpacketVector;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+public class WrappedUserAttribute implements Serializable {
+
+ public static final int UAT_NONE = 0;
+ public static final int UAT_IMAGE = UserAttributeSubpacketTags.IMAGE_ATTRIBUTE;
+
+ private PGPUserAttributeSubpacketVector mVector;
+
+ WrappedUserAttribute(PGPUserAttributeSubpacketVector vector) {
+ mVector = vector;
+ }
+
+ PGPUserAttributeSubpacketVector getVector() {
+ return mVector;
+ }
+
+ public int getType() {
+ UserAttributeSubpacket[] subpackets = mVector.toSubpacketArray();
+ if (subpackets.length > 0) {
+ return subpackets[0].getType();
+ }
+ return 0;
+ }
+
+ public static WrappedUserAttribute fromSubpacket (int type, byte[] data) {
+ UserAttributeSubpacket subpacket = new UserAttributeSubpacket(type, data);
+ PGPUserAttributeSubpacketVector vector = new PGPUserAttributeSubpacketVector(
+ new UserAttributeSubpacket[] { subpacket });
+
+ return new WrappedUserAttribute(vector);
+
+ }
+
+ public byte[] getEncoded () throws IOException {
+ UserAttributeSubpacket[] subpackets = mVector.toSubpacketArray();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ for (UserAttributeSubpacket subpacket : subpackets) {
+ subpacket.encode(out);
+ }
+ return out.toByteArray();
+ }
+
+ public static WrappedUserAttribute fromData (byte[] data) throws IOException {
+ UserAttributeSubpacketInputStream in =
+ new UserAttributeSubpacketInputStream(new ByteArrayInputStream(data));
+ ArrayList<UserAttributeSubpacket> list = new ArrayList<UserAttributeSubpacket>();
+ while (in.available() > 0) {
+ list.add(in.readPacket());
+ }
+ UserAttributeSubpacket[] result = new UserAttributeSubpacket[list.size()];
+ list.toArray(result);
+ return new WrappedUserAttribute(
+ new PGPUserAttributeSubpacketVector(result));
+ }
+
+ /** Writes this object to an ObjectOutputStream. */
+ private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ BCPGOutputStream bcpg = new BCPGOutputStream(baos);
+ bcpg.writePacket(new UserAttributePacket(mVector.toSubpacketArray()));
+ out.writeObject(baos.toByteArray());
+
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+
+ byte[] data = (byte[]) in.readObject();
+ BCPGInputStream bcpg = new BCPGInputStream(new ByteArrayInputStream(data));
+ Packet p = bcpg.readPacket();
+ if ( ! UserAttributePacket.class.isInstance(p)) {
+ throw new IOException("Could not decode UserAttributePacket!");
+ }
+ mVector = new PGPUserAttributeSubpacketVector(((UserAttributePacket) p).getSubpackets());
+
+ }
+
+ private void readObjectNoData() throws ObjectStreamException {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!WrappedUserAttribute.class.isInstance(o)) {
+ return false;
+ }
+ return mVector.equals(((WrappedUserAttribute) o).mVector);
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
index 6127002bb..5856589c4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
@@ -51,9 +51,11 @@ public class KeychainContract {
String EXPIRY = "expiry";
}
- interface UserIdsColumns {
+ interface UserPacketsColumns {
String MASTER_KEY_ID = "master_key_id"; // foreign key to key_rings._ID
+ String TYPE = "type"; // not a database id
String USER_ID = "user_id"; // not a database id
+ String ATTRIBUTE_DATA = "attribute_data"; // not a database id
String RANK = "rank"; // ONLY used for sorting! no key, no nothing!
String IS_PRIMARY = "is_primary";
String IS_REVOKED = "is_revoked";
@@ -83,6 +85,11 @@ public class KeychainContract {
String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name
}
+ interface ApiAppsAllowedKeysColumns {
+ String KEY_ID = "key_id"; // not a database id
+ String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name
+ }
+
public static final String CONTENT_AUTHORITY = Constants.PACKAGE_NAME + ".provider";
private static final Uri BASE_CONTENT_URI_INTERNAL = Uri
@@ -104,8 +111,9 @@ public class KeychainContract {
public static final String BASE_API_APPS = "api_apps";
public static final String PATH_ACCOUNTS = "accounts";
+ public static final String PATH_ALLOWED_KEYS = "allowed_keys";
- public static class KeyRings implements BaseColumns, KeysColumns, UserIdsColumns {
+ public static class KeyRings implements BaseColumns, KeysColumns, UserPacketsColumns {
public static final String MASTER_KEY_ID = KeysColumns.MASTER_KEY_ID;
public static final String IS_REVOKED = KeysColumns.IS_REVOKED;
public static final String VERIFIED = CertsColumns.VERIFIED;
@@ -225,7 +233,7 @@ public class KeychainContract {
}
- public static class UserIds implements UserIdsColumns, BaseColumns {
+ public static class UserPackets implements UserPacketsColumns, BaseColumns {
public static final String VERIFIED = "verified";
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
.appendPath(BASE_KEY_RINGS).build();
@@ -303,10 +311,27 @@ public class KeychainContract {
}
}
+ public static class ApiAllowedKeys implements ApiAppsAllowedKeysColumns, BaseColumns {
+ public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
+ .appendPath(BASE_API_APPS).build();
+
+ /**
+ * Use if multiple items get returned
+ */
+ public static final String CONTENT_TYPE
+ = "vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.api_apps.allowed_keys";
+
+ public static Uri buildBaseUri(String packageName) {
+ return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ALLOWED_KEYS)
+ .build();
+ }
+ }
+
public static class Certs implements CertsColumns, BaseColumns {
- public static final String USER_ID = UserIdsColumns.USER_ID;
+ public static final String USER_ID = UserPacketsColumns.USER_ID;
public static final String SIGNER_UID = "signer_user_id";
+ public static final int UNVERIFIED = 0;
public static final int VERIFIED_SECRET = 1;
public static final int VERIFIED_SELF = 2;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
index 84a50dc65..b88cd6006 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
@@ -29,11 +29,12 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAllowedKeysColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.CertsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPacketsColumns;
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
import org.sufficientlysecure.keychain.util.Log;
@@ -52,7 +53,7 @@ import java.io.IOException;
*/
public class KeychainDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "openkeychain.db";
- private static final int DATABASE_VERSION = 6;
+ private static final int DATABASE_VERSION = 8;
static Boolean apgHack = false;
private Context mContext;
@@ -60,10 +61,11 @@ public class KeychainDatabase extends SQLiteOpenHelper {
String KEY_RINGS_PUBLIC = "keyrings_public";
String KEY_RINGS_SECRET = "keyrings_secret";
String KEYS = "keys";
- String USER_IDS = "user_ids";
+ String USER_PACKETS = "user_ids";
String CERTS = "certs";
String API_APPS = "api_apps";
String API_ACCOUNTS = "api_accounts";
+ String API_ALLOWED_KEYS = "api_allowed_keys";
}
private static final String CREATE_KEYRINGS_PUBLIC =
@@ -106,18 +108,20 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
+ ")";
- private static final String CREATE_USER_IDS =
- "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS + "("
- + UserIdsColumns.MASTER_KEY_ID + " INTEGER, "
- + UserIdsColumns.USER_ID + " TEXT, "
+ private static final String CREATE_USER_PACKETS =
+ "CREATE TABLE IF NOT EXISTS " + Tables.USER_PACKETS + "("
+ + UserPacketsColumns.MASTER_KEY_ID + " INTEGER, "
+ + UserPacketsColumns.TYPE + " INT, "
+ + UserPacketsColumns.USER_ID + " TEXT, "
+ + UserPacketsColumns.ATTRIBUTE_DATA + " BLOB, "
- + UserIdsColumns.IS_PRIMARY + " INTEGER, "
- + UserIdsColumns.IS_REVOKED + " INTEGER, "
- + UserIdsColumns.RANK+ " INTEGER, "
+ + UserPacketsColumns.IS_PRIMARY + " INTEGER, "
+ + UserPacketsColumns.IS_REVOKED + " INTEGER, "
+ + UserPacketsColumns.RANK+ " INTEGER, "
- + "PRIMARY KEY(" + UserIdsColumns.MASTER_KEY_ID + ", " + UserIdsColumns.USER_ID + "), "
- + "UNIQUE (" + UserIdsColumns.MASTER_KEY_ID + ", " + UserIdsColumns.RANK + "), "
- + "FOREIGN KEY(" + UserIdsColumns.MASTER_KEY_ID + ") REFERENCES "
+ + "PRIMARY KEY(" + UserPacketsColumns.MASTER_KEY_ID + ", " + UserPacketsColumns.USER_ID + "), "
+ + "UNIQUE (" + UserPacketsColumns.MASTER_KEY_ID + ", " + UserPacketsColumns.RANK + "), "
+ + "FOREIGN KEY(" + UserPacketsColumns.MASTER_KEY_ID + ") REFERENCES "
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
+ ")";
@@ -138,7 +142,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ "FOREIGN KEY(" + CertsColumns.MASTER_KEY_ID + ") REFERENCES "
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE,"
+ "FOREIGN KEY(" + CertsColumns.MASTER_KEY_ID + ", " + CertsColumns.RANK + ") REFERENCES "
- + Tables.USER_IDS + "(" + UserIdsColumns.MASTER_KEY_ID + ", " + UserIdsColumns.RANK + ") ON DELETE CASCADE"
+ + Tables.USER_PACKETS + "(" + UserPacketsColumns.MASTER_KEY_ID + ", " + UserPacketsColumns.RANK + ") ON DELETE CASCADE"
+ ")";
private static final String CREATE_API_APPS =
@@ -164,6 +168,18 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE"
+ ")";
+ private static final String CREATE_API_APPS_ALLOWED_KEYS =
+ "CREATE TABLE IF NOT EXISTS " + Tables.API_ALLOWED_KEYS + " ("
+ + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + ApiAppsAllowedKeysColumns.KEY_ID + " INTEGER, "
+ + ApiAppsAllowedKeysColumns.PACKAGE_NAME + " TEXT NOT NULL, "
+
+ + "UNIQUE(" + ApiAppsAllowedKeysColumns.KEY_ID + ", "
+ + ApiAppsAllowedKeysColumns.PACKAGE_NAME + "), "
+ + "FOREIGN KEY(" + ApiAppsAllowedKeysColumns.PACKAGE_NAME + ") REFERENCES "
+ + Tables.API_APPS + "(" + ApiAppsAllowedKeysColumns.PACKAGE_NAME + ") ON DELETE CASCADE"
+ + ")";
+
KeychainDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
@@ -189,10 +205,11 @@ public class KeychainDatabase extends SQLiteOpenHelper {
db.execSQL(CREATE_KEYRINGS_PUBLIC);
db.execSQL(CREATE_KEYRINGS_SECRET);
db.execSQL(CREATE_KEYS);
- db.execSQL(CREATE_USER_IDS);
+ db.execSQL(CREATE_USER_PACKETS);
db.execSQL(CREATE_CERTS);
db.execSQL(CREATE_API_APPS);
db.execSQL(CREATE_API_APPS_ACCOUNTS);
+ db.execSQL(CREATE_API_APPS_ALLOWED_KEYS);
}
@Override
@@ -238,6 +255,18 @@ public class KeychainDatabase extends SQLiteOpenHelper {
case 5:
// do consolidate for 3.0 beta3
// fall through
+ case 6:
+ db.execSQL("ALTER TABLE user_ids ADD COLUMN type INTEGER");
+ db.execSQL("ALTER TABLE user_ids ADD COLUMN attribute_data BLOB");
+ case 7:
+ // consolidate
+ case 8:
+ // new table for allowed key ids in API
+ try {
+ db.execSQL(CREATE_API_APPS_ALLOWED_KEYS);
+ } catch (Exception e) {
+ // never mind, the column probably already existed
+ }
}
// always do consolidate after upgrade
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
index d40287690..2601c1f69 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
@@ -32,12 +32,14 @@ import android.text.TextUtils;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPacketsColumns;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.util.Log;
@@ -62,9 +64,10 @@ public class KeychainProvider extends ContentProvider {
private static final int KEY_RING_CERTS_SPECIFIC = 206;
private static final int API_APPS = 301;
- private static final int API_APPS_BY_PACKAGE_NAME = 303;
- private static final int API_ACCOUNTS = 304;
- private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306;
+ private static final int API_APPS_BY_PACKAGE_NAME = 302;
+ private static final int API_ACCOUNTS = 303;
+ private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 304;
+ private static final int API_ALLOWED_KEYS = 305;
private static final int KEY_RINGS_FIND_BY_EMAIL = 400;
private static final int KEY_RINGS_FIND_BY_SUBKEY = 401;
@@ -161,6 +164,8 @@ public class KeychainProvider extends ContentProvider {
*
* api_apps/_/accounts
* api_apps/_/accounts/_ (account name)
+ *
+ * api_apps/_/allowed_keys
* </pre>
*/
matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS);
@@ -171,6 +176,9 @@ public class KeychainProvider extends ContentProvider {
matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/"
+ KeychainContract.PATH_ACCOUNTS + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME);
+ matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/"
+ + KeychainContract.PATH_ALLOWED_KEYS, API_ALLOWED_KEYS);
+
return matcher;
}
@@ -205,7 +213,7 @@ public class KeychainProvider extends ContentProvider {
return Keys.CONTENT_TYPE;
case KEY_RING_USER_IDS:
- return UserIds.CONTENT_TYPE;
+ return UserPackets.CONTENT_TYPE;
case KEY_RING_SECRET:
return KeyRings.CONTENT_ITEM_TYPE;
@@ -222,6 +230,9 @@ public class KeychainProvider extends ContentProvider {
case API_ACCOUNTS_BY_ACCOUNT_NAME:
return ApiAccounts.CONTENT_ITEM_TYPE;
+ case API_ALLOWED_KEYS:
+ return ApiAllowedKeys.CONTENT_TYPE;
+
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
@@ -247,7 +258,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_UNIFIED:
case KEY_RINGS_FIND_BY_EMAIL:
case KEY_RINGS_FIND_BY_SUBKEY: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(KeyRings._ID, Tables.KEYS + ".oid AS _id");
projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
projectionMap.put(KeyRings.KEY_ID, Tables.KEYS + "." + Keys.KEY_ID);
@@ -262,7 +273,7 @@ public class KeychainProvider extends ContentProvider {
projectionMap.put(KeyRings.EXPIRY, Tables.KEYS + "." + Keys.EXPIRY);
projectionMap.put(KeyRings.ALGORITHM, Tables.KEYS + "." + Keys.ALGORITHM);
projectionMap.put(KeyRings.FINGERPRINT, Tables.KEYS + "." + Keys.FINGERPRINT);
- projectionMap.put(KeyRings.USER_ID, UserIds.USER_ID);
+ projectionMap.put(KeyRings.USER_ID, UserPackets.USER_ID);
projectionMap.put(KeyRings.VERIFIED, KeyRings.VERIFIED);
projectionMap.put(KeyRings.PUBKEY_DATA,
Tables.KEY_RINGS_PUBLIC + "." + KeyRingData.KEY_RING_DATA
@@ -296,11 +307,12 @@ public class KeychainProvider extends ContentProvider {
qb.setTables(
Tables.KEYS
- + " INNER JOIN " + Tables.USER_IDS + " ON ("
+ + " INNER JOIN " + Tables.USER_PACKETS + " ON ("
+ Tables.KEYS + "." + Keys.MASTER_KEY_ID
+ " = "
- + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID
- + " AND " + Tables.USER_IDS + "." + UserIds.RANK + " = 0"
+ + Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID
+ // we KNOW that the rank zero user packet is a user id!
+ + " AND " + Tables.USER_PACKETS + "." + UserPackets.RANK + " = 0"
+ ") LEFT JOIN " + Tables.CERTS + " ON ("
+ Tables.KEYS + "." + Keys.MASTER_KEY_ID
+ " = "
@@ -376,7 +388,7 @@ public class KeychainProvider extends ContentProvider {
String subkey = Long.valueOf(uri.getLastPathSegment()).toString();
qb.appendWhere(" AND EXISTS ("
+ " SELECT 1 FROM " + Tables.KEYS + " AS tmp"
- + " WHERE tmp." + UserIds.MASTER_KEY_ID
+ + " WHERE tmp." + UserPackets.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
+ " AND tmp." + Keys.KEY_ID + " = " + subkey + ""
+ ")");
@@ -398,15 +410,15 @@ public class KeychainProvider extends ContentProvider {
if (i != 0) {
emailWhere += " OR ";
}
- emailWhere += "tmp." + UserIds.USER_ID + " LIKE ";
+ emailWhere += "tmp." + UserPackets.USER_ID + " LIKE ";
// match '*<email>', so it has to be at the *end* of the user id
emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
gotCondition = true;
}
if(gotCondition) {
qb.appendWhere(" AND EXISTS ("
- + " SELECT 1 FROM " + Tables.USER_IDS + " AS tmp"
- + " WHERE tmp." + UserIds.MASTER_KEY_ID
+ + " SELECT 1 FROM " + Tables.USER_PACKETS + " AS tmp"
+ + " WHERE tmp." + UserPackets.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
+ " AND (" + emailWhere + ")"
+ ")");
@@ -420,7 +432,7 @@ public class KeychainProvider extends ContentProvider {
}
if (TextUtils.isEmpty(sortOrder)) {
- sortOrder = Tables.USER_IDS + "." + UserIds.USER_ID + " ASC";
+ sortOrder = Tables.USER_PACKETS + "." + UserPackets.USER_ID + " ASC";
}
// uri to watch is all /key_rings/
@@ -430,7 +442,7 @@ public class KeychainProvider extends ContentProvider {
}
case KEY_RING_KEYS: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(Keys._ID, Tables.KEYS + ".oid AS _id");
projectionMap.put(Keys.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
projectionMap.put(Keys.RANK, Tables.KEYS + "." + Keys.RANK);
@@ -458,37 +470,45 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_USER_IDS:
case KEY_RING_USER_IDS: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
- projectionMap.put(UserIds._ID, Tables.USER_IDS + ".oid AS _id");
- projectionMap.put(UserIds.MASTER_KEY_ID, Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID);
- projectionMap.put(UserIds.USER_ID, Tables.USER_IDS + "." + UserIds.USER_ID);
- projectionMap.put(UserIds.RANK, Tables.USER_IDS + "." + UserIds.RANK);
- projectionMap.put(UserIds.IS_PRIMARY, Tables.USER_IDS + "." + UserIds.IS_PRIMARY);
- projectionMap.put(UserIds.IS_REVOKED, Tables.USER_IDS + "." + UserIds.IS_REVOKED);
+ HashMap<String, String> projectionMap = new HashMap<>();
+ projectionMap.put(UserPackets._ID, Tables.USER_PACKETS + ".oid AS _id");
+ projectionMap.put(UserPackets.MASTER_KEY_ID, Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID);
+ projectionMap.put(UserPackets.TYPE, Tables.USER_PACKETS + "." + UserPackets.TYPE);
+ projectionMap.put(UserPackets.USER_ID, Tables.USER_PACKETS + "." + UserPackets.USER_ID);
+ projectionMap.put(UserPackets.ATTRIBUTE_DATA, Tables.USER_PACKETS + "." + UserPackets.ATTRIBUTE_DATA);
+ projectionMap.put(UserPackets.RANK, Tables.USER_PACKETS + "." + UserPackets.RANK);
+ projectionMap.put(UserPackets.IS_PRIMARY, Tables.USER_PACKETS + "." + UserPackets.IS_PRIMARY);
+ projectionMap.put(UserPackets.IS_REVOKED, Tables.USER_PACKETS + "." + UserPackets.IS_REVOKED);
// we take the minimum (>0) here, where "1" is "verified by known secret key"
- projectionMap.put(UserIds.VERIFIED, "MIN(" + Certs.VERIFIED + ") AS " + UserIds.VERIFIED);
+ projectionMap.put(UserPackets.VERIFIED, "MIN(" + Certs.VERIFIED + ") AS " + UserPackets.VERIFIED);
qb.setProjectionMap(projectionMap);
- qb.setTables(Tables.USER_IDS
+ qb.setTables(Tables.USER_PACKETS
+ " LEFT JOIN " + Tables.CERTS + " ON ("
- + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID + " = "
+ + Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " = "
+ Tables.CERTS + "." + Certs.MASTER_KEY_ID
- + " AND " + Tables.USER_IDS + "." + UserIds.RANK + " = "
+ + " AND " + Tables.USER_PACKETS + "." + UserPackets.RANK + " = "
+ Tables.CERTS + "." + Certs.RANK
+ " AND " + Tables.CERTS + "." + Certs.VERIFIED + " > 0"
+ ")");
- groupBy = Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID
- + ", " + Tables.USER_IDS + "." + UserIds.RANK;
+ groupBy = Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID
+ + ", " + Tables.USER_PACKETS + "." + UserPackets.RANK;
+
+ // for now, we only respect user ids here, so TYPE must be NULL
+ // TODO expand with KEY_RING_USER_PACKETS query type which lifts this restriction
+ qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL");
// If we are searching for a particular keyring's ids, add where
if (match == KEY_RING_USER_IDS) {
- qb.appendWhere(Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID + " = ");
+ // TODO remove with the thing above
+ qb.appendWhere(" AND ");
+ qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " = ");
qb.appendWhereEscapeString(uri.getPathSegments().get(1));
}
if (TextUtils.isEmpty(sortOrder)) {
- sortOrder = Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID + " ASC"
- + "," + Tables.USER_IDS + "." + UserIds.RANK + " ASC";
+ sortOrder = Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " ASC"
+ + "," + Tables.USER_PACKETS + "." + UserPackets.RANK + " ASC";
}
break;
@@ -497,7 +517,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_PUBLIC:
case KEY_RING_PUBLIC: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_PUBLIC + ".oid AS _id");
projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID);
projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA);
@@ -515,7 +535,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_SECRET:
case KEY_RING_SECRET: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_SECRET + ".oid AS _id");
projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID);
projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA);
@@ -533,7 +553,7 @@ public class KeychainProvider extends ContentProvider {
case KEY_RING_CERTS:
case KEY_RING_CERTS_SPECIFIC: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
+ HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(Certs._ID, Tables.CERTS + ".oid AS " + Certs._ID);
projectionMap.put(Certs.MASTER_KEY_ID, Tables.CERTS + "." + Certs.MASTER_KEY_ID);
projectionMap.put(Certs.RANK, Tables.CERTS + "." + Certs.RANK);
@@ -542,20 +562,24 @@ public class KeychainProvider extends ContentProvider {
projectionMap.put(Certs.CREATION, Tables.CERTS + "." + Certs.CREATION);
projectionMap.put(Certs.KEY_ID_CERTIFIER, Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER);
projectionMap.put(Certs.DATA, Tables.CERTS + "." + Certs.DATA);
- projectionMap.put(Certs.USER_ID, Tables.USER_IDS + "." + UserIds.USER_ID);
- projectionMap.put(Certs.SIGNER_UID, "signer." + UserIds.USER_ID + " AS " + Certs.SIGNER_UID);
+ projectionMap.put(Certs.USER_ID, Tables.USER_PACKETS + "." + UserPackets.USER_ID);
+ projectionMap.put(Certs.SIGNER_UID, "signer." + UserPackets.USER_ID + " AS " + Certs.SIGNER_UID);
qb.setProjectionMap(projectionMap);
qb.setTables(Tables.CERTS
- + " JOIN " + Tables.USER_IDS + " ON ("
+ + " JOIN " + Tables.USER_PACKETS + " ON ("
+ Tables.CERTS + "." + Certs.MASTER_KEY_ID + " = "
- + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID
+ + Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID
+ " AND "
+ Tables.CERTS + "." + Certs.RANK + " = "
- + Tables.USER_IDS + "." + UserIds.RANK
- + ") LEFT JOIN " + Tables.USER_IDS + " AS signer ON ("
+ + Tables.USER_PACKETS + "." + UserPackets.RANK
+ // for now, we only return user ids here, so TYPE must be NULL
+ // TODO at some point, we should lift this restriction
+ + " AND "
+ + Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL"
+ + ") LEFT JOIN " + Tables.USER_PACKETS + " AS signer ON ("
+ Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER + " = "
- + "signer." + UserIds.MASTER_KEY_ID
+ + "signer." + UserPackets.MASTER_KEY_ID
+ " AND "
+ "signer." + Keys.RANK + " = 0"
+ ")");
@@ -600,6 +624,12 @@ public class KeychainProvider extends ContentProvider {
qb.appendWhereEscapeString(uri.getLastPathSegment());
break;
+ case API_ALLOWED_KEYS:
+ qb.setTables(Tables.API_ALLOWED_KEYS);
+ qb.appendWhere(Tables.API_ALLOWED_KEYS + "." + ApiAccounts.PACKAGE_NAME + " = ");
+ qb.appendWhereEscapeString(uri.getPathSegments().get(1));
+
+ break;
default:
throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")");
@@ -662,8 +692,18 @@ public class KeychainProvider extends ContentProvider {
break;
case KEY_RING_USER_IDS:
- db.insertOrThrow(Tables.USER_IDS, null, values);
- keyId = values.getAsLong(UserIds.MASTER_KEY_ID);
+ // iff TYPE is null, user_id MUST be null as well
+ if ( ! (values.get(UserPacketsColumns.TYPE) == null
+ ? (values.get(UserPacketsColumns.USER_ID) != null && values.get(UserPacketsColumns.ATTRIBUTE_DATA) == null)
+ : (values.get(UserPacketsColumns.ATTRIBUTE_DATA) != null && values.get(UserPacketsColumns.USER_ID) == null)
+ )) {
+ throw new AssertionError("Incorrect type for user packet! This is a bug!");
+ }
+ if (((Number)values.get(UserPacketsColumns.RANK)).intValue() == 0 && values.get(UserPacketsColumns.USER_ID) == null) {
+ throw new AssertionError("Rank 0 user packet must be a user id!");
+ }
+ db.insertOrThrow(Tables.USER_PACKETS, null, values);
+ keyId = values.getAsLong(UserPackets.MASTER_KEY_ID);
break;
case KEY_RING_CERTS:
@@ -677,7 +717,7 @@ public class KeychainProvider extends ContentProvider {
db.insertOrThrow(Tables.API_APPS, null, values);
break;
- case API_ACCOUNTS:
+ case API_ACCOUNTS: {
// set foreign key automatically based on given uri
// e.g., api_apps/com.example.app/accounts/
String packageName = uri.getPathSegments().get(1);
@@ -685,12 +725,21 @@ public class KeychainProvider extends ContentProvider {
db.insertOrThrow(Tables.API_ACCOUNTS, null, values);
break;
+ }
+ case API_ALLOWED_KEYS: {
+ // set foreign key automatically based on given uri
+ // e.g., api_apps/com.example.app/allowed_keys/
+ String packageName = uri.getPathSegments().get(1);
+ values.put(ApiAllowedKeys.PACKAGE_NAME, packageName);
+ db.insertOrThrow(Tables.API_ALLOWED_KEYS, null, values);
+ break;
+ }
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
- if(keyId != null) {
+ if (keyId != null) {
uri = KeyRings.buildGenericKeyRingUri(keyId);
rowUri = uri;
}
@@ -753,6 +802,10 @@ public class KeychainProvider extends ContentProvider {
count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, additionalSelection),
selectionArgs);
break;
+ case API_ALLOWED_KEYS:
+ count = db.delete(Tables.API_ALLOWED_KEYS, buildDefaultApiAllowedKeysSelection(uri, additionalSelection),
+ selectionArgs);
+ break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
@@ -845,4 +898,15 @@ public class KeychainProvider extends ContentProvider {
+ andSelection;
}
+ private String buildDefaultApiAllowedKeysSelection(Uri uri, String selection) {
+ String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(1));
+
+ String andSelection = "";
+ if (!TextUtils.isEmpty(selection)) {
+ andSelection = " AND (" + selection + ")";
+ }
+
+ return ApiAllowedKeys.PACKAGE_NAME + "=" + packageName + andSelection;
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index 05dc99c5e..d947ae053 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -30,11 +30,13 @@ import android.support.v4.util.LongSparseArray;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
-import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
+import org.sufficientlysecure.keychain.operations.ImportExportOperation;
+import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
+import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
+import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
@@ -42,27 +44,27 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.operations.ImportExportOperation;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
import org.sufficientlysecure.keychain.pgp.WrappedSignature;
+import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.remote.AccountSettings;
import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
-import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
-import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
-import org.sufficientlysecure.keychain.util.ParcelableFileCache;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.ParcelableFileCache;
+import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
+import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import org.sufficientlysecure.keychain.util.Utf8Util;
@@ -169,7 +171,7 @@ public class ProviderHelper {
Cursor cursor = mContentResolver.query(uri, proj, selection, null, null);
try {
- HashMap<String, Object> result = new HashMap<String, Object>(proj.length);
+ HashMap<String, Object> result = new HashMap<>(proj.length);
if (cursor != null && cursor.moveToFirst()) {
int pos = 0;
for (String p : proj) {
@@ -192,6 +194,9 @@ public class ProviderHelper {
}
pos += 1;
}
+ } else {
+ // If no data was found, throw an appropriate exception
+ throw new NotFoundException();
}
return result;
@@ -217,7 +222,7 @@ public class ProviderHelper {
}, KeyRings.HAS_ANY_SECRET + " = 1", null, null);
try {
- LongSparseArray<CanonicalizedPublicKey> result = new LongSparseArray<CanonicalizedPublicKey>();
+ LongSparseArray<CanonicalizedPublicKey> result = new LongSparseArray<>();
if (cursor != null && cursor.moveToFirst()) do {
long masterKeyId = cursor.getLong(0);
@@ -346,7 +351,7 @@ public class ProviderHelper {
mIndent += 1;
// save all keys and userIds included in keyRing object in database
- operations = new ArrayList<ContentProviderOperation>();
+ operations = new ArrayList<>();
log(LogType.MSG_IP_INSERT_KEYRING);
{ // insert keyring
@@ -436,18 +441,18 @@ public class ProviderHelper {
// classify and order user ids. primary are moved to the front, revoked to the back,
// otherwise the order in the keyfile is preserved.
+ List<UserPacketItem> uids = new ArrayList<>();
+
if (trustedKeys.size() == 0) {
log(LogType.MSG_IP_UID_CLASSIFYING_ZERO);
} else {
log(LogType.MSG_IP_UID_CLASSIFYING, trustedKeys.size());
}
mIndent += 1;
- List<UserIdItem> uids = new ArrayList<UserIdItem>();
- for (byte[] rawUserId : new IterableIterator<byte[]>(
- masterKey.getUnorderedRawUserIds().iterator())) {
+ for (byte[] rawUserId : masterKey.getUnorderedRawUserIds()) {
String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId);
- UserIdItem item = new UserIdItem();
+ UserPacketItem item = new UserPacketItem();
uids.add(item);
item.userId = userId;
@@ -456,7 +461,7 @@ public class ProviderHelper {
log(LogType.MSG_IP_UID_PROCESSING, userId);
mIndent += 1;
// look through signatures for this specific key
- for (WrappedSignature cert : new IterableIterator<WrappedSignature>(
+ for (WrappedSignature cert : new IterableIterator<>(
masterKey.getSignaturesForRawId(rawUserId))) {
long certId = cert.getKeyId();
// self signature
@@ -468,7 +473,7 @@ public class ProviderHelper {
item.selfCert = cert;
item.isPrimary = cert.isPrimaryUserId();
} else {
- item.isRevoked = true;
+ item.selfRevocation = cert;
log(LogType.MSG_IP_UID_REVOKED);
}
continue;
@@ -530,6 +535,106 @@ public class ProviderHelper {
}
mIndent -= 1;
+ ArrayList<WrappedUserAttribute> userAttributes = masterKey.getUnorderedUserAttributes();
+ // Don't spam the log if there aren't even any attributes
+ if ( ! userAttributes.isEmpty()) {
+ log(LogType.MSG_IP_UAT_CLASSIFYING);
+ }
+
+ mIndent += 1;
+ for (WrappedUserAttribute userAttribute : userAttributes) {
+
+ UserPacketItem item = new UserPacketItem();
+ uids.add(item);
+ item.type = userAttribute.getType();
+ item.attributeData = userAttribute.getEncoded();
+
+ int unknownCerts = 0;
+
+ switch (item.type) {
+ case WrappedUserAttribute.UAT_IMAGE:
+ log(LogType.MSG_IP_UAT_PROCESSING_IMAGE);
+ break;
+ default:
+ log(LogType.MSG_IP_UAT_PROCESSING_UNKNOWN);
+ break;
+ }
+ mIndent += 1;
+ // look through signatures for this specific key
+ for (WrappedSignature cert : new IterableIterator<>(
+ masterKey.getSignaturesForUserAttribute(userAttribute))) {
+ long certId = cert.getKeyId();
+ // self signature
+ if (certId == masterKeyId) {
+
+ // NOTE self-certificates are already verified during canonicalization,
+ // AND we know there is at most one cert plus at most one revocation
+ // AND the revocation only exists if there is no newer certification
+ if (!cert.isRevocation()) {
+ item.selfCert = cert;
+ } else {
+ item.selfRevocation = cert;
+ log(LogType.MSG_IP_UAT_REVOKED);
+ }
+ continue;
+
+ }
+
+ // do we have a trusted key for this?
+ if (trustedKeys.indexOfKey(certId) < 0) {
+ unknownCerts += 1;
+ continue;
+ }
+
+ // verify signatures from known private keys
+ CanonicalizedPublicKey trustedKey = trustedKeys.get(certId);
+
+ try {
+ cert.init(trustedKey);
+ // if it doesn't certify, leave a note and skip
+ if ( ! cert.verifySignature(masterKey, userAttribute)) {
+ log(LogType.MSG_IP_UAT_CERT_BAD);
+ continue;
+ }
+
+ log(cert.isRevocation()
+ ? LogType.MSG_IP_UAT_CERT_GOOD_REVOKE
+ : LogType.MSG_IP_UAT_CERT_GOOD,
+ KeyFormattingUtils.convertKeyIdToHexShort(trustedKey.getKeyId())
+ );
+
+ // check if there is a previous certificate
+ WrappedSignature prev = item.trustedCerts.get(cert.getKeyId());
+ if (prev != null) {
+ // if it's newer, skip this one
+ if (prev.getCreationTime().after(cert.getCreationTime())) {
+ log(LogType.MSG_IP_UAT_CERT_OLD);
+ continue;
+ }
+ // if the previous one was a non-revokable certification, no need to look further
+ if (!prev.isRevocation() && !prev.isRevokable()) {
+ log(LogType.MSG_IP_UAT_CERT_NONREVOKE);
+ continue;
+ }
+ log(LogType.MSG_IP_UAT_CERT_NEW);
+ }
+ item.trustedCerts.put(cert.getKeyId(), cert);
+
+ } catch (PgpGeneralException e) {
+ log(LogType.MSG_IP_UAT_CERT_ERROR,
+ KeyFormattingUtils.convertKeyIdToHex(cert.getKeyId()));
+ }
+
+ }
+
+ if (unknownCerts > 0) {
+ log(LogType.MSG_IP_UAT_CERTS_UNKNOWN, unknownCerts);
+ }
+ mIndent -= 1;
+
+ }
+ mIndent -= 1;
+
progress.setProgress(LogType.MSG_IP_UID_REORDER.getMsgId(), 65, 100);
log(LogType.MSG_IP_UID_REORDER);
// primary before regular before revoked (see UserIdItem.compareTo)
@@ -537,17 +642,23 @@ public class ProviderHelper {
Collections.sort(uids);
// iterate and put into db
for (int userIdRank = 0; userIdRank < uids.size(); userIdRank++) {
- UserIdItem item = uids.get(userIdRank);
+ UserPacketItem item = uids.get(userIdRank);
operations.add(buildUserIdOperations(masterKeyId, item, userIdRank));
- if (item.selfCert != null) {
- operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert,
- selfCertsAreTrusted ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF));
+
+ if (item.selfCert == null) {
+ throw new AssertionError("User ids MUST be self-certified at this point!!");
}
- // don't bother with trusted certs if the uid is revoked, anyways
- if (item.isRevoked) {
+
+ if (item.selfRevocation != null) {
+ operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfRevocation,
+ Certs.VERIFIED_SELF));
+ // don't bother with trusted certs if the uid is revoked, anyways
continue;
}
+ operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert,
+ selfCertsAreTrusted ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF));
+
// iterate over signatures
for (int i = 0; i < item.trustedCerts.size() ; i++) {
WrappedSignature sig = item.trustedCerts.valueAt(i);
@@ -601,23 +712,32 @@ public class ProviderHelper {
}
- private static class UserIdItem implements Comparable<UserIdItem> {
+ private static class UserPacketItem implements Comparable<UserPacketItem> {
+ Integer type;
String userId;
+ byte[] attributeData;
boolean isPrimary = false;
- boolean isRevoked = false;
WrappedSignature selfCert;
- LongSparseArray<WrappedSignature> trustedCerts = new LongSparseArray<WrappedSignature>();
+ WrappedSignature selfRevocation;
+ LongSparseArray<WrappedSignature> trustedCerts = new LongSparseArray<>();
@Override
- public int compareTo(UserIdItem o) {
+ public int compareTo(UserPacketItem o) {
+ // revoked keys always come last!
+ //noinspection DoubleNegation
+ if ( (selfRevocation != null) != (o.selfRevocation != null)) {
+ return selfRevocation != null ? 1 : -1;
+ }
+ // if one is a user id, but the other isn't, the user id always comes first.
+ // we compare for null values here, so != is the correct operator!
+ // noinspection NumberEquality
+ if (type != o.type) {
+ return type == null ? -1 : 1;
+ }
// if one key is primary but the other isn't, the primary one always comes first
if (isPrimary != o.isPrimary) {
return isPrimary ? -1 : 1;
}
- // revoked keys always come last!
- if (isRevoked != o.isRevoked) {
- return isRevoked ? 1 : -1;
- }
return 0;
}
}
@@ -682,6 +802,11 @@ public class ProviderHelper {
KeyFormattingUtils.convertKeyIdToHex(id)
);
break;
+ case PIN:
+ log(LogType.MSG_IS_SUBKEY_PIN,
+ KeyFormattingUtils.convertKeyIdToHex(id)
+ );
+ break;
case GNU_DUMMY:
log(LogType.MSG_IS_SUBKEY_STRIPPED,
KeyFormattingUtils.convertKeyIdToHex(id)
@@ -936,6 +1061,11 @@ public class ProviderHelper {
log.add(LogType.MSG_CON, indent);
indent += 1;
+ if (mConsolidateCritical) {
+ log.add(LogType.MSG_CON_RECURSIVE, indent);
+ return new ConsolidateResult(ConsolidateResult.RESULT_OK, log);
+ }
+
progress.setProgress(R.string.progress_con_saving, 0, 100);
// The consolidate operation can never be cancelled!
@@ -958,7 +1088,7 @@ public class ProviderHelper {
// No keys existing might be a legitimate option, we write an empty file in that case
cursor.moveToFirst();
ParcelableFileCache<ParcelableKeyRing> cache =
- new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
+ new ParcelableFileCache<>(mContext, "consolidate_secret.pcl");
cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring;
@@ -1020,7 +1150,7 @@ public class ProviderHelper {
// No keys existing might be a legitimate option, we write an empty file in that case
cursor.moveToFirst();
ParcelableFileCache<ParcelableKeyRing> cache =
- new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl");
+ new ParcelableFileCache<>(mContext, "consolidate_public.pcl");
cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring;
@@ -1102,13 +1232,11 @@ public class ProviderHelper {
log.add(LogType.MSG_CON_DB_CLEAR, indent);
mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null);
- ParcelableFileCache<ParcelableKeyRing> cacheSecret =
- new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
- ParcelableFileCache<ParcelableKeyRing> cachePublic =
- new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl");
+ ParcelableFileCache<ParcelableKeyRing> cacheSecret, cachePublic;
// Set flag that we have a cached consolidation here
try {
+ cacheSecret = new ParcelableFileCache<>(mContext, "consolidate_secret.pcl");
IteratorWithSize<ParcelableKeyRing> itSecrets = cacheSecret.readCache(false);
int numSecrets = itSecrets.getSize();
@@ -1136,6 +1264,7 @@ public class ProviderHelper {
try {
+ cachePublic = new ParcelableFileCache<>(mContext, "consolidate_public.pcl");
IteratorWithSize<ParcelableKeyRing> itPublics = cachePublic.readCache();
int numPublics = itPublics.getSize();
@@ -1191,7 +1320,6 @@ public class ProviderHelper {
progress.setProgress(100, 100);
log.add(LogType.MSG_CON_SUCCESS, indent);
- indent -= 1;
return new ConsolidateResult(ConsolidateResult.RESULT_OK, log);
@@ -1225,15 +1353,17 @@ public class ProviderHelper {
* Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing
*/
private ContentProviderOperation
- buildUserIdOperations(long masterKeyId, UserIdItem item, int rank) {
+ buildUserIdOperations(long masterKeyId, UserPacketItem item, int rank) {
ContentValues values = new ContentValues();
- values.put(UserIds.MASTER_KEY_ID, masterKeyId);
- values.put(UserIds.USER_ID, item.userId);
- values.put(UserIds.IS_PRIMARY, item.isPrimary);
- values.put(UserIds.IS_REVOKED, item.isRevoked);
- values.put(UserIds.RANK, rank);
+ values.put(UserPackets.MASTER_KEY_ID, masterKeyId);
+ values.put(UserPackets.TYPE, item.type);
+ values.put(UserPackets.USER_ID, item.userId);
+ values.put(UserPackets.ATTRIBUTE_DATA, item.attributeData);
+ values.put(UserPackets.IS_PRIMARY, item.isPrimary);
+ values.put(UserPackets.IS_REVOKED, item.selfRevocation != null);
+ values.put(UserPackets.RANK, rank);
- Uri uri = UserIds.buildUserIdsUri(masterKeyId);
+ Uri uri = UserPackets.buildUserIdsUri(masterKeyId);
return ContentProviderOperation.newInsert(uri).withValues(values).build();
}
@@ -1261,7 +1391,7 @@ public class ProviderHelper {
public ArrayList<String> getRegisteredApiApps() {
Cursor cursor = mContentResolver.query(ApiApps.CONTENT_URI, null, null, null, null);
- ArrayList<String> packageNames = new ArrayList<String>();
+ ArrayList<String> packageNames = new ArrayList<>();
try {
if (cursor != null) {
int packageNameCol = cursor.getColumnIndex(ApiApps.PACKAGE_NAME);
@@ -1366,7 +1496,7 @@ public class ProviderHelper {
}
public Set<Long> getAllKeyIdsForApp(Uri uri) {
- Set<Long> keyIds = new HashSet<Long>();
+ Set<Long> keyIds = new HashSet<>();
Cursor cursor = mContentResolver.query(uri, null, null, null, null);
try {
@@ -1385,8 +1515,41 @@ public class ProviderHelper {
return keyIds;
}
+ public Set<Long> getAllowedKeyIdsForApp(Uri uri) {
+ Set<Long> keyIds = new HashSet<>();
+
+ Cursor cursor = mContentResolver.query(uri, null, null, null, null);
+ try {
+ if (cursor != null) {
+ int keyIdColumn = cursor.getColumnIndex(KeychainContract.ApiAllowedKeys.KEY_ID);
+ while (cursor.moveToNext()) {
+ keyIds.add(cursor.getLong(keyIdColumn));
+ }
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ return keyIds;
+ }
+
+ public void saveAllowedKeyIdsForApp(Uri uri, Set<Long> allowedKeyIds)
+ throws RemoteException, OperationApplicationException {
+ // wipe whole table of allowed keys for this account
+ mContentResolver.delete(uri, null, null);
+
+ // re-insert allowed key ids
+ for (Long keyId : allowedKeyIds) {
+ ContentValues values = new ContentValues();
+ values.put(ApiAllowedKeys.KEY_ID, keyId);
+ mContentResolver.insert(uri, values);
+ }
+ }
+
public Set<String> getAllFingerprints(Uri uri) {
- Set<String> fingerprints = new HashSet<String>();
+ Set<String> fingerprints = new HashSet<>();
String[] projection = new String[]{KeyRings.FINGERPRINT};
Cursor cursor = mContentResolver.query(uri, projection, null, null, null);
try {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
index a5813567a..1a65b1bee 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -26,35 +26,34 @@ import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
import org.openintents.openpgp.IOpenPgpService;
-import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpError;
+import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi;
import org.spongycastle.util.encoders.Hex;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.ui.NfcActivity;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
-import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
+import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
+import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInput;
+import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
-import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
+import org.sufficientlysecure.keychain.ui.NfcActivity;
import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity;
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
@@ -85,9 +84,9 @@ public class OpenPgpService extends RemoteService {
boolean missingUserIdsCheck = false;
boolean duplicateUserIdsCheck = false;
- ArrayList<Long> keyIds = new ArrayList<Long>();
- ArrayList<String> missingUserIds = new ArrayList<String>();
- ArrayList<String> duplicateUserIds = new ArrayList<String>();
+ ArrayList<Long> keyIds = new ArrayList<>();
+ ArrayList<String> missingUserIds = new ArrayList<>();
+ ArrayList<String> duplicateUserIds = new ArrayList<>();
if (!noUserIdsCheck) {
for (String email : encryptionUserIds) {
// try to find the key for this specific email
@@ -222,9 +221,12 @@ public class OpenPgpService extends RemoteService {
}
private Intent signImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AccountSettings accSettings) {
+ ParcelFileDescriptor output, AccountSettings accSettings,
+ boolean cleartextSign) {
+ InputStream is = null;
+ OutputStream os = null;
try {
- boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
+ boolean asciiArmor = cleartextSign || data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
byte[] nfcSignedHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH);
if (nfcSignedHash != null) {
@@ -242,91 +244,55 @@ public class OpenPgpService extends RemoteService {
}
// Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
- try {
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- // Find the appropriate subkey to sign with
- long sigSubKeyId;
- try {
- CachedPublicKeyRing signingRing =
- new ProviderHelper(this).getCachedPublicKeyRing(accSettings.getKeyId());
- sigSubKeyId = signingRing.getSecretSignId();
- } catch (PgpKeyNotFoundException e) {
- // secret key that is set for this account is deleted?
- // show account config again!
- return getCreateAccountIntent(data, getAccountName(data));
- }
-
- // get passphrase from cache, if key has "no" passphrase, this returns an empty String
- String passphrase;
- if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
- passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
+ is = new ParcelFileDescriptor.AutoCloseInputStream(input);
+ if (cleartextSign) {
+ // output stream only needed for cleartext signatures,
+ // detached signatures are returned as extra
+ os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
+ }
+ long inputLength = is.available();
+ InputData inputData = new InputData(is, inputLength);
+
+ // sign-only
+ PgpSignEncryptInput pseInput = new PgpSignEncryptInput()
+ .setEnableAsciiArmorOutput(asciiArmor)
+ .setCleartextSignature(cleartextSign)
+ .setDetachedSignature(!cleartextSign)
+ .setVersionHeader(PgpHelper.getVersionForHeader(this))
+ .setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
+ .setSignatureMasterKeyId(accSettings.getKeyId())
+ .setNfcState(nfcSignedHash, nfcCreationDate);
+
+ // execute PGP operation!
+ PgpSignEncryptOperation pse = new PgpSignEncryptOperation(this, new ProviderHelper(getContext()), null);
+ PgpSignEncryptResult pgpResult = pse.execute(pseInput, inputData, os);
+
+ if (pgpResult.isPending()) {
+ if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) ==
+ PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) {
+ return getPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded());
+ } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) ==
+ PgpSignEncryptResult.RESULT_PENDING_NFC) {
+ // return PendingIntent to execute NFC activity
+ // pass through the signature creation timestamp to be used again on second execution
+ // of PgpSignEncrypt when we have the signed hash!
+ data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, pgpResult.getNfcTimestamp().getTime());
+ return getNfcSignIntent(data, pgpResult.getNfcKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcHash(), pgpResult.getNfcAlgo());
} else {
- try {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(),
- accSettings.getKeyId(), sigSubKeyId);
- } catch (PassphraseCacheService.KeyNotFoundException e) {
- // should happen earlier, but return again here if it happens
- return getCreateAccountIntent(data, getAccountName(data));
- }
+ throw new PgpGeneralException(
+ "Encountered unhandled type of pending action not supported by API!");
}
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- return getPassphraseIntent(data, sigSubKeyId);
- }
-
- // sign-only
- PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(
- this, new ProviderHelper(getContext()), null,
- inputData, os
- );
- builder.setEnableAsciiArmorOutput(asciiArmor)
- .setVersionHeader(PgpHelper.getVersionForHeader(this))
- .setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
- .setSignatureMasterKeyId(accSettings.getKeyId())
- .setSignatureSubKeyId(sigSubKeyId)
- .setSignaturePassphrase(passphrase)
- .setNfcState(nfcSignedHash, nfcCreationDate);
-
- // TODO: currently always assume cleartext input, no sign-only of binary currently!
- builder.setCleartextInput(true);
-
- // execute PGP operation!
- SignEncryptResult pgpResult = builder.build().execute();
-
- if (pgpResult.isPending()) {
- if ((pgpResult.getResult() & SignEncryptResult.RESULT_PENDING_PASSPHRASE) ==
- SignEncryptResult.RESULT_PENDING_PASSPHRASE) {
- return getPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded());
- } else if ((pgpResult.getResult() & SignEncryptResult.RESULT_PENDING_NFC) ==
- SignEncryptResult.RESULT_PENDING_NFC) {
- // return PendingIntent to execute NFC activity
- // pass through the signature creation timestamp to be used again on second execution
- // of PgpSignEncrypt when we have the signed hash!
- data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, pgpResult.getNfcTimestamp().getTime());
- return getNfcSignIntent(data, pgpResult.getNfcKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcHash(), pgpResult.getNfcAlgo());
- } else {
- throw new PgpGeneralException(
- "Encountered unhandled type of pending action not supported by API!");
- }
- } else if (pgpResult.success()) {
- // see end of method
- } else {
- LogEntryParcel errorMsg = pgpResult.getLog().getLast();
- throw new Exception(getString(errorMsg.mType.getMsgId()));
+ } else if (pgpResult.success()) {
+ Intent result = new Intent();
+ if (!cleartextSign) {
+ result.putExtra(OpenPgpApi.RESULT_DETACHED_SIGNATURE, pgpResult.getDetachedSignature());
}
-
- } finally {
- is.close();
- os.close();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
+ return result;
+ } else {
+ LogEntryParcel errorMsg = pgpResult.getLog().getLast();
+ throw new Exception(getString(errorMsg.mType.getMsgId()));
}
-
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
- return result;
} catch (Exception e) {
Log.d(Constants.TAG, "signImpl", e);
Intent result = new Intent();
@@ -334,12 +300,29 @@ public class OpenPgpService extends RemoteService {
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException when closing InputStream", e);
+ }
+ }
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException when closing OutputStream", e);
+ }
+ }
}
}
private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input,
ParcelFileDescriptor output, AccountSettings accSettings,
boolean sign) {
+ InputStream is = null;
+ OutputStream os = null;
try {
boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
String originalFilename = data.getStringExtra(OpenPgpApi.EXTRA_ORIGINAL_FILENAME);
@@ -365,99 +348,65 @@ public class OpenPgpService extends RemoteService {
// build InputData and write into OutputStream
// Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
- try {
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(
- this, new ProviderHelper(getContext()), null, inputData, os
- );
- builder.setEnableAsciiArmorOutput(asciiArmor)
- .setVersionHeader(PgpHelper.getVersionForHeader(this))
- .setCompressionId(accSettings.getCompression())
- .setSymmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm())
- .setEncryptionMasterKeyIds(keyIds)
- .setFailOnMissingEncryptionKeyIds(true)
- .setOriginalFilename(originalFilename)
- .setAdditionalEncryptId(accSettings.getKeyId()); // add acc key for encryption
-
- if (sign) {
-
- // Find the appropriate subkey to sign with
- long sigSubKeyId;
- try {
- CachedPublicKeyRing signingRing =
- new ProviderHelper(this).getCachedPublicKeyRing(accSettings.getKeyId());
- sigSubKeyId = signingRing.getSecretSignId();
- } catch (PgpKeyNotFoundException e) {
- // secret key that is set for this account is deleted?
- // show account config again!
- return getCreateAccountIntent(data, getAccountName(data));
- }
-
- String passphrase;
- if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
- passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- } else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(),
- accSettings.getKeyId(), sigSubKeyId);
- }
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- return getPassphraseIntent(data, sigSubKeyId);
- }
-
- byte[] nfcSignedHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH);
- // carefully: only set if timestamp exists
- Date nfcCreationDate = null;
- long nfcCreationTimestamp = data.getLongExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, -1);
- if (nfcCreationTimestamp != -1) {
- nfcCreationDate = new Date(nfcCreationTimestamp);
- }
-
- // sign and encrypt
- builder.setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
- .setSignatureMasterKeyId(accSettings.getKeyId())
- .setSignatureSubKeyId(sigSubKeyId)
- .setSignaturePassphrase(passphrase)
- .setNfcState(nfcSignedHash, nfcCreationDate);
+ is = new ParcelFileDescriptor.AutoCloseInputStream(input);
+ os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
+
+ long inputLength = is.available();
+ InputData inputData = new InputData(is, inputLength, originalFilename);
+
+ PgpSignEncryptInput pseInput = new PgpSignEncryptInput();
+ pseInput.setEnableAsciiArmorOutput(asciiArmor)
+ .setVersionHeader(PgpHelper.getVersionForHeader(this))
+ .setCompressionId(accSettings.getCompression())
+ .setSymmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm())
+ .setEncryptionMasterKeyIds(keyIds)
+ .setFailOnMissingEncryptionKeyIds(true)
+ .setAdditionalEncryptId(accSettings.getKeyId()); // add acc key for encryption
+
+ if (sign) {
+
+ byte[] nfcSignedHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH);
+ // carefully: only set if timestamp exists
+ Date nfcCreationDate = null;
+ long nfcCreationTimestamp = data.getLongExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, -1);
+ if (nfcCreationTimestamp != -1) {
+ nfcCreationDate = new Date(nfcCreationTimestamp);
}
- // execute PGP operation!
- SignEncryptResult pgpResult = builder.build().execute();
-
- if (pgpResult.isPending()) {
- if ((pgpResult.getResult() & SignEncryptResult.RESULT_PENDING_PASSPHRASE) ==
- SignEncryptResult.RESULT_PENDING_PASSPHRASE) {
- return getPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded());
- } else if ((pgpResult.getResult() & SignEncryptResult.RESULT_PENDING_NFC) ==
- SignEncryptResult.RESULT_PENDING_NFC) {
- // return PendingIntent to execute NFC activity
- // pass through the signature creation timestamp to be used again on second execution
- // of PgpSignEncrypt when we have the signed hash!
- data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, pgpResult.getNfcTimestamp().getTime());
- return getNfcSignIntent(data, pgpResult.getNfcKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcHash(), pgpResult.getNfcAlgo());
- } else {
- throw new PgpGeneralException(
- "Encountered unhandled type of pending action not supported by API!");
- }
- } else if (pgpResult.success()) {
- // see end of method
+ // sign and encrypt
+ pseInput.setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
+ .setSignatureMasterKeyId(accSettings.getKeyId())
+ .setNfcState(nfcSignedHash, nfcCreationDate);
+ }
+
+ PgpSignEncryptOperation op = new PgpSignEncryptOperation(this, new ProviderHelper(getContext()), null);
+
+ // execute PGP operation!
+ PgpSignEncryptResult pgpResult = op.execute(pseInput, inputData, os);
+
+ if (pgpResult.isPending()) {
+ if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) ==
+ PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) {
+ return getPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded());
+ } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) ==
+ PgpSignEncryptResult.RESULT_PENDING_NFC) {
+ // return PendingIntent to execute NFC activity
+ // pass through the signature creation timestamp to be used again on second execution
+ // of PgpSignEncrypt when we have the signed hash!
+ data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, pgpResult.getNfcTimestamp().getTime());
+ return getNfcSignIntent(data, pgpResult.getNfcKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcHash(), pgpResult.getNfcAlgo());
} else {
- LogEntryParcel errorMsg = pgpResult.getLog().getLast();
- throw new Exception(getString(errorMsg.mType.getMsgId()));
+ throw new PgpGeneralException(
+ "Encountered unhandled type of pending action not supported by API!");
}
-
- } finally {
- is.close();
- os.close();
+ } else if (pgpResult.success()) {
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
+ return result;
+ } else {
+ LogEntryParcel errorMsg = pgpResult.getLog().getLast();
+ throw new Exception(getString(errorMsg.mType.getMsgId()));
}
-
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
- return result;
} catch (Exception e) {
Log.d(Constants.TAG, "encryptAndSignImpl", e);
Intent result = new Intent();
@@ -465,111 +414,129 @@ public class OpenPgpService extends RemoteService {
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException when closing InputStream", e);
+ }
+ }
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException when closing OutputStream", e);
+ }
+ }
}
}
private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input,
ParcelFileDescriptor output, Set<Long> allowedKeyIds,
boolean decryptMetadataOnly) {
+ InputStream is = null;
+ OutputStream os = null;
try {
// Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
+ is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os;
- if (decryptMetadataOnly) {
+ // output is optional, e.g., for verifying detached signatures
+ if (decryptMetadataOnly || output == null) {
os = null;
} else {
os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
}
- Intent result = new Intent();
- try {
- String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
- this, new ProviderHelper(getContext()), null, inputData, os
- );
-
- byte[] nfcDecryptedSessionKey = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_DECRYPTED_SESSION_KEY);
-
- // allow only private keys associated with accounts of this app
- // no support for symmetric encryption
- builder.setPassphrase(passphrase)
- .setAllowSymmetricDecryption(false)
- .setAllowedKeyIds(allowedKeyIds)
- .setDecryptMetadataOnly(decryptMetadataOnly)
- .setNfcState(nfcDecryptedSessionKey);
-
- // TODO: currently does not support binary signed-only content
- DecryptVerifyResult pgpResult = builder.build().execute();
-
- if (pgpResult.isPending()) {
- if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) ==
- DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) {
- return getPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded());
- } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) ==
- DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) {
- throw new PgpGeneralException(
- "Decryption of symmetric content not supported by API!");
- } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_NFC) ==
- DecryptVerifyResult.RESULT_PENDING_NFC) {
- return getNfcDecryptIntent(
- data, pgpResult.getNfcSubKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcEncryptedSessionKey());
- } else {
- throw new PgpGeneralException(
- "Encountered unhandled type of pending action not supported by API!");
- }
- } else if (pgpResult.success()) {
-
- OpenPgpSignatureResult signatureResult = pgpResult.getSignatureResult();
- if (signatureResult != null) {
- result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
-
- if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 5) {
- // SIGNATURE_KEY_REVOKED and SIGNATURE_KEY_EXPIRED have been added in version 5
- if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED
- || signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED) {
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
- }
+ String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
+ long inputLength = is.available();
+ InputData inputData = new InputData(is, inputLength);
+
+ PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
+ this, new ProviderHelper(getContext()), null, inputData, os
+ );
+
+ byte[] nfcDecryptedSessionKey = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_DECRYPTED_SESSION_KEY);
+
+ byte[] detachedSignature = data.getByteArrayExtra(OpenPgpApi.EXTRA_DETACHED_SIGNATURE);
+
+ // allow only private keys associated with accounts of this app
+ // no support for symmetric encryption
+ builder.setPassphrase(passphrase)
+ .setAllowSymmetricDecryption(false)
+ .setAllowedKeyIds(allowedKeyIds)
+ .setDecryptMetadataOnly(decryptMetadataOnly)
+ .setNfcState(nfcDecryptedSessionKey)
+ .setDetachedSignature(detachedSignature);
+
+ DecryptVerifyResult pgpResult = builder.build().execute();
+
+ if (pgpResult.isPending()) {
+ if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) ==
+ DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) {
+ return getPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded());
+ } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) ==
+ DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) {
+ throw new PgpGeneralException(
+ "Decryption of symmetric content not supported by API!");
+ } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_NFC) ==
+ DecryptVerifyResult.RESULT_PENDING_NFC) {
+ return getNfcDecryptIntent(
+ data, pgpResult.getNfcSubKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcEncryptedSessionKey());
+ } else {
+ throw new PgpGeneralException(
+ "Encountered unhandled type of pending action not supported by API!");
+ }
+ } else if (pgpResult.success()) {
+ Intent result = new Intent();
+
+ OpenPgpSignatureResult signatureResult = pgpResult.getSignatureResult();
+ if (signatureResult != null) {
+ result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
+
+ if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 5) {
+ // SIGNATURE_KEY_REVOKED and SIGNATURE_KEY_EXPIRED have been added in version 5
+ if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED
+ || signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED) {
+ signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
}
+ }
- if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_MISSING) {
- // If signature is unknown we return an _additional_ PendingIntent
- // to retrieve the missing key
- Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE);
- intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, signatureResult.getKeyId());
- intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data);
+ if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_KEY_MISSING) {
+ // If signature is unknown we return an _additional_ PendingIntent
+ // to retrieve the missing key
+ Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class);
+ intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE);
+ intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, signatureResult.getKeyId());
+ intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data);
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
+ intent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- }
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
}
+ }
- if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) >= 4) {
- OpenPgpMetadata metadata = pgpResult.getDecryptMetadata();
- if (metadata != null) {
- result.putExtra(OpenPgpApi.RESULT_METADATA, metadata);
- }
+ if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) >= 4) {
+ OpenPgpMetadata metadata = pgpResult.getDecryptMetadata();
+ if (metadata != null) {
+ result.putExtra(OpenPgpApi.RESULT_METADATA, metadata);
}
- } else {
- LogEntryParcel errorMsg = pgpResult.getLog().getLast();
- throw new Exception(getString(errorMsg.mType.getMsgId()));
}
- } finally {
- is.close();
- if (os != null) {
- os.close();
+
+ String charset = pgpResult.getCharset();
+ if (charset != null) {
+ result.putExtra(OpenPgpApi.RESULT_CHARSET, charset);
}
+
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
+ return result;
+ } else {
+ LogEntryParcel errorMsg = pgpResult.getLog().getLast();
+ throw new Exception(getString(errorMsg.mType.getMsgId()));
}
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
- return result;
} catch (Exception e) {
Log.d(Constants.TAG, "decryptAndVerifyImpl", e);
Intent result = new Intent();
@@ -577,6 +544,21 @@ public class OpenPgpService extends RemoteService {
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException when closing InputStream", e);
+ }
+ }
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException when closing OutputStream", e);
+ }
+ }
}
}
@@ -668,15 +650,16 @@ public class OpenPgpService extends RemoteService {
// version code is required and needs to correspond to version code of service!
// History of versions in org.openintents.openpgp.util.OpenPgpApi
- // we support 3, 4, 5
+ // we support 3, 4, 5, 6
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 3
&& data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 4
- && data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 5) {
+ && data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 5
+ && data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 6) {
Intent result = new Intent();
OpenPgpError error = new OpenPgpError
(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!\n"
+ "used API version: " + data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) + "\n"
- + "supported API versions: 3, 4");
+ + "supported API versions: 3, 4, 5, 6");
result.putExtra(OpenPgpApi.RESULT_ERROR, error);
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
@@ -706,42 +689,66 @@ public class OpenPgpService extends RemoteService {
@Override
public Intent execute(Intent data, ParcelFileDescriptor input, ParcelFileDescriptor output) {
- Intent errorResult = checkRequirements(data);
- if (errorResult != null) {
- return errorResult;
- }
+ try {
+ Intent errorResult = checkRequirements(data);
+ if (errorResult != null) {
+ return errorResult;
+ }
- String accName = getAccountName(data);
- final AccountSettings accSettings = getAccSettings(accName);
- if (accSettings == null) {
- return getCreateAccountIntent(data, accName);
- }
+ String accName = getAccountName(data);
+ final AccountSettings accSettings = getAccSettings(accName);
+ if (accSettings == null) {
+ return getCreateAccountIntent(data, accName);
+ }
- String action = data.getAction();
- if (OpenPgpApi.ACTION_SIGN.equals(action)) {
- return signImpl(data, input, output, accSettings);
- } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, accSettings, false);
- } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, accSettings, true);
- } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
- String currentPkg = getCurrentCallingPackage();
- Set<Long> allowedKeyIds =
- mProviderHelper.getAllKeyIdsForApp(
- ApiAccounts.buildBaseUri(currentPkg));
- return decryptAndVerifyImpl(data, input, output, allowedKeyIds, false);
- } else if (OpenPgpApi.ACTION_DECRYPT_METADATA.equals(action)) {
- String currentPkg = getCurrentCallingPackage();
- Set<Long> allowedKeyIds =
- mProviderHelper.getAllKeyIdsForApp(
- ApiAccounts.buildBaseUri(currentPkg));
- return decryptAndVerifyImpl(data, input, output, allowedKeyIds, true);
- } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
- return getKeyImpl(data);
- } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
- return getKeyIdsImpl(data);
- } else {
- return null;
+ String action = data.getAction();
+ if (OpenPgpApi.ACTION_CLEARTEXT_SIGN.equals(action)) {
+ return signImpl(data, input, output, accSettings, true);
+ } else if (OpenPgpApi.ACTION_SIGN.equals(action)) {
+ // DEPRECATED: same as ACTION_CLEARTEXT_SIGN
+ Log.w(Constants.TAG, "You are using a deprecated API call, please use ACTION_CLEARTEXT_SIGN instead of ACTION_SIGN!");
+ return signImpl(data, input, output, accSettings, true);
+ } else if (OpenPgpApi.ACTION_DETACHED_SIGN.equals(action)) {
+ return signImpl(data, input, output, accSettings, false);
+ } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
+ return encryptAndSignImpl(data, input, output, accSettings, false);
+ } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
+ return encryptAndSignImpl(data, input, output, accSettings, true);
+ } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
+ String currentPkg = getCurrentCallingPackage();
+ Set<Long> allowedKeyIds =
+ mProviderHelper.getAllKeyIdsForApp(
+ ApiAccounts.buildBaseUri(currentPkg));
+ return decryptAndVerifyImpl(data, input, output, allowedKeyIds, false);
+ } else if (OpenPgpApi.ACTION_DECRYPT_METADATA.equals(action)) {
+ String currentPkg = getCurrentCallingPackage();
+ Set<Long> allowedKeyIds =
+ mProviderHelper.getAllKeyIdsForApp(
+ ApiAccounts.buildBaseUri(currentPkg));
+ return decryptAndVerifyImpl(data, input, output, allowedKeyIds, true);
+ } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
+ return getKeyImpl(data);
+ } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
+ return getKeyIdsImpl(data);
+ } else {
+ return null;
+ }
+ } finally {
+ // always close input and output file descriptors even in error cases
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException when closing input ParcelFileDescriptor", e);
+ }
+ }
+ if (output != null) {
+ try {
+ output.close();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException when closing output ParcelFileDescriptor", e);
+ }
+ }
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
index e71b52ccd..672f59285 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
@@ -27,7 +27,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.net.Uri;
import android.os.Binder;
-import android.text.TextUtils;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.util.OpenPgpApi;
@@ -216,9 +215,7 @@ public abstract class RemoteService extends Service {
String[] callingPackages = getPackageManager().getPackagesForUid(uid);
// is calling package allowed to use this service?
- for (int i = 0; i < callingPackages.length; i++) {
- String currentPkg = callingPackages[i];
-
+ for (String currentPkg : callingPackages) {
if (isPackageAllowed(currentPkg)) {
return true;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
index 0e9678980..4d6df24d2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
@@ -20,22 +20,21 @@ package org.sufficientlysecure.keychain.remote.ui;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.ActionBarHelper;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.SingletonResult;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.remote.AccountSettings;
+import org.sufficientlysecure.keychain.ui.BaseActivity;
import org.sufficientlysecure.keychain.util.Log;
-public class AccountSettingsActivity extends ActionBarActivity {
+public class AccountSettingsActivity extends BaseActivity {
private Uri mAccountUri;
private AccountSettingsFragment mAccountSettingsFragment;
@@ -45,17 +44,20 @@ public class AccountSettingsActivity extends ActionBarActivity {
super.onCreate(savedInstanceState);
// Inflate a "Done" custom action bar
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.api_settings_save, R.drawable.ic_action_done,
+ setFullScreenDialogDoneClose(R.string.api_settings_save,
new View.OnClickListener() {
@Override
public void onClick(View v) {
- // "Done"
save();
}
+ },
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
});
-
- setContentView(R.layout.api_account_settings_activity);
+ setTitle(null);
mAccountSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
R.id.api_account_settings_fragment);
@@ -73,6 +75,11 @@ public class AccountSettingsActivity extends ActionBarActivity {
}
@Override
+ protected void initLayout() {
+ setContentView(R.layout.api_account_settings_activity);
+ }
+
+ @Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.api_account_settings, menu);
@@ -85,9 +92,6 @@ public class AccountSettingsActivity extends ActionBarActivity {
case R.id.menu_account_settings_delete:
deleteAccount();
return true;
- case R.id.menu_account_settings_cancel:
- finish();
- return true;
}
return super.onOptionsItemSelected(item);
}
@@ -125,9 +129,4 @@ public class AccountSettingsActivity extends ActionBarActivity {
}
}
- @Override
- public void onBackPressed() {
- save();
- super.onBackPressed();
- }
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
index a3027f728..a5bc05ba8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
@@ -31,10 +31,10 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.remote.AccountSettings;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity;
import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter;
import org.sufficientlysecure.keychain.ui.widget.KeySpinner;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
index 56e3b22e2..407480c98 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
@@ -17,29 +17,54 @@
package org.sufficientlysecure.keychain.remote.ui;
+import android.app.Activity;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.getbase.floatingactionbutton.FloatingActionButton;
+
+import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.operations.results.OperationResult;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.ui.BaseActivity;
+import org.sufficientlysecure.keychain.ui.dialog.AddSubkeyDialogFragment;
+import org.sufficientlysecure.keychain.ui.dialog.AdvancedAppSettingsDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
-public class AppSettingsActivity extends ActionBarActivity {
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class AppSettingsActivity extends BaseActivity {
private Uri mAppUri;
- private AppSettingsFragment mSettingsFragment;
+ private AppSettingsAllowedKeysListFragment mAllowedKeysFragment;
+
+ private TextView mAppNameView;
+ private ImageView mAppIconView;
+ private TextView mPackageName;
+ private TextView mPackageSignature;
+
+ private FloatingActionButton mStartFab;
+
+ // deprecated API
private AccountsListFragment mAccountsListFragment;
+ private TextView mAccountsLabel;
+
// model
AppSettings mAppSettings;
@@ -48,16 +73,27 @@ public class AppSettingsActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // let the actionbar look like Android's contact app
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setIcon(android.R.color.transparent);
- actionBar.setHomeButtonEnabled(true);
+ mAccountsLabel = (TextView) findViewById(R.id.api_accounts_label);
+ mAppNameView = (TextView) findViewById(R.id.api_app_settings_app_name);
+ mAppIconView = (ImageView) findViewById(R.id.api_app_settings_app_icon);
+ mPackageName = (TextView) findViewById(R.id.api_app_settings_package_name);
+ mPackageSignature = (TextView) findViewById(R.id.api_app_settings_package_signature);
+ mStartFab = (FloatingActionButton) findViewById(R.id.fab);
- setContentView(R.layout.api_app_settings_activity);
+ mStartFab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startApp();
+ }
+ });
- mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_app_settings_fragment);
+ setFullScreenDialogClose(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ cancel();
+ }
+ });
+ setTitle(null);
Intent intent = getIntent();
mAppUri = intent.getData();
@@ -71,6 +107,22 @@ public class AppSettingsActivity extends ActionBarActivity {
}
}
+ private void save() {
+ mAllowedKeysFragment.saveAllowedKeys();
+ setResult(Activity.RESULT_OK);
+ finish();
+ }
+
+ private void cancel() {
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ }
+
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.api_app_settings_activity);
+ }
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
@@ -81,16 +133,40 @@ public class AppSettingsActivity extends ActionBarActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
- case R.id.menu_api_settings_revoke:
+ case R.id.menu_api_save: {
+ save();
+ return true;
+ }
+ case R.id.menu_api_settings_revoke: {
revokeAccess();
return true;
- case R.id.menu_api_settings_start:
- startApp();
+ }
+ case R.id.menu_api_settings_advanced: {
+ showAdvancedInfo();
return true;
+ }
}
return super.onOptionsItemSelected(item);
}
+ private void showAdvancedInfo() {
+ String signature = null;
+ // advanced info: package signature SHA-256
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ md.update(mAppSettings.getPackageSignature());
+ byte[] digest = md.digest();
+ signature = new String(Hex.encode(digest));
+ } catch (NoSuchAlgorithmException e) {
+ Log.e(Constants.TAG, "Should not happen!", e);
+ }
+
+ AdvancedAppSettingsDialogFragment dialogFragment =
+ AdvancedAppSettingsDialogFragment.newInstance(mAppSettings.getPackageName(), signature);
+
+ dialogFragment.show(getSupportFragmentManager(), "advancedDialog");
+ }
+
private void startApp() {
Intent i;
PackageManager manager = getPackageManager();
@@ -109,25 +185,31 @@ public class AppSettingsActivity extends ActionBarActivity {
private void loadData(Bundle savedInstanceState, Uri appUri) {
mAppSettings = new ProviderHelper(this).getApiAppSettings(appUri);
- mSettingsFragment.setAppSettings(mAppSettings);
+ // get application name and icon from package manager
String appName;
- PackageManager pm = getPackageManager();
+ Drawable appIcon = null;
+ PackageManager pm = getApplicationContext().getPackageManager();
try {
ApplicationInfo ai = pm.getApplicationInfo(mAppSettings.getPackageName(), 0);
+
appName = (String) pm.getApplicationLabel(ai);
+ appIcon = pm.getApplicationIcon(ai);
} catch (PackageManager.NameNotFoundException e) {
// fallback
appName = mAppSettings.getPackageName();
}
- setTitle(appName);
+ mAppNameView.setText(appName);
+ mAppIconView.setImageDrawable(appIcon);
Uri accountsUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ACCOUNTS).build();
Log.d(Constants.TAG, "accountsUri: " + accountsUri);
- startListFragment(savedInstanceState, accountsUri);
+ Uri allowedKeysUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ALLOWED_KEYS).build();
+ Log.d(Constants.TAG, "allowedKeysUri: " + allowedKeysUri);
+ startListFragments(savedInstanceState, accountsUri, allowedKeysUri);
}
- private void startListFragment(Bundle savedInstanceState, Uri dataUri) {
+ private void startListFragments(Bundle savedInstanceState, Uri accountsUri, Uri allowedKeysUri) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
@@ -135,13 +217,23 @@ public class AppSettingsActivity extends ActionBarActivity {
return;
}
- // Create an instance of the fragment
- mAccountsListFragment = AccountsListFragment.newInstance(dataUri);
+ // show accounts only if available (deprecated API)
+ Cursor cursor = getContentResolver().query(accountsUri, null, null, null, null);
+ if (cursor.moveToFirst()) {
+ mAccountsLabel.setVisibility(View.VISIBLE);
+ mAccountsListFragment = AccountsListFragment.newInstance(accountsUri);
+ // Create an instance of the fragments
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.api_accounts_list_fragment, mAccountsListFragment)
+ .commitAllowingStateLoss();
+ }
+ // Create an instance of the fragments
+ mAllowedKeysFragment = AppSettingsAllowedKeysListFragment.newInstance(allowedKeysUri);
// Add the fragment to the 'fragment_container' FrameLayout
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
getSupportFragmentManager().beginTransaction()
- .replace(R.id.api_accounts_list_fragment, mAccountsListFragment)
+ .replace(R.id.api_allowed_keys_list_fragment, mAllowedKeysFragment)
.commitAllowingStateLoss();
// do it immediately!
getSupportFragmentManager().executePendingTransactions();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java
new file mode 100644
index 000000000..13b242a5e
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.remote.ui;
+
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.compatibility.ListFragmentWorkaround;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
+import org.sufficientlysecure.keychain.ui.widget.FixedListView;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+public class AppSettingsAllowedKeysListFragment extends ListFragmentWorkaround implements LoaderManager.LoaderCallbacks<Cursor> {
+ private static final String ARG_DATA_URI = "uri";
+
+ private SelectKeyCursorAdapter mAdapter;
+ private Set<Long> mSelectedMasterKeyIds;
+ private ProviderHelper mProviderHelper;
+
+ private Uri mDataUri;
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static AppSettingsAllowedKeysListFragment newInstance(Uri dataUri) {
+ AppSettingsAllowedKeysListFragment frag = new AppSettingsAllowedKeysListFragment();
+ Bundle args = new Bundle();
+
+ args.putParcelable(ARG_DATA_URI, dataUri);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mProviderHelper = new ProviderHelper(getActivity());
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View layout = super.onCreateView(inflater, container,
+ savedInstanceState);
+ ListView lv = (ListView) layout.findViewById(android.R.id.list);
+ ViewGroup parent = (ViewGroup) lv.getParent();
+
+ /*
+ * http://stackoverflow.com/a/15880684
+ * Remove ListView and add FixedListView in its place.
+ * This is done here programatically to be still able to use the progressBar of ListFragment.
+ *
+ * We want FixedListView to be able to put this ListFragment inside a ScrollView
+ */
+ int lvIndex = parent.indexOfChild(lv);
+ parent.removeViewAt(lvIndex);
+ FixedListView newLv = new FixedListView(getActivity());
+ newLv.setId(android.R.id.list);
+ parent.addView(newLv, lvIndex, lv.getLayoutParams());
+ return layout;
+ }
+
+ /**
+ * Define Adapter and Loader on create of Activity
+ */
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ mDataUri = getArguments().getParcelable(ARG_DATA_URI);
+
+ getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+
+ // Give some text to display if there is no data. In a real
+ // application this would come from a resource.
+ setEmptyText(getString(R.string.list_empty));
+
+ mAdapter = new SecretKeyCursorAdapter(getActivity(), null, 0, getListView());
+
+ setListAdapter(mAdapter);
+
+ // Start out with a progress indicator.
+ setListShown(false);
+
+ mSelectedMasterKeyIds = mProviderHelper.getAllKeyIdsForApp(mDataUri);
+ Log.d(Constants.TAG, "allowed: " + mSelectedMasterKeyIds.toString());
+
+ // Prepare the loader. Either re-connect with an existing one,
+ // or start a new one.
+ getLoaderManager().initLoader(0, null, this);
+ }
+
+ /**
+ * Selects items based on master key ids in list view
+ *
+ * @param masterKeyIds
+ */
+ private void preselectMasterKeyIds(Set<Long> masterKeyIds) {
+ for (int i = 0; i < getListView().getCount(); ++i) {
+ long listKeyId = mAdapter.getMasterKeyId(i);
+ for (long keyId : masterKeyIds) {
+ if (listKeyId == keyId) {
+ getListView().setItemChecked(i, true);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns all selected master key ids
+ *
+ * @return
+ */
+ public Set<Long> getSelectedMasterKeyIds() {
+ // mListView.getCheckedItemIds() would give the row ids of the KeyRings not the master key
+ // ids!
+ Set<Long> keyIds = new HashSet<>();
+ for (int i = 0; i < getListView().getCount(); ++i) {
+ if (getListView().isItemChecked(i)) {
+ keyIds.add(mAdapter.getMasterKeyId(i));
+ }
+ }
+
+ return keyIds;
+ }
+
+ /**
+ * Returns all selected user ids
+ *
+ * @return
+ */
+ public String[] getSelectedUserIds() {
+ Vector<String> userIds = new Vector<>();
+ for (int i = 0; i < getListView().getCount(); ++i) {
+ if (getListView().isItemChecked(i)) {
+ userIds.add(mAdapter.getUserId(i));
+ }
+ }
+
+ // make empty array to not return null
+ String userIdArray[] = new String[0];
+ return userIds.toArray(userIdArray);
+ }
+
+ public void saveAllowedKeys() {
+ try {
+ mProviderHelper.saveAllowedKeyIdsForApp(mDataUri, getSelectedMasterKeyIds());
+ } catch (RemoteException | OperationApplicationException e) {
+ Log.e(Constants.TAG, "Problem saving allowed key ids!", e);
+ }
+ }
+
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
+
+ // These are the rows that we will retrieve.
+ String[] projection = new String[]{
+ KeyRings._ID,
+ KeyRings.MASTER_KEY_ID,
+ KeyRings.USER_ID,
+ KeyRings.IS_EXPIRED,
+ KeyRings.IS_REVOKED,
+ KeyRings.HAS_ENCRYPT,
+ KeyRings.VERIFIED,
+ KeyRings.HAS_ANY_SECRET,
+ };
+
+ String inMasterKeyList = null;
+ if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.size() > 0) {
+ inMasterKeyList = Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + " IN (";
+ Iterator iter = mSelectedMasterKeyIds.iterator();
+ while (iter.hasNext()) {
+ inMasterKeyList += DatabaseUtils.sqlEscapeString("" + iter.next());
+ if (iter.hasNext()) {
+ inMasterKeyList += ", ";
+ }
+ }
+ inMasterKeyList += ")";
+ }
+
+ String selection = KeyRings.HAS_ANY_SECRET + " != 0";
+
+ String orderBy = KeyRings.USER_ID + " ASC";
+ if (inMasterKeyList != null) {
+ // sort by selected master keys
+ orderBy = inMasterKeyList + " DESC, " + orderBy;
+ }
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), baseUri, projection, selection, null, orderBy);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ mAdapter.swapCursor(data);
+
+ // The list should now be shown.
+ if (isResumed()) {
+ setListShown(true);
+ } else {
+ setListShownNoAnimation(true);
+ }
+
+ // preselect given master keys
+ preselectMasterKeyIds(mSelectedMasterKeyIds);
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ // This is called when the last Cursor provided to onLoadFinished()
+ // above is about to be closed. We need to make sure we are no
+ // longer using it.
+ mAdapter.swapCursor(null);
+ }
+
+ private class SecretKeyCursorAdapter extends SelectKeyCursorAdapter {
+
+ public SecretKeyCursorAdapter(Context context, Cursor c, int flags, ListView listView) {
+ super(context, c, flags, listView);
+ }
+
+ @Override
+ protected void initIndex(Cursor cursor) {
+ super.initIndex(cursor);
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ super.bindView(view, context, cursor);
+ ViewHolderItem h = (ViewHolderItem) view.getTag();
+
+ // We care about the checkbox
+ h.selected.setVisibility(View.VISIBLE);
+ // the getListView works because this is not a static subclass!
+ h.selected.setChecked(getListView().isItemChecked(cursor.getPosition()));
+
+ boolean enabled = false;
+ if ((Boolean) h.statusIcon.getTag()) {
+ h.statusIcon.setVisibility(View.GONE);
+ enabled = true;
+ }
+
+ h.setEnabled(enabled);
+ }
+
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java
deleted file mode 100644
index a6db02708..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.spongycastle.util.encoders.Hex;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-public class AppSettingsFragment extends Fragment {
-
- // model
- private AppSettings mAppSettings;
-
- // view
- private TextView mAppNameView;
- private ImageView mAppIconView;
- private TextView mPackageName;
- private TextView mPackageSignature;
-
- public AppSettings getAppSettings() {
- return mAppSettings;
- }
-
- public void setAppSettings(AppSettings appSettings) {
- this.mAppSettings = appSettings;
- updateView(appSettings);
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false);
- mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name);
- mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon);
- mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name);
- mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature);
- return view;
- }
-
- private void updateView(AppSettings appSettings) {
- // get application name and icon from package manager
- String appName;
- Drawable appIcon = null;
- PackageManager pm = getActivity().getApplicationContext().getPackageManager();
- try {
- ApplicationInfo ai = pm.getApplicationInfo(appSettings.getPackageName(), 0);
-
- appName = (String) pm.getApplicationLabel(ai);
- appIcon = pm.getApplicationIcon(ai);
- } catch (NameNotFoundException e) {
- // fallback
- appName = appSettings.getPackageName();
- }
- mAppNameView.setText(appName);
- mAppIconView.setImageDrawable(appIcon);
-
- // advanced info: package name
- mPackageName.setText(appSettings.getPackageName());
-
- // advanced info: package signature SHA-256
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-256");
- md.update(appSettings.getPackageSignature());
- byte[] digest = md.digest();
- String signature = new String(Hex.encode(digest));
-
- mPackageSignature.setText(signature);
- } catch (NoSuchAlgorithmException e) {
- Log.e(Constants.TAG, "Should not happen!", e);
- }
- }
-
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsHeaderFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsHeaderFragment.java
new file mode 100644
index 000000000..7beac8973
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsHeaderFragment.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.remote.ui;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.spongycastle.util.encoders.Hex;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.remote.AppSettings;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class AppSettingsHeaderFragment extends Fragment {
+
+ // model
+ private AppSettings mAppSettings;
+
+ // view
+ private TextView mAppNameView;
+ private ImageView mAppIconView;
+ private TextView mPackageName;
+ private TextView mPackageSignature;
+
+ public AppSettings getAppSettings() {
+ return mAppSettings;
+ }
+
+ public void setAppSettings(AppSettings appSettings) {
+ this.mAppSettings = appSettings;
+ updateView(appSettings);
+ }
+
+ /**
+ * Inflate the layout for this fragment
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false);
+ mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name);
+ mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon);
+ mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name);
+ mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature);
+ return view;
+ }
+
+ private void updateView(AppSettings appSettings) {
+ // get application name and icon from package manager
+ String appName;
+ Drawable appIcon = null;
+ PackageManager pm = getActivity().getApplicationContext().getPackageManager();
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(appSettings.getPackageName(), 0);
+
+ appName = (String) pm.getApplicationLabel(ai);
+ appIcon = pm.getApplicationIcon(ai);
+ } catch (NameNotFoundException e) {
+ // fallback
+ appName = appSettings.getPackageName();
+ }
+ mAppNameView.setText(appName);
+ mAppIconView.setImageDrawable(appIcon);
+
+ // advanced info: package name
+ mPackageName.setText(appSettings.getPackageName());
+
+ // advanced info: package signature SHA-256
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ md.update(appSettings.getPackageSignature());
+ byte[] digest = md.digest();
+ String signature = new String(Hex.encode(digest));
+
+ mPackageSignature.setText(signature);
+ } catch (NoSuchAlgorithmException e) {
+ Log.e(Constants.TAG, "Should not happen!", e);
+ }
+ }
+
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java
deleted file mode 100644
index 11b0deb33..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.os.Bundle;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.DrawerActivity;
-
-public class AppsListActivity extends DrawerActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.api_apps_list_activity);
-
- activateDrawerNavigation(savedInstanceState);
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
index 976ce20d6..2deb33a67 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2013-2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,82 +48,83 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
import org.sufficientlysecure.keychain.util.Log;
public class AppsListFragment extends ListFragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
+ LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener {
- // This is the Adapter being used to display the list's data.
- RegisteredAppsAdapter mAdapter;
+ AppsAdapter mAdapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- getListView().setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- String selectedPackageName = mAdapter.getItemPackageName(position);
- boolean installed = mAdapter.getItemIsInstalled(position);
- boolean registered = mAdapter.getItemIsRegistered(position);
-
- if (installed) {
- if (registered) {
- // edit app settings
- Intent intent = new Intent(getActivity(), AppSettingsActivity.class);
- intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName));
- startActivity(intent);
- } else {
- Intent i;
- PackageManager manager = getActivity().getPackageManager();
- try {
- i = manager.getLaunchIntentForPackage(selectedPackageName);
- if (i == null)
- throw new PackageManager.NameNotFoundException();
- // start like the Android launcher would do
- i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- i.addCategory(Intent.CATEGORY_LAUNCHER);
- startActivity(i);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(Constants.TAG, "startApp", e);
- }
- }
- } else {
- try {
- startActivity(new Intent(Intent.ACTION_VIEW,
- Uri.parse("market://details?id=" + selectedPackageName)));
- } catch (ActivityNotFoundException anfe) {
- startActivity(new Intent(Intent.ACTION_VIEW,
- Uri.parse("http://play.google.com/store/apps/details?id=" + selectedPackageName)));
- }
- }
- }
- });
+ getListView().setOnItemClickListener(this);
- // Give some text to display if there is no data. In a real
- // application this would come from a resource.
- setEmptyText(getString(R.string.api_no_apps));
+ // NOTE: No setEmptyText(), we always have the default entries
// We have a menu item to show in action bar.
setHasOptionsMenu(true);
// Create an empty adapter we will use to display the loaded data.
- mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0);
+ mAdapter = new AppsAdapter(getActivity(), null, 0);
setListAdapter(mAdapter);
- // Loader is started in onResume!
+ // NOTE: Loader is started in onResume!
}
@Override
public void onResume() {
super.onResume();
- // after coming back from Google Play -> reload
+
+ // Start out with a progress indicator.
+ setListShown(false);
+
+ // After coming back from Google Play -> reload
getLoaderManager().restartLoader(0, null, this);
}
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ String selectedPackageName = mAdapter.getItemPackageName(position);
+ boolean installed = mAdapter.getItemIsInstalled(position);
+ boolean registered = mAdapter.getItemIsRegistered(position);
+
+ if (installed) {
+ if (registered) {
+ // Edit app settings
+ Intent intent = new Intent(getActivity(), AppSettingsActivity.class);
+ intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName));
+ startActivity(intent);
+ } else {
+ Intent i;
+ PackageManager manager = getActivity().getPackageManager();
+ try {
+ i = manager.getLaunchIntentForPackage(selectedPackageName);
+ if (i == null) {
+ throw new PackageManager.NameNotFoundException();
+ }
+ // Start like the Android launcher would do
+ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ i.addCategory(Intent.CATEGORY_LAUNCHER);
+ startActivity(i);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(Constants.TAG, "startApp", e);
+ }
+ }
+ } else {
+ try {
+ startActivity(new Intent(Intent.ACTION_VIEW,
+ Uri.parse("market://details?id=" + selectedPackageName)));
+ } catch (ActivityNotFoundException anfe) {
+ startActivity(new Intent(Intent.ACTION_VIEW,
+ Uri.parse("https://play.google.com/store/apps/details?id=" + selectedPackageName)));
+ }
+ }
+ }
+
private static final String TEMP_COLUMN_NAME = "NAME";
private static final String TEMP_COLUMN_INSTALLED = "INSTALLED";
private static final String TEMP_COLUMN_REGISTERED = "REGISTERED";
private static final String TEMP_COLUMN_ICON_RES_ID = "ICON_RES_ID";
- // These are the Contacts rows that we will retrieve.
static final String[] PROJECTION = new String[]{
ApiApps._ID, // 0
ApiApps.PACKAGE_NAME, // 1
@@ -149,106 +150,17 @@ public class AppsListFragment extends ListFragment implements
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null,
+ return new AppsLoader(getActivity(), baseUri, PROJECTION, null, null,
ApiApps.PACKAGE_NAME + " COLLATE LOCALIZED ASC");
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- MatrixCursor availableAppsCursor = new MatrixCursor(new String[]{
- ApiApps._ID,
- ApiApps.PACKAGE_NAME,
- TEMP_COLUMN_NAME,
- TEMP_COLUMN_INSTALLED,
- TEMP_COLUMN_REGISTERED,
- TEMP_COLUMN_ICON_RES_ID
- });
- // NOTE: SORT ascending by package name, this is REQUIRED for CursorJoiner!
- // Drawables taken from projects res/drawables-xxhdpi/ic_launcher.png
- availableAppsCursor.addRow(new Object[]{1, "com.fsck.k9", "K-9 Mail", 0, 0, R.drawable.apps_k9});
- availableAppsCursor.addRow(new Object[]{1, "com.zeapo.pwdstore", "Password Store", 0, 0, R.drawable.apps_password_store});
- availableAppsCursor.addRow(new Object[]{1, "eu.siacs.conversations", "Conversations (Instant Messaging)", 0, 0, R.drawable.apps_conversations});
-
- MatrixCursor mergedCursor = new MatrixCursor(new String[]{
- ApiApps._ID,
- ApiApps.PACKAGE_NAME,
- TEMP_COLUMN_NAME,
- TEMP_COLUMN_INSTALLED,
- TEMP_COLUMN_REGISTERED,
- TEMP_COLUMN_ICON_RES_ID
- });
-
- CursorJoiner joiner = new CursorJoiner(
- availableAppsCursor,
- new String[]{ApiApps.PACKAGE_NAME},
- data,
- new String[]{ApiApps.PACKAGE_NAME});
- for (CursorJoiner.Result joinerResult : joiner) {
- switch (joinerResult) {
- case LEFT: {
- // handle case where a row in availableAppsCursor is unique
- String packageName = availableAppsCursor.getString(INDEX_PACKAGE_NAME);
-
- mergedCursor.addRow(new Object[]{
- 1, // no need for unique _ID
- packageName,
- availableAppsCursor.getString(INDEX_NAME),
- isInstalled(packageName),
- 0,
- availableAppsCursor.getInt(INDEX_ICON_RES_ID)
- });
- break;
- }
- case RIGHT: {
- // handle case where a row in data is unique
- String packageName = data.getString(INDEX_PACKAGE_NAME);
-
- mergedCursor.addRow(new Object[]{
- 1, // no need for unique _ID
- packageName,
- null,
- isInstalled(packageName),
- 1, // registered!
- R.drawable.ic_launcher // icon is retrieved later
- });
- break;
- }
- case BOTH: {
- // handle case where a row with the same key is in both cursors
- String packageName = data.getString(INDEX_PACKAGE_NAME);
-
- String name;
- if (isInstalled(packageName) == 1) {
- name = data.getString(INDEX_NAME);
- } else {
- // if not installed take name from available apps list
- name = availableAppsCursor.getString(INDEX_NAME);
- }
-
- mergedCursor.addRow(new Object[]{
- 1, // no need for unique _ID
- packageName,
- name,
- isInstalled(packageName),
- 1, // registered!
- R.drawable.ic_launcher // icon is retrieved later
- });
- break;
- }
- }
- }
-
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
- mAdapter.swapCursor(mergedCursor);
- }
+ mAdapter.swapCursor(data);
- private int isInstalled(String packageName) {
- try {
- getActivity().getPackageManager().getApplicationInfo(packageName, 0);
- return 1;
- } catch (final PackageManager.NameNotFoundException e) {
- return 0;
- }
+ // The list should now be shown.
+ setListShown(true);
}
public void onLoaderReset(Loader<Cursor> loader) {
@@ -258,12 +170,127 @@ public class AppsListFragment extends ListFragment implements
mAdapter.swapCursor(null);
}
- private class RegisteredAppsAdapter extends CursorAdapter {
+ /**
+ * Besides the queried cursor with all registered apps, this loader also returns non-installed
+ * proposed apps using a MatrixCursor.
+ */
+ private static class AppsLoader extends CursorLoader {
+
+ public AppsLoader(Context context) {
+ super(context);
+ }
+
+ public AppsLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+ super(context, uri, projection, selection, selectionArgs, sortOrder);
+ }
+
+ @Override
+ public Cursor loadInBackground() {
+ // Load registered apps from content provider
+ Cursor data = super.loadInBackground();
+
+ MatrixCursor availableAppsCursor = new MatrixCursor(new String[]{
+ ApiApps._ID,
+ ApiApps.PACKAGE_NAME,
+ TEMP_COLUMN_NAME,
+ TEMP_COLUMN_INSTALLED,
+ TEMP_COLUMN_REGISTERED,
+ TEMP_COLUMN_ICON_RES_ID
+ });
+ // NOTE: SORT ascending by package name, this is REQUIRED for CursorJoiner!
+ // Drawables taken from projects res/drawables-xxhdpi/ic_launcher.png
+ availableAppsCursor.addRow(new Object[]{1, "com.fsck.k9", "K-9 Mail", 0, 0, R.drawable.apps_k9});
+ availableAppsCursor.addRow(new Object[]{1, "com.zeapo.pwdstore", "Password Store", 0, 0, R.drawable.apps_password_store});
+ availableAppsCursor.addRow(new Object[]{1, "eu.siacs.conversations", "Conversations (Instant Messaging)", 0, 0, R.drawable.apps_conversations});
+
+ MatrixCursor mergedCursor = new MatrixCursor(new String[]{
+ ApiApps._ID,
+ ApiApps.PACKAGE_NAME,
+ TEMP_COLUMN_NAME,
+ TEMP_COLUMN_INSTALLED,
+ TEMP_COLUMN_REGISTERED,
+ TEMP_COLUMN_ICON_RES_ID
+ });
+
+ CursorJoiner joiner = new CursorJoiner(
+ availableAppsCursor,
+ new String[]{ApiApps.PACKAGE_NAME},
+ data,
+ new String[]{ApiApps.PACKAGE_NAME});
+ for (CursorJoiner.Result joinerResult : joiner) {
+ switch (joinerResult) {
+ case LEFT: {
+ // handle case where a row in availableAppsCursor is unique
+ String packageName = availableAppsCursor.getString(INDEX_PACKAGE_NAME);
+
+ mergedCursor.addRow(new Object[]{
+ 1, // no need for unique _ID
+ packageName,
+ availableAppsCursor.getString(INDEX_NAME),
+ isInstalled(packageName),
+ 0,
+ availableAppsCursor.getInt(INDEX_ICON_RES_ID)
+ });
+ break;
+ }
+ case RIGHT: {
+ // handle case where a row in data is unique
+ String packageName = data.getString(INDEX_PACKAGE_NAME);
+
+ mergedCursor.addRow(new Object[]{
+ 1, // no need for unique _ID
+ packageName,
+ null,
+ isInstalled(packageName),
+ 1, // registered!
+ R.drawable.ic_launcher // icon is retrieved later
+ });
+ break;
+ }
+ case BOTH: {
+ // handle case where a row with the same key is in both cursors
+ String packageName = data.getString(INDEX_PACKAGE_NAME);
+
+ String name;
+ if (isInstalled(packageName) == 1) {
+ name = data.getString(INDEX_NAME);
+ } else {
+ // if not installed take name from available apps list
+ name = availableAppsCursor.getString(INDEX_NAME);
+ }
+
+ mergedCursor.addRow(new Object[]{
+ 1, // no need for unique _ID
+ packageName,
+ name,
+ isInstalled(packageName),
+ 1, // registered!
+ R.drawable.ic_launcher // icon is retrieved later
+ });
+ break;
+ }
+ }
+ }
+
+ return mergedCursor;
+ }
+
+ private int isInstalled(String packageName) {
+ try {
+ getContext().getPackageManager().getApplicationInfo(packageName, 0);
+ return 1;
+ } catch (final PackageManager.NameNotFoundException e) {
+ return 0;
+ }
+ }
+ }
+
+ private class AppsAdapter extends CursorAdapter {
private LayoutInflater mInflater;
private PackageManager mPM;
- public RegisteredAppsAdapter(Context context, Cursor c, int flags) {
+ public AppsAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
mInflater = LayoutInflater.from(context);
@@ -273,44 +300,23 @@ public class AppsListFragment extends ListFragment implements
/**
* Similar to CursorAdapter.getItemId().
* Required to build Uris for api apps, which are not based on row ids
- *
- * @param position
- * @return
*/
public String getItemPackageName(int position) {
- if (mDataValid && mCursor != null) {
- if (mCursor.moveToPosition(position)) {
- return mCursor.getString(INDEX_PACKAGE_NAME);
- } else {
- return null;
- }
+ if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
+ return mCursor.getString(INDEX_PACKAGE_NAME);
} else {
return null;
}
}
public boolean getItemIsInstalled(int position) {
- if (mDataValid && mCursor != null) {
- if (mCursor.moveToPosition(position)) {
- return (mCursor.getInt(INDEX_INSTALLED) == 1);
- } else {
- return false;
- }
- } else {
- return false;
- }
+ return mDataValid && mCursor != null
+ && mCursor.moveToPosition(position) && (mCursor.getInt(INDEX_INSTALLED) == 1);
}
public boolean getItemIsRegistered(int position) {
- if (mDataValid && mCursor != null) {
- if (mCursor.moveToPosition(position)) {
- return (mCursor.getInt(INDEX_REGISTERED) == 1);
- } else {
- return false;
- }
- } else {
- return false;
- }
+ return mDataValid && mCursor != null
+ && mCursor.moveToPosition(position) && (mCursor.getInt(INDEX_REGISTERED) == 1);
}
@Override
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
index d7b723eb0..2c5c78161 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
@@ -22,7 +22,6 @@ import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
@@ -39,14 +38,14 @@ import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.remote.AccountSettings;
import org.sufficientlysecure.keychain.remote.AppSettings;
+import org.sufficientlysecure.keychain.ui.BaseActivity;
import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment;
-import org.sufficientlysecure.keychain.ui.util.ActionBarHelper;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
-public class RemoteServiceActivity extends ActionBarActivity {
+public class RemoteServiceActivity extends BaseActivity {
public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER";
public static final String ACTION_CREATE_ACCOUNT = Constants.INTENT_PREFIX
@@ -76,7 +75,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
public static final String EXTRA_ERROR_MESSAGE = "error_message";
// register view
- private AppSettingsFragment mAppSettingsFragment;
+ private AppSettingsHeaderFragment mAppSettingsHeaderFragment;
// create acc view
private AccountSettingsFragment mAccSettingsFragment;
// select pub keys view
@@ -96,235 +95,250 @@ public class RemoteServiceActivity extends ActionBarActivity {
handleActions(getIntent(), savedInstanceState);
}
+ @Override
+ protected void initLayout() {
+ // done in handleActions()
+ }
+
protected void handleActions(Intent intent, Bundle savedInstanceState) {
String action = intent.getAction();
final Bundle extras = intent.getExtras();
- if (ACTION_REGISTER.equals(action)) {
- final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
- final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE);
- Log.d(Constants.TAG, "ACTION_REGISTER packageName: " + packageName);
+ switch (action) {
+ case ACTION_REGISTER: {
+ final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
+ final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE);
+ Log.d(Constants.TAG, "ACTION_REGISTER packageName: " + packageName);
- setContentView(R.layout.api_remote_register_app);
+ setContentView(R.layout.api_remote_register_app);
+ initToolbar();
- mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_app_settings_fragment);
+ mAppSettingsHeaderFragment = (AppSettingsHeaderFragment) getSupportFragmentManager().findFragmentById(
+ R.id.api_app_settings_fragment);
- AppSettings settings = new AppSettings(packageName, packageSignature);
- mAppSettingsFragment.setAppSettings(settings);
+ AppSettings settings = new AppSettings(packageName, packageSignature);
+ mAppSettingsHeaderFragment.setAppSettings(settings);
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.api_register_allow, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Allow
+ // Inflate a "Done"/"Cancel" custom action bar view
+ setFullScreenDialogTwoButtons(
+ R.string.api_register_allow, R.drawable.ic_check_white_24dp,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Allow
- mProviderHelper.insertApiApp(mAppSettingsFragment.getAppSettings());
+ mProviderHelper.insertApiApp(mAppSettingsHeaderFragment.getAppSettings());
- // give data through for new service call
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- RemoteServiceActivity.this.finish();
- }
- }, R.string.api_register_disallow, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Disallow
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
+ // give data through for new service call
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
+ RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
+ RemoteServiceActivity.this.finish();
+ }
+ }, R.string.api_register_disallow, R.drawable.ic_close_white_24dp,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Disallow
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
+ RemoteServiceActivity.this.finish();
+ }
}
- }
- );
- } else if (ACTION_CREATE_ACCOUNT.equals(action)) {
- final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
- final String accName = extras.getString(EXTRA_ACC_NAME);
+ );
+ break;
+ }
+ case ACTION_CREATE_ACCOUNT: {
+ final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
+ final String accName = extras.getString(EXTRA_ACC_NAME);
- setContentView(R.layout.api_remote_create_account);
+ setContentView(R.layout.api_remote_create_account);
+ initToolbar();
- mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_account_settings_fragment);
+ mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
+ R.id.api_account_settings_fragment);
- TextView text = (TextView) findViewById(R.id.api_remote_create_account_text);
+ TextView text = (TextView) findViewById(R.id.api_remote_create_account_text);
- // update existing?
- Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(packageName, accName);
- AccountSettings settings = mProviderHelper.getApiAccountSettings(uri);
- if (settings == null) {
- // create new account
- settings = new AccountSettings(accName);
- mUpdateExistingAccount = false;
+ // update existing?
+ Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(packageName, accName);
+ AccountSettings settings = mProviderHelper.getApiAccountSettings(uri);
+ if (settings == null) {
+ // create new account
+ settings = new AccountSettings(accName);
+ mUpdateExistingAccount = false;
- text.setText(R.string.api_create_account_text);
- } else {
- // update existing account
- mUpdateExistingAccount = true;
+ text.setText(R.string.api_create_account_text);
+ } else {
+ // update existing account
+ mUpdateExistingAccount = true;
- text.setText(R.string.api_update_account_text);
- }
- mAccSettingsFragment.setAccSettings(settings);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.api_settings_save, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Save
-
- // user needs to select a key if it has explicitly requested (None is only allowed for new accounts)
- if (mUpdateExistingAccount && mAccSettingsFragment.getAccSettings().getKeyId() == Constants.key.none) {
- Notify.showNotify(RemoteServiceActivity.this, getString(R.string.api_register_error_select_key), Notify.Style.ERROR);
- } else {
- if (mUpdateExistingAccount) {
- Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(packageName);
- Uri accountUri = baseUri.buildUpon().appendEncodedPath(accName).build();
- mProviderHelper.updateApiAccount(
- accountUri,
- mAccSettingsFragment.getAccSettings());
+ text.setText(R.string.api_update_account_text);
+ }
+ mAccSettingsFragment.setAccSettings(settings);
+
+ // Inflate a "Done"/"Cancel" custom action bar view
+ setFullScreenDialogDoneClose(R.string.api_settings_save,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Save
+
+ // user needs to select a key if it has explicitly requested (None is only allowed for new accounts)
+ if (mUpdateExistingAccount && mAccSettingsFragment.getAccSettings().getKeyId() == Constants.key.none) {
+ Notify.showNotify(RemoteServiceActivity.this, getString(R.string.api_register_error_select_key), Notify.Style.ERROR);
} else {
- mProviderHelper.insertApiAccount(
- KeychainContract.ApiAccounts.buildBaseUri(packageName),
- mAccSettingsFragment.getAccSettings());
+ if (mUpdateExistingAccount) {
+ Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(packageName);
+ Uri accountUri = baseUri.buildUpon().appendEncodedPath(accName).build();
+ mProviderHelper.updateApiAccount(
+ accountUri,
+ mAccSettingsFragment.getAccSettings());
+ } else {
+ mProviderHelper.insertApiAccount(
+ KeychainContract.ApiAccounts.buildBaseUri(packageName),
+ mAccSettingsFragment.getAccSettings());
+ }
+
+ // give data through for new service call
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
+ RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
+ RemoteServiceActivity.this.finish();
}
-
- // give data through for new service call
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
+ }
+ },
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Cancel
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
RemoteServiceActivity.this.finish();
}
- }
- }, R.string.api_settings_cancel, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Cancel
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
+ });
+
+ break;
+ }
+ case ACTION_SELECT_PUB_KEYS: {
+ long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
+ boolean noUserIdsCheck = intent.getBooleanExtra(EXTRA_NO_USER_IDS_CHECK, true);
+ ArrayList<String> missingUserIds = intent
+ .getStringArrayListExtra(EXTRA_MISSING_USER_IDS);
+ ArrayList<String> dublicateUserIds = intent
+ .getStringArrayListExtra(EXTRA_DUPLICATE_USER_IDS);
+
+ SpannableStringBuilder ssb = new SpannableStringBuilder();
+ final SpannableString textIntro = new SpannableString(
+ noUserIdsCheck ? getString(R.string.api_select_pub_keys_text_no_user_ids)
+ : getString(R.string.api_select_pub_keys_text)
+ );
+ textIntro.setSpan(new StyleSpan(Typeface.BOLD), 0, textIntro.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ssb.append(textIntro);
+
+ if (missingUserIds != null && missingUserIds.size() > 0) {
+ ssb.append("\n\n");
+ ssb.append(getString(R.string.api_select_pub_keys_missing_text));
+ ssb.append("\n");
+ for (String userId : missingUserIds) {
+ SpannableString ss = new SpannableString(userId + "\n");
+ ss.setSpan(new BulletSpan(15, Color.BLACK), 0, ss.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ssb.append(ss);
}
- );
-
- } else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
- long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
- boolean noUserIdsCheck = intent.getBooleanExtra(EXTRA_NO_USER_IDS_CHECK, true);
- ArrayList<String> missingUserIds = intent
- .getStringArrayListExtra(EXTRA_MISSING_USER_IDS);
- ArrayList<String> dublicateUserIds = intent
- .getStringArrayListExtra(EXTRA_DUPLICATE_USER_IDS);
-
- SpannableStringBuilder ssb = new SpannableStringBuilder();
- final SpannableString textIntro = new SpannableString(
- noUserIdsCheck ? getString(R.string.api_select_pub_keys_text_no_user_ids)
- : getString(R.string.api_select_pub_keys_text)
- );
- textIntro.setSpan(new StyleSpan(Typeface.BOLD), 0, textIntro.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- ssb.append(textIntro);
-
- if (missingUserIds != null && missingUserIds.size() > 0) {
- ssb.append("\n\n");
- ssb.append(getString(R.string.api_select_pub_keys_missing_text));
- ssb.append("\n");
- for (String userId : missingUserIds) {
- SpannableString ss = new SpannableString(userId + "\n");
- ss.setSpan(new BulletSpan(15, Color.BLACK), 0, ss.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- ssb.append(ss);
}
- }
- if (dublicateUserIds != null && dublicateUserIds.size() > 0) {
- ssb.append("\n\n");
- ssb.append(getString(R.string.api_select_pub_keys_dublicates_text));
- ssb.append("\n");
- for (String userId : dublicateUserIds) {
- SpannableString ss = new SpannableString(userId + "\n");
- ss.setSpan(new BulletSpan(15, Color.BLACK), 0, ss.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- ssb.append(ss);
+ if (dublicateUserIds != null && dublicateUserIds.size() > 0) {
+ ssb.append("\n\n");
+ ssb.append(getString(R.string.api_select_pub_keys_dublicates_text));
+ ssb.append("\n");
+ for (String userId : dublicateUserIds) {
+ SpannableString ss = new SpannableString(userId + "\n");
+ ss.setSpan(new BulletSpan(15, Color.BLACK), 0, ss.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ssb.append(ss);
+ }
}
- }
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // add key ids to params Bundle for new request
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS,
- mSelectFragment.getSelectedMasterKeyIds());
-
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- RemoteServiceActivity.this.finish();
- }
- }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // cancel
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- }
- );
+ setContentView(R.layout.api_remote_select_pub_keys);
+ initToolbar();
- setContentView(R.layout.api_remote_select_pub_keys);
+ // Inflate a "Done"/"Cancel" custom action bar view
+ setFullScreenDialogDoneClose(R.string.btn_okay,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // add key ids to params Bundle for new request
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
+ resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS,
+ mSelectFragment.getSelectedMasterKeyIds());
- // set text on view
- TextView textView = (TextView) findViewById(R.id.api_select_pub_keys_text);
- textView.setText(ssb, TextView.BufferType.SPANNABLE);
+ RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
+ RemoteServiceActivity.this.finish();
+ }
+ },
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // cancel
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
+ RemoteServiceActivity.this.finish();
+ }
+ });
+
+ // set text on view
+ TextView textView = (TextView) findViewById(R.id.api_select_pub_keys_text);
+ textView.setText(ssb, TextView.BufferType.SPANNABLE);
+
+ /* Load select pub keys fragment */
+ // Check that the activity is using the layout version with
+ // the fragment_container FrameLayout
+ if (findViewById(R.id.api_select_pub_keys_fragment_container) != null) {
+
+ // However, if we're being restored from a previous state,
+ // then we don't need to do anything and should return or else
+ // we could end up with overlapping fragments.
+ if (savedInstanceState != null) {
+ return;
+ }
- /* Load select pub keys fragment */
- // Check that the activity is using the layout version with
- // the fragment_container FrameLayout
- if (findViewById(R.id.api_select_pub_keys_fragment_container) != null) {
+ // Create an instance of the fragment
+ mSelectFragment = SelectPublicKeyFragment.newInstance(selectedMasterKeyIds);
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
+ // Add the fragment to the 'fragment_container' FrameLayout
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.api_select_pub_keys_fragment_container, mSelectFragment).commit();
}
-
- // Create an instance of the fragment
- mSelectFragment = SelectPublicKeyFragment.newInstance(selectedMasterKeyIds);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- getSupportFragmentManager().beginTransaction()
- .add(R.id.api_select_pub_keys_fragment_container, mSelectFragment).commit();
+ break;
}
- } else if (ACTION_ERROR_MESSAGE.equals(action)) {
- String errorMessage = intent.getStringExtra(EXTRA_ERROR_MESSAGE);
+ case ACTION_ERROR_MESSAGE: {
+ String errorMessage = intent.getStringExtra(EXTRA_ERROR_MESSAGE);
- Spannable redErrorMessage = new SpannableString(errorMessage);
- redErrorMessage.setSpan(new ForegroundColorSpan(Color.RED), 0, errorMessage.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ Spannable redErrorMessage = new SpannableString(errorMessage);
+ redErrorMessage.setSpan(new ForegroundColorSpan(Color.RED), 0, errorMessage.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- // Inflate a "Done" custom action bar view
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
+ setContentView(R.layout.api_remote_error_message);
+ initToolbar();
- @Override
- public void onClick(View v) {
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- }
- );
+ // Inflate a "Done" custom action bar view
+ setFullScreenDialogClose(
+ new View.OnClickListener() {
- setContentView(R.layout.api_remote_error_message);
+ @Override
+ public void onClick(View v) {
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
+ RemoteServiceActivity.this.finish();
+ }
+ }
+ );
- // set text on view
- TextView textView = (TextView) findViewById(R.id.api_app_error_message_text);
- textView.setText(redErrorMessage);
- } else {
- Log.e(Constants.TAG, "Action does not exist!");
- setResult(RESULT_CANCELED);
- finish();
+ // set text on view
+ TextView textView = (TextView) findViewById(R.id.api_app_error_message_text);
+ textView.setText(redErrorMessage);
+ break;
+ }
+ default:
+ Log.e(Constants.TAG, "Action does not exist!");
+ setResult(RESULT_CANCELED);
+ finish();
+ break;
}
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java
index dd9c0d769..f0dbf0820 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java
@@ -34,7 +34,7 @@ public class CertifyActionsParcel implements Parcelable {
final public long mMasterKeyId;
public CertifyLevel mLevel;
- public ArrayList<CertifyAction> mCertifyActions = new ArrayList<CertifyAction>();
+ public ArrayList<CertifyAction> mCertifyActions = new ArrayList<>();
public CertifyActionsParcel(long masterKeyId) {
mMasterKeyId = masterKeyId;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java
index 447f413ef..7688b9252 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java
@@ -53,7 +53,7 @@ public class ContactSyncAdapterService extends Service {
// new Handler.Callback() {
// @Override
// public boolean handleMessage(Message msg) {
-// Bundle data = msg.getData();
+// Bundle data = msg.getInputData();
// switch (msg.arg1) {
// case KeychainIntentServiceHandler.MESSAGE_OKAY:
// Log.d(Constants.TAG, "Syncing... Done.");
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index dc9592710..d95701458 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -38,7 +38,10 @@ import org.sufficientlysecure.keychain.keyimport.Keyserver;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.CertifyOperation;
import org.sufficientlysecure.keychain.operations.DeleteOperation;
+import org.sufficientlysecure.keychain.operations.EditKeyOperation;
import org.sufficientlysecure.keychain.operations.ImportExportOperation;
+import org.sufficientlysecure.keychain.operations.PromoteKeyOperation;
+import org.sufficientlysecure.keychain.operations.SignEncryptOperation;
import org.sufficientlysecure.keychain.operations.results.CertifyResult;
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
@@ -47,30 +50,20 @@ import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.operations.results.ExportResult;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
-import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
+import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
-import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
-import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
import org.sufficientlysecure.keychain.pgp.Progressable;
-import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
-import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
-import org.sufficientlysecure.keychain.util.Preferences;
-import org.sufficientlysecure.keychain.util.ProgressScaler;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -79,8 +72,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -113,6 +104,8 @@ public class KeychainIntentService extends IntentService implements Progressable
public static final String ACTION_EDIT_KEYRING = Constants.INTENT_PREFIX + "EDIT_KEYRING";
+ public static final String ACTION_PROMOTE_KEYRING = Constants.INTENT_PREFIX + "PROMOTE_KEYRING";
+
public static final String ACTION_IMPORT_KEYRING = Constants.INTENT_PREFIX + "IMPORT_KEYRING";
public static final String ACTION_EXPORT_KEYRING = Constants.INTENT_PREFIX + "EXPORT_KEYRING";
@@ -135,24 +128,11 @@ public class KeychainIntentService extends IntentService implements Progressable
// possible targets:
public static final int IO_BYTES = 1;
public static final int IO_URI = 2;
- public static final int IO_URIS = 3;
-
- public static final String SELECTED_URI = "selected_uri";
// encrypt
- public static final String ENCRYPT_SIGNATURE_MASTER_ID = "secret_key_id";
- public static final String ENCRYPT_SIGNATURE_KEY_PASSPHRASE = "secret_key_passphrase";
- public static final String ENCRYPT_SIGNATURE_NFC_TIMESTAMP = "signature_nfc_timestamp";
- public static final String ENCRYPT_SIGNATURE_NFC_HASH = "signature_nfc_hash";
- public static final String ENCRYPT_USE_ASCII_ARMOR = "use_ascii_armor";
- public static final String ENCRYPT_ENCRYPTION_KEYS_IDS = "encryption_keys_ids";
- public static final String ENCRYPT_COMPRESSION_ID = "compression_id";
- public static final String ENCRYPT_MESSAGE_BYTES = "message_bytes";
public static final String ENCRYPT_DECRYPT_INPUT_URI = "input_uri";
- public static final String ENCRYPT_INPUT_URIS = "input_uris";
public static final String ENCRYPT_DECRYPT_OUTPUT_URI = "output_uri";
- public static final String ENCRYPT_OUTPUT_URIS = "output_uris";
- public static final String ENCRYPT_SYMMETRIC_PASSPHRASE = "passphrase";
+ public static final String SIGN_ENCRYPT_PARCEL = "sign_encrypt_parcel";
// decrypt/verify
public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes";
@@ -188,6 +168,10 @@ public class KeychainIntentService extends IntentService implements Progressable
// certify key
public static final String CERTIFY_PARCEL = "certify_parcel";
+ // promote key
+ public static final String PROMOTE_MASTER_KEY_ID = "promote_master_key_id";
+ public static final String PROMOTE_TYPE = "promote_type";
+
// consolidate
public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery";
@@ -196,9 +180,6 @@ public class KeychainIntentService extends IntentService implements Progressable
* possible data keys as result send over messenger
*/
- // encrypt
- public static final String RESULT_BYTES = "encrypted_data";
-
// decrypt/verify
public static final String RESULT_DECRYPTED_BYTES = "decrypted_data";
@@ -251,461 +232,341 @@ public class KeychainIntentService extends IntentService implements Progressable
String action = intent.getAction();
// executeServiceMethod action from extra bundle
- if (ACTION_CERTIFY_KEYRING.equals(action)) {
-
- // Input
- CertifyActionsParcel parcel = data.getParcelable(CERTIFY_PARCEL);
- String keyServerUri = data.getString(UPLOAD_KEY_SERVER);
+ switch (action) {
+ case ACTION_CERTIFY_KEYRING: {
- // Operation
- CertifyOperation op = new CertifyOperation(this, providerHelper, this, mActionCanceled);
- CertifyResult result = op.certify(parcel, keyServerUri);
+ // Input
+ CertifyActionsParcel parcel = data.getParcelable(CERTIFY_PARCEL);
+ String keyServerUri = data.getString(UPLOAD_KEY_SERVER);
- // Result
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
+ // Operation
+ CertifyOperation op = new CertifyOperation(this, providerHelper, this, mActionCanceled);
+ CertifyResult result = op.certify(parcel, keyServerUri);
- } else if (ACTION_CONSOLIDATE.equals(action)) {
+ // Result
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
- // Operation
- ConsolidateResult result;
- if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) {
- result = new ProviderHelper(this).consolidateDatabaseStep2(this);
- } else {
- result = new ProviderHelper(this).consolidateDatabaseStep1(this);
+ break;
}
+ case ACTION_CONSOLIDATE: {
- // Result
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
+ // Operation
+ ConsolidateResult result;
+ if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) {
+ result = new ProviderHelper(this).consolidateDatabaseStep2(this);
+ } else {
+ result = new ProviderHelper(this).consolidateDatabaseStep1(this);
+ }
- } else if (ACTION_DECRYPT_METADATA.equals(action)) {
+ // Result
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
- try {
+ break;
+ }
+ case ACTION_DECRYPT_METADATA: {
+
+ try {
/* Input */
- String passphrase = data.getString(DECRYPT_PASSPHRASE);
- byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);
+ String passphrase = data.getString(DECRYPT_PASSPHRASE);
+ byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);
- InputData inputData = createDecryptInputData(data);
+ InputData inputData = createDecryptInputData(data);
/* Operation */
- Bundle resultData = new Bundle();
-
- // verifyText and decrypt returning additional resultData values for the
- // verification of signatures
- PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
- this, new ProviderHelper(this), this, inputData, null
- );
- builder.setAllowSymmetricDecryption(true)
- .setPassphrase(passphrase)
- .setDecryptMetadataOnly(true)
- .setNfcState(nfcDecryptedSessionKey);
+ Bundle resultData = new Bundle();
- DecryptVerifyResult decryptVerifyResult = builder.build().execute();
+ // verifyText and decrypt returning additional resultData values for the
+ // verification of signatures
+ PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
+ this, new ProviderHelper(this), this, inputData, null
+ );
+ builder.setAllowSymmetricDecryption(true)
+ .setPassphrase(passphrase)
+ .setDecryptMetadataOnly(true)
+ .setNfcState(nfcDecryptedSessionKey);
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, decryptVerifyResult);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
+ DecryptVerifyResult decryptVerifyResult = builder.build().execute();
- } else if (ACTION_VERIFY_KEYBASE_PROOF.equals(action)) {
- try {
- Proof proof = new Proof(new JSONObject(data.getString(KEYBASE_PROOF)));
- setProgress(R.string.keybase_message_fetching_data, 0, 100);
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, decryptVerifyResult);
+ } catch (Exception e) {
+ sendErrorToHandler(e);
+ }
- Prover prover = Prover.findProverFor(proof);
+ break;
+ }
+ case ACTION_VERIFY_KEYBASE_PROOF: {
- if (prover == null) {
- sendProofError(getString(R.string.keybase_no_prover_found) + ": " + proof.getPrettyName());
- return;
- }
+ try {
+ Proof proof = new Proof(new JSONObject(data.getString(KEYBASE_PROOF)));
+ setProgress(R.string.keybase_message_fetching_data, 0, 100);
- if (!prover.fetchProofData()) {
- sendProofError(prover.getLog(), getString(R.string.keybase_problem_fetching_evidence));
- return;
- }
- String requiredFingerprint = data.getString(KEYBASE_REQUIRED_FINGERPRINT);
- if (!prover.checkFingerprint(requiredFingerprint)) {
- sendProofError(getString(R.string.keybase_key_mismatch));
- return;
- }
+ Prover prover = Prover.findProverFor(proof);
- String domain = prover.dnsTxtCheckRequired();
- if (domain != null) {
- DNSMessage dnsQuery = new Client().query(new Question(domain, Record.TYPE.TXT));
- if (dnsQuery == null) {
- sendProofError(prover.getLog(), getString(R.string.keybase_dns_query_failure));
+ if (prover == null) {
+ sendProofError(getString(R.string.keybase_no_prover_found) + ": " + proof.getPrettyName());
return;
}
- Record[] records = dnsQuery.getAnswers();
- List<List<byte[]>> extents = new ArrayList<List<byte[]>>();
- for (Record r : records) {
- Data d = r.getPayload();
- if (d instanceof TXT) {
- extents.add(((TXT) d).getExtents());
- }
+
+ if (!prover.fetchProofData()) {
+ sendProofError(prover.getLog(), getString(R.string.keybase_problem_fetching_evidence));
+ return;
}
- if (!prover.checkDnsTxt(extents)) {
- sendProofError(prover.getLog(), null);
+ String requiredFingerprint = data.getString(KEYBASE_REQUIRED_FINGERPRINT);
+ if (!prover.checkFingerprint(requiredFingerprint)) {
+ sendProofError(getString(R.string.keybase_key_mismatch));
return;
}
- }
- byte[] messageBytes = prover.getPgpMessage().getBytes();
- if (prover.rawMessageCheckRequired()) {
- InputStream messageByteStream = PGPUtil.getDecoderStream(new ByteArrayInputStream(messageBytes));
- if (!prover.checkRawMessageBytes(messageByteStream)) {
- sendProofError(prover.getLog(), null);
- return;
+ String domain = prover.dnsTxtCheckRequired();
+ if (domain != null) {
+ DNSMessage dnsQuery = new Client().query(new Question(domain, Record.TYPE.TXT));
+ if (dnsQuery == null) {
+ sendProofError(prover.getLog(), getString(R.string.keybase_dns_query_failure));
+ return;
+ }
+ Record[] records = dnsQuery.getAnswers();
+ List<List<byte[]>> extents = new ArrayList<List<byte[]>>();
+ for (Record r : records) {
+ Data d = r.getPayload();
+ if (d instanceof TXT) {
+ extents.add(((TXT) d).getExtents());
+ }
+ }
+ if (!prover.checkDnsTxt(extents)) {
+ sendProofError(prover.getLog(), null);
+ return;
+ }
}
- }
- // kind of awkward, but this whole class wants to pull bytes out of “dataâ€
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES);
- data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, messageBytes);
+ byte[] messageBytes = prover.getPgpMessage().getBytes();
+ if (prover.rawMessageCheckRequired()) {
+ InputStream messageByteStream = PGPUtil.getDecoderStream(new ByteArrayInputStream(messageBytes));
+ if (!prover.checkRawMessageBytes(messageByteStream)) {
+ sendProofError(prover.getLog(), null);
+ return;
+ }
+ }
+
+ // kind of awkward, but this whole class wants to pull bytes out of “dataâ€
+ data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES);
+ data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, messageBytes);
- InputData inputData = createDecryptInputData(data);
- OutputStream outStream = createCryptOutputStream(data);
+ InputData inputData = createDecryptInputData(data);
+ OutputStream outStream = createCryptOutputStream(data);
+
+ PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
+ this, new ProviderHelper(this), this,
+ inputData, outStream
+ );
+ builder.setSignedLiteralData(true).setRequiredSignerFingerprint(requiredFingerprint);
- PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
- this, new ProviderHelper(this), this,
- inputData, outStream
- );
- builder.setSignedLiteralData(true).setRequiredSignerFingerprint(requiredFingerprint);
+ DecryptVerifyResult decryptVerifyResult = builder.build().execute();
+ outStream.close();
- DecryptVerifyResult decryptVerifyResult = builder.build().execute();
- outStream.close();
+ if (!decryptVerifyResult.success()) {
+ OperationLog log = decryptVerifyResult.getLog();
+ OperationResult.LogEntryParcel lastEntry = null;
+ for (OperationResult.LogEntryParcel entry : log) {
+ lastEntry = entry;
+ }
+ sendProofError(getString(lastEntry.mType.getMsgId()));
+ return;
+ }
- if (!decryptVerifyResult.success()) {
- OperationLog log = decryptVerifyResult.getLog();
- OperationResult.LogEntryParcel lastEntry = null;
- for (OperationResult.LogEntryParcel entry : log) {
- lastEntry = entry;
+ if (!prover.validate(outStream.toString())) {
+ sendProofError(getString(R.string.keybase_message_payload_mismatch));
+ return;
}
- sendProofError(getString(lastEntry.mType.getMsgId()));
- return;
- }
- if (!prover.validate(outStream.toString())) {
- sendProofError(getString(R.string.keybase_message_payload_mismatch));
- return;
- }
+ Bundle resultData = new Bundle();
+ resultData.putString(KeychainIntentServiceHandler.DATA_MESSAGE, "OK");
- Bundle resultData = new Bundle();
- resultData.putString(KeychainIntentServiceHandler.DATA_MESSAGE, "OK");
+ // these help the handler construct a useful human-readable message
+ resultData.putString(KeychainIntentServiceHandler.KEYBASE_PROOF_URL, prover.getProofUrl());
+ resultData.putString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_URL, prover.getPresenceUrl());
+ resultData.putString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_LABEL, prover.getPresenceLabel());
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
+ } catch (Exception e) {
+ sendErrorToHandler(e);
+ }
- // these help the handler construct a useful human-readable message
- resultData.putString(KeychainIntentServiceHandler.KEYBASE_PROOF_URL, prover.getProofUrl());
- resultData.putString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_URL, prover.getPresenceUrl());
- resultData.putString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_LABEL, prover.getPresenceLabel());
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
+ break;
}
+ case ACTION_DECRYPT_VERIFY: {
- } else if (ACTION_DECRYPT_VERIFY.equals(action)) {
-
- try {
+ try {
/* Input */
- String passphrase = data.getString(DECRYPT_PASSPHRASE);
- byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);
+ String passphrase = data.getString(DECRYPT_PASSPHRASE);
+ byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);
- InputData inputData = createDecryptInputData(data);
- OutputStream outStream = createCryptOutputStream(data);
+ InputData inputData = createDecryptInputData(data);
+ OutputStream outStream = createCryptOutputStream(data);
/* Operation */
- Bundle resultData = new Bundle();
+ Bundle resultData = new Bundle();
- // verifyText and decrypt returning additional resultData values for the
- // verification of signatures
- PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
- this, new ProviderHelper(this), this,
- inputData, outStream
- );
- builder.setAllowSymmetricDecryption(true)
- .setPassphrase(passphrase)
- .setNfcState(nfcDecryptedSessionKey);
+ // verifyText and decrypt returning additional resultData values for the
+ // verification of signatures
+ PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
+ this, new ProviderHelper(this), this,
+ inputData, outStream
+ );
+ builder.setAllowSymmetricDecryption(true)
+ .setPassphrase(passphrase)
+ .setNfcState(nfcDecryptedSessionKey);
- DecryptVerifyResult decryptVerifyResult = builder.build().execute();
+ DecryptVerifyResult decryptVerifyResult = builder.build().execute();
- outStream.close();
+ outStream.close();
- resultData.putParcelable(DecryptVerifyResult.EXTRA_RESULT, decryptVerifyResult);
+ resultData.putParcelable(DecryptVerifyResult.EXTRA_RESULT, decryptVerifyResult);
/* Output */
- finalizeDecryptOutputStream(data, resultData, outStream);
+ finalizeDecryptOutputStream(data, resultData, outStream);
- Log.logDebugBundle(resultData, "resultData");
+ Log.logDebugBundle(resultData, "resultData");
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
+ } catch (Exception e) {
+ sendErrorToHandler(e);
+ }
- } else if (ACTION_DELETE.equals(action)) {
+ break;
+ }
+ case ACTION_DELETE: {
- // Input
- long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST);
- boolean isSecret = data.getBoolean(DELETE_IS_SECRET);
+ // Input
+ long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST);
+ boolean isSecret = data.getBoolean(DELETE_IS_SECRET);
- // Operation
- DeleteOperation op = new DeleteOperation(this, new ProviderHelper(this), this);
- DeleteResult result = op.execute(masterKeyIds, isSecret);
+ // Operation
+ DeleteOperation op = new DeleteOperation(this, new ProviderHelper(this), this);
+ DeleteResult result = op.execute(masterKeyIds, isSecret);
- // Result
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
+ // Result
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
- } else if (ACTION_EDIT_KEYRING.equals(action)) {
+ break;
+ }
+ case ACTION_EDIT_KEYRING: {
- try {
- /* Input */
+ // Input
SaveKeyringParcel saveParcel = data.getParcelable(EDIT_KEYRING_PARCEL);
- if (saveParcel == null) {
- Log.e(Constants.TAG, "bug: missing save_keyring_parcel in data!");
- return;
- }
-
- /* Operation */
- PgpKeyOperation keyOperations =
- new PgpKeyOperation(new ProgressScaler(this, 10, 60, 100), mActionCanceled);
- EditKeyResult modifyResult;
-
- if (saveParcel.mMasterKeyId != null) {
- String passphrase = data.getString(EDIT_KEYRING_PASSPHRASE);
- CanonicalizedSecretKeyRing secRing =
- new ProviderHelper(this).getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
-
- modifyResult = keyOperations.modifySecretKeyRing(secRing, saveParcel, passphrase);
- } else {
- modifyResult = keyOperations.createSecretKeyRing(saveParcel);
- }
-
- // If the edit operation didn't succeed, exit here
- if (!modifyResult.success()) {
- // always return SaveKeyringResult, so create one out of the EditKeyResult
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, modifyResult);
- return;
- }
-
- UncachedKeyRing ring = modifyResult.getRing();
+ String passphrase = data.getString(EDIT_KEYRING_PASSPHRASE);
- // Check if the action was cancelled
- if (mActionCanceled.get()) {
- OperationLog log = modifyResult.getLog();
- // If it wasn't added before, add log entry
- if (!modifyResult.cancelled()) {
- log.add(LogType.MSG_OPERATION_CANCELLED, 0);
- }
- // If so, just stop without saving
- modifyResult = new EditKeyResult(
- EditKeyResult.RESULT_CANCELLED, log, null);
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, modifyResult);
- return;
- }
+ // Operation
+ EditKeyOperation op = new EditKeyOperation(this, providerHelper, this, mActionCanceled);
+ EditKeyResult result = op.execute(saveParcel, passphrase);
- // Save the keyring. The ProviderHelper is initialized with the previous log
- SaveKeyringResult saveResult = new ProviderHelper(this, modifyResult.getLog())
- .saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
+ // Result
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
- // If the edit operation didn't succeed, exit here
- if (!saveResult.success()) {
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult);
- return;
- }
+ break;
+ }
+ case ACTION_PROMOTE_KEYRING: {
- // cache new passphrase
- if (saveParcel.mNewPassphrase != null) {
- PassphraseCacheService.addCachedPassphrase(this, ring.getMasterKeyId(), ring.getMasterKeyId(),
- saveParcel.mNewPassphrase, ring.getPublicKey().getPrimaryUserIdWithFallback());
- }
+ // Input
+ long keyRingId = data.getInt(EXPORT_KEY_RING_MASTER_KEY_ID);
- setProgress(R.string.progress_done, 100, 100);
+ // Operation
+ PromoteKeyOperation op = new PromoteKeyOperation(this, providerHelper, this, mActionCanceled);
+ PromoteKeyResult result = op.execute(keyRingId);
- // make sure new data is synced into contacts
- ContactSyncAdapterService.requestSync();
+ // Result
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
- /* Output */
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult);
- } catch (Exception e) {
- sendErrorToHandler(e);
+ break;
}
+ case ACTION_EXPORT_KEYRING: {
- } else if (ACTION_EXPORT_KEYRING.equals(action)) {
+ // Input
+ boolean exportSecret = data.getBoolean(EXPORT_SECRET, false);
+ String outputFile = data.getString(EXPORT_FILENAME);
+ Uri outputUri = data.getParcelable(EXPORT_URI);
- // Input
- boolean exportSecret = data.getBoolean(EXPORT_SECRET, false);
- String outputFile = data.getString(EXPORT_FILENAME);
- Uri outputUri = data.getParcelable(EXPORT_URI);
+ boolean exportAll = data.getBoolean(EXPORT_ALL);
+ long[] masterKeyIds = exportAll ? null : data.getLongArray(EXPORT_KEY_RING_MASTER_KEY_ID);
- boolean exportAll = data.getBoolean(EXPORT_ALL);
- long[] masterKeyIds = exportAll ? null : data.getLongArray(EXPORT_KEY_RING_MASTER_KEY_ID);
+ // Operation
+ ImportExportOperation importExportOperation = new ImportExportOperation(this, new ProviderHelper(this), this);
+ ExportResult result;
+ if (outputFile != null) {
+ result = importExportOperation.exportToFile(masterKeyIds, exportSecret, outputFile);
+ } else {
+ result = importExportOperation.exportToUri(masterKeyIds, exportSecret, outputUri);
+ }
+ // Result
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
- // Operation
- ImportExportOperation importExportOperation = new ImportExportOperation(this, new ProviderHelper(this), this);
- ExportResult result;
- if (outputFile != null) {
- result = importExportOperation.exportToFile(masterKeyIds, exportSecret, outputFile);
- } else {
- result = importExportOperation.exportToUri(masterKeyIds, exportSecret, outputUri);
+ break;
}
-
- // Result
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
-
- } else if (ACTION_IMPORT_KEYRING.equals(action)) {
-
- try {
+ case ACTION_IMPORT_KEYRING: {
// Input
String keyServer = data.getString(IMPORT_KEY_SERVER);
- Iterator<ParcelableKeyRing> entries;
- int numEntries;
- if (data.containsKey(IMPORT_KEY_LIST)) {
- // get entries from intent
- ArrayList<ParcelableKeyRing> list = data.getParcelableArrayList(IMPORT_KEY_LIST);
- entries = list.iterator();
- numEntries = list.size();
- } else {
- // get entries from cached file
- ParcelableFileCache<ParcelableKeyRing> cache =
- new ParcelableFileCache<ParcelableKeyRing>(this, "key_import.pcl");
- IteratorWithSize<ParcelableKeyRing> it = cache.readCache();
- entries = it;
- numEntries = it.getSize();
- }
+ ArrayList<ParcelableKeyRing> list = data.getParcelableArrayList(IMPORT_KEY_LIST);
+ ParcelableFileCache<ParcelableKeyRing> cache =
+ new ParcelableFileCache<>(this, "key_import.pcl");
// Operation
ImportExportOperation importExportOperation = new ImportExportOperation(
this, providerHelper, this, mActionCanceled);
- ImportKeyResult result = importExportOperation.importKeyRings(entries, numEntries, keyServer);
-
- // Special: consolidate on secret key import (cannot be cancelled!)
- if (result.mSecret > 0) {
- // TODO move this into the import operation
- providerHelper.consolidateDatabaseStep1(this);
- }
-
- // Special: make sure new data is synced into contacts
- ContactSyncAdapterService.requestSync();
+ // Either list or cache must be null, no guarantees otherwise.
+ ImportKeyResult result = list != null
+ ? importExportOperation.importKeyRings(list, keyServer)
+ : importExportOperation.importKeyRings(cache, keyServer);
// Result
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_SIGN_ENCRYPT.equals(action)) {
-
- try {
- /* Input */
- int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET);
- Bundle resultData = new Bundle();
-
- long sigMasterKeyId = data.getLong(ENCRYPT_SIGNATURE_MASTER_ID);
- String sigKeyPassphrase = data.getString(ENCRYPT_SIGNATURE_KEY_PASSPHRASE);
-
- byte[] nfcHash = data.getByteArray(ENCRYPT_SIGNATURE_NFC_HASH);
- Date nfcTimestamp = (Date) data.getSerializable(ENCRYPT_SIGNATURE_NFC_TIMESTAMP);
-
- String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE);
-
- boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR);
- long encryptionKeyIds[] = data.getLongArray(ENCRYPT_ENCRYPTION_KEYS_IDS);
- int compressionId = data.getInt(ENCRYPT_COMPRESSION_ID);
- int urisCount = data.containsKey(ENCRYPT_INPUT_URIS) ? data.getParcelableArrayList(ENCRYPT_INPUT_URIS).size() : 1;
- for (int i = 0; i < urisCount; i++) {
- data.putInt(SELECTED_URI, i);
- InputData inputData = createEncryptInputData(data);
- OutputStream outStream = createCryptOutputStream(data);
- String originalFilename = getOriginalFilename(data);
-
- /* Operation */
- PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(
- this, new ProviderHelper(this), this, inputData, outStream
- );
- builder.setEnableAsciiArmorOutput(useAsciiArmor)
- .setVersionHeader(PgpHelper.getVersionForHeader(this))
- .setCompressionId(compressionId)
- .setSymmetricEncryptionAlgorithm(
- Preferences.getPreferences(this).getDefaultEncryptionAlgorithm())
- .setEncryptionMasterKeyIds(encryptionKeyIds)
- .setSymmetricPassphrase(symmetricPassphrase)
- .setOriginalFilename(originalFilename);
-
- try {
-
- // Find the appropriate subkey to sign with
- CachedPublicKeyRing signingRing =
- new ProviderHelper(this).getCachedPublicKeyRing(sigMasterKeyId);
- long sigSubKeyId = signingRing.getSecretSignId();
-
- // Set signature settings
- builder.setSignatureMasterKeyId(sigMasterKeyId)
- .setSignatureSubKeyId(sigSubKeyId)
- .setSignaturePassphrase(sigKeyPassphrase)
- .setSignatureHashAlgorithm(
- Preferences.getPreferences(this).getDefaultHashAlgorithm())
- .setAdditionalEncryptId(sigMasterKeyId);
- if (nfcHash != null && nfcTimestamp != null) {
- builder.setNfcState(nfcHash, nfcTimestamp);
- }
-
- } catch (PgpKeyNotFoundException e) {
- // encrypt-only
- // TODO Just silently drop the requested signature? Shouldn't we throw here?
- }
-
- // this assumes that the bytes are cleartext (valid for current implementation!)
- if (source == IO_BYTES) {
- builder.setCleartextInput(true);
- }
-
- SignEncryptResult result = builder.build().execute();
- resultData.putParcelable(SignEncryptResult.EXTRA_RESULT, result);
-
- outStream.close();
+ break;
- /* Output */
+ }
+ case ACTION_SIGN_ENCRYPT: {
- finalizeEncryptOutputStream(data, resultData, outStream);
+ // Input
+ SignEncryptParcel inputParcel = data.getParcelable(SIGN_ENCRYPT_PARCEL);
- }
+ // Operation
+ SignEncryptOperation op = new SignEncryptOperation(
+ this, new ProviderHelper(this), this, mActionCanceled);
+ SignEncryptResult result = op.execute(inputParcel);
- Log.logDebugBundle(resultData, "resultData");
+ // Result
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
+ break;
}
+ case ACTION_UPLOAD_KEYRING: {
+ try {
- } else if (ACTION_UPLOAD_KEYRING.equals(action)) {
-
- try {
+ /* Input */
+ String keyServer = data.getString(UPLOAD_KEY_SERVER);
+ // and dataUri!
- /* Input */
- String keyServer = data.getString(UPLOAD_KEY_SERVER);
- // and dataUri!
+ /* Operation */
+ HkpKeyserver server = new HkpKeyserver(keyServer);
- /* Operation */
- HkpKeyserver server = new HkpKeyserver(keyServer);
+ CanonicalizedPublicKeyRing keyring = providerHelper.getCanonicalizedPublicKeyRing(dataUri);
+ ImportExportOperation importExportOperation = new ImportExportOperation(this, new ProviderHelper(this), this);
- CanonicalizedPublicKeyRing keyring = providerHelper.getCanonicalizedPublicKeyRing(dataUri);
- ImportExportOperation importExportOperation = new ImportExportOperation(this, new ProviderHelper(this), this);
+ try {
+ importExportOperation.uploadKeyRingToServer(server, keyring);
+ } catch (Keyserver.AddKeyException e) {
+ throw new PgpGeneralException("Unable to export key to selected server");
+ }
- try {
- importExportOperation.uploadKeyRingToServer(server, keyring);
- } catch (Keyserver.AddKeyException e) {
- throw new PgpGeneralException("Unable to export key to selected server");
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY);
+ } catch (Exception e) {
+ sendErrorToHandler(e);
}
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY);
- } catch (Exception e) {
- sendErrorToHandler(e);
+ break;
}
}
-
}
private void sendProofError(List<String> log, String label) {
@@ -810,10 +671,6 @@ public class KeychainIntentService extends IntentService implements Progressable
return createCryptInputData(data, DECRYPT_CIPHERTEXT_BYTES);
}
- private InputData createEncryptInputData(Bundle data) throws IOException, PgpGeneralException {
- return createCryptInputData(data, ENCRYPT_MESSAGE_BYTES);
- }
-
private InputData createCryptInputData(Bundle data, String bytesName) throws PgpGeneralException, IOException {
int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET);
switch (source) {
@@ -827,33 +684,6 @@ public class KeychainIntentService extends IntentService implements Progressable
// InputStream
return new InputData(getContentResolver().openInputStream(providerUri), FileHelper.getFileSize(this, providerUri, 0));
- case IO_URIS:
- providerUri = data.<Uri>getParcelableArrayList(ENCRYPT_INPUT_URIS).get(data.getInt(SELECTED_URI));
-
- // InputStream
- return new InputData(getContentResolver().openInputStream(providerUri), FileHelper.getFileSize(this, providerUri, 0));
-
- default:
- throw new PgpGeneralException("No target choosen!");
- }
- }
-
- private String getOriginalFilename(Bundle data) throws PgpGeneralException, FileNotFoundException {
- int target = data.getInt(TARGET);
- switch (target) {
- case IO_BYTES:
- return "";
-
- case IO_URI:
- Uri providerUri = data.getParcelable(ENCRYPT_DECRYPT_INPUT_URI);
-
- return FileHelper.getFilename(this, providerUri);
-
- case IO_URIS:
- providerUri = data.<Uri>getParcelableArrayList(ENCRYPT_INPUT_URIS).get(data.getInt(SELECTED_URI));
-
- return FileHelper.getFilename(this, providerUri);
-
default:
throw new PgpGeneralException("No target choosen!");
}
@@ -870,20 +700,11 @@ public class KeychainIntentService extends IntentService implements Progressable
return getContentResolver().openOutputStream(providerUri);
- case IO_URIS:
- providerUri = data.<Uri>getParcelableArrayList(ENCRYPT_OUTPUT_URIS).get(data.getInt(SELECTED_URI));
-
- return getContentResolver().openOutputStream(providerUri);
-
default:
throw new PgpGeneralException("No target choosen!");
}
}
- private void finalizeEncryptOutputStream(Bundle data, Bundle resultData, OutputStream outStream) {
- finalizeCryptOutputStream(data, resultData, outStream, RESULT_BYTES);
- }
-
private void finalizeDecryptOutputStream(Bundle data, Bundle resultData, OutputStream outStream) {
finalizeCryptOutputStream(data, resultData, outStream, RESULT_DECRYPTED_BYTES);
}
@@ -896,7 +717,6 @@ public class KeychainIntentService extends IntentService implements Progressable
resultData.putByteArray(bytesName, output);
break;
case IO_URI:
- case IO_URIS:
// nothing, output was written, just send okay and verification bundle
break;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
index fc65757f5..ceb0a2d2b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
@@ -27,8 +27,8 @@ import android.support.v4.app.FragmentManager;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.util.Log;
public class KeychainIntentServiceHandler extends Handler {
@@ -136,6 +136,7 @@ public class KeychainIntentServiceHandler extends Handler {
case MESSAGE_PREVENT_CANCEL:
mProgressDialogFragment.setPreventCancel(true);
+ break;
default:
Log.e(Constants.TAG, "unknown handler message!");
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
index 869d2e71b..57881f8ee 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
@@ -39,12 +39,11 @@ import android.support.v4.util.LongSparseArray;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
import java.util.Date;
@@ -103,7 +102,7 @@ public class PassphraseCacheService extends Service {
private BroadcastReceiver mIntentReceiver;
- private LongSparseArray<CachedPassphrase> mPassphraseCache = new LongSparseArray<CachedPassphrase>();
+ private LongSparseArray<CachedPassphrase> mPassphraseCache = new LongSparseArray<>();
Context mContext;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
index c4be467e4..e2d0c03c9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
@@ -21,6 +21,8 @@ package org.sufficientlysecure.keychain.service;
import android.os.Parcel;
import android.os.Parcelable;
+import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
+
import java.io.Serializable;
import java.util.ArrayList;
@@ -46,9 +48,10 @@ public class SaveKeyringParcel implements Parcelable {
// the key fingerprint, for safety. MUST be null for a new key.
public byte[] mFingerprint;
- public String mNewPassphrase;
+ public ChangeUnlockParcel mNewUnlock;
public ArrayList<String> mAddUserIds;
+ public ArrayList<WrappedUserAttribute> mAddUserAttribute;
public ArrayList<SubkeyAdd> mAddSubKeys;
public ArrayList<SubkeyChange> mChangeSubKeys;
@@ -56,7 +59,6 @@ public class SaveKeyringParcel implements Parcelable {
public ArrayList<String> mRevokeUserIds;
public ArrayList<Long> mRevokeSubKeys;
- public ArrayList<Long> mStripSubKeys;
public SaveKeyringParcel() {
reset();
@@ -69,14 +71,31 @@ public class SaveKeyringParcel implements Parcelable {
}
public void reset() {
- mNewPassphrase = null;
- mAddUserIds = new ArrayList<String>();
- mAddSubKeys = new ArrayList<SubkeyAdd>();
+ mNewUnlock = null;
+ mAddUserIds = new ArrayList<>();
+ mAddUserAttribute = new ArrayList<>();
+ mAddSubKeys = new ArrayList<>();
mChangePrimaryUserId = null;
- mChangeSubKeys = new ArrayList<SubkeyChange>();
- mRevokeUserIds = new ArrayList<String>();
- mRevokeSubKeys = new ArrayList<Long>();
- mStripSubKeys = new ArrayList<Long>();
+ mChangeSubKeys = new ArrayList<>();
+ mRevokeUserIds = new ArrayList<>();
+ mRevokeSubKeys = new ArrayList<>();
+ }
+
+ /** Returns true iff this parcel does not contain any operations which require a passphrase. */
+ public boolean isRestrictedOnly() {
+ if (mNewUnlock != null || !mAddUserIds.isEmpty() || !mAddUserAttribute.isEmpty()
+ || !mAddSubKeys.isEmpty() || mChangePrimaryUserId != null || !mRevokeSubKeys .isEmpty()
+ || !mRevokeSubKeys.isEmpty()) {
+ return false;
+ }
+
+ for (SubkeyChange change : mChangeSubKeys) {
+ if (change.mRecertify || change.mFlags != null || change.mExpiry != null) {
+ return false;
+ }
+ }
+
+ return true;
}
// performance gain for using Parcelable here would probably be negligible,
@@ -109,26 +128,53 @@ public class SaveKeyringParcel implements Parcelable {
}
public static class SubkeyChange implements Serializable {
- public long mKeyId;
+ public final long mKeyId;
public Integer mFlags;
// this is a long unix timestamp, in seconds (NOT MILLISECONDS!)
public Long mExpiry;
+ // if this flag is true, the key will be recertified even if all above
+ // values are no-ops
+ public boolean mRecertify;
+ // if this flag is true, the subkey should be changed to a stripped key
+ public boolean mDummyStrip;
+ // if this is non-null, the subkey will be changed to a divert-to-card
+ // key for the given serial number
+ public byte[] mDummyDivert;
public SubkeyChange(long keyId) {
mKeyId = keyId;
}
+ public SubkeyChange(long keyId, boolean recertify) {
+ mKeyId = keyId;
+ mRecertify = recertify;
+ }
+
public SubkeyChange(long keyId, Integer flags, Long expiry) {
mKeyId = keyId;
mFlags = flags;
mExpiry = expiry;
}
+ public SubkeyChange(long keyId, boolean dummyStrip, byte[] dummyDivert) {
+ this(keyId, null, null);
+
+ // these flags are mutually exclusive!
+ if (dummyStrip && dummyDivert != null) {
+ throw new AssertionError(
+ "cannot set strip and divert flags at the same time - this is a bug!");
+ }
+ mDummyStrip = dummyStrip;
+ mDummyDivert = dummyDivert;
+ }
+
@Override
public String toString() {
String out = "mKeyId: " + mKeyId + ", ";
out += "mFlags: " + mFlags + ", ";
- out += "mExpiry: " + mExpiry;
+ out += "mExpiry: " + mExpiry + ", ";
+ out += "mDummyStrip: " + mDummyStrip + ", ";
+ out += "mDummyDivert: [" + (mDummyDivert == null ? 0 : mDummyDivert.length) + " bytes]";
return out;
}
@@ -159,9 +205,10 @@ public class SaveKeyringParcel implements Parcelable {
mMasterKeyId = source.readInt() != 0 ? source.readLong() : null;
mFingerprint = source.createByteArray();
- mNewPassphrase = source.readString();
+ mNewUnlock = source.readParcelable(getClass().getClassLoader());
mAddUserIds = source.createStringArrayList();
+ mAddUserAttribute = (ArrayList<WrappedUserAttribute>) source.readSerializable();
mAddSubKeys = (ArrayList<SubkeyAdd>) source.readSerializable();
mChangeSubKeys = (ArrayList<SubkeyChange>) source.readSerializable();
@@ -169,7 +216,6 @@ public class SaveKeyringParcel implements Parcelable {
mRevokeUserIds = source.createStringArrayList();
mRevokeSubKeys = (ArrayList<Long>) source.readSerializable();
- mStripSubKeys = (ArrayList<Long>) source.readSerializable();
}
@Override
@@ -180,9 +226,11 @@ public class SaveKeyringParcel implements Parcelable {
}
destination.writeByteArray(mFingerprint);
- destination.writeString(mNewPassphrase);
+ // yes, null values are ok for parcelables
+ destination.writeParcelable(mNewUnlock, 0);
destination.writeStringList(mAddUserIds);
+ destination.writeSerializable(mAddUserAttribute);
destination.writeSerializable(mAddSubKeys);
destination.writeSerializable(mChangeSubKeys);
@@ -190,7 +238,6 @@ public class SaveKeyringParcel implements Parcelable {
destination.writeStringList(mRevokeUserIds);
destination.writeSerializable(mRevokeSubKeys);
- destination.writeSerializable(mStripSubKeys);
}
public static final Creator<SaveKeyringParcel> CREATOR = new Creator<SaveKeyringParcel>() {
@@ -211,14 +258,14 @@ public class SaveKeyringParcel implements Parcelable {
@Override
public String toString() {
String out = "mMasterKeyId: " + mMasterKeyId + "\n";
- out += "mNewPassphrase: " + mNewPassphrase + "\n";
+ out += "mNewUnlock: " + mNewUnlock + "\n";
out += "mAddUserIds: " + mAddUserIds + "\n";
+ out += "mAddUserAttribute: " + mAddUserAttribute + "\n";
out += "mAddSubKeys: " + mAddSubKeys + "\n";
out += "mChangeSubKeys: " + mChangeSubKeys + "\n";
out += "mChangePrimaryUserId: " + mChangePrimaryUserId + "\n";
out += "mRevokeUserIds: " + mRevokeUserIds + "\n";
- out += "mRevokeSubKeys: " + mRevokeSubKeys + "\n";
- out += "mStripSubKeys: " + mStripSubKeys;
+ out += "mRevokeSubKeys: " + mRevokeSubKeys;
return out;
}
@@ -238,4 +285,67 @@ public class SaveKeyringParcel implements Parcelable {
// BRAINPOOL_P256, BRAINPOOL_P384, BRAINPOOL_P512
}
+ /** This subclass contains information on how the passphrase should be changed.
+ *
+ * If no changes are to be made, this class should NOT be used!
+ *
+ * At this point, there must be *exactly one* non-null value here, which specifies the type
+ * of unlocking mechanism to use.
+ *
+ */
+ public static class ChangeUnlockParcel implements Parcelable {
+
+ // The new passphrase to use
+ public final String mNewPassphrase;
+ // A new pin to use. Must only contain [0-9]+
+ public final String mNewPin;
+
+ public ChangeUnlockParcel(String newPassphrase) {
+ this(newPassphrase, null);
+ }
+ public ChangeUnlockParcel(String newPassphrase, String newPin) {
+ if (newPassphrase == null && newPin == null) {
+ throw new RuntimeException("Cannot set both passphrase and pin. THIS IS A BUG!");
+ }
+ if (newPin != null && !newPin.matches("[0-9]+")) {
+ throw new RuntimeException("Pin must be numeric digits only. THIS IS A BUG!");
+ }
+ mNewPassphrase = newPassphrase;
+ mNewPin = newPin;
+ }
+
+ public ChangeUnlockParcel(Parcel source) {
+ mNewPassphrase = source.readString();
+ mNewPin = source.readString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel destination, int flags) {
+ destination.writeString(mNewPassphrase);
+ destination.writeString(mNewPin);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<ChangeUnlockParcel> CREATOR = new Creator<ChangeUnlockParcel>() {
+ public ChangeUnlockParcel createFromParcel(final Parcel source) {
+ return new ChangeUnlockParcel(source);
+ }
+
+ public ChangeUnlockParcel[] newArray(final int size) {
+ return new ChangeUnlockParcel[size];
+ }
+ };
+
+ public String toString() {
+ return mNewPassphrase != null
+ ? ("passphrase (" + mNewPassphrase + ")")
+ : ("pin (" + mNewPin + ")");
+ }
+
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BaseActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BaseActivity.java
new file mode 100644
index 000000000..e6c2542a2
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BaseActivity.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.sufficientlysecure.keychain.R;
+
+/**
+ * Setups Toolbar
+ */
+public abstract class BaseActivity extends ActionBarActivity {
+ protected Toolbar mToolbar;
+ protected View mStatusBar;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ initLayout();
+ initToolbar();
+ }
+
+ protected abstract void initLayout();
+
+ protected void initToolbar() {
+ mToolbar = (Toolbar) findViewById(R.id.toolbar);
+ if (mToolbar != null) {
+ setSupportActionBar(mToolbar);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+ mStatusBar = findViewById(R.id.status_bar);
+ }
+
+ protected void setActionBarIcon(int iconRes) {
+ mToolbar.setNavigationIcon(iconRes);
+ }
+
+ /**
+ * Inflate custom design to look like a full screen dialog, as specified in Material Design Guidelines
+ * see http://www.google.com/design/spec/components/dialogs.html#dialogs-full-screen-dialogs
+ */
+ protected void setFullScreenDialogDoneClose(int doneText, View.OnClickListener doneOnClickListener,
+ View.OnClickListener cancelOnClickListener) {
+ setActionBarIcon(R.drawable.ic_close_white_24dp);
+
+ // Inflate the custom action bar view
+ final LayoutInflater inflater = (LayoutInflater) getSupportActionBar().getThemedContext()
+ .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
+ final View customActionBarView = inflater.inflate(R.layout.full_screen_dialog, null);
+
+ TextView firstTextView = ((TextView) customActionBarView.findViewById(R.id.full_screen_dialog_done_text));
+ firstTextView.setText(doneText);
+ customActionBarView.findViewById(R.id.full_screen_dialog_done).setOnClickListener(
+ doneOnClickListener);
+
+ getSupportActionBar().setDisplayShowCustomEnabled(true);
+ getSupportActionBar().setDisplayShowTitleEnabled(true);
+ getSupportActionBar().setCustomView(customActionBarView, new ActionBar.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT,
+ Gravity.END));
+ mToolbar.setNavigationOnClickListener(cancelOnClickListener);
+ }
+
+ /**
+ * Close button only
+ */
+ protected void setFullScreenDialogClose(View.OnClickListener cancelOnClickListener) {
+ setActionBarIcon(R.drawable.ic_close_white_24dp);
+ getSupportActionBar().setDisplayShowTitleEnabled(true);
+ mToolbar.setNavigationOnClickListener(cancelOnClickListener);
+ }
+
+ /**
+ * Inflate custom design with two buttons using drawables.
+ * This does not conform to the Material Design Guidelines, but we deviate here as this is used
+ * to indicate "Allow access"/"Disallow access" to the API, which must be clearly indicated
+ */
+ protected void setFullScreenDialogTwoButtons(int firstText, int firstDrawableId, View.OnClickListener firstOnClickListener,
+ int secondText, int secondDrawableId, View.OnClickListener secondOnClickListener) {
+
+ // Inflate the custom action bar view
+ final LayoutInflater inflater = (LayoutInflater) getSupportActionBar().getThemedContext()
+ .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
+ final View customActionBarView = inflater.inflate(
+ R.layout.full_screen_dialog_2, null);
+
+ TextView firstTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text));
+ firstTextView.setText(firstText);
+ firstTextView.setCompoundDrawablesWithIntrinsicBounds(firstDrawableId, 0, 0, 0);
+ customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
+ firstOnClickListener);
+ TextView secondTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_cancel_text));
+ secondTextView.setText(secondText);
+ secondTextView.setCompoundDrawablesWithIntrinsicBounds(secondDrawableId, 0, 0, 0);
+ customActionBarView.findViewById(R.id.actionbar_cancel).setOnClickListener(
+ secondOnClickListener);
+
+ // Show the custom action bar view and hide the normal Home icon and title.
+ getSupportActionBar().setDisplayShowTitleEnabled(false);
+ getSupportActionBar().setDisplayShowHomeEnabled(false);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(false);
+ getSupportActionBar().setDisplayShowCustomEnabled(true);
+ getSupportActionBar().setCustomView(customActionBarView, new ActionBar.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java
new file mode 100644
index 000000000..777288e69
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
+import org.sufficientlysecure.keychain.util.Log;
+
+public class CertifyFingerprintActivity extends BaseActivity {
+
+ protected Uri mDataUri;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mDataUri = getIntent().getData();
+ if (mDataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be uri of key!");
+ finish();
+ return;
+ }
+
+ setFullScreenDialogClose(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ startFragment(savedInstanceState, mDataUri);
+ }
+
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.certify_fingerprint_activity);
+ }
+
+ private void startFragment(Bundle savedInstanceState, Uri dataUri) {
+ // However, if we're being restored from a previous state,
+ // then we don't need to do anything and should return or else
+ // we could end up with overlapping fragments.
+ if (savedInstanceState != null) {
+ return;
+ }
+
+ // Create an instance of the fragment
+ CertifyFingerprintFragment frag = CertifyFingerprintFragment.newInstance(dataUri);
+
+ // Add the fragment to the 'fragment_container' FrameLayout
+ // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.certify_fingerprint_fragment, frag)
+ .commitAllowingStateLoss();
+ // do it immediately!
+ getSupportFragmentManager().executePendingTransactions();
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // if a result has been returned, display a notify
+ if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
+ OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
+ result.createNotify(this).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java
new file mode 100644
index 000000000..aef705ee9
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.Log;
+
+
+public class CertifyFingerprintFragment extends LoaderFragment implements
+ LoaderManager.LoaderCallbacks<Cursor> {
+
+ public static final String ARG_DATA_URI = "uri";
+
+ private TextView mFingerprint;
+
+ private static final int LOADER_ID_UNIFIED = 0;
+
+ private Uri mDataUri;
+
+ private View mActionNo;
+ private View mActionYes;
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static CertifyFingerprintFragment newInstance(Uri dataUri) {
+ CertifyFingerprintFragment frag = new CertifyFingerprintFragment();
+ Bundle args = new Bundle();
+ args.putParcelable(ARG_DATA_URI, dataUri);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
+ View root = super.onCreateView(inflater, superContainer, savedInstanceState);
+ View view = inflater.inflate(R.layout.certify_fingerprint_fragment, getContainer());
+
+ mActionNo = view.findViewById(R.id.certify_fingerprint_button_no);
+ mActionYes = view.findViewById(R.id.certify_fingerprint_button_yes);
+
+ mFingerprint = (TextView) view.findViewById(R.id.certify_fingerprint_fingerprint);
+
+ mActionNo.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getActivity().finish();
+ }
+ });
+ mActionYes.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ certify(mDataUri);
+ }
+ });
+
+ return root;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ mDataUri = dataUri;
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
+ }
+
+ static final String[] UNIFIED_PROJECTION = new String[]{
+ KeyRings._ID, KeyRings.FINGERPRINT,
+
+ };
+ static final int INDEX_UNIFIED_FINGERPRINT = 1;
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ setContentShown(false);
+ switch (id) {
+ case LOADER_ID_UNIFIED: {
+ Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
+ return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
+ }
+
+ default:
+ return null;
+ }
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ /* TODO better error handling? May cause problems when a key is deleted,
+ * because the notification triggers faster than the activity closes.
+ */
+ // Avoid NullPointerExceptions...
+ if (data.getCount() == 0) {
+ return;
+ }
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ switch (loader.getId()) {
+ case LOADER_ID_UNIFIED: {
+ if (data.moveToFirst()) {
+
+ byte[] fingerprintBlob = data.getBlob(INDEX_UNIFIED_FINGERPRINT);
+ String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fingerprintBlob);
+ mFingerprint.setText(KeyFormattingUtils.colorizeFingerprint(fingerprint));
+
+ break;
+ }
+ }
+
+ }
+ setContentShown(true);
+ }
+
+ /**
+ * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
+ * We need to make sure we are no longer using it.
+ */
+ public void onLoaderReset(Loader<Cursor> loader) {
+ }
+
+ private void certify(Uri dataUri) {
+ long keyId = 0;
+ try {
+ keyId = new ProviderHelper(getActivity())
+ .getCachedPublicKeyRing(dataUri)
+ .extractOrGetMasterKeyId();
+ } catch (PgpKeyNotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ }
+ Intent certifyIntent = new Intent(getActivity(), CertifyKeyActivity.class);
+ certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{keyId});
+ startActivityForResult(certifyIntent, 0);
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
index a97e73934..1fb88b182 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
@@ -18,24 +18,19 @@
package org.sufficientlysecure.keychain.ui;
-import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
-
import org.sufficientlysecure.keychain.R;
/**
* Signs the specified public key with the specified secret master key
*/
-public class CertifyKeyActivity extends ActionBarActivity {
+public class CertifyKeyActivity extends BaseActivity {
public static final String EXTRA_RESULT = "operation_result";
public static final String EXTRA_KEY_IDS = "extra_key_ids";
public static final String EXTRA_CERTIFY_KEY_ID = "certify_key_id";
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
+ protected void initLayout() {
setContentView(R.layout.certify_key_activity);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
index 4d10d8639..50d5e3229 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
@@ -49,7 +49,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
@@ -82,11 +82,11 @@ public class CertifyKeyFragment extends LoaderFragment
private long mSignMasterKeyId = Constants.key.none;
public static final String[] USER_IDS_PROJECTION = new String[]{
- UserIds._ID,
- UserIds.MASTER_KEY_ID,
- UserIds.USER_ID,
- UserIds.IS_PRIMARY,
- UserIds.IS_REVOKED
+ UserPackets._ID,
+ UserPackets.MASTER_KEY_ID,
+ UserPackets.USER_ID,
+ UserPackets.IS_PRIMARY,
+ UserPackets.IS_REVOKED
};
private static final int INDEX_MASTER_KEY_ID = 1;
private static final int INDEX_USER_ID = 2;
@@ -182,7 +182,7 @@ public class CertifyKeyFragment extends LoaderFragment
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- Uri uri = UserIds.buildUserIdsUri();
+ Uri uri = UserPackets.buildUserIdsUri();
String selection, ids[];
{
@@ -196,15 +196,15 @@ public class CertifyKeyFragment extends LoaderFragment
}
}
// put together selection string
- selection = UserIds.IS_REVOKED + " = 0" + " AND "
- + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID
+ selection = UserPackets.IS_REVOKED + " = 0" + " AND "
+ + Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID
+ " IN (" + placeholders + ")";
}
return new CursorLoader(getActivity(), uri,
USER_IDS_PROJECTION, selection, ids,
- Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID + " ASC"
- + ", " + Tables.USER_IDS + "." + UserIds.USER_ID + " ASC"
+ Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " ASC"
+ + ", " + Tables.USER_PACKETS + "." + UserPackets.USER_ID + " ASC"
);
}
@@ -234,7 +234,7 @@ public class CertifyKeyFragment extends LoaderFragment
long lastMasterKeyId = 0;
String lastName = "";
- ArrayList<String> uids = new ArrayList<String>();
+ ArrayList<String> uids = new ArrayList<>();
boolean header = true;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java
index 0d8905c5b..f0ef8b9ef 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java
@@ -61,7 +61,7 @@ public class ConsolidateDialogActivity extends FragmentActivity {
/* don't care about the results (for now?)
// get returned data bundle
- Bundle returnData = message.getData();
+ Bundle returnData = message.getInputData();
if (returnData == null) {
return;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
index 534ac5811..62c38d136 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
@@ -20,11 +20,10 @@ package org.sufficientlysecure.keychain.ui;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.ActionBarActivity;
import org.sufficientlysecure.keychain.R;
-public class CreateKeyActivity extends ActionBarActivity {
+public class CreateKeyActivity extends BaseActivity {
public static final String EXTRA_NAME = "name";
public static final String EXTRA_EMAIL = "email";
@@ -37,8 +36,6 @@ public class CreateKeyActivity extends ActionBarActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.create_key_activity);
-
// pass extras into fragment
CreateKeyInputFragment frag =
CreateKeyInputFragment.newInstance(
@@ -48,6 +45,11 @@ public class CreateKeyActivity extends ActionBarActivity {
loadFragment(null, frag, FRAG_ACTION_START);
}
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.create_key_activity);
+ }
+
public void loadFragment(Bundle savedInstanceState, Fragment fragment, int action) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
index bcc98a5d7..6e0115342 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
@@ -34,16 +34,17 @@ import android.widget.TextView;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Preferences;
+import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
-import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
public class CreateKeyFinalFragment extends Fragment {
@@ -165,7 +166,9 @@ public class CreateKeyFinalFragment extends Fragment {
String userId = KeyRing.createUserId(mName, mEmail, null);
mSaveKeyringParcel.mAddUserIds.add(userId);
mSaveKeyringParcel.mChangePrimaryUserId = userId;
- mSaveKeyringParcel.mNewPassphrase = mPassphrase;
+ mSaveKeyringParcel.mNewUnlock = mPassphrase != null
+ ? new ChangeUnlockParcel(mPassphrase, null)
+ : null;
}
}
@@ -187,14 +190,14 @@ public class CreateKeyFinalFragment extends Fragment {
if (returnData == null) {
return;
}
- final SaveKeyringResult result =
+ final EditKeyResult result =
returnData.getParcelable(OperationResult.EXTRA_RESULT);
if (result == null) {
Log.e(Constants.TAG, "result == null");
return;
}
- if (mUploadCheckbox.isChecked()) {
+ if (result.mMasterKeyId != null && mUploadCheckbox.isChecked()) {
// result will be displayed after upload
uploadKey(result);
} else {
@@ -224,7 +227,8 @@ public class CreateKeyFinalFragment extends Fragment {
getActivity().startService(intent);
}
- private void uploadKey(final SaveKeyringResult saveKeyResult) {
+ // TODO move into EditKeyOperation
+ private void uploadKey(final EditKeyResult saveKeyResult) {
// Send all information needed to service to upload key in other thread
final Intent intent = new Intent(getActivity(), KeychainIntentService.class);
@@ -232,7 +236,7 @@ public class CreateKeyFinalFragment extends Fragment {
// set data uri as path to keyring
Uri blobUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(
- saveKeyResult.mRingMasterKeyId);
+ saveKeyResult.mMasterKeyId);
intent.setData(blobUri);
// fill values for this action
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java
index 6079062a7..8aa9fa6db 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java
@@ -89,7 +89,7 @@ public class CreateKeyInputFragment extends Fragment {
mEmailEdit.setThreshold(1); // Start working from first character
mEmailEdit.setAdapter(
- new ArrayAdapter<String>
+ new ArrayAdapter<>
(getActivity(), android.R.layout.simple_spinner_dropdown_item,
ContactHelper.getPossibleUserEmails(getActivity())
)
@@ -124,7 +124,7 @@ public class CreateKeyInputFragment extends Fragment {
mNameEdit.setThreshold(1); // Start working from first character
mNameEdit.setAdapter(
- new ArrayAdapter<String>
+ new ArrayAdapter<>
(getActivity(), android.R.layout.simple_spinner_dropdown_item,
ContactHelper.getPossibleUserNames(getActivity())
)
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
deleted file mode 100644
index 681e22e1e..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.annotation.TargetApi;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import android.view.View;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.ui.util.SubtleAttentionSeeker;
-
-import java.util.regex.Matcher;
-
-public class DecryptActivity extends DrawerActivity {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.decrypt_activity);
-
- activateDrawerNavigation(savedInstanceState);
-
- View actionFile = findViewById(R.id.decrypt_files);
- View actionFromClipboard = findViewById(R.id.decrypt_from_clipboard);
-
- actionFile.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent filesDecrypt = new Intent(DecryptActivity.this, DecryptFilesActivity.class);
- filesDecrypt.setAction(DecryptFilesActivity.ACTION_DECRYPT_DATA_OPEN);
- startActivity(filesDecrypt);
- }
- });
-
- actionFromClipboard.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent clipboardDecrypt = new Intent(DecryptActivity.this, DecryptTextActivity.class);
- clipboardDecrypt.setAction(DecryptTextActivity.ACTION_DECRYPT_FROM_CLIPBOARD);
- startActivityForResult(clipboardDecrypt, 0);
- }
- });
- }
-
- @TargetApi(VERSION_CODES.HONEYCOMB)
- @Override
- protected void onResume() {
- super.onResume();
-
- // This is an eye candy ice cream sandwich feature, nvm on versions below
- if (Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
-
- // get text from clipboard
- final CharSequence clipboardText =
- ClipboardReflection.getClipboardText(DecryptActivity.this);
-
- // if it's null, nothing to do here /o/
- if (clipboardText == null) {
- return;
- }
-
- new AsyncTask<String, Void, Boolean>() {
- @Override
- protected Boolean doInBackground(String... clipboardText) {
-
- // see if it looks like a pgp thing
- Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText[0]);
- boolean animate = matcher.matches();
-
- // see if it looks like another pgp thing
- if (!animate) {
- matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText[0]);
- animate = matcher.matches();
- }
- return animate;
- }
-
- @Override
- protected void onPostExecute(Boolean animate) {
- super.onPostExecute(animate);
-
- // if so, animate the clipboard icon just a bit~
- if (animate) {
- SubtleAttentionSeeker.tada(findViewById(R.id.clipboard_icon), 1.5f).start();
- }
- }
- }.execute(clipboardText.toString());
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- // if a result has been returned, display a notify
- if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
- OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
- result.createNotify(this).show();
- } else {
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java
index 9d972d8c0..89dd4970b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesActivity.java
@@ -20,14 +20,13 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
import org.sufficientlysecure.keychain.util.Log;
-public class DecryptFilesActivity extends ActionBarActivity {
+public class DecryptFilesActivity extends BaseActivity {
/* Intents */
public static final String ACTION_DECRYPT_DATA = OpenKeychainIntents.DECRYPT_DATA;
@@ -41,12 +40,15 @@ public class DecryptFilesActivity extends ActionBarActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.decrypt_files_activity);
-
// Handle intent actions
handleActions(savedInstanceState, getIntent());
}
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.decrypt_files_activity);
+ }
+
/**
* Handles all actions with this intent
*
@@ -86,7 +88,7 @@ public class DecryptFilesActivity extends ActionBarActivity {
loadFragment(savedInstanceState, null, true);
} else if (ACTION_DECRYPT_DATA.equals(action)) {
Log.e(Constants.TAG,
- "Include an Uri with setData() in your Intent!");
+ "Include an Uri with setInputData() in your Intent!");
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
index 691f1c240..5606523be 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
@@ -35,13 +35,13 @@ import android.widget.TextView;
import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.util.FileHelper;
+import org.sufficientlysecure.keychain.util.Log;
import java.io.File;
@@ -310,7 +310,7 @@ public class DecryptFilesFragment extends DecryptFragment {
// A future open after decryption feature
if () {
Intent viewFile = new Intent(Intent.ACTION_VIEW);
- viewFile.setData(mOutputUri);
+ viewFile.setInputData(mOutputUri);
startActivity(viewFile);
}
*/
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
index 7f06d36e8..8723c7255 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
@@ -27,9 +27,9 @@ import android.widget.TextView;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
public abstract class DecryptFragment extends Fragment {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java
index 2da76088a..81a8a2ac4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java
@@ -20,22 +20,21 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import android.text.TextUtils;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.SingletonResult;
-import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.util.Log;
import java.util.regex.Matcher;
-public class DecryptTextActivity extends ActionBarActivity {
+public class DecryptTextActivity extends BaseActivity {
/* Intents */
public static final String ACTION_DECRYPT_TEXT = OpenKeychainIntents.DECRYPT_TEXT;
@@ -50,12 +49,15 @@ public class DecryptTextActivity extends ActionBarActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.decrypt_text_activity);
-
// Handle intent actions
handleActions(savedInstanceState, getIntent());
}
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.decrypt_text_activity);
+ }
+
/**
* Fixing broken PGP MESSAGE Strings coming from GMail/AOSP Mail
*/
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
index fa7abf0f5..a15b23c06 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
@@ -34,13 +34,15 @@ import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
+import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ShareHelper;
+import java.io.UnsupportedEncodingException;
+
public class DecryptTextFragment extends DecryptFragment {
public static final String ARG_CIPHERTEXT = "ciphertext";
@@ -111,7 +113,7 @@ public class DecryptTextFragment extends DecryptFragment {
Intent prototype = createSendIntent(text);
String title = getString(R.string.title_share_file);
- // we don't want to decrypt the decypted, no inception ;)
+ // we don't want to decrypt the decrypted, no inception ;)
String[] blacklist = new String[]{
Constants.PACKAGE_NAME + ".ui.DecryptTextActivity",
"org.thialfihar.android.apg.ui.DecryptActivity"
@@ -194,7 +196,18 @@ public class DecryptTextFragment extends DecryptFragment {
byte[] decryptedMessage = returnData
.getByteArray(KeychainIntentService.RESULT_DECRYPTED_BYTES);
- mText.setText(new String(decryptedMessage));
+ String displayMessage;
+ if (pgpResult.getCharset() != null) {
+ try {
+ displayMessage = new String(decryptedMessage, pgpResult.getCharset());
+ } catch (UnsupportedEncodingException e) {
+ // if we can't decode properly, just fall back to utf-8
+ displayMessage = new String(decryptedMessage);
+ }
+ } else {
+ displayMessage = new String(decryptedMessage);
+ }
+ mText.setText(displayMessage);
pgpResult.createNotify(getActivity()).show();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java
deleted file mode 100644
index da46de486..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v4.widget.FixedDrawerLayout;
-import android.support.v7.app.ActionBarActivity;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-
-public class DrawerActivity extends ActionBarActivity {
- private FixedDrawerLayout mDrawerLayout;
- private ListView mDrawerList;
- private ActionBarDrawerToggle mDrawerToggle;
-
- private CharSequence mDrawerTitle;
- private CharSequence mTitle;
- private boolean mIsDrawerLocked = false;
-
- private Class mSelectedItem;
-
- private static final int MENU_ID_PREFERENCE = 222;
- private static final int MENU_ID_HELP = 223;
-
- protected void deactivateDrawerNavigation() {
- ((DrawerLayout) findViewById(R.id.drawer_layout)).setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
- }
-
- protected void activateDrawerNavigation(Bundle savedInstanceState) {
- mDrawerTitle = getString(R.string.app_name);
- mDrawerLayout = (FixedDrawerLayout) findViewById(R.id.drawer_layout);
- mDrawerList = (ListView) findViewById(R.id.left_drawer);
- ViewGroup viewGroup = (ViewGroup) findViewById(R.id.content_frame);
- int leftMarginLoaded = ((ViewGroup.MarginLayoutParams) viewGroup.getLayoutParams()).leftMargin;
- int leftMarginInTablets = (int) getResources().getDimension(R.dimen.drawer_size);
- int errorInMarginAllowed = 5;
-
- // if the left margin of the loaded layout is close to the
- // one used in tablets then set drawer as open and locked
- if (Math.abs(leftMarginLoaded - leftMarginInTablets) < errorInMarginAllowed) {
- mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, mDrawerList);
- mDrawerLayout.setScrimColor(Color.TRANSPARENT);
- mIsDrawerLocked = true;
- } else {
- // set a custom shadow that overlays the main content when the drawer opens
- mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
- mIsDrawerLocked = false;
- }
-
- NavItem mItemIconTexts[] = new NavItem[]{
- new NavItem(R.drawable.ic_action_accounts, getString(R.string.nav_keys)),
- new NavItem(R.drawable.ic_action_secure, getString(R.string.nav_encrypt_text)),
- new NavItem(R.drawable.ic_action_secure, getString(R.string.nav_encrypt_files)),
- new NavItem(R.drawable.ic_action_not_secure, getString(R.string.nav_decrypt)),
- new NavItem(R.drawable.ic_action_view_as_list, getString(R.string.nav_apps))};
-
- mDrawerList.setAdapter(new NavigationDrawerAdapter(this, R.layout.drawer_list_item,
- mItemIconTexts));
-
- mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
-
- // enable ActionBar app icon to behave as action to toggle nav drawer
- // if the drawer is not locked
- if (!mIsDrawerLocked) {
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setHomeButtonEnabled(true);
- }
-
- // ActionBarDrawerToggle ties together the the proper interactions
- // between the sliding drawer and the action bar app icon
- mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
- mDrawerLayout, /* DrawerLayout object */
- R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
- R.string.drawer_open, /* "open drawer" description for accessibility */
- R.string.drawer_close /* "close drawer" description for accessibility */
- ) {
- public void onDrawerClosed(View view) {
- getSupportActionBar().setTitle(mTitle);
-
- callIntentForDrawerItem(mSelectedItem);
- }
-
- public void onDrawerOpened(View drawerView) {
- mTitle = getSupportActionBar().getTitle();
- getSupportActionBar().setTitle(mDrawerTitle);
- // creates call to onPrepareOptionsMenu()
- supportInvalidateOptionsMenu();
- }
- };
-
- if (!mIsDrawerLocked) {
- mDrawerLayout.setDrawerListener(mDrawerToggle);
- } else {
- // If the drawer is locked open make it un-focusable
- // so that it doesn't consume all the Back button presses
- mDrawerLayout.setFocusableInTouchMode(false);
- }
- }
-
- /**
- * Uses startActivity to call the Intent of the given class
- *
- * @param drawerItem the class of the drawer item you want to load. Based on Constants.DrawerItems.*
- */
- public void callIntentForDrawerItem(Class drawerItem) {
- // creates call to onPrepareOptionsMenu()
- supportInvalidateOptionsMenu();
-
- // call intent activity if selected
- if (drawerItem != null) {
- finish();
- overridePendingTransition(0, 0);
-
- Intent intent = new Intent(this, drawerItem);
- startActivity(intent);
-
- // disable animation of activity start
- overridePendingTransition(0, 0);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (mDrawerToggle == null) {
- return super.onCreateOptionsMenu(menu);
- }
-
- menu.add(42, MENU_ID_PREFERENCE, 100, R.string.menu_preferences);
- menu.add(42, MENU_ID_HELP, 101, R.string.menu_help);
-
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (mDrawerToggle == null) {
- return super.onOptionsItemSelected(item);
- }
-
- // The action bar home/up action should open or close the drawer.
- // ActionBarDrawerToggle will take care of this.
- if (mDrawerToggle.onOptionsItemSelected(item)) {
- return true;
- }
-
- switch (item.getItemId()) {
- case MENU_ID_PREFERENCE: {
- Intent intent = new Intent(this, PreferencesActivity.class);
- startActivity(intent);
- return true;
- }
- case MENU_ID_HELP: {
- Intent intent = new Intent(this, HelpActivity.class);
- startActivity(intent);
- return true;
- }
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- /**
- * The click listener for ListView in the navigation drawer
- */
- private class DrawerItemClickListener implements ListView.OnItemClickListener {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- selectItem(position);
- }
- }
-
- private void selectItem(int position) {
- // update selected item and title, then close the drawer
- mDrawerList.setItemChecked(position, true);
- // set selected class
- mSelectedItem = Constants.DrawerItems.ARRAY[position];
-
- // setTitle(mDrawerTitles[position]);
- // If drawer isn't locked just close the drawer and
- // it will move to the selected item by itself (via drawer toggle listener)
- if (!mIsDrawerLocked) {
- mDrawerLayout.closeDrawer(mDrawerList);
- // else move to the selected item yourself
- } else {
- callIntentForDrawerItem(mSelectedItem);
- }
- }
-
- /**
- * When using the ActionBarDrawerToggle, you must call it during onPostCreate() and
- * onConfigurationChanged()...
- */
- @Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
- // Sync the toggle state after onRestoreInstanceState has occurred.
- if (mDrawerToggle != null) {
- mDrawerToggle.syncState();
- }
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- // Pass any configuration change to the drawer toggles
- if (mDrawerToggle != null) {
- mDrawerToggle.onConfigurationChanged(newConfig);
- }
- }
-
- private class NavItem {
- public int icon; // res-id
- public String title;
-
- /**
- * NavItem constructor
- *
- * @param icon The icons resource-id
- * @param title The title of the menu entry
- */
- public NavItem(int icon, String title) {
- super();
- this.icon = icon;
- this.title = title;
- }
- }
-
- private class NavigationDrawerAdapter extends ArrayAdapter<NavItem> {
- Context mContext;
- int mLayoutResourceId;
- NavItem mData[] = null;
-
- public NavigationDrawerAdapter(Context context, int layoutResourceId, NavItem[] data) {
- super(context, layoutResourceId, data);
- this.mLayoutResourceId = layoutResourceId;
- this.mContext = context;
- this.mData = data;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View row = convertView;
- NavItemHolder holder;
-
- if (row == null) {
- LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
- row = inflater.inflate(mLayoutResourceId, parent, false);
-
- holder = new NavItemHolder();
- holder.mImg = (ImageView) row.findViewById(R.id.drawer_item_icon);
- holder.mTxtTitle = (TextView) row.findViewById(R.id.drawer_item_text);
-
- row.setTag(holder);
- } else {
- holder = (NavItemHolder) row.getTag();
- }
-
- NavItem item = mData[position];
- holder.mTxtTitle.setText(item.title);
- holder.mImg.setImageResource(item.icon);
-
- return row;
- }
-
- }
-
- static class NavItemHolder {
- ImageView mImg;
- TextView mTxtTitle;
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
index 98049d89b..6dc2994cf 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
@@ -19,14 +19,13 @@ package org.sufficientlysecure.keychain.ui;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.util.Log;
-public class EditKeyActivity extends ActionBarActivity {
+public class EditKeyActivity extends BaseActivity {
public static final String EXTRA_SAVE_KEYRING_PARCEL = "save_keyring_parcel";
@@ -36,8 +35,6 @@ public class EditKeyActivity extends ActionBarActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.edit_key_activity);
-
Uri dataUri = getIntent().getData();
SaveKeyringParcel saveKeyringParcel = getIntent().getParcelableExtra(EXTRA_SAVE_KEYRING_PARCEL);
if (dataUri == null && saveKeyringParcel == null) {
@@ -49,6 +46,11 @@ public class EditKeyActivity extends ActionBarActivity {
loadFragment(savedInstanceState, dataUri, saveKeyringParcel);
}
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.edit_key_activity);
+ }
+
private void loadFragment(Bundle savedInstanceState, Uri dataUri, SaveKeyringParcel saveKeyringParcel) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
index a18eb76d1..25ca6e8fd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
@@ -29,7 +29,6 @@ import android.os.Messenger;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
-import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -47,12 +46,15 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
@@ -63,7 +65,6 @@ import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyExpiryDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
-import org.sufficientlysecure.keychain.ui.util.ActionBarHelper;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
@@ -145,10 +146,8 @@ public class EditKeyFragment extends LoaderFragment implements
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(((ActionBarActivity) getActivity()).getSupportActionBar(),
- R.string.btn_save, R.drawable.ic_action_save,
+ ((EditKeyActivity) getActivity()).setFullScreenDialogDoneClose(
+ R.string.btn_save,
new OnClickListener() {
@Override
public void onClick(View v) {
@@ -159,16 +158,13 @@ public class EditKeyFragment extends LoaderFragment implements
saveInDatabase(mCurrentPassphrase);
}
}
- }, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel,
- new OnClickListener() {
+ }, new OnClickListener() {
@Override
public void onClick(View v) {
- // cancel
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
- }
- );
+ });
Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
SaveKeyringParcel saveKeyringParcel = getArguments().getParcelable(ARG_SAVE_KEYRING_PARCEL);
@@ -189,7 +185,9 @@ public class EditKeyFragment extends LoaderFragment implements
private void loadSaveKeyringParcel(SaveKeyringParcel saveKeyringParcel) {
mSaveKeyringParcel = saveKeyringParcel;
mPrimaryUserId = saveKeyringParcel.mChangePrimaryUserId;
- mCurrentPassphrase = saveKeyringParcel.mNewPassphrase;
+ if (saveKeyringParcel.mNewUnlock != null) {
+ mCurrentPassphrase = saveKeyringParcel.mNewUnlock.mNewPassphrase;
+ }
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds, true);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
@@ -226,10 +224,7 @@ public class EditKeyFragment extends LoaderFragment implements
mSaveKeyringParcel = new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint());
mPrimaryUserId = keyRing.getPrimaryUserIdWithFallback();
- } catch (PgpKeyNotFoundException e) {
- finishWithError(LogType.MSG_EK_ERROR_NOT_FOUND);
- return;
- } catch (NotFoundException e) {
+ } catch (PgpKeyNotFoundException | NotFoundException e) {
finishWithError(LogType.MSG_EK_ERROR_NOT_FOUND);
return;
}
@@ -331,7 +326,7 @@ public class EditKeyFragment extends LoaderFragment implements
switch (id) {
case LOADER_ID_USER_IDS: {
- Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
+ Uri baseUri = UserPackets.buildUserIdsUri(mDataUri);
return new CursorLoader(getActivity(), baseUri,
UserIdsAdapter.USER_IDS_PROJECTION, null, null, null);
}
@@ -379,6 +374,9 @@ public class EditKeyFragment extends LoaderFragment implements
}
private void changePassphrase() {
+// Intent passIntent = new Intent(getActivity(), PassphraseWizardActivity.class);
+// passIntent.setAction(PassphraseWizardActivity.CREATE_METHOD);
+// startActivityForResult(passIntent, 12);
// Message is received after passphrase is cached
Handler returnHandler = new Handler() {
@Override
@@ -387,8 +385,10 @@ public class EditKeyFragment extends LoaderFragment implements
Bundle data = message.getData();
// cache new returned passphrase!
- mSaveKeyringParcel.mNewPassphrase = data
- .getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE);
+ mSaveKeyringParcel.mNewUnlock = new ChangeUnlockParcel(
+ data.getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE),
+ null
+ );
}
}
};
@@ -469,12 +469,13 @@ public class EditKeyFragment extends LoaderFragment implements
}
break;
case EditSubkeyDialogFragment.MESSAGE_STRIP:
- // toggle
- if (mSaveKeyringParcel.mStripSubKeys.contains(keyId)) {
- mSaveKeyringParcel.mStripSubKeys.remove(keyId);
- } else {
- mSaveKeyringParcel.mStripSubKeys.add(keyId);
+ SubkeyChange change = mSaveKeyringParcel.getSubkeyChange(keyId);
+ if (change == null) {
+ mSaveKeyringParcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, null));
+ break;
}
+ // toggle
+ change.mDummyStrip = !change.mDummyStrip;
break;
}
getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index b9058a37d..0d7e6056e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -8,13 +8,15 @@ import android.os.Messenger;
import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
+import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
+import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
import java.util.Date;
-public abstract class EncryptActivity extends DrawerActivity {
+public abstract class EncryptActivity extends BaseActivity {
public static final int REQUEST_CODE_PASSPHRASE = 0x00008001;
public static final int REQUEST_CODE_NFC = 0x00008002;
@@ -82,7 +84,10 @@ public abstract class EncryptActivity extends DrawerActivity {
// Send all information needed to service to edit key in other thread
Intent intent = new Intent(this, KeychainIntentService.class);
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
- intent.putExtra(KeychainIntentService.EXTRA_DATA, createEncryptBundle());
+
+ Bundle data = new Bundle();
+ data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, createEncryptBundle());
+ intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after encrypting is done in KeychainIntentService
KeychainIntentServiceHandler serviceHandler = new KeychainIntentServiceHandler(this,
@@ -92,28 +97,31 @@ public abstract class EncryptActivity extends DrawerActivity {
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- SignEncryptResult pgpResult =
+ SignEncryptResult result =
message.getData().getParcelable(SignEncryptResult.EXTRA_RESULT);
- if (pgpResult.isPending()) {
- if ((pgpResult.getResult() & SignEncryptResult.RESULT_PENDING_PASSPHRASE) ==
- SignEncryptResult.RESULT_PENDING_PASSPHRASE) {
+ PgpSignEncryptResult pgpResult = result.getPending();
+
+ if (pgpResult != null && pgpResult.isPending()) {
+ if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) ==
+ PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) {
startPassphraseDialog(pgpResult.getKeyIdPassphraseNeeded());
- } else if ((pgpResult.getResult() & SignEncryptResult.RESULT_PENDING_NFC) ==
- SignEncryptResult.RESULT_PENDING_NFC) {
+ } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) ==
+ PgpSignEncryptResult.RESULT_PENDING_NFC) {
mNfcTimestamp = pgpResult.getNfcTimestamp();
- startNfcSign(pgpResult.getNfcKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcHash(), pgpResult.getNfcAlgo());
+ startNfcSign(pgpResult.getNfcKeyId(), pgpResult.getNfcPassphrase(),
+ pgpResult.getNfcHash(), pgpResult.getNfcAlgo());
} else {
throw new RuntimeException("Unhandled pending result!");
}
return;
}
- if (pgpResult.success()) {
- onEncryptSuccess(message, pgpResult);
+ if (result.success()) {
+ onEncryptSuccess(result);
} else {
- pgpResult.createNotify(EncryptActivity.this).show();
+ result.createNotify(EncryptActivity.this).show();
}
// no matter the result, reset parameters
@@ -136,8 +144,8 @@ public abstract class EncryptActivity extends DrawerActivity {
protected abstract boolean inputIsValid();
- protected abstract void onEncryptSuccess(Message message, SignEncryptResult result);
+ protected abstract void onEncryptSuccess(SignEncryptResult result);
- protected abstract Bundle createEncryptBundle();
+ protected abstract SignEncryptParcel createEncryptBundle();
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
index 2d1b66daa..c5404094a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
@@ -28,7 +28,6 @@ import com.tokenautocomplete.TokenCompleteTextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
@@ -164,8 +163,8 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi
private void updateEncryptionKeys() {
List<Object> objects = mEncryptKeyView.getObjects();
- List<Long> keyIds = new ArrayList<Long>();
- List<String> userIds = new ArrayList<String>();
+ List<Long> keyIds = new ArrayList<>();
+ List<String> userIds = new ArrayList<>();
for (Object object : objects) {
if (object instanceof EncryptKeyCompletionView.EncryptionKey) {
keyIds.add(((EncryptKeyCompletionView.EncryptionKey) object).getKeyId());
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptDecryptOverviewFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptDecryptOverviewFragment.java
new file mode 100644
index 000000000..a498d0763
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptDecryptOverviewFragment.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
+import org.sufficientlysecure.keychain.pgp.PgpHelper;
+import org.sufficientlysecure.keychain.ui.util.SubtleAttentionSeeker;
+
+import java.util.regex.Matcher;
+
+public class EncryptDecryptOverviewFragment extends Fragment {
+
+ View mEncryptFile;
+ View mEncryptText;
+ View mDecryptFile;
+ View mDecryptFromClipboard;
+ View mClipboardIcon;
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.encrypt_decrypt_overview_fragment, container, false);
+
+ mEncryptFile = view.findViewById(R.id.encrypt_files);
+ mEncryptText = view.findViewById(R.id.encrypt_text);
+ mDecryptFile = view.findViewById(R.id.decrypt_files);
+ mDecryptFromClipboard = view.findViewById(R.id.decrypt_from_clipboard);
+ mClipboardIcon = view.findViewById(R.id.clipboard_icon);
+
+ mEncryptFile.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent encrypt = new Intent(getActivity(), EncryptFilesActivity.class);
+ startActivity(encrypt);
+ }
+ });
+
+ mEncryptText.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent encrypt = new Intent(getActivity(), EncryptTextActivity.class);
+ startActivity(encrypt);
+ }
+ });
+
+ mDecryptFile.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent filesDecrypt = new Intent(getActivity(), DecryptFilesActivity.class);
+ filesDecrypt.setAction(DecryptFilesActivity.ACTION_DECRYPT_DATA_OPEN);
+ startActivity(filesDecrypt);
+ }
+ });
+
+ mDecryptFromClipboard.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent clipboardDecrypt = new Intent(getActivity(), DecryptTextActivity.class);
+ clipboardDecrypt.setAction(DecryptTextActivity.ACTION_DECRYPT_FROM_CLIPBOARD);
+ startActivityForResult(clipboardDecrypt, 0);
+ }
+ });
+
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ // get text from clipboard
+ final CharSequence clipboardText =
+ ClipboardReflection.getClipboardText(getActivity());
+
+ // if it's null, nothing to do here /o/
+ if (clipboardText == null) {
+ return;
+ }
+
+ new AsyncTask<String, Void, Boolean>() {
+ @Override
+ protected Boolean doInBackground(String... clipboardText) {
+
+ // see if it looks like a pgp thing
+ Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText[0]);
+ boolean animate = matcher.matches();
+
+ // see if it looks like another pgp thing
+ if (!animate) {
+ matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText[0]);
+ animate = matcher.matches();
+ }
+ return animate;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean animate) {
+ super.onPostExecute(animate);
+
+ // if so, animate the clipboard icon just a bit~
+ if (animate) {
+ SubtleAttentionSeeker.tada(mClipboardIcon, 1.5f).start();
+ }
+ }
+ }.execute(clipboardText.toString());
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // if a result has been returned, display a notify
+ if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
+ OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
+ result.createNotify(getActivity()).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
index 054d85323..1286617d3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
@@ -21,7 +21,6 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.Menu;
import android.view.MenuItem;
@@ -29,14 +28,14 @@ import android.view.MenuItem;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
-import org.sufficientlysecure.keychain.util.Preferences;
-import org.sufficientlysecure.keychain.util.ShareHelper;
-import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
+import org.sufficientlysecure.keychain.util.ShareHelper;
import java.util.ArrayList;
import java.util.HashSet;
@@ -122,13 +121,13 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
@Override
public ArrayList<Uri> getInputUris() {
- if (mInputUris == null) mInputUris = new ArrayList<Uri>();
+ if (mInputUris == null) mInputUris = new ArrayList<>();
return mInputUris;
}
@Override
public ArrayList<Uri> getOutputUris() {
- if (mOutputUris == null) mOutputUris = new ArrayList<Uri>();
+ if (mOutputUris == null) mOutputUris = new ArrayList<>();
return mOutputUris;
}
@@ -170,7 +169,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
}
@Override
- public void onEncryptSuccess(Message message, SignEncryptResult pgpResult) {
+ public void onEncryptSuccess(SignEncryptResult result) {
if (mDeleteAfterEncrypt) {
for (Uri inputUri : mInputUris) {
DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment.newInstance(inputUri);
@@ -182,29 +181,25 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
if (mShareAfterEncrypt) {
// Share encrypted message/file
- startActivity(sendWithChooserExcludingEncrypt(message));
+ startActivity(sendWithChooserExcludingEncrypt());
} else {
// Save encrypted file
- pgpResult.createNotify(EncryptFilesActivity.this).show();
+ result.createNotify(EncryptFilesActivity.this).show();
}
}
@Override
- protected Bundle createEncryptBundle() {
+ protected SignEncryptParcel createEncryptBundle() {
// fill values for this action
- Bundle data = new Bundle();
+ SignEncryptParcel data = new SignEncryptParcel();
- data.putInt(KeychainIntentService.SOURCE, KeychainIntentService.IO_URIS);
- data.putParcelableArrayList(KeychainIntentService.ENCRYPT_INPUT_URIS, mInputUris);
+ data.addInputUris(mInputUris);
+ data.addOutputUris(mOutputUris);
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_URIS);
- data.putParcelableArrayList(KeychainIntentService.ENCRYPT_OUTPUT_URIS, mOutputUris);
-
- data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID,
- Preferences.getPreferences(this).getDefaultFileCompression());
+ data.setCompressionId(Preferences.getPreferences(this).getDefaultMessageCompression());
// Always use armor for messages
- data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, mUseArmor);
+ data.setEnableAsciiArmorOutput(mUseArmor);
if (isModeSymmetric()) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
@@ -212,13 +207,12 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
if (passphrase.length() == 0) {
passphrase = null;
}
- data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
+ data.setSymmetricPassphrase(passphrase);
} else {
- data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_MASTER_ID, mSigningKeyId);
- data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds);
- data.putString(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_PASSPHRASE, mSigningKeyPassphrase);
- data.putSerializable(KeychainIntentService.ENCRYPT_SIGNATURE_NFC_TIMESTAMP, mNfcTimestamp);
- data.putByteArray(KeychainIntentService.ENCRYPT_SIGNATURE_NFC_HASH, mNfcHash);
+ data.setEncryptionMasterKeyIds(mEncryptionKeyIds);
+ data.setSignatureMasterKeyId(mSigningKeyId);
+ data.setSignaturePassphrase(mSigningKeyPassphrase);
+ data.setNfcState(mNfcHash, mNfcTimestamp);
}
return data;
}
@@ -226,8 +220,8 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
/**
* Create Intent Chooser but exclude OK's EncryptActivity.
*/
- private Intent sendWithChooserExcludingEncrypt(Message message) {
- Intent prototype = createSendIntent(message);
+ private Intent sendWithChooserExcludingEncrypt() {
+ Intent prototype = createSendIntent();
String title = getString(R.string.title_share_file);
// we don't want to encrypt the encrypted, no inception ;)
@@ -239,7 +233,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
return new ShareHelper(this).createChooserExcluding(prototype, title, blacklist);
}
- private Intent createSendIntent(Message message) {
+ private Intent createSendIntent() {
Intent sendIntent;
// file
if (mOutputUris.size() == 1) {
@@ -252,7 +246,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
sendIntent.setType("application/octet-stream");
if (!isModeSymmetric() && mEncryptionUserIds != null) {
- Set<String> users = new HashSet<String>();
+ Set<String> users = new HashSet<>();
for (String user : mEncryptionUserIds) {
String[] userId = KeyRing.splitUserId(user);
if (userId[1] != null) {
@@ -309,15 +303,13 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.encrypt_files_activity);
-
// if called with an intent action, do not init drawer navigation
if (ACTION_ENCRYPT_DATA.equals(getIntent().getAction())) {
// lock drawer
- deactivateDrawerNavigation();
+// deactivateDrawerNavigation();
// TODO: back button to key?
} else {
- activateDrawerNavigation(savedInstanceState);
+// activateDrawerNavigation(savedInstanceState);
}
// Handle intent actions
@@ -328,6 +320,11 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
}
@Override
+ protected void initLayout() {
+ setContentView(R.layout.encrypt_files_activity);
+ }
+
+ @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.encrypt_file_activity, menu);
menu.findItem(R.id.check_use_armor).setChecked(mUseArmor);
@@ -379,7 +376,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
String action = intent.getAction();
Bundle extras = intent.getExtras();
String type = intent.getType();
- ArrayList<Uri> uris = new ArrayList<Uri>();
+ ArrayList<Uri> uris = new ArrayList<>();
if (extras == null) {
extras = new Bundle();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java
index 6961f5ee7..860bd8502 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java
@@ -36,10 +36,10 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.FileHelper;
-import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
import java.io.File;
import java.util.HashMap;
@@ -59,7 +59,7 @@ public class EncryptFilesFragment extends Fragment implements EncryptActivityInt
private View mShareFile;
private ListView mSelectedFiles;
private SelectedFilesAdapter mAdapter = new SelectedFilesAdapter();
- private final Map<Uri, Bitmap> thumbnailCache = new HashMap<Uri, Bitmap>();
+ private final Map<Uri, Bitmap> thumbnailCache = new HashMap<>();
@Override
public void onAttach(Activity activity) {
@@ -224,7 +224,7 @@ public class EncryptFilesFragment extends Fragment implements EncryptActivityInt
@Override
public void onNotifyUpdate() {
// Clear cache if needed
- for (Uri uri : new HashSet<Uri>(thumbnailCache.keySet())) {
+ for (Uri uri : new HashSet<>(thumbnailCache.keySet())) {
if (!mEncryptInterface.getInputUris().contains(uri)) {
thumbnailCache.remove(uri);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
index 958daa122..2dd861d07 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
@@ -21,7 +21,6 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.Menu;
import android.view.MenuItem;
@@ -30,13 +29,13 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-import org.sufficientlysecure.keychain.util.Preferences;
-import org.sufficientlysecure.keychain.util.ShareHelper;
-import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
-import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
+import org.sufficientlysecure.keychain.util.ShareHelper;
import java.util.ArrayList;
import java.util.HashSet;
@@ -121,13 +120,13 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
@Override
public ArrayList<Uri> getInputUris() {
- if (mInputUris == null) mInputUris = new ArrayList<Uri>();
+ if (mInputUris == null) mInputUris = new ArrayList<>();
return mInputUris;
}
@Override
public ArrayList<Uri> getOutputUris() {
- if (mOutputUris == null) mOutputUris = new ArrayList<Uri>();
+ if (mOutputUris == null) mOutputUris = new ArrayList<>();
return mOutputUris;
}
@@ -169,32 +168,31 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
}
@Override
- protected void onEncryptSuccess(Message message, SignEncryptResult pgpResult) {
+ protected void onEncryptSuccess(SignEncryptResult result) {
if (mShareAfterEncrypt) {
// Share encrypted message/file
- startActivity(sendWithChooserExcludingEncrypt(message));
+ startActivity(sendWithChooserExcludingEncrypt(result.getResultBytes()));
} else {
// Copy to clipboard
- copyToClipboard(message);
- pgpResult.createNotify(EncryptTextActivity.this).show();
+ copyToClipboard(result.getResultBytes());
+ result.createNotify(EncryptTextActivity.this).show();
// Notify.showNotify(EncryptTextActivity.this,
// R.string.encrypt_sign_clipboard_successful, Notify.Style.INFO);
}
}
@Override
- protected Bundle createEncryptBundle() {
+ protected SignEncryptParcel createEncryptBundle() {
// fill values for this action
- Bundle data = new Bundle();
+ SignEncryptParcel data = new SignEncryptParcel();
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES);
- data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, mMessage.getBytes());
+ data.setBytes(mMessage.getBytes());
+ data.setCleartextSignature(true);
- data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID,
- Preferences.getPreferences(this).getDefaultMessageCompression());
+ data.setCompressionId(Preferences.getPreferences(this).getDefaultMessageCompression());
// Always use armor for messages
- data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, true);
+ data.setEnableAsciiArmorOutput(true);
if (isModeSymmetric()) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
@@ -202,26 +200,25 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
if (passphrase.length() == 0) {
passphrase = null;
}
- data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
+ data.setSymmetricPassphrase(passphrase);
} else {
- data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_MASTER_ID, mSigningKeyId);
- data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds);
- data.putString(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_PASSPHRASE, mSigningKeyPassphrase);
- data.putSerializable(KeychainIntentService.ENCRYPT_SIGNATURE_NFC_TIMESTAMP, mNfcTimestamp);
- data.putByteArray(KeychainIntentService.ENCRYPT_SIGNATURE_NFC_HASH, mNfcHash);
+ data.setEncryptionMasterKeyIds(mEncryptionKeyIds);
+ data.setSignatureMasterKeyId(mSigningKeyId);
+ data.setSignaturePassphrase(mSigningKeyPassphrase);
+ data.setNfcState(mNfcHash, mNfcTimestamp);
}
return data;
}
- private void copyToClipboard(Message message) {
- ClipboardReflection.copyToClipboard(this, new String(message.getData().getByteArray(KeychainIntentService.RESULT_BYTES)));
+ private void copyToClipboard(byte[] resultBytes) {
+ ClipboardReflection.copyToClipboard(this, new String(resultBytes));
}
/**
* Create Intent Chooser but exclude OK's EncryptActivity.
*/
- private Intent sendWithChooserExcludingEncrypt(Message message) {
- Intent prototype = createSendIntent(message);
+ private Intent sendWithChooserExcludingEncrypt(byte[] resultBytes) {
+ Intent prototype = createSendIntent(resultBytes);
String title = getString(R.string.title_share_message);
// we don't want to encrypt the encrypted, no inception ;)
@@ -233,20 +230,21 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
return new ShareHelper(this).createChooserExcluding(prototype, title, blacklist);
}
- private Intent createSendIntent(Message message) {
+ private Intent createSendIntent(byte[] resultBytes) {
Intent sendIntent;
sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
- sendIntent.putExtra(Intent.EXTRA_TEXT, new String(message.getData().getByteArray(KeychainIntentService.RESULT_BYTES)));
+ sendIntent.putExtra(Intent.EXTRA_TEXT, new String(resultBytes));
if (!isModeSymmetric() && mEncryptionUserIds != null) {
- Set<String> users = new HashSet<String>();
+ Set<String> users = new HashSet<>();
for (String user : mEncryptionUserIds) {
String[] userId = KeyRing.splitUserId(user);
if (userId[1] != null) {
users.add(userId[1]);
}
}
+ // pass trough email addresses as extra for email applications
sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()]));
}
return sendIntent;
@@ -288,15 +286,13 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.encrypt_text_activity);
-
// if called with an intent action, do not init drawer navigation
if (ACTION_ENCRYPT_TEXT.equals(getIntent().getAction())) {
// lock drawer
- deactivateDrawerNavigation();
+// deactivateDrawerNavigation();
// TODO: back button to key?
} else {
- activateDrawerNavigation(savedInstanceState);
+// activateDrawerNavigation(savedInstanceState);
}
// Handle intent actions
@@ -305,6 +301,11 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
}
@Override
+ protected void initLayout() {
+ setContentView(R.layout.encrypt_text_activity);
+ }
+
+ @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.encrypt_text_activity, menu);
return super.onCreateOptionsMenu(menu);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java
index ed29fc909..393e15cfa 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java
@@ -19,17 +19,16 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
-public class FirstTimeActivity extends ActionBarActivity {
+public class FirstTimeActivity extends BaseActivity {
View mCreateKey;
View mImportKey;
@@ -39,11 +38,9 @@ public class FirstTimeActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.first_time_activity);
+ super.onCreate(savedInstanceState);
mCreateKey = findViewById(R.id.first_time_create_key);
mImportKey = findViewById(R.id.first_time_import_key);
@@ -72,7 +69,11 @@ public class FirstTimeActivity extends ActionBarActivity {
startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY);
}
});
+ }
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.first_time_activity);
}
@Override
@@ -91,12 +92,12 @@ public class FirstTimeActivity extends ActionBarActivity {
private void finishSetup(Intent srcData) {
Preferences prefs = Preferences.getPreferences(this);
prefs.setFirstTime(false);
- Intent intent = new Intent(this, KeyListActivity.class);
+ Intent intent = new Intent(this, MainActivity.class);
// give intent through to display notify
if (srcData != null) {
intent.putExtras(srcData);
}
- startActivityForResult(intent, 0);
+ startActivity(intent);
finish();
}
@@ -105,4 +106,5 @@ public class FirstTimeActivity extends ActionBarActivity {
public boolean onKeyDown(int keyCode, KeyEvent event) {
return keyCode == KeyEvent.KEYCODE_MENU || super.onKeyDown(keyCode, event);
}
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
index bbc1e4b1f..2eb35351e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
@@ -20,14 +20,14 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
+import android.view.View;
+
+import com.astuetz.PagerSlidingTabStrip;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
-import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout;
-public class HelpActivity extends ActionBarActivity {
+public class HelpActivity extends BaseActivity {
public static final String EXTRA_SELECTED_TAB = "selected_tab";
public static final int TAB_START = 0;
@@ -44,16 +44,16 @@ public class HelpActivity extends ActionBarActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayShowTitleEnabled(true);
- actionBar.setDisplayHomeAsUpEnabled(false);
- actionBar.setHomeButtonEnabled(false);
-
- setContentView(R.layout.help_activity);
+ mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
mViewPager = (ViewPager) findViewById(R.id.pager);
- SlidingTabLayout slidingTabLayout =
- (SlidingTabLayout) findViewById(R.id.sliding_tab_layout);
+ PagerSlidingTabStrip slidingTabLayout =
+ (PagerSlidingTabStrip) findViewById(R.id.sliding_tab_layout);
mTabsAdapter = new PagerTabStripAdapter(this);
mViewPager.setAdapter(mTabsAdapter);
@@ -98,4 +98,9 @@ public class HelpActivity extends ActionBarActivity {
// switch to tab selected by extra
mViewPager.setCurrentItem(selectedTab);
}
+
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.help_activity);
+ }
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index dfb7b3056..6638c9944 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -29,7 +29,6 @@ import android.os.Message;
import android.os.Messenger;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
-import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
@@ -51,7 +50,7 @@ import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize
import java.io.IOException;
import java.util.ArrayList;
-public class ImportKeysActivity extends ActionBarActivity {
+public class ImportKeysActivity extends BaseActivity {
public static final String ACTION_IMPORT_KEY = OpenKeychainIntents.IMPORT_KEY;
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = OpenKeychainIntents.IMPORT_KEY_FROM_KEYSERVER;
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT =
@@ -90,8 +89,6 @@ public class ImportKeysActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.import_keys_activity);
-
mImportButton = findViewById(R.id.import_import);
mImportButton.setOnClickListener(new OnClickListener() {
@Override
@@ -103,6 +100,11 @@ public class ImportKeysActivity extends ActionBarActivity {
handleActions(savedInstanceState, getIntent());
}
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.import_keys_activity);
+ }
+
protected void handleActions(Bundle savedInstanceState, Intent intent) {
String action = intent.getAction();
Bundle extras = intent.getExtras();
@@ -113,105 +115,123 @@ public class ImportKeysActivity extends ActionBarActivity {
extras = new Bundle();
}
+ if (action == null) {
+ startCloudFragment(savedInstanceState, null, false);
+ startListFragment(savedInstanceState, null, null, null);
+ return;
+ }
+
if (Intent.ACTION_VIEW.equals(action)) {
// Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
// delegate action to ACTION_IMPORT_KEY
action = ACTION_IMPORT_KEY;
}
- if (ACTION_IMPORT_KEY.equals(action)) {
- /* Keychain's own Actions */
- startFileFragment(savedInstanceState);
+ switch (action) {
+ case ACTION_IMPORT_KEY: {
+ /* Keychain's own Actions */
+ startFileFragment(savedInstanceState);
- if (dataUri != null) {
- // action: directly load data
- startListFragment(savedInstanceState, null, dataUri, null);
- } else if (extras.containsKey(EXTRA_KEY_BYTES)) {
- byte[] importData = extras.getByteArray(EXTRA_KEY_BYTES);
+ if (dataUri != null) {
+ // action: directly load data
+ startListFragment(savedInstanceState, null, dataUri, null);
+ } else if (extras.containsKey(EXTRA_KEY_BYTES)) {
+ byte[] importData = extras.getByteArray(EXTRA_KEY_BYTES);
- // action: directly load data
- startListFragment(savedInstanceState, importData, null, null);
+ // action: directly load data
+ startListFragment(savedInstanceState, importData, null, null);
+ }
+ break;
}
- } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)
- || ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE.equals(action)
- || ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(action)) {
+ case ACTION_IMPORT_KEY_FROM_KEYSERVER:
+ case ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE:
+ case ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT: {
- // only used for OpenPgpService
- if (extras.containsKey(EXTRA_PENDING_INTENT_DATA)) {
- mPendingIntentData = extras.getParcelable(EXTRA_PENDING_INTENT_DATA);
- }
- if (extras.containsKey(EXTRA_QUERY) || extras.containsKey(EXTRA_KEY_ID)) {
- /* simple search based on query or key id */
-
- String query = null;
- if (extras.containsKey(EXTRA_QUERY)) {
- query = extras.getString(EXTRA_QUERY);
- } else if (extras.containsKey(EXTRA_KEY_ID)) {
- long keyId = extras.getLong(EXTRA_KEY_ID, 0);
- if (keyId != 0) {
- query = KeyFormattingUtils.convertKeyIdToHex(keyId);
- }
+ // only used for OpenPgpService
+ if (extras.containsKey(EXTRA_PENDING_INTENT_DATA)) {
+ mPendingIntentData = extras.getParcelable(EXTRA_PENDING_INTENT_DATA);
}
+ if (extras.containsKey(EXTRA_QUERY) || extras.containsKey(EXTRA_KEY_ID)) {
+ /* simple search based on query or key id */
+
+ String query = null;
+ if (extras.containsKey(EXTRA_QUERY)) {
+ query = extras.getString(EXTRA_QUERY);
+ } else if (extras.containsKey(EXTRA_KEY_ID)) {
+ long keyId = extras.getLong(EXTRA_KEY_ID, 0);
+ if (keyId != 0) {
+ query = KeyFormattingUtils.convertKeyIdToHex(keyId);
+ }
+ }
- if (query != null && query.length() > 0) {
- // display keyserver fragment with query
- startCloudFragment(savedInstanceState, query, false);
+ if (query != null && query.length() > 0) {
+ // display keyserver fragment with query
+ startCloudFragment(savedInstanceState, query, false);
- // action: search immediately
- startListFragment(savedInstanceState, null, null, query);
- } else {
- Log.e(Constants.TAG, "Query is empty!");
- return;
- }
- } else if (extras.containsKey(EXTRA_FINGERPRINT)) {
- /*
- * search based on fingerprint, here we can enforce a check in the end
- * if the right key has been downloaded
- */
+ // action: search immediately
+ startListFragment(savedInstanceState, null, null, query);
+ } else {
+ Log.e(Constants.TAG, "Query is empty!");
+ return;
+ }
+ } else if (extras.containsKey(EXTRA_FINGERPRINT)) {
+ /*
+ * search based on fingerprint, here we can enforce a check in the end
+ * if the right key has been downloaded
+ */
- String fingerprint = extras.getString(EXTRA_FINGERPRINT);
- if (isFingerprintValid(fingerprint)) {
- String query = "0x" + fingerprint;
+ String fingerprint = extras.getString(EXTRA_FINGERPRINT);
+ if (isFingerprintValid(fingerprint)) {
+ String query = "0x" + fingerprint;
- // display keyserver fragment with query
- startCloudFragment(savedInstanceState, query, true);
+ // display keyserver fragment with query
+ startCloudFragment(savedInstanceState, query, true);
- // action: search immediately
- startListFragment(savedInstanceState, null, null, query);
+ // action: search immediately
+ startListFragment(savedInstanceState, null, null, query);
+ }
+ } else {
+ Log.e(Constants.TAG,
+ "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or " +
+ "'fingerprint' extra!"
+ );
+ return;
}
- } else {
- Log.e(Constants.TAG,
- "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or " +
- "'fingerprint' extra!"
- );
- return;
+ break;
}
- } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
- // NOTE: this only displays the appropriate fragment, no actions are taken
- startFileFragment(savedInstanceState);
-
- // no immediate actions!
- startListFragment(savedInstanceState, null, null, null);
- } else if (ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(action)) {
- // NOTE: this only displays the appropriate fragment, no actions are taken
- startFileFragment(savedInstanceState);
+ case ACTION_IMPORT_KEY_FROM_FILE: {
+ // NOTE: this only displays the appropriate fragment, no actions are taken
+ startFileFragment(savedInstanceState);
- // no immediate actions!
- startListFragment(savedInstanceState, null, null, null);
- } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) {
- // NOTE: this only displays the appropriate fragment, no actions are taken
- startFileFragment(savedInstanceState);
- // TODO!!!!!
+ // no immediate actions!
+ startListFragment(savedInstanceState, null, null, null);
+ break;
+ }
+ case ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN: {
+ // NOTE: this only displays the appropriate fragment, no actions are taken
+ startFileFragment(savedInstanceState);
- // no immediate actions!
- startListFragment(savedInstanceState, null, null, null);
- } else {
- startCloudFragment(savedInstanceState, null, false);
- startListFragment(savedInstanceState, null, null, null);
+ // no immediate actions!
+ startListFragment(savedInstanceState, null, null, null);
+ break;
+ }
+ case ACTION_IMPORT_KEY_FROM_NFC: {
+ // NOTE: this only displays the appropriate fragment, no actions are taken
+ startFileFragment(savedInstanceState);
+ // TODO!!!!!
+
+ // no immediate actions!
+ startListFragment(savedInstanceState, null, null, null);
+ break;
+ }
+ default: {
+ startCloudFragment(savedInstanceState, null, false);
+ startListFragment(savedInstanceState, null, null, null);
+ break;
+ }
}
}
-
private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri, String serverQuery) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
@@ -353,7 +373,7 @@ public class ImportKeysActivity extends ActionBarActivity {
// We parcel this iteratively into a file - anything we can
// display here, we should be able to import.
ParcelableFileCache<ParcelableKeyRing> cache =
- new ParcelableFileCache<ParcelableKeyRing>(this, "key_import.pcl");
+ new ParcelableFileCache<>(this, "key_import.pcl");
cache.writeCache(selectedEntries);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
@@ -385,7 +405,7 @@ public class ImportKeysActivity extends ActionBarActivity {
data.putString(KeychainIntentService.IMPORT_KEY_SERVER, sls.mCloudPrefs.keyserver);
// get selected key entries
- ArrayList<ParcelableKeyRing> keys = new ArrayList<ParcelableKeyRing>();
+ ArrayList<ParcelableKeyRing> keys = new ArrayList<>();
{
// change the format into ParcelableKeyRing
ArrayList<ImportKeysListEntry> entries = mListFragment.getSelectedEntries();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java
index 03aba344a..91ca93c36 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java
@@ -21,6 +21,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.preference.PreferenceActivity;
import android.support.v4.app.Fragment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -36,8 +37,8 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.ContactHelper;
-import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
import java.util.List;
@@ -81,7 +82,7 @@ public class ImportKeysCloudFragment extends Fragment {
namesAndEmails.addAll(ContactHelper.getContactMails(getActivity()));
mQueryEditText.setThreshold(3);
mQueryEditText.setAdapter(
- new ArrayAdapter<String>
+ new ArrayAdapter<>
(getActivity(), android.R.layout.simple_spinner_dropdown_item,
namesAndEmails
)
@@ -110,11 +111,9 @@ public class ImportKeysCloudFragment extends Fragment {
mConfigButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- Intent i = new Intent(mImportActivity, PreferencesActivity.class);
- // GRR, for some reason I can’t set the Action or I get an incomprehensible
- // exception about “modern two-pane layoutsâ€
- // i.setAction(PreferencesActivity.ACTION_PREFS_CLOUD);
- startActivity(i);
+ Intent intent = new Intent(mImportActivity, SettingsActivity.class);
+ intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.CloudSearchPrefsFragment.class.getName());
+ startActivity(intent);
}
});
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
index 4fe53fb09..6a6140892 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
@@ -113,7 +113,7 @@ public class ImportKeysListFragment extends ListFragment implements
return mAdapter.getSelectedEntries();
} else {
Log.e(Constants.TAG, "Adapter not initialized, returning empty list");
- return new ArrayList<ImportKeysListEntry>();
+ return new ArrayList<>();
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
deleted file mode 100644
index ba03400d7..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
-import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.ui.util.Notify;
-import org.sufficientlysecure.keychain.util.ExportHelper;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.Preferences;
-
-import java.io.IOException;
-
-public class KeyListActivity extends DrawerActivity {
-
- public static final int REQUEST_CODE_RESULT_TO_LIST = 1;
-
- ExportHelper mExportHelper;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setTitle(R.string.nav_keys);
-
- // if this is the first time show first time activity
- Preferences prefs = Preferences.getPreferences(this);
- if (prefs.isFirstTime()) {
- startActivity(new Intent(this, FirstTimeActivity.class));
- finish();
- return;
- }
-
- mExportHelper = new ExportHelper(this);
-
- setContentView(R.layout.key_list_activity);
-
- // now setup navigation drawer in DrawerActivity...
- activateDrawerNavigation(savedInstanceState);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.key_list, menu);
-
- if (Constants.DEBUG) {
- menu.findItem(R.id.menu_key_list_debug_cons).setVisible(true);
- menu.findItem(R.id.menu_key_list_debug_read).setVisible(true);
- menu.findItem(R.id.menu_key_list_debug_write).setVisible(true);
- menu.findItem(R.id.menu_key_list_debug_first_time).setVisible(true);
- }
-
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_key_list_add:
- Intent scanQrCode = new Intent(this, QrCodeScanActivity.class);
- scanQrCode.setAction(QrCodeScanActivity.ACTION_SCAN_WITH_RESULT);
- startActivityForResult(scanQrCode, 0);
- return true;
-
- case R.id.menu_key_list_search_cloud:
- searchCloud();
- return true;
-
- case R.id.menu_key_list_create:
- createKey();
- return true;
-
- case R.id.menu_key_list_import_existing_key:
- Intent intentImportExisting = new Intent(this, ImportKeysActivity.class);
- intentImportExisting.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN);
- startActivityForResult(intentImportExisting, 0);
- return true;
-
- case R.id.menu_key_list_export:
- mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE, true);
- return true;
-
- case R.id.menu_key_list_debug_cons:
- consolidate();
- return true;
-
- case R.id.menu_key_list_debug_read:
- try {
- KeychainDatabase.debugBackup(this, true);
- Notify.showNotify(this, "Restored debug_backup.db", Notify.Style.INFO);
- getContentResolver().notifyChange(KeychainContract.KeyRings.CONTENT_URI, null);
- } catch (IOException e) {
- Log.e(Constants.TAG, "IO Error", e);
- Notify.showNotify(this, "IO Error " + e.getMessage(), Notify.Style.ERROR);
- }
- return true;
-
- case R.id.menu_key_list_debug_write:
- try {
- KeychainDatabase.debugBackup(this, false);
- Notify.showNotify(this, "Backup to debug_backup.db completed", Notify.Style.INFO);
- } catch (IOException e) {
- Log.e(Constants.TAG, "IO Error", e);
- Notify.showNotify(this, "IO Error: " + e.getMessage(), Notify.Style.ERROR);
- }
- return true;
-
- case R.id.menu_key_list_debug_first_time:
- Preferences prefs = Preferences.getPreferences(this);
- prefs.setFirstTime(true);
- Intent intent = new Intent(this, FirstTimeActivity.class);
- startActivity(intent);
- finish();
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void searchCloud() {
- Intent importIntent = new Intent(this, ImportKeysActivity.class);
- importIntent.putExtra(ImportKeysActivity.EXTRA_QUERY, (String) null); // hack to show only cloud tab
- startActivity(importIntent);
- }
-
- private void createKey() {
- Intent intent = new Intent(this, CreateKeyActivity.class);
- startActivityForResult(intent, 0);
- }
-
- private void consolidate() {
- // Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- this,
- getString(R.string.progress_importing),
- ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle returnData = message.getData();
- if (returnData == null) {
- return;
- }
- final ConsolidateResult result =
- returnData.getParcelable(OperationResult.EXTRA_RESULT);
- if (result == null) {
- return;
- }
-
- result.createNotify(KeyListActivity.this).show();
- }
- }
- };
-
- // Send all information needed to service to import key in other thread
- Intent intent = new Intent(this, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_CONSOLIDATE);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- // if a result has been returned, display a notify
- if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
- OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
- result.createNotify(this).show();
- } else {
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index d0be052d8..3da185dd2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -31,7 +31,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
-import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
@@ -52,41 +51,37 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
-import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
+import com.getbase.floatingactionbutton.FloatingActionButton;
+
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
+import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.operations.results.DeleteResult;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.util.ExportHelper;
-import org.sufficientlysecure.keychain.util.KeyUpdateHelper;
import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.KeychainDatabase;
+import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
-import org.sufficientlysecure.keychain.ui.widget.ListAwareSwipeRefreshLayout;
import org.sufficientlysecure.keychain.ui.util.Highlighter;
-import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Notify;
-import org.sufficientlysecure.keychain.util.ParcelableFileCache;
+import org.sufficientlysecure.keychain.ui.widget.ListAwareSwipeRefreshLayout;
+import org.sufficientlysecure.keychain.util.ExportHelper;
+import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import edu.cmu.cylab.starslinger.exchange.ExchangeActivity;
-import edu.cmu.cylab.starslinger.exchange.ExchangeConfig;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
@@ -98,6 +93,8 @@ public class KeyListFragment extends LoaderFragment
implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener,
LoaderManager.LoaderCallbacks<Cursor> {
+ ExportHelper mExportHelper;
+
private KeyListAdapter mAdapter;
private StickyListHeadersListView mStickyList;
private ListAwareSwipeRefreshLayout mSwipeRefreshLayout;
@@ -110,7 +107,16 @@ public class KeyListFragment extends LoaderFragment
private String mQuery;
private SearchView mSearchView;
- boolean hideMenu = false;
+ private FloatingActionButton mFabQrCode;
+ private FloatingActionButton mFabCloud;
+ private FloatingActionButton mFabFile;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mExportHelper = new ExportHelper(getActivity());
+ }
/**
* Load custom layout with StickyListView from library
@@ -123,6 +129,29 @@ public class KeyListFragment extends LoaderFragment
mStickyList = (StickyListHeadersListView) view.findViewById(R.id.key_list_list);
mStickyList.setOnItemClickListener(this);
+ mFabQrCode = (FloatingActionButton) view.findViewById(R.id.fab_add_qr_code);
+ mFabCloud = (FloatingActionButton) view.findViewById(R.id.fab_add_cloud);
+ mFabFile = (FloatingActionButton) view.findViewById(R.id.fab_add_file);
+
+ mFabQrCode.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ scanQrCode();
+ }
+ });
+ mFabCloud.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ searchCloud();
+ }
+ });
+ mFabFile.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ importFile();
+ }
+ });
+
mSwipeRefreshLayout = (ListAwareSwipeRefreshLayout) view.findViewById(R.id.key_list_swipe_container);
mSwipeRefreshLayout.setOnRefreshListener(new NoScrollableSwipeRefreshLayout.OnRefreshListener() {
@Override
@@ -172,8 +201,8 @@ public class KeyListFragment extends LoaderFragment
TextView title = (TextView) getActivity().findViewById(R.id.custom_actionbar_text);
title.setText(R.string.swipe_to_update);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- hideMenu = true;
- activity.invalidateOptionsMenu();
+// hideMenu = true;
+// activity.invalidateOptionsMenu();
}
} else {
bar.setTitle(getActivity().getTitle());
@@ -184,8 +213,8 @@ public class KeyListFragment extends LoaderFragment
bar.setDisplayShowCustomEnabled(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- hideMenu = false;
- activity.invalidateOptionsMenu();
+// hideMenu = false;
+// activity.invalidateOptionsMenu();
}
}
}
@@ -198,90 +227,91 @@ public class KeyListFragment extends LoaderFragment
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
+ // show app name instead of "keys" from nav drawer
+ getActivity().setTitle(R.string.app_name);
+
mStickyList.setOnItemClickListener(this);
mStickyList.setAreHeadersSticky(true);
mStickyList.setDrawingListUnderStickyHeader(false);
mStickyList.setFastScrollEnabled(true);
/*
- * Multi-selection is only available for Android >= 3.0
+ * Multi-selection
*/
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mStickyList.setFastScrollAlwaysVisible(true);
+ mStickyList.setFastScrollAlwaysVisible(true);
- mStickyList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
- mStickyList.getWrappedList().setMultiChoiceModeListener(new MultiChoiceModeListener() {
+ mStickyList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ mStickyList.getWrappedList().setMultiChoiceModeListener(new MultiChoiceModeListener() {
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- android.view.MenuInflater inflater = getActivity().getMenuInflater();
- inflater.inflate(R.menu.key_list_multi, menu);
- mActionMode = mode;
- return true;
- }
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ android.view.MenuInflater inflater = getActivity().getMenuInflater();
+ inflater.inflate(R.menu.key_list_multi, menu);
+ mActionMode = mode;
+ return true;
+ }
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- return false;
- }
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false;
+ }
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- // get IDs for checked positions as long array
- long[] ids;
+ // get IDs for checked positions as long array
+ long[] ids;
- switch (item.getItemId()) {
- case R.id.menu_key_list_multi_encrypt: {
- ids = mAdapter.getCurrentSelectedMasterKeyIds();
- encrypt(mode, ids);
- break;
- }
- case R.id.menu_key_list_multi_delete: {
- ids = mAdapter.getCurrentSelectedMasterKeyIds();
- showDeleteKeyDialog(mode, ids, mAdapter.isAnySecretSelected());
- break;
- }
- case R.id.menu_key_list_multi_export: {
- ids = mAdapter.getCurrentSelectedMasterKeyIds();
- ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
- mExportHelper.showExportKeysDialog(ids, Constants.Path.APP_DIR_FILE,
- mAdapter.isAnySecretSelected());
- break;
- }
- case R.id.menu_key_list_multi_select_all: {
- // select all
- for (int i = 0; i < mStickyList.getCount(); i++) {
- mStickyList.setItemChecked(i, true);
- }
- break;
+ switch (item.getItemId()) {
+ case R.id.menu_key_list_multi_encrypt: {
+ ids = mAdapter.getCurrentSelectedMasterKeyIds();
+ encrypt(mode, ids);
+ break;
+ }
+ case R.id.menu_key_list_multi_delete: {
+ ids = mAdapter.getCurrentSelectedMasterKeyIds();
+ showDeleteKeyDialog(mode, ids, mAdapter.isAnySecretSelected());
+ break;
+ }
+ case R.id.menu_key_list_multi_export: {
+ ids = mAdapter.getCurrentSelectedMasterKeyIds();
+ ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
+ mExportHelper.showExportKeysDialog(ids, Constants.Path.APP_DIR_FILE,
+ mAdapter.isAnySecretSelected());
+ break;
+ }
+ case R.id.menu_key_list_multi_select_all: {
+ // select all
+ for (int i = 0; i < mStickyList.getCount(); i++) {
+ mStickyList.setItemChecked(i, true);
}
+ break;
}
- return true;
}
+ return true;
+ }
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- mActionMode = null;
- mAdapter.clearSelection();
- }
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ mActionMode = null;
+ mAdapter.clearSelection();
+ }
- @Override
- public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
- boolean checked) {
- if (checked) {
- mAdapter.setNewSelection(position, checked);
- } else {
- mAdapter.removeSelection(position);
- }
- int count = mStickyList.getCheckedItemCount();
- String keysSelected = getResources().getQuantityString(
- R.plurals.key_list_selected_keys, count, count);
- mode.setTitle(keysSelected);
+ @Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
+ boolean checked) {
+ if (checked) {
+ mAdapter.setNewSelection(position, checked);
+ } else {
+ mAdapter.removeSelection(position);
}
+ int count = mStickyList.getCheckedItemCount();
+ String keysSelected = getResources().getQuantityString(
+ R.plurals.key_list_selected_keys, count, count);
+ mode.setTitle(keysSelected);
+ }
- });
- }
+ });
// We have a menu item to show in action bar.
setHasOptionsMenu(true);
@@ -368,9 +398,7 @@ public class KeyListFragment extends LoaderFragment
// end action mode, if any
if (mActionMode != null) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mActionMode.finish();
- }
+ mActionMode.finish();
}
// The list should now be shown.
@@ -400,7 +428,6 @@ public class KeyListFragment extends LoaderFragment
startActivity(viewIntent);
}
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
protected void encrypt(ActionMode mode, long[] masterKeyIds) {
Intent intent = new Intent(getActivity(), EncryptFilesActivity.class);
intent.setAction(EncryptFilesActivity.ACTION_ENCRYPT_DATA);
@@ -417,7 +444,6 @@ public class KeyListFragment extends LoaderFragment
* @param masterKeyIds
* @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not
*/
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds, boolean hasSecret) {
// Can only work on singular secret keys
if (hasSecret && masterKeyIds.length > 1) {
@@ -455,6 +481,15 @@ public class KeyListFragment extends LoaderFragment
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+ inflater.inflate(R.menu.key_list, menu);
+
+ if (Constants.DEBUG) {
+ menu.findItem(R.id.menu_key_list_debug_cons).setVisible(true);
+ menu.findItem(R.id.menu_key_list_debug_read).setVisible(true);
+ menu.findItem(R.id.menu_key_list_debug_write).setVisible(true);
+ menu.findItem(R.id.menu_key_list_debug_first_time).setVisible(true);
+ }
+
// Get the searchview
MenuItem searchItem = menu.findItem(R.id.menu_key_list_search);
@@ -463,17 +498,10 @@ public class KeyListFragment extends LoaderFragment
// Execute this when searching
mSearchView.setOnQueryTextListener(this);
- View searchPlate = mSearchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
- searchPlate.setBackgroundResource(R.drawable.keychaintheme_searchview_holo_light);
-
// Erase search result without focus
MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- hideMenu = true;
- getActivity().invalidateOptionsMenu();
- }
// disable swipe-to-refresh
// mSwipeRefreshLayout.setIsLocked(true);
@@ -485,26 +513,66 @@ public class KeyListFragment extends LoaderFragment
mQuery = null;
getLoaderManager().restartLoader(0, null, KeyListFragment.this);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- hideMenu = false;
- getActivity().invalidateOptionsMenu();
- }
// enable swipe-to-refresh
// mSwipeRefreshLayout.setIsLocked(false);
return true;
}
});
- if (hideMenu) {
- for (int i = 0; i < menu.size(); i++) {
- menu.getItem(i).setVisible(false);
- }
- }
-
super.onCreateOptionsMenu(menu, inflater);
}
@Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+
+ case R.id.menu_key_list_create:
+ createKey();
+ return true;
+
+ case R.id.menu_key_list_export:
+ mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE, true);
+ return true;
+
+ case R.id.menu_key_list_debug_cons:
+ consolidate();
+ return true;
+
+ case R.id.menu_key_list_debug_read:
+ try {
+ KeychainDatabase.debugBackup(getActivity(), true);
+ Notify.showNotify(getActivity(), "Restored debug_backup.db", Notify.Style.INFO);
+ getActivity().getContentResolver().notifyChange(KeychainContract.KeyRings.CONTENT_URI, null);
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IO Error", e);
+ Notify.showNotify(getActivity(), "IO Error " + e.getMessage(), Notify.Style.ERROR);
+ }
+ return true;
+
+ case R.id.menu_key_list_debug_write:
+ try {
+ KeychainDatabase.debugBackup(getActivity(), false);
+ Notify.showNotify(getActivity(), "Backup to debug_backup.db completed", Notify.Style.INFO);
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IO Error", e);
+ Notify.showNotify(getActivity(), "IO Error: " + e.getMessage(), Notify.Style.ERROR);
+ }
+ return true;
+
+ case R.id.menu_key_list_debug_first_time:
+ Preferences prefs = Preferences.getPreferences(getActivity());
+ prefs.setFirstTime(true);
+ Intent intent = new Intent(getActivity(), FirstTimeActivity.class);
+ startActivity(intent);
+ getActivity().finish();
+ return true;
+
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ @Override
public boolean onQueryTextSubmit(String s) {
return true;
}
@@ -526,6 +594,89 @@ public class KeyListFragment extends LoaderFragment
return true;
}
+
+ private void searchCloud() {
+ Intent importIntent = new Intent(getActivity(), ImportKeysActivity.class);
+ importIntent.putExtra(ImportKeysActivity.EXTRA_QUERY, (String) null); // hack to show only cloud tab
+ startActivity(importIntent);
+ }
+
+ private void scanQrCode() {
+ Intent scanQrCode = new Intent(getActivity(), QrCodeScanActivity.class);
+ scanQrCode.setAction(QrCodeScanActivity.ACTION_SCAN_WITH_RESULT);
+ startActivityForResult(scanQrCode, 0);
+ }
+
+ private void importFile() {
+ Intent intentImportExisting = new Intent(getActivity(), ImportKeysActivity.class);
+ intentImportExisting.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN);
+ startActivityForResult(intentImportExisting, 0);
+ }
+
+ private void createKey() {
+ Intent intent = new Intent(getActivity(), CreateKeyActivity.class);
+ startActivityForResult(intent, 0);
+ }
+
+ private void consolidate() {
+ // Message is received after importing is done in KeychainIntentService
+ KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ getActivity(),
+ getString(R.string.progress_importing),
+ ProgressDialog.STYLE_HORIZONTAL) {
+ public void handleMessage(Message message) {
+ // handle messages by standard KeychainIntentServiceHandler first
+ super.handleMessage(message);
+
+ if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
+ // get returned data bundle
+ Bundle returnData = message.getData();
+ if (returnData == null) {
+ return;
+ }
+ final ConsolidateResult result =
+ returnData.getParcelable(OperationResult.EXTRA_RESULT);
+ if (result == null) {
+ return;
+ }
+
+ result.createNotify(getActivity()).show();
+ }
+ }
+ };
+
+ // Send all information needed to service to import key in other thread
+ Intent intent = new Intent(getActivity(), KeychainIntentService.class);
+
+ intent.setAction(KeychainIntentService.ACTION_CONSOLIDATE);
+
+ // fill values for this action
+ Bundle data = new Bundle();
+
+ intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(saveHandler);
+ intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
+
+ // show progress dialog
+ saveHandler.showProgressDialog(getActivity());
+
+ // start service with intent
+ getActivity().startService(intent);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // if a result has been returned, display a notify
+ if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
+ OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
+ result.createNotify(getActivity()).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
/**
* Implements StickyListHeadersAdapter from library
*/
@@ -533,7 +684,7 @@ public class KeyListFragment extends LoaderFragment
private String mQuery;
private LayoutInflater mInflater;
- private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
+ private HashMap<Integer, Boolean> mSelection = new HashMap<>();
public KeyListAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
@@ -624,13 +775,13 @@ public class KeyListFragment extends LoaderFragment
// Note: order is important!
if (isRevoked) {
- KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, KeyFormattingUtils.STATE_REVOKED, true);
+ KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
h.mStatus.setVisibility(View.VISIBLE);
h.mSlinger.setVisibility(View.GONE);
h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray));
h.mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.bg_gray));
} else if (isExpired) {
- KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, KeyFormattingUtils.STATE_EXPIRED, true);
+ KeyFormattingUtils.setStatusImage(getActivity(), h.mStatus, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
h.mStatus.setVisibility(View.VISIBLE);
h.mSlinger.setVisibility(View.GONE);
h.mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java
index 4a2b88518..0de7bb391 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayActivity.java
@@ -19,21 +19,18 @@
package org.sufficientlysecure.keychain.ui;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import android.view.View;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.ActionBarHelper;
-public class LogDisplayActivity extends ActionBarActivity {
+public class LogDisplayActivity extends BaseActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Inflate a "Done" custom action bar
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
+ setFullScreenDialogClose(
new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -42,7 +39,10 @@ public class LogDisplayActivity extends ActionBarActivity {
}
}
);
+ }
+ @Override
+ protected void initLayout() {
setContentView(R.layout.log_display_activity);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
index 2baebc83d..b655a7e55 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
@@ -153,11 +153,11 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
switch (subEntry.mType.mLevel) {
case DEBUG: ih.mSecondImg.setBackgroundColor(Color.GRAY); break;
case INFO: ih.mSecondImg.setBackgroundColor(Color.BLACK); break;
- case WARN: ih.mSecondImg.setBackgroundColor(Color.YELLOW); break;
- case ERROR: ih.mSecondImg.setBackgroundColor(Color.RED); break;
- case START: ih.mSecondImg.setBackgroundColor(getResources().getColor(R.color.emphasis)); break;
- case OK: ih.mSecondImg.setBackgroundColor(Color.GREEN); break;
- case CANCELLED: ih.mSecondImg.setBackgroundColor(Color.RED); break;
+ case WARN: ih.mSecondImg.setBackgroundColor(getResources().getColor(R.color.android_orange_light)); break;
+ case ERROR: ih.mSecondImg.setBackgroundColor(getResources().getColor(R.color.android_red_light)); break;
+ case START: ih.mSecondImg.setBackgroundColor(Color.BLACK); break;
+ case OK: ih.mSecondImg.setBackgroundColor(getResources().getColor(R.color.android_green_light)); break;
+ case CANCELLED: ih.mSecondImg.setBackgroundColor(getResources().getColor(R.color.android_red_light)); break;
}
} else {
ih.mSecond.setVisibility(View.GONE);
@@ -184,11 +184,11 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe
switch (entry.mType.mLevel) {
case DEBUG: ih.mImg.setBackgroundColor(Color.GRAY); break;
case INFO: ih.mImg.setBackgroundColor(Color.BLACK); break;
- case WARN: ih.mImg.setBackgroundColor(Color.YELLOW); break;
- case ERROR: ih.mImg.setBackgroundColor(Color.RED); break;
- case START: ih.mImg.setBackgroundColor(getResources().getColor(R.color.emphasis)); break;
- case OK: ih.mImg.setBackgroundColor(Color.GREEN); break;
- case CANCELLED: ih.mImg.setBackgroundColor(Color.RED); break;
+ case WARN: ih.mImg.setBackgroundColor(getResources().getColor(R.color.android_orange_light)); break;
+ case ERROR: ih.mImg.setBackgroundColor(getResources().getColor(R.color.android_red_light)); break;
+ case START: ih.mImg.setBackgroundColor(Color.BLACK); break;
+ case OK: ih.mImg.setBackgroundColor(getResources().getColor(R.color.android_green_light)); break;
+ case CANCELLED: ih.mImg.setBackgroundColor(getResources().getColor(R.color.android_red_light)); break;
}
return convertView;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java
new file mode 100644
index 000000000..2f29f9360
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
+import org.sufficientlysecure.keychain.util.Preferences;
+
+public class MainActivity extends NavDrawerActivity {
+
+ @Override
+ public void init(Bundle savedInstanceState) {
+ super.init(savedInstanceState);
+
+ // if this is the first time show first time activity
+ Preferences prefs = Preferences.getPreferences(this);
+ if (prefs.isFirstTime()) {
+ startActivity(new Intent(this, FirstTimeActivity.class));
+ finish();
+ return;
+ }
+
+ Intent data = getIntent();
+ // If we got an EXTRA_RESULT in the intent, show the notification
+ if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
+ OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
+ result.createNotify(this).show();
+ }
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NavDrawerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NavDrawerActivity.java
new file mode 100644
index 000000000..fb23c7d3a
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NavDrawerActivity.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.remote.ui.AppsListFragment;
+
+import it.neokree.materialnavigationdrawer.MaterialNavigationDrawer;
+
+public abstract class NavDrawerActivity extends MaterialNavigationDrawer {
+
+ @Override
+ public void init(Bundle savedInstanceState) {
+ // don't open drawer on first run
+ disableLearningPattern();
+
+// addMultiPaneSupport();
+
+ // set the header image
+ // create and set the header
+ setDrawerHeaderImage(R.drawable.drawer_header);
+
+ // create sections
+ addSection(newSection(getString(R.string.nav_keys), R.drawable.ic_vpn_key_black_24dp, new KeyListFragment()));
+ addSection(newSection(getString(R.string.nav_encrypt_decrypt), R.drawable.ic_lock_black_24dp, new EncryptDecryptOverviewFragment()));
+ addSection(newSection(getString(R.string.title_api_registered_apps), R.drawable.ic_apps_black_24dp, new AppsListFragment()));
+
+ // create bottom section
+ addBottomSection(newSection(getString(R.string.menu_preferences), R.drawable.ic_settings_black_24dp, new Intent(this, SettingsActivity.class)));
+ addBottomSection(newSection(getString(R.string.menu_help), R.drawable.ic_help_black_24dp, new Intent(this, HelpActivity.class)));
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcActivity.java
index d0e40a9b8..7311f4879 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcActivity.java
@@ -15,7 +15,6 @@ import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.os.Build;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import android.view.WindowManager;
import android.widget.Toast;
@@ -23,13 +22,11 @@ import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Iso7816TLV;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.util.Locale;
/**
* This class provides a communication interface to OpenPGP applications on ISO SmartCard compliant
@@ -38,7 +35,7 @@ import java.util.Locale;
* For the full specs, see http://g10code.com/docs/openpgp-card-2.0.pdf
*/
@TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
-public class NfcActivity extends ActionBarActivity {
+public class NfcActivity extends BaseActivity {
// actions
public static final String ACTION_SIGN_HASH = "sign_hash";
@@ -82,8 +79,6 @@ public class NfcActivity extends ActionBarActivity {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- setContentView(R.layout.nfc_activity);
-
Intent intent = getIntent();
Bundle data = intent.getExtras();
String action = intent.getAction();
@@ -93,36 +88,46 @@ public class NfcActivity extends ActionBarActivity {
mKeyId = data.getLong(EXTRA_KEY_ID);
}
- if (ACTION_SIGN_HASH.equals(action)) {
- mAction = action;
- mPin = data.getString(EXTRA_PIN);
- mHashToSign = data.getByteArray(EXTRA_NFC_HASH_TO_SIGN);
- mHashAlgo = data.getInt(EXTRA_NFC_HASH_ALGO);
- mServiceIntent = data.getParcelable(EXTRA_DATA);
-
- Log.d(Constants.TAG, "NfcActivity mAction: " + mAction);
- Log.d(Constants.TAG, "NfcActivity mPin: " + mPin);
- Log.d(Constants.TAG, "NfcActivity mHashToSign as hex: " + getHex(mHashToSign));
- Log.d(Constants.TAG, "NfcActivity mServiceIntent: " + mServiceIntent.toString());
- } else if (ACTION_DECRYPT_SESSION_KEY.equals(action)) {
- mAction = action;
- mPin = data.getString(EXTRA_PIN);
- mEncryptedSessionKey = data.getByteArray(EXTRA_NFC_ENC_SESSION_KEY);
- mServiceIntent = data.getParcelable(EXTRA_DATA);
-
- Log.d(Constants.TAG, "NfcActivity mAction: " + mAction);
- Log.d(Constants.TAG, "NfcActivity mPin: " + mPin);
- Log.d(Constants.TAG, "NfcActivity mEncryptedSessionKey as hex: " + getHex(mEncryptedSessionKey));
- Log.d(Constants.TAG, "NfcActivity mServiceIntent: " + mServiceIntent.toString());
- } else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
- Log.e(Constants.TAG, "This should not happen! NfcActivity.onCreate() is being called instead of onNewIntent()!");
- toast("This should not happen! Please create a new bug report that the NFC screen is restarted!");
- finish();
- } else {
- Log.d(Constants.TAG, "Action not supported: " + action);
+ switch (action) {
+ case ACTION_SIGN_HASH:
+ mAction = action;
+ mPin = data.getString(EXTRA_PIN);
+ mHashToSign = data.getByteArray(EXTRA_NFC_HASH_TO_SIGN);
+ mHashAlgo = data.getInt(EXTRA_NFC_HASH_ALGO);
+ mServiceIntent = data.getParcelable(EXTRA_DATA);
+
+ Log.d(Constants.TAG, "NfcActivity mAction: " + mAction);
+ Log.d(Constants.TAG, "NfcActivity mPin: " + mPin);
+ Log.d(Constants.TAG, "NfcActivity mHashToSign as hex: " + getHex(mHashToSign));
+ Log.d(Constants.TAG, "NfcActivity mServiceIntent: " + mServiceIntent.toString());
+ break;
+ case ACTION_DECRYPT_SESSION_KEY:
+ mAction = action;
+ mPin = data.getString(EXTRA_PIN);
+ mEncryptedSessionKey = data.getByteArray(EXTRA_NFC_ENC_SESSION_KEY);
+ mServiceIntent = data.getParcelable(EXTRA_DATA);
+
+ Log.d(Constants.TAG, "NfcActivity mAction: " + mAction);
+ Log.d(Constants.TAG, "NfcActivity mPin: " + mPin);
+ Log.d(Constants.TAG, "NfcActivity mEncryptedSessionKey as hex: " + getHex(mEncryptedSessionKey));
+ Log.d(Constants.TAG, "NfcActivity mServiceIntent: " + mServiceIntent.toString());
+ break;
+ case NfcAdapter.ACTION_TAG_DISCOVERED:
+ Log.e(Constants.TAG, "This should not happen! NfcActivity.onCreate() is being called instead of onNewIntent()!");
+ toast("This should not happen! Please create a new bug report that the NFC screen is restarted!");
+ finish();
+ break;
+ default:
+ Log.d(Constants.TAG, "Action not supported: " + action);
+ break;
}
}
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.nfc_activity);
+ }
+
/**
* Called when the system is about to start resuming a previous activity,
* disables NFC Foreground Dispatch
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcIntentActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcIntentActivity.java
index cb15dbec2..0ccb206d1 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcIntentActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcIntentActivity.java
@@ -15,15 +15,14 @@ import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.os.Build;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
import android.view.WindowManager;
import android.widget.Toast;
import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Iso7816TLV;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.Iso7816TLV;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
@@ -36,7 +35,7 @@ import java.nio.ByteBuffer;
* For the full specs, see http://g10code.com/docs/openpgp-card-2.0.pdf
*/
@TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
-public class NfcIntentActivity extends ActionBarActivity {
+public class NfcIntentActivity extends BaseActivity {
// special extra for OpenPgpService
public static final String EXTRA_DATA = "data";
@@ -54,8 +53,6 @@ public class NfcIntentActivity extends ActionBarActivity {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- setContentView(R.layout.nfc_activity);
-
Intent intent = getIntent();
Bundle data = intent.getExtras();
String action = intent.getAction();
@@ -87,7 +84,11 @@ public class NfcIntentActivity extends ActionBarActivity {
Log.e(Constants.TAG, "IOException!", e);
finish();
}
+ }
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.nfc_activity);
}
/**
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
index deff648ba..d5ca08936 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
@@ -68,6 +68,8 @@ public class PassphraseDialogActivity extends FragmentActivity {
// special extra for OpenPgpService
public static final String EXTRA_DATA = "data";
+ private static final int REQUEST_CODE_ENTER_PATTERN = 2;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -90,6 +92,40 @@ public class PassphraseDialogActivity extends FragmentActivity {
show(this, keyId, serviceIntent);
}
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case REQUEST_CODE_ENTER_PATTERN: {
+ /*
+ * NOTE that there are 4 possible result codes!!!
+ */
+ switch (resultCode) {
+ case RESULT_OK:
+ // The user passed
+ break;
+ case RESULT_CANCELED:
+ // The user cancelled the task
+ break;
+// case LockPatternActivity.RESULT_FAILED:
+// // The user failed to enter the pattern
+// break;
+// case LockPatternActivity.RESULT_FORGOT_PATTERN:
+// // The user forgot the pattern and invoked your recovery Activity.
+// break;
+ }
+
+ /*
+ * In any case, there's always a key EXTRA_RETRY_COUNT, which holds
+ * the number of tries that the user did.
+ */
+// int retryCount = data.getIntExtra(
+// LockPatternActivity.EXTRA_RETRY_COUNT, 0);
+
+ break;
+ }
+ }
+ }
+
/**
* Shows passphrase dialog to cache a new passphrase the user enters for using it later for
* encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks
@@ -138,7 +174,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(theme);
- alert.setTitle(R.string.title_authentication);
+ alert.setTitle(R.string.title_unlock);
String userId;
CanonicalizedSecretKey.SecretKeyType keyType = CanonicalizedSecretKey.SecretKeyType.PASSPHRASE;
@@ -170,8 +206,11 @@ public class PassphraseDialogActivity extends FragmentActivity {
case PASSPHRASE:
message = getString(R.string.passphrase_for, userId);
break;
+ case PIN:
+ message = getString(R.string.pin_for, userId);
+ break;
case DIVERT_TO_CARD:
- message = getString(R.string.yubikey_pin, userId);
+ message = getString(R.string.yubikey_pin_for, userId);
break;
default:
message = "This should not happen!";
@@ -209,40 +248,52 @@ public class PassphraseDialogActivity extends FragmentActivity {
}
});
- // Hack to open keyboard.
- // This is the only method that I found to work across all Android versions
- // http://turbomanage.wordpress.com/2012/05/02/show-soft-keyboard-automatically-when-edittext-receives-focus/
- // Notes: * onCreateView can't be used because we want to add buttons to the dialog
- // * opening in onActivityCreated does not work on Android 4.4
- mPassphraseEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- mPassphraseEditText.post(new Runnable() {
- @Override
- public void run() {
- if (getActivity() == null || mPassphraseEditText == null) {
- return;
+
+ if (keyType == CanonicalizedSecretKey.SecretKeyType.PATTERN) {
+ // start pattern dialog and show progress circle here...
+// Intent patternActivity = new Intent(getActivity(), LockPatternActivity.class);
+// patternActivity.putExtra(LockPatternActivity.EXTRA_PATTERN, "123");
+// startActivityForResult(patternActivity, REQUEST_CODE_ENTER_PATTERN);
+ mInput.setVisibility(View.GONE);
+ mProgress.setVisibility(View.VISIBLE);
+ } else {
+ // Hack to open keyboard.
+ // This is the only method that I found to work across all Android versions
+ // http://turbomanage.wordpress.com/2012/05/02/show-soft-keyboard-automatically-when-edittext-receives-focus/
+ // Notes: * onCreateView can't be used because we want to add buttons to the dialog
+ // * opening in onActivityCreated does not work on Android 4.4
+ mPassphraseEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ mPassphraseEditText.post(new Runnable() {
+ @Override
+ public void run() {
+ if (getActivity() == null || mPassphraseEditText == null) {
+ return;
+ }
+ InputMethodManager imm = (InputMethodManager) getActivity()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(mPassphraseEditText, InputMethodManager.SHOW_IMPLICIT);
}
- InputMethodManager imm = (InputMethodManager) getActivity()
- .getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.showSoftInput(mPassphraseEditText, InputMethodManager.SHOW_IMPLICIT);
- }
- });
+ });
+ }
+ });
+ mPassphraseEditText.requestFocus();
+
+ mPassphraseEditText.setImeActionLabel(getString(android.R.string.ok), EditorInfo.IME_ACTION_DONE);
+ mPassphraseEditText.setOnEditorActionListener(this);
+
+ if (keyType == CanonicalizedSecretKey.SecretKeyType.DIVERT_TO_CARD && Preferences.getPreferences(activity).useNumKeypadForYubikeyPin()) {
+ mPassphraseEditText.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ } else if (keyType == CanonicalizedSecretKey.SecretKeyType.PIN) {
+ mPassphraseEditText.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ } else {
+ mPassphraseEditText.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
}
- });
- mPassphraseEditText.requestFocus();
-
- mPassphraseEditText.setImeActionLabel(getString(android.R.string.ok), EditorInfo.IME_ACTION_DONE);
- mPassphraseEditText.setOnEditorActionListener(this);
- if (keyType == CanonicalizedSecretKey.SecretKeyType.DIVERT_TO_CARD && Preferences.getPreferences(activity).useNumKeypadForYubikeyPin()) {
- mPassphraseEditText.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_TEXT_VARIATION_PASSWORD);
- } else {
- mPassphraseEditText.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ mPassphraseEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
}
- mPassphraseEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
-
AlertDialog dialog = alert.create();
dialog.setButton(DialogInterface.BUTTON_POSITIVE,
activity.getString(android.R.string.ok), (DialogInterface.OnClickListener) null);
@@ -264,7 +315,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
// Early breakout if we are dealing with a symmetric key
if (mSecretRing == null) {
PassphraseCacheService.addCachedPassphrase(getActivity(),
- Constants.key.symmetric, Constants.key.symmetric, passphrase,
+ Constants.key.symmetric, Constants.key.symmetric, passphrase,
getString(R.string.passp_cache_notif_pwd));
finishCaching(passphrase);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseWizardActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseWizardActivity.java
new file mode 100644
index 000000000..2e838535d
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseWizardActivity.java
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.annotation.TargetApi;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nfc.FormatException;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.nfc.tech.Ndef;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.sufficientlysecure.keychain.R;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.List;
+
+@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+public class PassphraseWizardActivity extends FragmentActivity {
+//public class PassphraseWizardActivity extends FragmentActivity implements LockPatternView.OnPatternListener {
+ //create or authenticate
+ public String selectedAction;
+ //for lockpattern
+ public static char[] pattern;
+ private static String passphrase = "";
+ //nfc string
+ private static byte[] output = new byte[8];
+
+ public static final String CREATE_METHOD = "create";
+ public static final String AUTHENTICATION = "authenticate";
+
+ NfcAdapter adapter;
+ PendingIntent pendingIntent;
+ IntentFilter writeTagFilters[];
+ boolean writeMode;
+ Tag myTag;
+ boolean writeNFC = false;
+ boolean readNFC = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getActionBar() != null) {
+ getActionBar().setTitle(R.string.unlock_method);
+ }
+
+ selectedAction = getIntent().getAction();
+ if (savedInstanceState == null) {
+ SelectMethods selectMethods = new SelectMethods();
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.add(R.id.fragmentContainer, selectMethods).commit();
+ }
+ setContentView(R.layout.passphrase_wizard);
+
+ adapter = NfcAdapter.getDefaultAdapter(this);
+ if (adapter != null) {
+ pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, PassphraseWizardActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
+ IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
+ tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
+ writeTagFilters = new IntentFilter[]{tagDetected};
+ }
+ }
+
+ public void noPassphrase(View view) {
+ passphrase = "";
+ Toast.makeText(this, R.string.no_passphrase_set, Toast.LENGTH_SHORT).show();
+ this.finish();
+ }
+
+ public void passphrase(View view) {
+ Passphrase passphrase = new Passphrase();
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.replace(R.id.fragmentContainer, passphrase).addToBackStack(null).commit();
+ }
+
+ public void startLockpattern(View view) {
+ if (getActionBar() != null) {
+ getActionBar().setTitle(R.string.draw_lockpattern);
+ }
+// LockPatternFragmentOld lpf = LockPatternFragmentOld.newInstance(selectedAction);
+// LockPatternFragment lpf = LockPatternFragment.newInstance("asd");
+
+// FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+// transaction.replace(R.id.fragmentContainer, lpf).addToBackStack(null).commit();
+ }
+
+ public void cancel(View view) {
+ this.finish();
+ }
+
+ public void savePassphrase(View view) {
+ EditText passphrase = (EditText) findViewById(R.id.passphrase);
+ passphrase.setError(null);
+ String pw = passphrase.getText().toString();
+ //check and save passphrase
+ if (selectedAction.equals(CREATE_METHOD)) {
+ EditText passphraseAgain = (EditText) findViewById(R.id.passphraseAgain);
+ passphraseAgain.setError(null);
+ String pwAgain = passphraseAgain.getText().toString();
+
+ if (!TextUtils.isEmpty(pw)) {
+ if (!TextUtils.isEmpty(pwAgain)) {
+ if (pw.equals(pwAgain)) {
+ PassphraseWizardActivity.passphrase = pw;
+ Toast.makeText(this, getString(R.string.passphrase_saved), Toast.LENGTH_SHORT).show();
+ this.finish();
+ } else {
+ passphrase.setError(getString(R.string.passphrase_invalid));
+ passphrase.requestFocus();
+ }
+ } else {
+ passphraseAgain.setError(getString(R.string.missing_passphrase));
+ passphraseAgain.requestFocus();
+ }
+ } else {
+ passphrase.setError(getString(R.string.missing_passphrase));
+ passphrase.requestFocus();
+ }
+ }
+ //check for right passphrase
+ if (selectedAction.equals(AUTHENTICATION)) {
+ if (pw.equals(PassphraseWizardActivity.passphrase)) {
+ Toast.makeText(this, getString(R.string.unlocked), Toast.LENGTH_SHORT).show();
+ this.finish();
+ } else {
+ passphrase.setError(getString(R.string.passphrase_invalid));
+ passphrase.requestFocus();
+ }
+ }
+ }
+
+ public void NFC(View view) {
+ if (adapter != null) {
+ if (getActionBar() != null) {
+ getActionBar().setTitle(R.string.nfc_title);
+ }
+ NFCFragment nfc = new NFCFragment();
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.replace(R.id.fragmentContainer, nfc).addToBackStack(null).commit();
+
+ //if you want to create a new method or just authenticate
+ if (CREATE_METHOD.equals(selectedAction)) {
+ writeNFC = true;
+ } else if (AUTHENTICATION.equals(selectedAction)) {
+ readNFC = true;
+ }
+
+ if (!adapter.isEnabled()) {
+ showAlertDialog(getString(R.string.enable_nfc), true);
+ }
+ } else {
+ showAlertDialog(getString(R.string.no_nfc_support), false);
+ }
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
+ myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
+
+ if (writeNFC && CREATE_METHOD.equals(selectedAction)) {
+ //write new password on NFC tag
+ try {
+ if (myTag != null) {
+ write(myTag);
+ writeNFC = false; //just write once
+ Toast.makeText(this, R.string.nfc_write_succesful, Toast.LENGTH_SHORT).show();
+ //advance to lockpattern
+// LockPatternFragmentOld lpf = LockPatternFragmentOld.newInstance(selectedAction);
+// FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+// transaction.replace(R.id.fragmentContainer, lpf).addToBackStack(null).commit();
+ }
+ } catch (IOException | FormatException e) {
+ e.printStackTrace();
+ }
+
+ } else if (readNFC && AUTHENTICATION.equals(selectedAction)) {
+ //read pw from NFC tag
+ try {
+ if (myTag != null) {
+ //if tag detected, read tag
+ String pwtag = read(myTag);
+ if (output != null && pwtag.equals(output.toString())) {
+
+ //passwort matches, go to next view
+ Toast.makeText(this, R.string.passphrases_match + "!", Toast.LENGTH_SHORT).show();
+
+// LockPatternFragmentOld lpf = LockPatternFragmentOld.newInstance(selectedAction);
+// FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+// transaction.replace(R.id.fragmentContainer, lpf).addToBackStack(null).commit();
+ readNFC = false; //just once
+ } else {
+ //passwort doesnt match
+ TextView nfc = (TextView) findViewById(R.id.nfcText);
+ nfc.setText(R.string.nfc_wrong_tag);
+ }
+ }
+ } catch (IOException | FormatException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void write(Tag tag) throws IOException, FormatException {
+ //generate new random key and write them on the tag
+ SecureRandom sr = new SecureRandom();
+ sr.nextBytes(output);
+ NdefRecord[] records = {createRecord(output.toString())};
+ NdefMessage message = new NdefMessage(records);
+ Ndef ndef = Ndef.get(tag);
+ ndef.connect();
+ ndef.writeNdefMessage(message);
+ ndef.close();
+ }
+
+ private String read(Tag tag) throws IOException, FormatException {
+ //read string from tag
+ String password = null;
+ Ndef ndef = Ndef.get(tag);
+ ndef.connect();
+ NdefMessage ndefMessage = ndef.getCachedNdefMessage();
+
+ NdefRecord[] records = ndefMessage.getRecords();
+ for (NdefRecord ndefRecord : records) {
+ if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
+ try {
+ password = readText(ndefRecord);
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ ndef.close();
+ return password;
+ }
+
+ private String readText(NdefRecord record) throws UnsupportedEncodingException {
+ //low-level method for reading nfc
+ byte[] payload = record.getPayload();
+ String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
+ int languageCodeLength = payload[0] & 0063;
+ return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
+ }
+
+ private NdefRecord createRecord(String text) throws UnsupportedEncodingException {
+ //low-level method for writing nfc
+ String lang = "en";
+ byte[] textBytes = text.getBytes();
+ byte[] langBytes = lang.getBytes("US-ASCII");
+ int langLength = langBytes.length;
+ int textLength = textBytes.length;
+ byte[] payload = new byte[1 + langLength + textLength];
+
+ // set status byte (see NDEF spec for actual bits)
+ payload[0] = (byte) langLength;
+ // copy langbytes and textbytes into payload
+ System.arraycopy(langBytes, 0, payload, 1, langLength);
+ System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength);
+ return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
+ }
+
+ public void showAlertDialog(String message, boolean nfc) {
+ //This method shows an AlertDialog
+ AlertDialog.Builder alert = new AlertDialog.Builder(this);
+ alert.setTitle("Information").setMessage(message).setPositiveButton("Ok",
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ }
+ }
+ );
+ if (nfc) {
+
+ alert.setNeutralButton(R.string.nfc_settings,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialogInterface, int i) {
+ startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
+ }
+ }
+ );
+ }
+ alert.show();
+ }
+
+ @Override
+ public void onPause() {
+ //pause this app and free nfc intent
+ super.onPause();
+ if (adapter != null) {
+ WriteModeOff();
+ }
+ }
+
+ @Override
+ public void onResume() {
+ //resume this app and get nfc intent
+ super.onResume();
+ if (adapter != null) {
+ WriteModeOn();
+ }
+ }
+
+ private void WriteModeOn() {
+ //enable nfc for this view
+ writeMode = true;
+ adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
+ }
+
+ private void WriteModeOff() {
+ //disable nfc for this view
+ writeMode = false;
+ adapter.disableForegroundDispatch(this);
+ }
+
+ public static class SelectMethods extends Fragment {
+// private OnFragmentInteractionListener mListener;
+
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ */
+ public SelectMethods() {
+
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (getActivity().getActionBar() != null) {
+ getActivity().getActionBar().setTitle(R.string.unlock_method);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.passphrase_wizard_fragment_select_methods, container, false);
+ }
+
+// @Override
+// public void onAttach(Activity activity) {
+// super.onAttach(activity);
+// try {
+// mListener = (OnFragmentInteractionListener) activity;
+// } catch (ClassCastException e) {
+// throw new ClassCastException(activity.toString()
+// + " must implement OnFragmentInteractionListener");
+// }
+// }
+//
+// @Override
+// public void onDetach() {
+// super.onDetach();
+// mListener = null;
+// }
+
+ /**
+ * This interface must be implemented by activities that contain this
+ * fragment to allow an interaction in this fragment to be communicated
+ * to the activity and potentially other fragments contained in that
+ * activity.
+ * <p/>
+ * See the Android Training lesson <a href=
+ * "http://developer.android.com/training/basics/fragments/communicating.html"
+ * >Communicating with Other Fragments</a> for more information.
+ */
+// public static interface OnFragmentInteractionListener {
+// public void onFragmentInteraction(Uri uri);
+// }
+
+ }
+
+
+ // /**
+// * A simple {@link android.support.v4.app.Fragment} subclass.
+// * Activities that contain this fragment must implement the
+// * {@link com.haibison.android.lockpattern.Passphrase.OnFragmentInteractionListener} interface
+// * to handle interaction events.
+// */
+ public static class Passphrase extends Fragment {
+
+// private OnFragmentInteractionListener mListener;
+
+ public Passphrase() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View view = inflater.inflate(R.layout.passphrase_wizard_fragment_passphrase, container, false);
+ EditText passphraseAgain = (EditText) view.findViewById(R.id.passphraseAgain);
+ TextView passphraseText = (TextView) view.findViewById(R.id.passphraseText);
+ TextView passphraseTextAgain = (TextView) view.findViewById(R.id.passphraseTextAgain);
+ String selectedAction = getActivity().getIntent().getAction();
+ if (selectedAction.equals(AUTHENTICATION)) {
+ passphraseAgain.setVisibility(View.GONE);
+ passphraseTextAgain.setVisibility(View.GONE);
+ passphraseText.setText(R.string.enter_passphrase);
+// getActivity().getActionBar().setTitle(R.string.enter_passphrase);
+ } else if (selectedAction.equals(CREATE_METHOD)) {
+ passphraseAgain.setVisibility(View.VISIBLE);
+ passphraseTextAgain.setVisibility(View.VISIBLE);
+ passphraseText.setText(R.string.passphrase);
+// getActivity().getActionBar().setTitle(R.string.set_passphrase);
+ }
+ return view;
+ }
+
+// @Override
+// public void onAttach(Activity activity) {
+// super.onAttach(activity);
+// try {
+// mListener = (OnFragmentInteractionListener) activity;
+// } catch (ClassCastException e) {
+// throw new ClassCastException(activity.toString()
+// + " must implement OnFragmentInteractionListener");
+// }
+// }
+//
+// @Override
+// public void onDetach() {
+// super.onDetach();
+// mListener = null;
+// }
+
+// /**
+// * This interface must be implemented by activities that contain this
+// * fragment to allow an interaction in this fragment to be communicated
+// * to the activity and potentially other fragments contained in that
+// * activity.
+// * <p/>
+// * See the Android Training lesson <a href=
+// * "http://developer.android.com/training/basics/fragments/communicating.html"
+// * >Communicating with Other Fragments</a> for more information.
+// */
+// public interface OnFragmentInteractionListener {
+// public void onFragmentInteraction(Uri uri);
+// }
+ }
+
+
+ /**
+ * A simple {@link android.support.v4.app.Fragment} subclass.
+ * Activities that contain this fragment must implement the
+ * interface
+ * to handle interaction events.
+ * Use the method to
+ * create an instance of this fragment.
+ */
+ public static class NFCFragment extends Fragment {
+ // TODO: Rename parameter arguments, choose names that match
+ // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+ private static final String ARG_PARAM1 = "param1";
+ private static final String ARG_PARAM2 = "param2";
+
+ // TODO: Rename and change types of parameters
+ private String mParam1;
+ private String mParam2;
+
+// private OnFragmentInteractionListener mListener;
+
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @param param1 Parameter 1.
+ * @param param2 Parameter 2.
+ * @return A new instance of fragment SelectMethods.
+ */
+ // TODO: Rename and change types and number of parameters
+ public static NFCFragment newInstance(String param1, String param2) {
+ NFCFragment fragment = new NFCFragment();
+ Bundle args = new Bundle();
+ args.putString(ARG_PARAM1, param1);
+ args.putString(ARG_PARAM2, param2);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ public NFCFragment() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ mParam1 = getArguments().getString(ARG_PARAM1);
+ mParam2 = getArguments().getString(ARG_PARAM2);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.passphrase_wizard_fragment_nfc, container, false);
+ }
+
+// // TODO: Rename method, update argument and hook method into UI event
+// public void onButtonPressed(Uri uri) {
+// if (mListener != null) {
+// mListener.onFragmentInteraction(uri);
+// }
+// }
+
+// @Override
+// public void onAttach(Activity activity) {
+// super.onAttach(activity);
+// try {
+// mListener = (OnFragmentInteractionListener) activity;
+// } catch (ClassCastException e) {
+// throw new ClassCastException(activity.toString()
+// + " must implement OnFragmentInteractionListener");
+// }
+// }
+
+
+// @Override
+// public void onDetach() {
+// super.onDetach();
+// mListener = null;
+// }
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
deleted file mode 100644
index 51fac4779..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceFragment;
-import android.preference.PreferenceScreen;
-
-import org.spongycastle.bcpg.CompressionAlgorithmTags;
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Preferences;
-import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
-
-import java.util.List;
-
-@SuppressLint("NewApi")
-public class PreferencesActivity extends PreferenceActivity {
-
- public static final String ACTION_PREFS_CLOUD = "org.sufficientlysecure.keychain.ui.PREFS_CLOUD";
- public static final String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
-
- public static final int REQUEST_CODE_KEYSERVER_PREF = 0x00007005;
-
- private PreferenceScreen mKeyServerPreference = null;
- private static Preferences sPreferences;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- sPreferences = Preferences.getPreferences(this);
- super.onCreate(savedInstanceState);
-
- String action = getIntent().getAction();
-
- if (action != null && action.equals(ACTION_PREFS_CLOUD)) {
- addPreferencesFromResource(R.xml.cloud_search_prefs);
-
- mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
- mKeyServerPreference.setSummary(keyserverSummary(this));
- mKeyServerPreference
- .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- public boolean onPreferenceClick(Preference preference) {
- Intent intent = new Intent(PreferencesActivity.this,
- PreferencesKeyServerActivity.class);
- intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
- sPreferences.getKeyServers());
- startActivityForResult(intent, REQUEST_CODE_KEYSERVER_PREF);
- return false;
- }
- });
- initializeSearchKeyserver(
- (CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYSERVER)
- );
- initializeSearchKeybase(
- (CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYBASE)
- );
-
- } else if (action != null && action.equals(ACTION_PREFS_ADV)) {
- addPreferencesFromResource(R.xml.adv_preferences);
-
- initializePassphraseCacheSubs(
- (CheckBoxPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_SUBS));
-
- initializePassphraseCacheTtl(
- (IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
-
- initializeEncryptionAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
-
- initializeHashAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM));
-
- int[] valueIds = new int[]{
- CompressionAlgorithmTags.UNCOMPRESSED,
- CompressionAlgorithmTags.ZIP,
- CompressionAlgorithmTags.ZLIB,
- CompressionAlgorithmTags.BZIP2,
- };
- String[] entries = new String[]{
- getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
- "ZIP (" + getString(R.string.compression_fast) + ")",
- "ZLIB (" + getString(R.string.compression_fast) + ")",
- "BZIP2 (" + getString(R.string.compression_very_slow) + ")",};
- String[] values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
-
- initializeMessageCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
- entries, values);
-
- initializeFileCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
- entries, values);
-
- initializeAsciiArmor(
- (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR));
-
- initializeWriteVersionHeader(
- (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER));
-
- initializeUseDefaultYubikeyPin(
- (CheckBoxPreference) findPreference(Constants.Pref.USE_DEFAULT_YUBIKEY_PIN));
-
- initializeUseNumKeypadForYubikeyPin(
- (CheckBoxPreference) findPreference(Constants.Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN));
-
- } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
- // Load the legacy preferences headers
- addPreferencesFromResource(R.xml.preference_headers_legacy);
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CODE_KEYSERVER_PREF: {
- if (resultCode == RESULT_CANCELED || data == null) {
- return;
- }
- String servers[] = data
- .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
- sPreferences.setKeyServers(servers);
- mKeyServerPreference.setSummary(keyserverSummary(this));
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
- break;
- }
- }
- }
-
- /* Called only on Honeycomb and later */
- @Override
- public void onBuildHeaders(List<Header> target) {
- super.onBuildHeaders(target);
- loadHeadersFromResource(R.xml.preference_headers, target);
- }
-
- /**
- * This fragment shows the Cloud Search preferences in android 3.0+
- */
- public static class CloudSearchPrefsFragment extends PreferenceFragment {
-
- private PreferenceScreen mKeyServerPreference = null;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.cloud_search_prefs);
-
- mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
- mKeyServerPreference.setSummary(keyserverSummary(getActivity()));
-
- mKeyServerPreference
- .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- public boolean onPreferenceClick(Preference preference) {
- Intent intent = new Intent(getActivity(),
- PreferencesKeyServerActivity.class);
- intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
- sPreferences.getKeyServers());
- startActivityForResult(intent, REQUEST_CODE_KEYSERVER_PREF);
- return false;
- }
- });
- initializeSearchKeyserver(
- (CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYSERVER)
- );
- initializeSearchKeybase(
- (CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYBASE)
- );
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CODE_KEYSERVER_PREF: {
- if (resultCode == RESULT_CANCELED || data == null) {
- return;
- }
- String servers[] = data
- .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
- sPreferences.setKeyServers(servers);
- mKeyServerPreference.setSummary(keyserverSummary(getActivity()));
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
- break;
- }
- }
- }
- }
-
- /**
- * This fragment shows the advanced preferences in android 3.0+
- */
- public static class AdvancedPrefsFragment extends PreferenceFragment {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.adv_preferences);
-
- initializePassphraseCacheSubs(
- (CheckBoxPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_SUBS));
-
- initializePassphraseCacheTtl(
- (IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
-
- initializeEncryptionAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
-
- initializeHashAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM));
-
- int[] valueIds = new int[]{
- CompressionAlgorithmTags.UNCOMPRESSED,
- CompressionAlgorithmTags.ZIP,
- CompressionAlgorithmTags.ZLIB,
- CompressionAlgorithmTags.BZIP2,
- };
-
- String[] entries = new String[]{
- getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
- "ZIP (" + getString(R.string.compression_fast) + ")",
- "ZLIB (" + getString(R.string.compression_fast) + ")",
- "BZIP2 (" + getString(R.string.compression_very_slow) + ")",
- };
-
- String[] values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
-
- initializeMessageCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
- entries, values);
-
- initializeFileCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
- entries, values);
-
- initializeAsciiArmor(
- (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR));
-
- initializeWriteVersionHeader(
- (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER));
-
- initializeUseDefaultYubikeyPin(
- (CheckBoxPreference) findPreference(Constants.Pref.USE_DEFAULT_YUBIKEY_PIN));
-
- initializeUseNumKeypadForYubikeyPin(
- (CheckBoxPreference) findPreference(Constants.Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN));
- }
- }
-
- protected boolean isValidFragment(String fragmentName) {
- return AdvancedPrefsFragment.class.getName().equals(fragmentName)
- || CloudSearchPrefsFragment.class.getName().equals(fragmentName)
- || super.isValidFragment(fragmentName);
- }
-
- private static void initializePassphraseCacheSubs(final CheckBoxPreference mPassphraseCacheSubs) {
- mPassphraseCacheSubs.setChecked(sPreferences.getPassphraseCacheSubs());
- mPassphraseCacheSubs.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mPassphraseCacheSubs.setChecked((Boolean) newValue);
- sPreferences.setPassphraseCacheSubs((Boolean) newValue);
- return false;
- }
- });
- }
-
- private static void initializePassphraseCacheTtl(final IntegerListPreference mPassphraseCacheTtl) {
- mPassphraseCacheTtl.setValue("" + sPreferences.getPassphraseCacheTtl());
- mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
- mPassphraseCacheTtl
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mPassphraseCacheTtl.setValue(newValue.toString());
- mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
- sPreferences.setPassphraseCacheTtl(Integer.parseInt(newValue.toString()));
- return false;
- }
- });
- }
-
- private static void initializeEncryptionAlgorithm(final IntegerListPreference mEncryptionAlgorithm) {
- int valueIds[] = {PGPEncryptedData.AES_128, PGPEncryptedData.AES_192,
- PGPEncryptedData.AES_256, PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH,
- PGPEncryptedData.CAST5, PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES,
- PGPEncryptedData.IDEA,};
- String entries[] = {"AES-128", "AES-192", "AES-256", "Blowfish", "Twofish", "CAST5",
- "DES", "Triple DES", "IDEA",};
- String values[] = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
- mEncryptionAlgorithm.setEntries(entries);
- mEncryptionAlgorithm.setEntryValues(values);
- mEncryptionAlgorithm.setValue("" + sPreferences.getDefaultEncryptionAlgorithm());
- mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
- mEncryptionAlgorithm
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mEncryptionAlgorithm.setValue(newValue.toString());
- mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
- sPreferences.setDefaultEncryptionAlgorithm(Integer.parseInt(newValue
- .toString()));
- return false;
- }
- });
- }
-
- private static void initializeHashAlgorithm(final IntegerListPreference mHashAlgorithm) {
- int[] valueIds = new int[]{HashAlgorithmTags.RIPEMD160,
- HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256,
- HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512,};
- String[] entries = new String[]{"RIPEMD-160", "SHA-1", "SHA-224", "SHA-256", "SHA-384",
- "SHA-512",};
- String[] values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
- mHashAlgorithm.setEntries(entries);
- mHashAlgorithm.setEntryValues(values);
- mHashAlgorithm.setValue("" + sPreferences.getDefaultHashAlgorithm());
- mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
- mHashAlgorithm.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mHashAlgorithm.setValue(newValue.toString());
- mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
- sPreferences.setDefaultHashAlgorithm(Integer.parseInt(newValue.toString()));
- return false;
- }
- });
- }
-
- private static void initializeMessageCompression(final IntegerListPreference mMessageCompression,
- String[] entries, String[] values) {
- mMessageCompression.setEntries(entries);
- mMessageCompression.setEntryValues(values);
- mMessageCompression.setValue("" + sPreferences.getDefaultMessageCompression());
- mMessageCompression.setSummary(mMessageCompression.getEntry());
- mMessageCompression
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mMessageCompression.setValue(newValue.toString());
- mMessageCompression.setSummary(mMessageCompression.getEntry());
- sPreferences.setDefaultMessageCompression(Integer.parseInt(newValue
- .toString()));
- return false;
- }
- });
- }
-
- private static void initializeFileCompression
- (final IntegerListPreference mFileCompression, String[] entries, String[] values) {
- mFileCompression.setEntries(entries);
- mFileCompression.setEntryValues(values);
- mFileCompression.setValue("" + sPreferences.getDefaultFileCompression());
- mFileCompression.setSummary(mFileCompression.getEntry());
- mFileCompression.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mFileCompression.setValue(newValue.toString());
- mFileCompression.setSummary(mFileCompression.getEntry());
- sPreferences.setDefaultFileCompression(Integer.parseInt(newValue.toString()));
- return false;
- }
- });
- }
-
- private static void initializeAsciiArmor(final CheckBoxPreference mAsciiArmor) {
- mAsciiArmor.setChecked(sPreferences.getDefaultAsciiArmor());
- mAsciiArmor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mAsciiArmor.setChecked((Boolean) newValue);
- sPreferences.setDefaultAsciiArmor((Boolean) newValue);
- return false;
- }
- });
- }
-
- private static void initializeWriteVersionHeader(final CheckBoxPreference mWriteVersionHeader) {
- mWriteVersionHeader.setChecked(sPreferences.getWriteVersionHeader());
- mWriteVersionHeader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mWriteVersionHeader.setChecked((Boolean) newValue);
- sPreferences.setWriteVersionHeader((Boolean) newValue);
- return false;
- }
- });
- }
-
- private static void initializeSearchKeyserver(final CheckBoxPreference mSearchKeyserver) {
- Preferences.CloudSearchPrefs prefs = sPreferences.getCloudSearchPrefs();
- mSearchKeyserver.setChecked(prefs.searchKeyserver);
- mSearchKeyserver.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mSearchKeyserver.setChecked((Boolean) newValue);
- sPreferences.setSearchKeyserver((Boolean) newValue);
- return false;
- }
- });
- }
-
- private static void initializeSearchKeybase(final CheckBoxPreference mSearchKeybase) {
- Preferences.CloudSearchPrefs prefs = sPreferences.getCloudSearchPrefs();
- mSearchKeybase.setChecked(prefs.searchKeybase);
- mSearchKeybase.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mSearchKeybase.setChecked((Boolean) newValue);
- sPreferences.setSearchKeybase((Boolean) newValue);
- return false;
- }
- });
- }
-
- public static String keyserverSummary(Context context) {
- String[] servers = sPreferences.getKeyServers();
- String serverSummary = context.getResources().getQuantityString(
- R.plurals.n_keyservers, servers.length, servers.length);
- return serverSummary + "; " + context.getString(R.string.label_preferred) + ": " + sPreferences.getPreferredKeyserver();
- }
-
- private static void initializeUseDefaultYubikeyPin(final CheckBoxPreference mUseDefaultYubikeyPin) {
- mUseDefaultYubikeyPin.setChecked(sPreferences.useDefaultYubikeyPin());
- mUseDefaultYubikeyPin.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mUseDefaultYubikeyPin.setChecked((Boolean) newValue);
- sPreferences.setUseDefaultYubikeyPin((Boolean) newValue);
- return false;
- }
- });
- }
-
- private static void initializeUseNumKeypadForYubikeyPin(final CheckBoxPreference mUseNumKeypadForYubikeyPin) {
- mUseNumKeypadForYubikeyPin.setChecked(sPreferences.useNumKeypadForYubikeyPin());
- mUseNumKeypadForYubikeyPin.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mUseNumKeypadForYubikeyPin.setChecked((Boolean) newValue);
- sPreferences.setUseNumKeypadForYubikeyPin((Boolean) newValue);
- return false;
- }
- });
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
deleted file mode 100644
index 2a8ef171c..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.ActionBarHelper;
-import org.sufficientlysecure.keychain.ui.widget.Editor;
-import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
-import org.sufficientlysecure.keychain.ui.widget.KeyServerEditor;
-
-import java.util.Vector;
-
-public class PreferencesKeyServerActivity extends ActionBarActivity implements OnClickListener,
- EditorListener {
-
- public static final String EXTRA_KEY_SERVERS = "key_servers";
-
- private LayoutInflater mInflater;
- private ViewGroup mEditors;
- private View mAdd;
- private View mRotate;
- private TextView mTitle;
- private TextView mSummary;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // ok
- okClicked();
- }
- }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // cancel
- cancelClicked();
- }
- }
- );
-
- setContentView(R.layout.key_server_preference);
-
- mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- mTitle = (TextView) findViewById(R.id.title);
- mSummary = (TextView) findViewById(R.id.summary);
- mSummary.setText(getText(R.string.label_first_keyserver_is_used));
-
- mTitle.setText(R.string.label_keyservers);
-
- mEditors = (ViewGroup) findViewById(R.id.editors);
- mAdd = findViewById(R.id.add);
- mAdd.setOnClickListener(this);
-
- mRotate = findViewById(R.id.rotate);
- mRotate.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- Vector<String> servers = serverList();
- String first = servers.get(0);
- if (first != null) {
- servers.remove(0);
- servers.add(first);
- String[] dummy = {};
- makeServerList(servers.toArray(dummy));
- }
- }
- });
-
- Intent intent = getIntent();
- String servers[] = intent.getStringArrayExtra(EXTRA_KEY_SERVERS);
- makeServerList(servers);
- }
-
- private void makeServerList(String[] servers) {
- if (servers != null) {
- mEditors.removeAllViews();
- for (String serv : servers) {
- KeyServerEditor view = (KeyServerEditor) mInflater.inflate(
- R.layout.key_server_editor, mEditors, false);
- view.setEditorListener(this);
- view.setValue(serv);
- mEditors.addView(view);
- }
- }
- }
-
- public void onDeleted(Editor editor, boolean wasNewItem) {
- // nothing to do
- }
-
- @Override
- public void onEdited() {
-
- }
-
- public void onClick(View v) {
- KeyServerEditor view = (KeyServerEditor) mInflater.inflate(R.layout.key_server_editor,
- mEditors, false);
- view.setEditorListener(this);
- mEditors.addView(view);
- }
-
- private void cancelClicked() {
- setResult(RESULT_CANCELED, null);
- finish();
- }
-
- private Vector<String> serverList() {
- Vector<String> servers = new Vector<String>();
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- KeyServerEditor editor = (KeyServerEditor) mEditors.getChildAt(i);
- String tmp = editor.getValue();
- if (tmp.length() > 0) {
- servers.add(tmp);
- }
- }
- return servers;
- }
-
- private void okClicked() {
- Intent data = new Intent();
- Vector<String> servers = new Vector<String>();
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- KeyServerEditor editor = (KeyServerEditor) mEditors.getChildAt(i);
- String tmp = editor.getValue();
- if (tmp.length() > 0) {
- servers.add(tmp);
- }
- }
- String[] dummy = new String[0];
- data.putExtra(EXTRA_KEY_SERVERS, servers.toArray(dummy));
- setResult(RESULT_OK, data);
- finish();
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeScanActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeScanActivity.java
index 5966870df..1a7a028c6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeScanActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeScanActivity.java
@@ -78,7 +78,11 @@ public class QrCodeScanActivity extends FragmentActivity {
// scan using xzing's Barcode Scanner and return result parcel in OpenKeychain
returnResult = true;
- new IntentIntegrator(this).initiateScan();
+ IntentIntegrator integrator = new IntentIntegrator(this);
+ integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES)
+ .setPrompt(getString(R.string.import_qr_code_text))
+ .setResultDisplayDuration(0)
+ .initiateScan();
} else if (ACTION_QR_CODE_API.equals(action)) {
// scan using xzing's Barcode Scanner from outside OpenKeychain
@@ -168,7 +172,7 @@ public class QrCodeScanActivity extends FragmentActivity {
return;
}
- if ( ! result.success()) {
+ if (!result.success()) {
// only return if no success...
Intent data = new Intent();
data.putExtras(returnData);
@@ -199,7 +203,7 @@ public class QrCodeScanActivity extends FragmentActivity {
data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null);
- ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<ParcelableKeyRing>();
+ ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
selectedEntries.add(keyEntry);
data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, selectedEntries);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java
index cf0c3eb88..d3c1d971a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java
@@ -20,57 +20,56 @@ package org.sufficientlysecure.keychain.ui;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v4.app.ActivityCompat;
+import android.support.v7.widget.CardView;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ImageView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.ActionBarHelper;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
+import org.sufficientlysecure.keychain.util.Log;
-public class QrCodeViewActivity extends ActionBarActivity {
+public class QrCodeViewActivity extends BaseActivity {
- private ImageView mFingerprintQrCode;
+ private ImageView mQrCode;
+ private CardView mQrCodeLayout;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Inflate a "Done" custom action bar
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
+ setFullScreenDialogClose(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// "Done"
- finish();
+ ActivityCompat.finishAfterTransition(QrCodeViewActivity.this);
}
}
);
- setContentView(R.layout.qr_code_activity);
-
Uri dataUri = getIntent().getData();
if (dataUri == null) {
Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
- finish();
+ ActivityCompat.finishAfterTransition(QrCodeViewActivity.this);
return;
}
- mFingerprintQrCode = (ImageView) findViewById(R.id.qr_code_image);
+ mQrCode = (ImageView) findViewById(R.id.qr_code_image);
+ mQrCodeLayout = (CardView) findViewById(R.id.qr_code_image_layout);
- mFingerprintQrCode.setOnClickListener(new View.OnClickListener() {
+ mQrCodeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- finish();
+ ActivityCompat.finishAfterTransition(QrCodeViewActivity.this);
}
});
@@ -82,7 +81,7 @@ public class QrCodeViewActivity extends ActionBarActivity {
if (blob == null) {
Log.e(Constants.TAG, "key not found!");
Notify.showNotify(this, R.string.error_key_not_found, Style.ERROR);
- finish();
+ ActivityCompat.finishAfterTransition(QrCodeViewActivity.this);
}
String fingerprint = KeyFormattingUtils.convertFingerprintToHex(blob);
@@ -91,37 +90,26 @@ public class QrCodeViewActivity extends ActionBarActivity {
// create a minimal size qr code, we can keep this in ram no problem
final Bitmap qrCode = QrCodeUtils.getQRCodeBitmap(qrCodeContent, 0);
- mFingerprintQrCode.getViewTreeObserver().addOnGlobalLayoutListener(
+ mQrCode.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- // create actual bitmap in display dimensions
- Bitmap scaled = Bitmap.createScaledBitmap(qrCode,
- mFingerprintQrCode.getWidth(), mFingerprintQrCode.getWidth(), false);
- mFingerprintQrCode.setImageBitmap(scaled);
- }
- });
+ @Override
+ public void onGlobalLayout() {
+ // create actual bitmap in display dimensions
+ Bitmap scaled = Bitmap.createScaledBitmap(qrCode,
+ mQrCode.getWidth(), mQrCode.getWidth(), false);
+ mQrCode.setImageBitmap(scaled);
+ }
+ });
} catch (ProviderHelper.NotFoundException e) {
Log.e(Constants.TAG, "key not found!", e);
Notify.showNotify(this, R.string.error_key_not_found, Style.ERROR);
- finish();
+ ActivityCompat.finishAfterTransition(QrCodeViewActivity.this);
}
}
@Override
- protected void onResume() {
- super.onResume();
-
- // custom activity transition to get zoom in effect
- this.overridePendingTransition(R.anim.qr_code_zoom_enter, android.R.anim.fade_out);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- // custom activity transition to get zoom out effect
- this.overridePendingTransition(0, R.anim.qr_code_zoom_exit);
+ protected void initLayout() {
+ setContentView(R.layout.qr_code_activity);
}
} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java
index 20e1bbe97..d1df2906d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java
@@ -27,13 +27,9 @@ import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.FragmentActivity;
-import android.support.v7.app.ActionBarActivity;
import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.NumberPicker;
-import android.widget.Spinner;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@@ -50,13 +46,12 @@ import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.List;
import edu.cmu.cylab.starslinger.exchange.ExchangeActivity;
import edu.cmu.cylab.starslinger.exchange.ExchangeConfig;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
-public class SafeSlingerActivity extends ActionBarActivity {
+public class SafeSlingerActivity extends BaseActivity {
private static final int REQUEST_CODE_SAFE_SLINGER = 211;
@@ -69,51 +64,17 @@ public class SafeSlingerActivity extends ActionBarActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.safe_slinger_activity);
-
mMasterKeyId = getIntent().getLongExtra(EXTRA_MASTER_KEY_ID, 0);
- // NOTE: there are two versions of this layout, for API >= 11 and one for < 11
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- NumberPicker picker = (NumberPicker) findViewById(R.id.safe_slinger_picker);
- picker.setMinValue(2);
- picker.setMaxValue(10);
- picker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
- @Override
- public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
- mSelectedNumber = newVal;
- }
- });
- } else {
- Spinner spinner = (Spinner) findViewById(R.id.safe_slinger_spinner);
-
- List<String> list = new ArrayList<String>();
- list.add("2");
- list.add("3");
- list.add("4");
- list.add("5");
- list.add("6");
- list.add("7");
- list.add("8");
- list.add("9");
- list.add("10");
-
- ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
- android.R.layout.simple_spinner_item, list);
- dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- spinner.setAdapter(dataAdapter);
- spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mSelectedNumber = position + 2;
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
-
- }
- });
- }
+ NumberPicker picker = (NumberPicker) findViewById(R.id.safe_slinger_picker);
+ picker.setMinValue(2);
+ picker.setMaxValue(10);
+ picker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ mSelectedNumber = newVal;
+ }
+ });
ImageView buttonIcon = (ImageView) findViewById(R.id.safe_slinger_button_image);
buttonIcon.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
@@ -128,6 +89,11 @@ public class SafeSlingerActivity extends ActionBarActivity {
});
}
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.safe_slinger_activity);
+ }
+
private void startExchange(long masterKeyId, int number) {
// retrieve public key blob and start SafeSlinger
Uri uri = KeychainContract.KeyRingData.buildPublicKeyRingUri(masterKeyId);
@@ -197,7 +163,7 @@ public class SafeSlingerActivity extends ActionBarActivity {
certifyIntent.putExtra(CertifyKeyActivity.EXTRA_RESULT, result);
certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, result.getImportedMasterKeyIds());
certifyIntent.putExtra(CertifyKeyActivity.EXTRA_CERTIFY_KEY_ID, mMasterKeyId);
- startActivityForResult(certifyIntent, KeyListActivity.REQUEST_CODE_RESULT_TO_LIST);
+ startActivityForResult(certifyIntent, 0);
// mExchangeMasterKeyId = null;
}
@@ -221,7 +187,7 @@ public class SafeSlingerActivity extends ActionBarActivity {
// We parcel this iteratively into a file - anything we can
// display here, we should be able to import.
ParcelableFileCache<ParcelableKeyRing> cache =
- new ParcelableFileCache<ParcelableKeyRing>(activity, "key_import.pcl");
+ new ParcelableFileCache<>(activity, "key_import.pcl");
cache.writeCache(it.size(), it.iterator());
// fill values for this action
@@ -249,7 +215,7 @@ public class SafeSlingerActivity extends ActionBarActivity {
}
private static ArrayList<ParcelableKeyRing> getSlingedKeys(Bundle extras) {
- ArrayList<ParcelableKeyRing> list = new ArrayList<ParcelableKeyRing>();
+ ArrayList<ParcelableKeyRing> list = new ArrayList<>();
if (extras != null) {
byte[] d;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
deleted file mode 100644
index 148aa7d67..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.ActionBarHelper;
-
-public class SelectPublicKeyActivity extends ActionBarActivity {
-
- // Actions for internal use only:
- public static final String ACTION_SELECT_PUBLIC_KEYS = Constants.INTENT_PREFIX
- + "SELECT_PUBLIC_KEYRINGS";
-
- public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids";
-
- public static final String RESULT_EXTRA_MASTER_KEY_IDS = "master_key_ids";
- public static final String RESULT_EXTRA_USER_IDS = "user_ids";
-
- SelectPublicKeyFragment mSelectFragment;
-
- long mSelectedMasterKeyIds[];
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // ok
- okClicked();
- }
- }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // cancel
- cancelClicked();
- }
- }
- );
-
- setContentView(R.layout.select_public_key_activity);
-
- setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
-
- handleIntent(getIntent());
-
- // Check that the activity is using the layout version with
- // the fragment_container FrameLayout
- if (findViewById(R.id.select_public_key_fragment_container) != null) {
-
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- mSelectFragment = SelectPublicKeyFragment.newInstance(mSelectedMasterKeyIds);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- getSupportFragmentManager().beginTransaction()
- .add(R.id.select_public_key_fragment_container, mSelectFragment).commit();
- }
-
- // TODO: reimplement!
- // mFilterLayout = findViewById(R.id.layout_filter);
- // mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo);
- // mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear);
- //
- // mClearFilterButton.setOnClickListener(new OnClickListener() {
- // public void onClick(View v) {
- // handleIntent(new Intent());
- // }
- // });
-
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- handleIntent(intent);
- }
-
- private void handleIntent(Intent intent) {
- // TODO: reimplement search!
-
- // String searchString = null;
- // if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
- // searchString = intent.getStringExtra(SearchManager.QUERY);
- // if (searchString != null && searchString.trim().length() == 0) {
- // searchString = null;
- // }
- // }
-
- // if (searchString == null) {
- // mFilterLayout.setVisibility(View.GONE);
- // } else {
- // mFilterLayout.setVisibility(View.VISIBLE);
- // mFilterInfo.setText(getString(R.string.filterInfo, searchString));
- // }
-
- // preselected master keys
- mSelectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
- }
-
- private void cancelClicked() {
- setResult(RESULT_CANCELED, null);
- finish();
- }
-
- private void okClicked() {
- Intent data = new Intent();
- data.putExtra(RESULT_EXTRA_MASTER_KEY_IDS, mSelectFragment.getSelectedMasterKeyIds());
- data.putExtra(RESULT_EXTRA_USER_IDS, mSelectFragment.getSelectedUserIds());
- setResult(RESULT_OK, data);
- finish();
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
index af583bf89..afec3bf06 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
@@ -42,7 +42,6 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ListFragmentWorkaround;
-import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
@@ -216,7 +215,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
public long[] getSelectedMasterKeyIds() {
// mListView.getCheckedItemIds() would give the row ids of the KeyRings not the master key
// ids!
- Vector<Long> vector = new Vector<Long>();
+ Vector<Long> vector = new Vector<>();
for (int i = 0; i < getListView().getCount(); ++i) {
if (getListView().isItemChecked(i)) {
vector.add(mAdapter.getMasterKeyId(i));
@@ -238,7 +237,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
* @return
*/
public String[] getSelectedUserIds() {
- Vector<String> userIds = new Vector<String>();
+ Vector<String> userIds = new Vector<>();
for (int i = 0; i < getListView().getCount(); ++i) {
if (getListView().isItemChecked(i)) {
userIds.add(mAdapter.getUserId(i));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java
new file mode 100644
index 000000000..53986a392
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import org.spongycastle.bcpg.CompressionAlgorithmTags;
+import org.spongycastle.bcpg.HashAlgorithmTags;
+import org.spongycastle.openpgp.PGPEncryptedData;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
+import org.sufficientlysecure.keychain.util.Preferences;
+
+import java.util.List;
+
+public class SettingsActivity extends PreferenceActivity {
+
+ public static final String ACTION_PREFS_CLOUD = "org.sufficientlysecure.keychain.ui.PREFS_CLOUD";
+ public static final String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
+
+ public static final int REQUEST_CODE_KEYSERVER_PREF = 0x00007005;
+
+ private PreferenceScreen mKeyServerPreference = null;
+ private static Preferences sPreferences;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ sPreferences = Preferences.getPreferences(this);
+ super.onCreate(savedInstanceState);
+
+ setupToolbar();
+
+ String action = getIntent().getAction();
+
+ if (action != null && action.equals(ACTION_PREFS_CLOUD)) {
+ addPreferencesFromResource(R.xml.cloud_search_prefs);
+
+ mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
+ mKeyServerPreference.setSummary(keyserverSummary(this));
+ mKeyServerPreference
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(SettingsActivity.this,
+ SettingsKeyServerActivity.class);
+ intent.putExtra(SettingsKeyServerActivity.EXTRA_KEY_SERVERS,
+ sPreferences.getKeyServers());
+ startActivityForResult(intent, REQUEST_CODE_KEYSERVER_PREF);
+ return false;
+ }
+ });
+ initializeSearchKeyserver(
+ (CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYSERVER)
+ );
+ initializeSearchKeybase(
+ (CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYBASE)
+ );
+
+ } else if (action != null && action.equals(ACTION_PREFS_ADV)) {
+ addPreferencesFromResource(R.xml.adv_preferences);
+
+ initializePassphraseCacheSubs(
+ (CheckBoxPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_SUBS));
+
+ initializePassphraseCacheTtl(
+ (IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
+
+ initializeEncryptionAlgorithm(
+ (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
+
+ initializeHashAlgorithm(
+ (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM));
+
+ int[] valueIds = new int[]{
+ CompressionAlgorithmTags.UNCOMPRESSED,
+ CompressionAlgorithmTags.ZIP,
+ CompressionAlgorithmTags.ZLIB,
+ CompressionAlgorithmTags.BZIP2,
+ };
+ String[] entries = new String[]{
+ getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
+ "ZIP (" + getString(R.string.compression_fast) + ")",
+ "ZLIB (" + getString(R.string.compression_fast) + ")",
+ "BZIP2 (" + getString(R.string.compression_very_slow) + ")",};
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+
+ initializeMessageCompression(
+ (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
+ entries, values);
+
+ initializeFileCompression(
+ (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
+ entries, values);
+
+ initializeAsciiArmor(
+ (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR));
+
+ initializeWriteVersionHeader(
+ (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER));
+
+ initializeUseDefaultYubikeyPin(
+ (CheckBoxPreference) findPreference(Constants.Pref.USE_DEFAULT_YUBIKEY_PIN));
+
+ initializeUseNumKeypadForYubikeyPin(
+ (CheckBoxPreference) findPreference(Constants.Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN));
+
+ }
+ }
+
+ /**
+ * Hack to get Toolbar in PreferenceActivity. See http://stackoverflow.com/a/26614696
+ */
+ private void setupToolbar() {
+ ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
+ LinearLayout content = (LinearLayout) root.getChildAt(0);
+ LinearLayout toolbarContainer = (LinearLayout) View.inflate(this, R.layout.preference_toolbar_activity, null);
+
+ root.removeAllViews();
+ toolbarContainer.addView(content);
+ root.addView(toolbarContainer);
+
+ Toolbar toolbar = (Toolbar) toolbarContainer.findViewById(R.id.toolbar);
+ toolbar.setTitle(R.string.title_preferences);
+ toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp));
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ //What to do on back clicked
+ finish();
+ }
+ });
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case REQUEST_CODE_KEYSERVER_PREF: {
+ if (resultCode == RESULT_CANCELED || data == null) {
+ return;
+ }
+ String servers[] = data
+ .getStringArrayExtra(SettingsKeyServerActivity.EXTRA_KEY_SERVERS);
+ sPreferences.setKeyServers(servers);
+ mKeyServerPreference.setSummary(keyserverSummary(this));
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onBuildHeaders(List<Header> target) {
+ super.onBuildHeaders(target);
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+
+ /**
+ * This fragment shows the Cloud Search preferences in android 3.0+
+ */
+ public static class CloudSearchPrefsFragment extends PreferenceFragment {
+
+ private PreferenceScreen mKeyServerPreference = null;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.cloud_search_prefs);
+
+ mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
+ mKeyServerPreference.setSummary(keyserverSummary(getActivity()));
+
+ mKeyServerPreference
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(getActivity(),
+ SettingsKeyServerActivity.class);
+ intent.putExtra(SettingsKeyServerActivity.EXTRA_KEY_SERVERS,
+ sPreferences.getKeyServers());
+ startActivityForResult(intent, REQUEST_CODE_KEYSERVER_PREF);
+ return false;
+ }
+ });
+ initializeSearchKeyserver(
+ (CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYSERVER)
+ );
+ initializeSearchKeybase(
+ (CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYBASE)
+ );
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case REQUEST_CODE_KEYSERVER_PREF: {
+ if (resultCode == RESULT_CANCELED || data == null) {
+ return;
+ }
+ String servers[] = data
+ .getStringArrayExtra(SettingsKeyServerActivity.EXTRA_KEY_SERVERS);
+ sPreferences.setKeyServers(servers);
+ mKeyServerPreference.setSummary(keyserverSummary(getActivity()));
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * This fragment shows the advanced preferences in android 3.0+
+ */
+ public static class AdvancedPrefsFragment extends PreferenceFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.adv_preferences);
+
+ initializePassphraseCacheSubs(
+ (CheckBoxPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_SUBS));
+
+ initializePassphraseCacheTtl(
+ (IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
+
+ initializeEncryptionAlgorithm(
+ (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
+
+ initializeHashAlgorithm(
+ (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM));
+
+ int[] valueIds = new int[]{
+ CompressionAlgorithmTags.UNCOMPRESSED,
+ CompressionAlgorithmTags.ZIP,
+ CompressionAlgorithmTags.ZLIB,
+ CompressionAlgorithmTags.BZIP2,
+ };
+
+ String[] entries = new String[]{
+ getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
+ "ZIP (" + getString(R.string.compression_fast) + ")",
+ "ZLIB (" + getString(R.string.compression_fast) + ")",
+ "BZIP2 (" + getString(R.string.compression_very_slow) + ")",
+ };
+
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+
+ initializeMessageCompression(
+ (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
+ entries, values);
+
+ initializeFileCompression(
+ (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
+ entries, values);
+
+ initializeAsciiArmor(
+ (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR));
+
+ initializeWriteVersionHeader(
+ (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER));
+
+ initializeUseDefaultYubikeyPin(
+ (CheckBoxPreference) findPreference(Constants.Pref.USE_DEFAULT_YUBIKEY_PIN));
+
+ initializeUseNumKeypadForYubikeyPin(
+ (CheckBoxPreference) findPreference(Constants.Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN));
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.KITKAT)
+ protected boolean isValidFragment(String fragmentName) {
+ return AdvancedPrefsFragment.class.getName().equals(fragmentName)
+ || CloudSearchPrefsFragment.class.getName().equals(fragmentName)
+ || super.isValidFragment(fragmentName);
+ }
+
+ private static void initializePassphraseCacheSubs(final CheckBoxPreference mPassphraseCacheSubs) {
+ mPassphraseCacheSubs.setChecked(sPreferences.getPassphraseCacheSubs());
+ mPassphraseCacheSubs.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mPassphraseCacheSubs.setChecked((Boolean) newValue);
+ sPreferences.setPassphraseCacheSubs((Boolean) newValue);
+ return false;
+ }
+ });
+ }
+
+ private static void initializePassphraseCacheTtl(final IntegerListPreference mPassphraseCacheTtl) {
+ mPassphraseCacheTtl.setValue("" + sPreferences.getPassphraseCacheTtl());
+ mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
+ mPassphraseCacheTtl
+ .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mPassphraseCacheTtl.setValue(newValue.toString());
+ mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
+ sPreferences.setPassphraseCacheTtl(Integer.parseInt(newValue.toString()));
+ return false;
+ }
+ });
+ }
+
+ private static void initializeEncryptionAlgorithm(final IntegerListPreference mEncryptionAlgorithm) {
+ int valueIds[] = {PGPEncryptedData.AES_128, PGPEncryptedData.AES_192,
+ PGPEncryptedData.AES_256, PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH,
+ PGPEncryptedData.CAST5, PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES,
+ PGPEncryptedData.IDEA,};
+ String entries[] = {"AES-128", "AES-192", "AES-256", "Blowfish", "Twofish", "CAST5",
+ "DES", "Triple DES", "IDEA",};
+ String values[] = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+ mEncryptionAlgorithm.setEntries(entries);
+ mEncryptionAlgorithm.setEntryValues(values);
+ mEncryptionAlgorithm.setValue("" + sPreferences.getDefaultEncryptionAlgorithm());
+ mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
+ mEncryptionAlgorithm
+ .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mEncryptionAlgorithm.setValue(newValue.toString());
+ mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
+ sPreferences.setDefaultEncryptionAlgorithm(Integer.parseInt(newValue
+ .toString()));
+ return false;
+ }
+ });
+ }
+
+ private static void initializeHashAlgorithm(final IntegerListPreference mHashAlgorithm) {
+ int[] valueIds = new int[]{HashAlgorithmTags.RIPEMD160,
+ HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256,
+ HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512,};
+ String[] entries = new String[]{"RIPEMD-160", "SHA-1", "SHA-224", "SHA-256", "SHA-384",
+ "SHA-512",};
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+ mHashAlgorithm.setEntries(entries);
+ mHashAlgorithm.setEntryValues(values);
+ mHashAlgorithm.setValue("" + sPreferences.getDefaultHashAlgorithm());
+ mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
+ mHashAlgorithm.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mHashAlgorithm.setValue(newValue.toString());
+ mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
+ sPreferences.setDefaultHashAlgorithm(Integer.parseInt(newValue.toString()));
+ return false;
+ }
+ });
+ }
+
+ private static void initializeMessageCompression(final IntegerListPreference mMessageCompression,
+ String[] entries, String[] values) {
+ mMessageCompression.setEntries(entries);
+ mMessageCompression.setEntryValues(values);
+ mMessageCompression.setValue("" + sPreferences.getDefaultMessageCompression());
+ mMessageCompression.setSummary(mMessageCompression.getEntry());
+ mMessageCompression
+ .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mMessageCompression.setValue(newValue.toString());
+ mMessageCompression.setSummary(mMessageCompression.getEntry());
+ sPreferences.setDefaultMessageCompression(Integer.parseInt(newValue
+ .toString()));
+ return false;
+ }
+ });
+ }
+
+ private static void initializeFileCompression
+ (final IntegerListPreference mFileCompression, String[] entries, String[] values) {
+ mFileCompression.setEntries(entries);
+ mFileCompression.setEntryValues(values);
+ mFileCompression.setValue("" + sPreferences.getDefaultFileCompression());
+ mFileCompression.setSummary(mFileCompression.getEntry());
+ mFileCompression.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mFileCompression.setValue(newValue.toString());
+ mFileCompression.setSummary(mFileCompression.getEntry());
+ sPreferences.setDefaultFileCompression(Integer.parseInt(newValue.toString()));
+ return false;
+ }
+ });
+ }
+
+ private static void initializeAsciiArmor(final CheckBoxPreference mAsciiArmor) {
+ mAsciiArmor.setChecked(sPreferences.getDefaultAsciiArmor());
+ mAsciiArmor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mAsciiArmor.setChecked((Boolean) newValue);
+ sPreferences.setDefaultAsciiArmor((Boolean) newValue);
+ return false;
+ }
+ });
+ }
+
+ private static void initializeWriteVersionHeader(final CheckBoxPreference mWriteVersionHeader) {
+ mWriteVersionHeader.setChecked(sPreferences.getWriteVersionHeader());
+ mWriteVersionHeader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mWriteVersionHeader.setChecked((Boolean) newValue);
+ sPreferences.setWriteVersionHeader((Boolean) newValue);
+ return false;
+ }
+ });
+ }
+
+ private static void initializeSearchKeyserver(final CheckBoxPreference mSearchKeyserver) {
+ Preferences.CloudSearchPrefs prefs = sPreferences.getCloudSearchPrefs();
+ mSearchKeyserver.setChecked(prefs.searchKeyserver);
+ mSearchKeyserver.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mSearchKeyserver.setChecked((Boolean) newValue);
+ sPreferences.setSearchKeyserver((Boolean) newValue);
+ return false;
+ }
+ });
+ }
+
+ private static void initializeSearchKeybase(final CheckBoxPreference mSearchKeybase) {
+ Preferences.CloudSearchPrefs prefs = sPreferences.getCloudSearchPrefs();
+ mSearchKeybase.setChecked(prefs.searchKeybase);
+ mSearchKeybase.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mSearchKeybase.setChecked((Boolean) newValue);
+ sPreferences.setSearchKeybase((Boolean) newValue);
+ return false;
+ }
+ });
+ }
+
+ public static String keyserverSummary(Context context) {
+ String[] servers = sPreferences.getKeyServers();
+ String serverSummary = context.getResources().getQuantityString(
+ R.plurals.n_keyservers, servers.length, servers.length);
+ return serverSummary + "; " + context.getString(R.string.label_preferred) + ": " + sPreferences.getPreferredKeyserver();
+ }
+
+ private static void initializeUseDefaultYubikeyPin(final CheckBoxPreference mUseDefaultYubikeyPin) {
+ mUseDefaultYubikeyPin.setChecked(sPreferences.useDefaultYubikeyPin());
+ mUseDefaultYubikeyPin.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mUseDefaultYubikeyPin.setChecked((Boolean) newValue);
+ sPreferences.setUseDefaultYubikeyPin((Boolean) newValue);
+ return false;
+ }
+ });
+ }
+
+ private static void initializeUseNumKeypadForYubikeyPin(final CheckBoxPreference mUseNumKeypadForYubikeyPin) {
+ mUseNumKeypadForYubikeyPin.setChecked(sPreferences.useNumKeypadForYubikeyPin());
+ mUseNumKeypadForYubikeyPin.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mUseNumKeypadForYubikeyPin.setChecked((Boolean) newValue);
+ sPreferences.setUseNumKeypadForYubikeyPin((Boolean) newValue);
+ return false;
+ }
+ });
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsKeyServerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsKeyServerActivity.java
new file mode 100644
index 000000000..080dc2495
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsKeyServerActivity.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.ui.widget.Editor;
+import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
+import org.sufficientlysecure.keychain.ui.widget.KeyServerEditor;
+
+import java.util.Vector;
+
+public class SettingsKeyServerActivity extends BaseActivity implements OnClickListener,
+ EditorListener {
+
+ public static final String EXTRA_KEY_SERVERS = "key_servers";
+
+ private LayoutInflater mInflater;
+ private ViewGroup mEditors;
+ private View mAdd;
+ private View mRotate;
+ private TextView mTitle;
+ private TextView mSummary;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Inflate a "Done"/"Cancel" custom action bar view
+ setFullScreenDialogDoneClose(R.string.btn_save,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ okClicked();
+ }
+ },
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ cancelClicked();
+ }
+ });
+
+ mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ mTitle = (TextView) findViewById(R.id.title);
+ mSummary = (TextView) findViewById(R.id.summary);
+ mSummary.setText(getText(R.string.label_first_keyserver_is_used));
+
+ mTitle.setText(R.string.label_keyservers);
+
+ mEditors = (ViewGroup) findViewById(R.id.editors);
+ mAdd = findViewById(R.id.add);
+ mAdd.setOnClickListener(this);
+
+ mRotate = findViewById(R.id.rotate);
+ mRotate.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Vector<String> servers = serverList();
+ String first = servers.get(0);
+ if (first != null) {
+ servers.remove(0);
+ servers.add(first);
+ String[] dummy = {};
+ makeServerList(servers.toArray(dummy));
+ }
+ }
+ });
+
+ Intent intent = getIntent();
+ String servers[] = intent.getStringArrayExtra(EXTRA_KEY_SERVERS);
+ makeServerList(servers);
+ }
+
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.key_server_preference);
+ }
+
+ private void makeServerList(String[] servers) {
+ if (servers != null) {
+ mEditors.removeAllViews();
+ for (String serv : servers) {
+ KeyServerEditor view = (KeyServerEditor) mInflater.inflate(
+ R.layout.key_server_editor, mEditors, false);
+ view.setEditorListener(this);
+ view.setValue(serv);
+ mEditors.addView(view);
+ }
+ }
+ }
+
+ public void onDeleted(Editor editor, boolean wasNewItem) {
+ // nothing to do
+ }
+
+ @Override
+ public void onEdited() {
+
+ }
+
+ public void onClick(View v) {
+ KeyServerEditor view = (KeyServerEditor) mInflater.inflate(R.layout.key_server_editor,
+ mEditors, false);
+ view.setEditorListener(this);
+ mEditors.addView(view);
+ }
+
+ private void cancelClicked() {
+ setResult(RESULT_CANCELED, null);
+ finish();
+ }
+
+ private Vector<String> serverList() {
+ Vector<String> servers = new Vector<>();
+ for (int i = 0; i < mEditors.getChildCount(); ++i) {
+ KeyServerEditor editor = (KeyServerEditor) mEditors.getChildAt(i);
+ String tmp = editor.getValue();
+ if (tmp.length() > 0) {
+ servers.add(tmp);
+ }
+ }
+ return servers;
+ }
+
+ private void okClicked() {
+ Intent data = new Intent();
+ Vector<String> servers = new Vector<>();
+ for (int i = 0; i < mEditors.getChildCount(); ++i) {
+ KeyServerEditor editor = (KeyServerEditor) mEditors.getChildAt(i);
+ String tmp = editor.getValue();
+ if (tmp.length() > 0) {
+ servers.add(tmp);
+ }
+ }
+ String[] dummy = new String[0];
+ data.putExtra(EXTRA_KEY_SERVERS, servers.toArray(dummy));
+ setResult(RESULT_OK, data);
+ finish();
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
index 497486a5e..e19793fd5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
@@ -24,7 +24,6 @@ import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.NavUtils;
-import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@@ -34,17 +33,17 @@ import android.widget.Toast;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
/**
* Sends the selected public key to a keyserver
*/
-public class UploadKeyActivity extends ActionBarActivity {
+public class UploadKeyActivity extends BaseActivity {
private View mUploadButton;
private Spinner mKeyServerSpinner;
@@ -54,12 +53,10 @@ public class UploadKeyActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.upload_key_activity);
-
mUploadButton = findViewById(R.id.upload_key_action_upload);
mKeyServerSpinner = (Spinner) findViewById(R.id.upload_key_keyserver);
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+ ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item, Preferences.getPreferences(this)
.getKeyServers()
);
@@ -86,6 +83,11 @@ public class UploadKeyActivity extends ActionBarActivity {
}
}
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.upload_key_activity);
+ }
+
private void uploadKey() {
// Send all information needed to service to upload key in other thread
Intent intent = new Intent(this, KeychainIntentService.class);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java
index 34c08a6c7..a80503591 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java
@@ -27,9 +27,6 @@ import android.support.v4.app.NavUtils;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
import android.view.MenuItem;
import android.view.View;
@@ -37,19 +34,18 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.pgp.WrappedSignature;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log;
import java.util.Date;
-public class ViewCertActivity extends ActionBarActivity
+public class ViewCertActivity extends BaseActivity
implements LoaderManager.LoaderCallbacks<Cursor> {
// These are the rows that we will retrieve.
@@ -86,8 +82,6 @@ public class ViewCertActivity extends ActionBarActivity
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
- setContentView(R.layout.view_cert_activity);
-
mSigneeKey = (TextView) findViewById(R.id.signee_key);
mSigneeUid = (TextView) findViewById(R.id.signee_uid);
mAlgorithm = (TextView) findViewById(R.id.algorithm);
@@ -113,6 +107,11 @@ public class ViewCertActivity extends ActionBarActivity
}
@Override
+ protected void initLayout() {
+ setContentView(R.layout.view_cert_activity);
+ }
+
+ @Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
index a7ba4accf..e1a8981c4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -19,9 +19,10 @@
package org.sufficientlysecure.keychain.ui;
import android.annotation.TargetApi;
+import android.app.ActivityOptions;
import android.content.Intent;
import android.database.Cursor;
-import android.graphics.PorterDuff;
+import android.graphics.Bitmap;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
@@ -33,41 +34,45 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
+import android.provider.Settings;
+import android.support.v4.app.ActivityCompat;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.CardView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.widget.ImageButton;
import android.widget.ImageView;
-import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
+import com.getbase.floatingactionbutton.FloatingActionButton;
+
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.util.ContactHelper;
-import org.sufficientlysecure.keychain.util.ExportHelper;
-import org.sufficientlysecure.keychain.util.Preferences;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
-import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout;
-import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout.TabColorizer;
-import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
+import org.sufficientlysecure.keychain.ui.widget.AspectRatioImageView;
+import org.sufficientlysecure.keychain.util.ContactHelper;
+import org.sufficientlysecure.keychain.util.ExportHelper;
+import org.sufficientlysecure.keychain.util.Log;
import java.util.Date;
import java.util.HashMap;
-public class ViewKeyActivity extends ActionBarActivity implements
+public class ViewKeyActivity extends BaseActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
ExportHelper mExportHelper;
@@ -75,20 +80,18 @@ public class ViewKeyActivity extends ActionBarActivity implements
protected Uri mDataUri;
- public static final String EXTRA_SELECTED_TAB = "selected_tab";
- public static final int TAB_MAIN = 0;
- public static final int TAB_SHARE = 1;
- public static final int TAB_TRUST = 2;
-
- // view
- private ViewPager mViewPager;
- private SlidingTabLayout mSlidingTabLayout;
- private PagerTabStripAdapter mTabsAdapter;
-
- private LinearLayout mStatusLayout;
+ private TextView mName;
private TextView mStatusText;
private ImageView mStatusImage;
- private View mStatusDivider;
+ private RelativeLayout mBigToolbar;
+
+ private ImageButton mActionEncryptFile;
+ private ImageButton mActionEncryptText;
+ private ImageButton mActionNfc;
+ private FloatingActionButton mFab;
+ private AspectRatioImageView mPhoto;
+ private ImageView mQrCode;
+ private CardView mQrCodeLayout;
// NFC
private NfcAdapter mNfcAdapter;
@@ -99,6 +102,10 @@ public class ViewKeyActivity extends ActionBarActivity implements
private static final int LOADER_ID_UNIFIED = 0;
+ private boolean mIsSecret = false;
+ private boolean mHasEncrypt = false;
+ private boolean mIsVerified = false;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -106,39 +113,20 @@ public class ViewKeyActivity extends ActionBarActivity implements
mExportHelper = new ExportHelper(this);
mProviderHelper = new ProviderHelper(this);
- // let the actionbar look like Android's contact app
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setIcon(android.R.color.transparent);
- actionBar.setHomeButtonEnabled(true);
-
- setContentView(R.layout.view_key_activity);
+ setTitle(null);
- mStatusLayout = (LinearLayout) findViewById(R.id.view_key_status_layout);
- mStatusText = (TextView) findViewById(R.id.view_key_status_text);
+ mName = (TextView) findViewById(R.id.view_key_name);
+ mStatusText = (TextView) findViewById(R.id.view_key_status);
mStatusImage = (ImageView) findViewById(R.id.view_key_status_image);
- mStatusDivider = findViewById(R.id.view_key_status_divider);
-
- mViewPager = (ViewPager) findViewById(R.id.view_key_pager);
- mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.view_key_sliding_tab_layout);
-
- mSlidingTabLayout.setCustomTabColorizer(new TabColorizer() {
- @Override
- public int getIndicatorColor(int position) {
- return 0xFFAA66CC;
- }
-
- @Override
- public int getDividerColor(int position) {
- return 0;
- }
- });
+ mBigToolbar = (RelativeLayout) findViewById(R.id.toolbar_big);
- int switchToTab = TAB_MAIN;
- Intent intent = getIntent();
- if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) {
- switchToTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
- }
+ mActionEncryptFile = (ImageButton) findViewById(R.id.view_key_action_encrypt_files);
+ mActionEncryptText = (ImageButton) findViewById(R.id.view_key_action_encrypt_text);
+ mActionNfc = (ImageButton) findViewById(R.id.view_key_action_nfc);
+ mFab = (FloatingActionButton) findViewById(R.id.fab);
+ mPhoto = (AspectRatioImageView) findViewById(R.id.view_key_photo);
+ mQrCode = (ImageView) findViewById(R.id.view_key_qr_code);
+ mQrCodeLayout = (CardView) findViewById(R.id.view_key_qr_code_layout);
mDataUri = getIntent().getData();
if (mDataUri == null) {
@@ -158,39 +146,77 @@ public class ViewKeyActivity extends ActionBarActivity implements
Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+ mActionEncryptFile.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ encrypt(mDataUri, false);
+ }
+ });
+ mActionEncryptText.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ encrypt(mDataUri, true);
+ }
+ });
+
+ mFab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mIsSecret) {
+ startSafeSlinger(mDataUri);
+ } else {
+ scanQrCode();
+ }
+ }
+ });
+
+ mQrCodeLayout.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showQrCodeDialog();
+ }
+ });
+
+ mActionNfc.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ invokeNfcBeam();
+ }
+ });
+
+
// Prepare the loaders. Either re-connect with an existing ones,
// or start new ones.
getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
initNfc(mDataUri);
- initTabs(mDataUri);
-
- // switch to tab selected by extra
- mViewPager.setCurrentItem(switchToTab);
+ startFragment(savedInstanceState, mDataUri);
}
- private void initTabs(Uri dataUri) {
- mTabsAdapter = new PagerTabStripAdapter(this);
- mViewPager.setAdapter(mTabsAdapter);
-
- Bundle mainBundle = new Bundle();
- mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
- mTabsAdapter.addTab(ViewKeyMainFragment.class,
- mainBundle, getString(R.string.key_view_tab_main));
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.view_key_activity);
+ }
- Bundle shareBundle = new Bundle();
- shareBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
- mTabsAdapter.addTab(ViewKeyShareFragment.class,
- shareBundle, getString(R.string.key_view_tab_share));
+ private void startFragment(Bundle savedInstanceState, Uri dataUri) {
+ // However, if we're being restored from a previous state,
+ // then we don't need to do anything and should return or else
+ // we could end up with overlapping fragments.
+ if (savedInstanceState != null) {
+ return;
+ }
- Bundle trustBundle = new Bundle();
- trustBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
- mTabsAdapter.addTab(ViewKeyTrustFragment.class, trustBundle,
- getString(R.string.key_view_tab_trust));
+ // Create an instance of the fragment
+ ViewKeyFragment frag = ViewKeyFragment.newInstance(dataUri);
- // update layout after operations
- mSlidingTabLayout.setViewPager(mViewPager);
+ // Add the fragment to the 'fragment_container' FrameLayout
+ // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.view_key_fragment, frag)
+ .commitAllowingStateLoss();
+ // do it immediately!
+ getSupportFragmentManager().executePendingTransactions();
}
@Override
@@ -206,7 +232,7 @@ public class ViewKeyActivity extends ActionBarActivity implements
try {
switch (item.getItemId()) {
case android.R.id.home: {
- Intent homeIntent = new Intent(this, KeyListActivity.class);
+ Intent homeIntent = new Intent(this, MainActivity.class);
homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);
return true;
@@ -220,9 +246,26 @@ public class ViewKeyActivity extends ActionBarActivity implements
return true;
}
case R.id.menu_key_view_advanced: {
- Intent advancedIntent = new Intent(this, ViewKeyAdvancedActivity.class);
+ Intent advancedIntent = new Intent(this, ViewKeyAdvActivity.class);
advancedIntent.setData(mDataUri);
startActivity(advancedIntent);
+ return true;
+ }
+ case R.id.menu_key_view_refresh: {
+ try {
+ updateFromKeyserver(mDataUri, mProviderHelper);
+ } catch (ProviderHelper.NotFoundException e) {
+ Notify.showNotify(this, R.string.error_key_not_found, Notify.Style.ERROR);
+ }
+ return true;
+ }
+ case R.id.menu_key_view_edit: {
+ editKey(mDataUri);
+ return true;
+ }
+ case R.id.menu_key_view_certify_fingerprint: {
+ certifyFingeprint(mDataUri);
+ return true;
}
}
} catch (ProviderHelper.NotFoundException e) {
@@ -232,6 +275,75 @@ public class ViewKeyActivity extends ActionBarActivity implements
return super.onOptionsItemSelected(item);
}
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MenuItem editKey = menu.findItem(R.id.menu_key_view_edit);
+ editKey.setVisible(mIsSecret);
+ MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint);
+ certifyFingerprint.setVisible(!mIsSecret && !mIsVerified);
+
+ return true;
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private void invokeNfcBeam() {
+ // Check for available NFC Adapter
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
+ if (mNfcAdapter == null || !mNfcAdapter.isEnabled()) {
+ Notify.createNotify(this, R.string.error_nfc_needed, Notify.LENGTH_LONG, Notify.Style.ERROR, new Notify.ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intentSettings = new Intent(Settings.ACTION_NFC_SETTINGS);
+ startActivity(intentSettings);
+ }
+ }, R.string.menu_nfc_preferences).show();
+
+ return;
+ }
+
+ if (!mNfcAdapter.isNdefPushEnabled()) {
+ Notify.createNotify(this, R.string.error_beam_needed, Notify.LENGTH_LONG, Notify.Style.ERROR, new Notify.ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intentSettings = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
+ startActivity(intentSettings);
+ }
+ }, R.string.menu_beam_preferences).show();
+
+ return;
+ }
+
+ mNfcAdapter.invokeBeam(this);
+ }
+
+ private void scanQrCode() {
+ Intent scanQrCode = new Intent(this, QrCodeScanActivity.class);
+ scanQrCode.setAction(QrCodeScanActivity.ACTION_SCAN_WITH_RESULT);
+ startActivityForResult(scanQrCode, 0);
+ }
+
+ private void certifyFingeprint(Uri dataUri) {
+ Intent intent = new Intent(this, CertifyFingerprintActivity.class);
+ intent.setData(dataUri);
+ startActivityForResult(intent, 0);
+ }
+
+ private void showQrCodeDialog() {
+ Intent qrCodeIntent = new Intent(this, QrCodeViewActivity.class);
+
+ // create the transition animation - the images in the layouts
+ // of both activities are defined with android:transitionName="qr_code"
+ Bundle opts = null;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ ActivityOptions options = ActivityOptions
+ .makeSceneTransitionAnimation(this, mQrCodeLayout, "qr_code");
+ opts = options.toBundle();
+ }
+
+ qrCodeIntent.setData(mDataUri);
+ ActivityCompat.startActivity(this, qrCodeIntent, opts);
+ }
+
private void exportToFile(Uri dataUri, ExportHelper exportHelper, ProviderHelper providerHelper)
throws ProviderHelper.NotFoundException {
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri);
@@ -273,6 +385,101 @@ public class ViewKeyActivity extends ActionBarActivity implements
}
}
+ private void encrypt(Uri dataUri, boolean text) {
+ // If there is no encryption key, don't bother.
+ if (!mHasEncrypt) {
+ Notify.showNotify(this, R.string.error_no_encrypt_subkey, Notify.Style.ERROR);
+ return;
+ }
+ try {
+ long keyId = new ProviderHelper(this)
+ .getCachedPublicKeyRing(dataUri)
+ .extractOrGetMasterKeyId();
+ long[] encryptionKeyIds = new long[]{keyId};
+ Intent intent;
+ if (text) {
+ intent = new Intent(this, EncryptTextActivity.class);
+ intent.setAction(EncryptTextActivity.ACTION_ENCRYPT_TEXT);
+ intent.putExtra(EncryptTextActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
+ } else {
+ intent = new Intent(this, EncryptFilesActivity.class);
+ intent.setAction(EncryptFilesActivity.ACTION_ENCRYPT_DATA);
+ intent.putExtra(EncryptFilesActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
+ }
+ // used instead of startActivity set actionbar based on callingPackage
+ startActivityForResult(intent, 0);
+ } catch (PgpKeyNotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ }
+ }
+
+ private void updateFromKeyserver(Uri dataUri, ProviderHelper providerHelper)
+ throws ProviderHelper.NotFoundException {
+ byte[] blob = (byte[]) providerHelper.getGenericData(
+ KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
+ KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
+ String fingerprint = KeyFormattingUtils.convertFingerprintToHex(blob);
+
+ Intent queryIntent = new Intent(this, ImportKeysActivity.class);
+ queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT);
+ queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint);
+
+ startActivityForResult(queryIntent, 0);
+ }
+
+ private void editKey(Uri dataUri) {
+ Intent editIntent = new Intent(this, EditKeyActivity.class);
+ editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri));
+ startActivityForResult(editIntent, 0);
+ }
+
+ private void startSafeSlinger(Uri dataUri) {
+ long keyId = 0;
+ try {
+ keyId = new ProviderHelper(this)
+ .getCachedPublicKeyRing(dataUri)
+ .extractOrGetMasterKeyId();
+ } catch (PgpKeyNotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ }
+ Intent safeSlingerIntent = new Intent(this, SafeSlingerActivity.class);
+ safeSlingerIntent.putExtra(SafeSlingerActivity.EXTRA_MASTER_KEY_ID, keyId);
+ startActivityForResult(safeSlingerIntent, 0);
+ }
+
+
+ /**
+ * Load QR Code asynchronously and with a fade in animation
+ *
+ * @param fingerprint
+ */
+ private void loadQrCode(final String fingerprint) {
+ AsyncTask<Void, Void, Bitmap> loadTask =
+ new AsyncTask<Void, Void, Bitmap>() {
+ protected Bitmap doInBackground(Void... unused) {
+ String qrCodeContent = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
+ // render with minimal size
+ return QrCodeUtils.getQRCodeBitmap(qrCodeContent, 0);
+ }
+
+ protected void onPostExecute(Bitmap qrCode) {
+ // scale the image up to our actual size. we do this in code rather
+ // than let the ImageView do this because we don't require filtering.
+ Bitmap scaled = Bitmap.createScaledBitmap(qrCode,
+ mQrCode.getHeight(), mQrCode.getHeight(),
+ false);
+ mQrCode.setImageBitmap(scaled);
+
+ // simple fade-in animation
+ AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
+ anim.setDuration(200);
+ mQrCode.startAnimation(anim);
+ }
+ };
+
+ loadTask.execute();
+ }
+
/**
* NFC: Initialize NFC sharing if OS and device supports it
*/
@@ -363,25 +570,34 @@ public class ViewKeyActivity extends ActionBarActivity implements
}
};
- static final String[] UNIFIED_PROJECTION = new String[]{
+ // These are the rows that we will retrieve.
+ static final String[] PROJECTION = new String[]{
KeychainContract.KeyRings._ID,
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID,
KeychainContract.KeyRings.IS_REVOKED,
KeychainContract.KeyRings.EXPIRY,
-
+ KeychainContract.KeyRings.VERIFIED,
+ KeychainContract.KeyRings.HAS_ANY_SECRET,
+ KeychainContract.KeyRings.FINGERPRINT,
+ KeychainContract.KeyRings.HAS_ENCRYPT
};
- static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
- static final int INDEX_UNIFIED_USER_ID = 2;
- static final int INDEX_UNIFIED_IS_REVOKED = 3;
- static final int INDEX_UNIFIED_EXPIRY = 4;
+
+ static final int INDEX_MASTER_KEY_ID = 1;
+ static final int INDEX_USER_ID = 2;
+ static final int INDEX_IS_REVOKED = 3;
+ static final int INDEX_EXPIRY = 4;
+ static final int INDEX_VERIFIED = 5;
+ static final int INDEX_HAS_ANY_SECRET = 6;
+ static final int INDEX_FINGERPRINT = 7;
+ static final int INDEX_HAS_ENCRYPT = 8;
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) {
case LOADER_ID_UNIFIED: {
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
- return new CursorLoader(this, baseUri, UNIFIED_PROJECTION, null, null, null);
+ return new CursorLoader(this, baseUri, PROJECTION, null, null, null);
}
default:
@@ -404,36 +620,136 @@ public class ViewKeyActivity extends ActionBarActivity implements
case LOADER_ID_UNIFIED: {
if (data.moveToFirst()) {
// get name, email, and comment from USER_ID
- String[] mainUserId = KeyRing.splitUserId(data.getString(INDEX_UNIFIED_USER_ID));
+ String[] mainUserId = KeyRing.splitUserId(data.getString(INDEX_USER_ID));
if (mainUserId[0] != null) {
- setTitle(mainUserId[0]);
+ mName.setText(mainUserId[0]);
} else {
- setTitle(R.string.user_id_no_name);
+ mName.setText(R.string.user_id_no_name);
}
- // get key id from MASTER_KEY_ID
- long masterKeyId = data.getLong(INDEX_UNIFIED_MASTER_KEY_ID);
- getSupportActionBar().setSubtitle(KeyFormattingUtils.beautifyKeyIdWithPrefix(this, masterKeyId));
+ String fingerprint = KeyFormattingUtils.convertFingerprintToHex(data.getBlob(INDEX_FINGERPRINT));
+
+ mIsSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
+ mHasEncrypt = data.getInt(INDEX_HAS_ENCRYPT) != 0;
+ boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
+ boolean isExpired = !data.isNull(INDEX_EXPIRY)
+ && new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
+ mIsVerified = data.getInt(INDEX_VERIFIED) > 0;
- boolean isRevoked = data.getInt(INDEX_UNIFIED_IS_REVOKED) > 0;
- boolean isExpired = !data.isNull(INDEX_UNIFIED_EXPIRY)
- && new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000).before(new Date());
+ // re-create options menu based on mIsSecret, mIsVerified
+ supportInvalidateOptionsMenu();
+
+ AsyncTask<String, Void, Bitmap> photoTask =
+ new AsyncTask<String, Void, Bitmap>() {
+ protected Bitmap doInBackground(String... fingerprint) {
+ return ContactHelper.photoFromFingerprint(getContentResolver(), fingerprint[0]);
+ }
+
+ protected void onPostExecute(Bitmap photo) {
+ mPhoto.setImageBitmap(photo);
+ mPhoto.setVisibility(View.VISIBLE);
+ }
+ };
// Note: order is important
+ int color;
if (isRevoked) {
mStatusText.setText(R.string.view_key_revoked);
- KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, KeyFormattingUtils.STATE_REVOKED);
- mStatusDivider.setVisibility(View.VISIBLE);
- mStatusLayout.setVisibility(View.VISIBLE);
+ mStatusImage.setVisibility(View.VISIBLE);
+ KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
+ KeyFormattingUtils.STATE_REVOKED, R.color.icons, true);
+ color = getResources().getColor(R.color.android_red_light);
+
+ mActionEncryptFile.setVisibility(View.GONE);
+ mActionEncryptText.setVisibility(View.GONE);
+ mActionNfc.setVisibility(View.GONE);
+ mFab.setVisibility(View.GONE);
+ mQrCodeLayout.setVisibility(View.GONE);
} else if (isExpired) {
- mStatusText.setText(R.string.view_key_expired);
- KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, KeyFormattingUtils.STATE_EXPIRED);
- mStatusDivider.setVisibility(View.VISIBLE);
- mStatusLayout.setVisibility(View.VISIBLE);
+ if (mIsSecret) {
+ mStatusText.setText(R.string.view_key_expired_secret);
+ } else {
+ mStatusText.setText(R.string.view_key_expired);
+ }
+ mStatusImage.setVisibility(View.VISIBLE);
+ KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
+ KeyFormattingUtils.STATE_EXPIRED, R.color.icons, true);
+ color = getResources().getColor(R.color.android_red_light);
+
+ mActionEncryptFile.setVisibility(View.GONE);
+ mActionEncryptText.setVisibility(View.GONE);
+ mActionNfc.setVisibility(View.GONE);
+ mFab.setVisibility(View.GONE);
+ mQrCodeLayout.setVisibility(View.GONE);
+ } else if (mIsSecret) {
+ mStatusText.setText(R.string.view_key_my_key);
+ mStatusImage.setVisibility(View.GONE);
+ color = getResources().getColor(R.color.primary);
+ photoTask.execute(fingerprint);
+ loadQrCode(fingerprint);
+ mQrCodeLayout.setVisibility(View.VISIBLE);
+
+ // and place leftOf qr code
+ RelativeLayout.LayoutParams nameParams = (RelativeLayout.LayoutParams)
+ mName.getLayoutParams();
+ // remove right margin
+ nameParams.setMargins(FormattingUtils.dpToPx(this, 48), 0, 0, 0);
+ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ nameParams.setMarginEnd(0);
+ }
+ nameParams.addRule(RelativeLayout.LEFT_OF, R.id.view_key_qr_code_layout);
+ mName.setLayoutParams(nameParams);
+
+ RelativeLayout.LayoutParams statusParams = (RelativeLayout.LayoutParams)
+ mStatusText.getLayoutParams();
+ statusParams.setMargins(FormattingUtils.dpToPx(this, 48), 0, 0, 0);
+ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ statusParams.setMarginEnd(0);
+ }
+ statusParams.addRule(RelativeLayout.LEFT_OF, R.id.view_key_qr_code_layout);
+ mStatusText.setLayoutParams(statusParams);
+
+ mActionEncryptFile.setVisibility(View.VISIBLE);
+ mActionEncryptText.setVisibility(View.VISIBLE);
+
+ // invokeBeam is available from API 21
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ mActionNfc.setVisibility(View.VISIBLE);
+ } else {
+ mActionNfc.setVisibility(View.GONE);
+ }
+ mFab.setVisibility(View.VISIBLE);
+ mFab.setIconDrawable(getResources().getDrawable(R.drawable.ic_repeat_white_24dp));
} else {
- mStatusDivider.setVisibility(View.GONE);
- mStatusLayout.setVisibility(View.GONE);
+ mActionEncryptFile.setVisibility(View.VISIBLE);
+ mActionEncryptText.setVisibility(View.VISIBLE);
+ mQrCodeLayout.setVisibility(View.GONE);
+ mActionNfc.setVisibility(View.GONE);
+
+ if (mIsVerified) {
+ mStatusText.setText(R.string.view_key_verified);
+ mStatusImage.setVisibility(View.VISIBLE);
+ KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
+ KeyFormattingUtils.STATE_VERIFIED, R.color.icons, true);
+ color = getResources().getColor(R.color.primary);
+ photoTask.execute(fingerprint);
+
+ mFab.setVisibility(View.GONE);
+ } else {
+ mStatusText.setText(R.string.view_key_unverified);
+ mStatusImage.setVisibility(View.VISIBLE);
+ KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText,
+ KeyFormattingUtils.STATE_UNVERIFIED, R.color.icons, true);
+ color = getResources().getColor(R.color.android_orange_light);
+
+ mFab.setVisibility(View.VISIBLE);
+ }
}
+ mToolbar.setBackgroundColor(color);
+ mStatusBar.setBackgroundColor(color);
+ mBigToolbar.setBackgroundColor(color);
+
+ mStatusImage.setAlpha(80);
break;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java
new file mode 100644
index 000000000..894529cc5
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.support.v4.view.ViewPager;
+import android.view.View;
+import android.widget.Toast;
+
+import com.astuetz.PagerSlidingTabStrip;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.OperationResult;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.ContactHelper;
+import org.sufficientlysecure.keychain.util.ExportHelper;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.Date;
+
+public class ViewKeyAdvActivity extends BaseActivity implements
+ LoaderManager.LoaderCallbacks<Cursor> {
+
+ ExportHelper mExportHelper;
+ ProviderHelper mProviderHelper;
+
+ protected Uri mDataUri;
+
+ public static final String EXTRA_SELECTED_TAB = "selected_tab";
+ public static final int TAB_MAIN = 0;
+ public static final int TAB_SHARE = 1;
+
+ // view
+ private ViewPager mViewPager;
+ private PagerSlidingTabStrip mSlidingTabLayout;
+ private PagerTabStripAdapter mTabsAdapter;
+
+ private static final int LOADER_ID_UNIFIED = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setFullScreenDialogClose(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+
+ mExportHelper = new ExportHelper(this);
+ mProviderHelper = new ProviderHelper(this);
+
+ mViewPager = (ViewPager) findViewById(R.id.view_key_pager);
+ mSlidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.view_key_sliding_tab_layout);
+
+ int switchToTab = TAB_MAIN;
+ Intent intent = getIntent();
+ if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) {
+ switchToTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
+ }
+
+ mDataUri = getIntent().getData();
+ if (mDataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be uri of key!");
+ finish();
+ return;
+ }
+ if (mDataUri.getHost().equals(ContactsContract.AUTHORITY)) {
+ mDataUri = ContactHelper.dataUriFromContactUri(this, mDataUri);
+ if (mDataUri == null) {
+ Log.e(Constants.TAG, "Contact Data missing. Should be uri of key!");
+ Toast.makeText(this, R.string.error_contacts_key_id_missing, Toast.LENGTH_LONG).show();
+ finish();
+ return;
+ }
+ }
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
+
+ initTabs(mDataUri);
+
+ // switch to tab selected by extra
+ mViewPager.setCurrentItem(switchToTab);
+ }
+
+ @Override
+ protected void initLayout() {
+ setContentView(R.layout.view_key_adv_activity);
+ }
+
+ private void initTabs(Uri dataUri) {
+ mTabsAdapter = new PagerTabStripAdapter(this);
+ mViewPager.setAdapter(mTabsAdapter);
+
+ Bundle mainBundle = new Bundle();
+ mainBundle.putParcelable(ViewKeyAdvMainFragment.ARG_DATA_URI, dataUri);
+ mTabsAdapter.addTab(ViewKeyAdvMainFragment.class,
+ mainBundle, getString(R.string.key_view_tab_main));
+
+ Bundle shareBundle = new Bundle();
+ shareBundle.putParcelable(ViewKeyAdvMainFragment.ARG_DATA_URI, dataUri);
+ mTabsAdapter.addTab(ViewKeyAdvShareFragment.class,
+ shareBundle, getString(R.string.key_view_tab_share));
+
+ Bundle keysBundle = new Bundle();
+ keysBundle.putParcelable(ViewKeyAdvSubkeysFragment.ARG_DATA_URI, dataUri);
+ mTabsAdapter.addTab(ViewKeyAdvSubkeysFragment.class,
+ keysBundle, getString(R.string.key_view_tab_keys));
+
+ Bundle certsBundle = new Bundle();
+ certsBundle.putParcelable(ViewKeyAdvCertsFragment.ARG_DATA_URI, dataUri);
+ mTabsAdapter.addTab(ViewKeyAdvCertsFragment.class,
+ certsBundle, getString(R.string.key_view_tab_certs));
+
+ Bundle trustBundle = new Bundle();
+ trustBundle.putParcelable(ViewKeyTrustFragment.ARG_DATA_URI, dataUri);
+ mTabsAdapter.addTab(ViewKeyTrustFragment.class,
+ trustBundle, getString(R.string.key_view_tab_keybase));
+
+ // update layout after operations
+ mSlidingTabLayout.setViewPager(mViewPager);
+ }
+
+ // These are the rows that we will retrieve.
+ static final String[] PROJECTION = new String[]{
+ KeychainContract.KeyRings._ID,
+ KeychainContract.KeyRings.MASTER_KEY_ID,
+ KeychainContract.KeyRings.USER_ID,
+ KeychainContract.KeyRings.IS_REVOKED,
+ KeychainContract.KeyRings.EXPIRY,
+ KeychainContract.KeyRings.VERIFIED,
+ KeychainContract.KeyRings.HAS_ANY_SECRET
+ };
+
+ static final int INDEX_MASTER_KEY_ID = 1;
+ static final int INDEX_USER_ID = 2;
+ static final int INDEX_IS_REVOKED = 3;
+ static final int INDEX_EXPIRY = 4;
+ static final int INDEX_VERIFIED = 5;
+ static final int INDEX_HAS_ANY_SECRET = 6;
+
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ switch (id) {
+ case LOADER_ID_UNIFIED: {
+ Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
+ return new CursorLoader(this, baseUri, PROJECTION, null, null, null);
+ }
+
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ /* TODO better error handling? May cause problems when a key is deleted,
+ * because the notification triggers faster than the activity closes.
+ */
+ // Avoid NullPointerExceptions...
+ if (data.getCount() == 0) {
+ return;
+ }
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ switch (loader.getId()) {
+ case LOADER_ID_UNIFIED: {
+ if (data.moveToFirst()) {
+ // get name, email, and comment from USER_ID
+ String[] mainUserId = KeyRing.splitUserId(data.getString(INDEX_USER_ID));
+ if (mainUserId[0] != null) {
+ setTitle(mainUserId[0]);
+ } else {
+ setTitle(R.string.user_id_no_name);
+ }
+
+ // get key id from MASTER_KEY_ID
+ long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID);
+ getSupportActionBar().setSubtitle(KeyFormattingUtils.beautifyKeyIdWithPrefix(this, masterKeyId));
+
+ boolean isSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
+ boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
+ boolean isExpired = !data.isNull(INDEX_EXPIRY)
+ && new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
+ boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
+
+ // Note: order is important
+ int color;
+ if (isRevoked || isExpired) {
+ color = getResources().getColor(R.color.android_red_light);
+ } else if (isSecret) {
+ color = getResources().getColor(R.color.primary);
+ } else {
+ if (isVerified) {
+ color = getResources().getColor(R.color.primary);
+ } else {
+ color = getResources().getColor(R.color.android_orange_light);
+ }
+ }
+ mToolbar.setBackgroundColor(color);
+ mStatusBar.setBackgroundColor(color);
+ mSlidingTabLayout.setBackgroundColor(color);
+
+ break;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // if a result has been returned, display a notify
+ if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
+ OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
+ result.createNotify(this).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvCertsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvCertsFragment.java
new file mode 100644
index 000000000..90d7a400f
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvCertsFragment.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.support.v4.widget.CursorAdapter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.TextView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.pgp.WrappedSignature;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainDatabase;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.Log;
+
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
+
+
+public class ViewKeyAdvCertsFragment extends LoaderFragment implements
+ LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
+
+ public static final String ARG_DATA_URI = "data_uri";
+
+ private StickyListHeadersListView mStickyList;
+ private CertListAdapter mCertsAdapter;
+
+ private Uri mDataUriCerts;
+
+ // These are the rows that we will retrieve.
+ static final String[] CERTS_PROJECTION = new String[]{
+ KeychainContract.Certs._ID,
+ KeychainContract.Certs.MASTER_KEY_ID,
+ KeychainContract.Certs.VERIFIED,
+ KeychainContract.Certs.TYPE,
+ KeychainContract.Certs.RANK,
+ KeychainContract.Certs.KEY_ID_CERTIFIER,
+ KeychainContract.Certs.USER_ID,
+ KeychainContract.Certs.SIGNER_UID
+ };
+
+ // sort by our user id,
+ static final String CERTS_SORT_ORDER =
+ KeychainDatabase.Tables.CERTS + "." + KeychainContract.Certs.RANK + " ASC, "
+ + KeychainContract.Certs.VERIFIED + " DESC, "
+ + KeychainDatabase.Tables.CERTS + "." + KeychainContract.Certs.TYPE + " DESC, "
+ + KeychainContract.Certs.SIGNER_UID + " ASC";
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static ViewKeyAdvCertsFragment newInstance(Uri dataUri) {
+ ViewKeyAdvCertsFragment frag = new ViewKeyAdvCertsFragment();
+
+ Bundle args = new Bundle();
+ args.putParcelable(ARG_DATA_URI, dataUri);
+
+ frag.setArguments(args);
+ return frag;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
+ View root = super.onCreateView(inflater, superContainer, savedInstanceState);
+ View view = inflater.inflate(R.layout.view_key_adv_certs_fragment, getContainer());
+
+ mStickyList = (StickyListHeadersListView) view.findViewById(R.id.certs_list);
+
+ return root;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ mDataUriCerts = KeychainContract.Certs.buildCertsUri(dataUri);
+
+ mStickyList.setAreHeadersSticky(true);
+ mStickyList.setDrawingListUnderStickyHeader(false);
+ mStickyList.setOnItemClickListener(this);
+
+ mStickyList.setEmptyView(getActivity().findViewById(R.id.empty));
+
+ // Create an empty adapter we will use to display the loaded data.
+ mCertsAdapter = new CertListAdapter(getActivity(), null);
+ mStickyList.setAdapter(mCertsAdapter);
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getLoaderManager().initLoader(0, null, this);
+ }
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ setContentShown(false);
+
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), mDataUriCerts,
+ CERTS_PROJECTION, null, null, CERTS_SORT_ORDER);
+
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ // Avoid NullPointerExceptions, if we get an empty result set.
+ if (data.getCount() == 0) {
+ return;
+ }
+
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ mCertsAdapter.swapCursor(data);
+ mStickyList.setAdapter(mCertsAdapter);
+
+ // TODO: maybe show not before both are loaded!
+ setContentShown(true);
+ }
+
+ /**
+ * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
+ * We need to make sure we are no longer using it.
+ */
+ public void onLoaderReset(Loader<Cursor> loader) {
+ mCertsAdapter.swapCursor(null);
+ }
+
+ /**
+ * On click on item, start key view activity
+ */
+ @Override
+ public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
+ if (view.getTag(R.id.tag_mki) != null) {
+ long masterKeyId = (Long) view.getTag(R.id.tag_mki);
+ long rank = (Long) view.getTag(R.id.tag_rank);
+ long certifierId = (Long) view.getTag(R.id.tag_certifierId);
+
+ Intent viewIntent = new Intent(getActivity(), ViewCertActivity.class);
+ viewIntent.setData(KeychainContract.Certs.buildCertsSpecificUri(
+ masterKeyId, rank, certifierId));
+ startActivity(viewIntent);
+ }
+ }
+
+
+ /**
+ * Implements StickyListHeadersAdapter from library
+ */
+ private class CertListAdapter extends CursorAdapter implements StickyListHeadersAdapter {
+ private LayoutInflater mInflater;
+ private int mIndexMasterKeyId, mIndexUserId, mIndexRank;
+ private int mIndexSignerKeyId, mIndexSignerUserId;
+ private int mIndexVerified, mIndexType;
+
+ public CertListAdapter(Context context, Cursor c) {
+ super(context, c, 0);
+
+ mInflater = LayoutInflater.from(context);
+ initIndex(c);
+ }
+
+ @Override
+ public Cursor swapCursor(Cursor newCursor) {
+ initIndex(newCursor);
+
+ return super.swapCursor(newCursor);
+ }
+
+ /**
+ * Get column indexes for performance reasons just once in constructor and swapCursor. For a
+ * performance comparison see http://stackoverflow.com/a/17999582
+ *
+ * @param cursor
+ */
+ private void initIndex(Cursor cursor) {
+ if (cursor != null) {
+ mIndexMasterKeyId = cursor.getColumnIndexOrThrow(KeychainContract.Certs.MASTER_KEY_ID);
+ mIndexUserId = cursor.getColumnIndexOrThrow(KeychainContract.Certs.USER_ID);
+ mIndexRank = cursor.getColumnIndexOrThrow(KeychainContract.Certs.RANK);
+ mIndexType = cursor.getColumnIndexOrThrow(KeychainContract.Certs.TYPE);
+ mIndexVerified = cursor.getColumnIndexOrThrow(KeychainContract.Certs.VERIFIED);
+ mIndexSignerKeyId = cursor.getColumnIndexOrThrow(KeychainContract.Certs.KEY_ID_CERTIFIER);
+ mIndexSignerUserId = cursor.getColumnIndexOrThrow(KeychainContract.Certs.SIGNER_UID);
+ }
+ }
+
+ /**
+ * Bind cursor data to the item list view
+ * <p/>
+ * NOTE: CursorAdapter already implements the ViewHolder pattern in its getView() method.
+ * Thus no ViewHolder is required here.
+ */
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+
+ // set name and stuff, common to both key types
+ TextView wSignerKeyId = (TextView) view.findViewById(R.id.signerKeyId);
+ TextView wSignerName = (TextView) view.findViewById(R.id.signerName);
+ TextView wSignStatus = (TextView) view.findViewById(R.id.signStatus);
+
+ String signerKeyId = KeyFormattingUtils.beautifyKeyIdWithPrefix(getActivity(), cursor.getLong(mIndexSignerKeyId));
+ String[] userId = KeyRing.splitUserId(cursor.getString(mIndexSignerUserId));
+ if (userId[0] != null) {
+ wSignerName.setText(userId[0]);
+ } else {
+ wSignerName.setText(R.string.user_id_no_name);
+ }
+ wSignerKeyId.setText(signerKeyId);
+
+ switch (cursor.getInt(mIndexType)) {
+ case WrappedSignature.DEFAULT_CERTIFICATION: // 0x10
+ wSignStatus.setText(R.string.cert_default);
+ break;
+ case WrappedSignature.NO_CERTIFICATION: // 0x11
+ wSignStatus.setText(R.string.cert_none);
+ break;
+ case WrappedSignature.CASUAL_CERTIFICATION: // 0x12
+ wSignStatus.setText(R.string.cert_casual);
+ break;
+ case WrappedSignature.POSITIVE_CERTIFICATION: // 0x13
+ wSignStatus.setText(R.string.cert_positive);
+ break;
+ case WrappedSignature.CERTIFICATION_REVOCATION: // 0x30
+ wSignStatus.setText(R.string.cert_revoke);
+ break;
+ }
+
+
+ view.setTag(R.id.tag_mki, cursor.getLong(mIndexMasterKeyId));
+ view.setTag(R.id.tag_rank, cursor.getLong(mIndexRank));
+ view.setTag(R.id.tag_certifierId, cursor.getLong(mIndexSignerKeyId));
+ }
+
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ return mInflater.inflate(R.layout.view_key_adv_certs_item, parent, false);
+ }
+
+ /**
+ * Creates a new header view and binds the section headers to it. It uses the ViewHolder
+ * pattern. Most functionality is similar to getView() from Android's CursorAdapter.
+ * <p/>
+ * NOTE: The variables mDataValid and mCursor are available due to the super class
+ * CursorAdapter.
+ */
+ @Override
+ public View getHeaderView(int position, View convertView, ViewGroup parent) {
+ HeaderViewHolder holder;
+ if (convertView == null) {
+ holder = new HeaderViewHolder();
+ convertView = mInflater.inflate(R.layout.view_key_adv_certs_header, parent, false);
+ holder.text = (TextView) convertView.findViewById(R.id.stickylist_header_text);
+ holder.count = (TextView) convertView.findViewById(R.id.certs_num);
+ convertView.setTag(holder);
+ } else {
+ holder = (HeaderViewHolder) convertView.getTag();
+ }
+
+ if (!mDataValid) {
+ // no data available at this point
+ Log.d(Constants.TAG, "getHeaderView: No data available at this point!");
+ return convertView;
+ }
+
+ if (!mCursor.moveToPosition(position)) {
+ throw new IllegalStateException("couldn't move cursor to position " + position);
+ }
+
+ // set header text as first char in user id
+ String userId = mCursor.getString(mIndexUserId);
+ holder.text.setText(userId);
+ holder.count.setVisibility(View.GONE);
+ return convertView;
+ }
+
+ /**
+ * Header IDs should be static, position=1 should always return the same Id that is.
+ */
+ @Override
+ public long getHeaderId(int position) {
+ if (!mDataValid) {
+ // no data available at this point
+ Log.d(Constants.TAG, "getHeaderView: No data available at this point!");
+ return -1;
+ }
+
+ if (!mCursor.moveToPosition(position)) {
+ throw new IllegalStateException("couldn't move cursor to position " + position);
+ }
+
+ // otherwise, return the first character of the name as ID
+ return mCursor.getInt(mIndexRank);
+
+ // sort by the first four characters (should be enough I guess?)
+ // return ByteBuffer.wrap(userId.getBytes()).asLongBuffer().get(0);
+ }
+
+ class HeaderViewHolder {
+ TextView text;
+ TextView count;
+ }
+
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvMainFragment.java
new file mode 100644
index 000000000..c9d20f9f4
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvMainFragment.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.PorterDuff;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.ListView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
+import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
+import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.Date;
+
+public class ViewKeyAdvMainFragment extends LoaderFragment implements
+ LoaderManager.LoaderCallbacks<Cursor> {
+
+ public static final String ARG_DATA_URI = "uri";
+
+ private View mActionEdit;
+ private View mActionEditDivider;
+ private View mActionEncryptFiles;
+ private View mActionEncryptText;
+ private View mActionEncryptTextText;
+ private View mActionCertify;
+ private View mActionCertifyText;
+ private ImageView mActionCertifyImage;
+ private View mActionUpdate;
+
+ private ListView mUserIds;
+
+ private static final int LOADER_ID_UNIFIED = 0;
+ private static final int LOADER_ID_USER_IDS = 1;
+
+ // conservative attitude
+ private boolean mHasEncrypt = true;
+
+ private UserIdsAdapter mUserIdsAdapter;
+
+ private Uri mDataUri;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
+ View root = super.onCreateView(inflater, superContainer, savedInstanceState);
+ View view = inflater.inflate(R.layout.view_key_adv_main_fragment, getContainer());
+
+ mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids);
+ mActionEdit = view.findViewById(R.id.view_key_action_edit);
+ mActionEditDivider = view.findViewById(R.id.view_key_action_edit_divider);
+ mActionEncryptText = view.findViewById(R.id.view_key_action_encrypt_text);
+ mActionEncryptTextText = view.findViewById(R.id.view_key_action_encrypt_text_text);
+ mActionEncryptFiles = view.findViewById(R.id.view_key_action_encrypt_files);
+ mActionCertify = view.findViewById(R.id.view_key_action_certify);
+ mActionCertifyText = view.findViewById(R.id.view_key_action_certify_text);
+ mActionCertifyImage = (ImageView) view.findViewById(R.id.view_key_action_certify_image);
+ // make certify image gray, like action icons
+ mActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
+ PorterDuff.Mode.SRC_IN);
+ mActionUpdate = view.findViewById(R.id.view_key_action_update);
+
+ mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ showUserIdInfo(position);
+ }
+ });
+
+ return root;
+ }
+
+ private void showUserIdInfo(final int position) {
+ final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position);
+ final int isVerified = mUserIdsAdapter.getIsVerified(position);
+
+ DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
+ public void run() {
+ UserIdInfoDialogFragment dialogFragment =
+ UserIdInfoDialogFragment.newInstance(isRevoked, isVerified);
+
+ dialogFragment.show(getActivity().getSupportFragmentManager(), "userIdInfoDialog");
+ }
+ });
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ mDataUri = dataUri;
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ mActionEncryptFiles.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ encrypt(mDataUri, false);
+ }
+ });
+ mActionEncryptText.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ encrypt(mDataUri, true);
+ }
+ });
+ mActionCertify.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ certify(mDataUri);
+ }
+ });
+ mActionEdit.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ editKey(mDataUri);
+ }
+ });
+ mActionUpdate.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ try {
+ updateFromKeyserver(mDataUri, new ProviderHelper(getActivity()));
+ } catch (NotFoundException e) {
+ Notify.showNotify(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR);
+ }
+ }
+ });
+
+ mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0);
+ mUserIds.setAdapter(mUserIdsAdapter);
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
+ getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
+ }
+
+ static final String[] UNIFIED_PROJECTION = new String[]{
+ KeyRings._ID, KeyRings.MASTER_KEY_ID,
+ KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED, KeyRings.EXPIRY, KeyRings.HAS_ENCRYPT
+ };
+ static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
+ static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
+ static final int INDEX_UNIFIED_IS_REVOKED = 3;
+ static final int INDEX_UNIFIED_EXPIRY = 4;
+ static final int INDEX_UNIFIED_HAS_ENCRYPT = 5;
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ setContentShown(false);
+
+ switch (id) {
+ case LOADER_ID_UNIFIED: {
+ Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
+ return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
+ }
+ case LOADER_ID_USER_IDS: {
+ Uri baseUri = UserPackets.buildUserIdsUri(mDataUri);
+ return new CursorLoader(getActivity(), baseUri,
+ UserIdsAdapter.USER_IDS_PROJECTION, null, null, null);
+ }
+
+ default:
+ return null;
+ }
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ /* TODO better error handling? May cause problems when a key is deleted,
+ * because the notification triggers faster than the activity closes.
+ */
+ // Avoid NullPointerExceptions...
+ if (data.getCount() == 0) {
+ return;
+ }
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ switch (loader.getId()) {
+ case LOADER_ID_UNIFIED: {
+ if (data.moveToFirst()) {
+ if (data.getInt(INDEX_UNIFIED_HAS_ANY_SECRET) != 0) {
+ // edit button
+ mActionEdit.setVisibility(View.VISIBLE);
+ mActionEditDivider.setVisibility(View.VISIBLE);
+ } else {
+ // edit button
+ mActionEdit.setVisibility(View.GONE);
+ mActionEditDivider.setVisibility(View.GONE);
+ }
+
+ // If this key is revoked, it cannot be used for anything!
+ if (data.getInt(INDEX_UNIFIED_IS_REVOKED) != 0) {
+ mActionEdit.setEnabled(false);
+ mActionCertify.setEnabled(false);
+ mActionCertifyText.setEnabled(false);
+ mActionEncryptText.setEnabled(false);
+ mActionEncryptTextText.setEnabled(false);
+ mActionEncryptFiles.setEnabled(false);
+ } else {
+ mActionEdit.setEnabled(true);
+
+ Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000);
+ if (!data.isNull(INDEX_UNIFIED_EXPIRY) && expiryDate.before(new Date())) {
+ mActionCertify.setEnabled(false);
+ mActionCertifyText.setEnabled(false);
+ mActionEncryptText.setEnabled(false);
+ mActionEncryptTextText.setEnabled(false);
+ mActionEncryptFiles.setEnabled(false);
+ } else {
+ mActionCertify.setEnabled(true);
+ mActionCertifyText.setEnabled(true);
+ mActionEncryptText.setEnabled(true);
+ mActionEncryptTextText.setEnabled(true);
+ mActionEncryptFiles.setEnabled(true);
+ }
+ }
+
+ mHasEncrypt = data.getInt(INDEX_UNIFIED_HAS_ENCRYPT) != 0;
+
+ break;
+ }
+ }
+
+ case LOADER_ID_USER_IDS: {
+ mUserIdsAdapter.swapCursor(data);
+ break;
+ }
+
+ }
+ setContentShown(true);
+ }
+
+ /**
+ * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
+ * We need to make sure we are no longer using it.
+ */
+ public void onLoaderReset(Loader<Cursor> loader) {
+ switch (loader.getId()) {
+ case LOADER_ID_USER_IDS:
+ mUserIdsAdapter.swapCursor(null);
+ break;
+ }
+ }
+
+ private void encrypt(Uri dataUri, boolean text) {
+ // If there is no encryption key, don't bother.
+ if (!mHasEncrypt) {
+ Notify.showNotify(getActivity(), R.string.error_no_encrypt_subkey, Notify.Style.ERROR);
+ return;
+ }
+ try {
+ long keyId = new ProviderHelper(getActivity())
+ .getCachedPublicKeyRing(dataUri)
+ .extractOrGetMasterKeyId();
+ long[] encryptionKeyIds = new long[]{keyId};
+ Intent intent;
+ if (text) {
+ intent = new Intent(getActivity(), EncryptTextActivity.class);
+ intent.setAction(EncryptTextActivity.ACTION_ENCRYPT_TEXT);
+ intent.putExtra(EncryptTextActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
+ } else {
+ intent = new Intent(getActivity(), EncryptFilesActivity.class);
+ intent.setAction(EncryptFilesActivity.ACTION_ENCRYPT_DATA);
+ intent.putExtra(EncryptFilesActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
+ }
+ // used instead of startActivity set actionbar based on callingPackage
+ startActivityForResult(intent, 0);
+ } catch (PgpKeyNotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ }
+ }
+
+ private void updateFromKeyserver(Uri dataUri, ProviderHelper providerHelper)
+ throws ProviderHelper.NotFoundException {
+ byte[] blob = (byte[]) providerHelper.getGenericData(
+ KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
+ KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
+ String fingerprint = KeyFormattingUtils.convertFingerprintToHex(blob);
+
+ Intent queryIntent = new Intent(getActivity(), ImportKeysActivity.class);
+ queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT);
+ queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint);
+
+ startActivityForResult(queryIntent, 0);
+ }
+
+ private void certify(Uri dataUri) {
+ long keyId = 0;
+ try {
+ keyId = new ProviderHelper(getActivity())
+ .getCachedPublicKeyRing(dataUri)
+ .extractOrGetMasterKeyId();
+ } catch (PgpKeyNotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ }
+ Intent certifyIntent = new Intent(getActivity(), CertifyKeyActivity.class);
+ certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{keyId});
+ startActivityForResult(certifyIntent, 0);
+ }
+
+ private void editKey(Uri dataUri) {
+ Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
+ editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri));
+ startActivityForResult(editIntent, 0);
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java
new file mode 100644
index 000000000..6208cff4e
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.annotation.TargetApi;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.PorterDuff;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AlphaAnimation;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
+import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.ui.util.Notify;
+import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.io.IOException;
+
+
+public class ViewKeyAdvShareFragment extends LoaderFragment implements
+ LoaderManager.LoaderCallbacks<Cursor> {
+
+ public static final String ARG_DATA_URI = "uri";
+
+ private TextView mFingerprint;
+ private ImageView mFingerprintQrCode;
+ private View mFingerprintShareButton;
+ private View mFingerprintClipboardButton;
+ private View mKeyShareButton;
+ private View mKeyClipboardButton;
+ private ImageButton mKeySafeSlingerButton;
+ private View mNfcHelpButton;
+ private View mNfcPrefsButton;
+ private View mKeyUploadButton;
+
+ ProviderHelper mProviderHelper;
+
+ private static final int LOADER_ID_UNIFIED = 0;
+
+ private Uri mDataUri;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
+ View root = super.onCreateView(inflater, superContainer, savedInstanceState);
+ View view = inflater.inflate(R.layout.view_key_adv_share_fragment, getContainer());
+
+ mProviderHelper = new ProviderHelper(ViewKeyAdvShareFragment.this.getActivity());
+
+ mFingerprint = (TextView) view.findViewById(R.id.view_key_fingerprint);
+ mFingerprintQrCode = (ImageView) view.findViewById(R.id.view_key_fingerprint_qr_code_image);
+ mFingerprintShareButton = view.findViewById(R.id.view_key_action_fingerprint_share);
+ mFingerprintClipboardButton = view.findViewById(R.id.view_key_action_fingerprint_clipboard);
+ mKeyShareButton = view.findViewById(R.id.view_key_action_key_share);
+ mKeyClipboardButton = view.findViewById(R.id.view_key_action_key_clipboard);
+ mKeySafeSlingerButton = (ImageButton) view.findViewById(R.id.view_key_action_key_safeslinger);
+ mNfcHelpButton = view.findViewById(R.id.view_key_action_nfc_help);
+ mNfcPrefsButton = view.findViewById(R.id.view_key_action_nfc_prefs);
+ mKeyUploadButton = view.findViewById(R.id.view_key_action_upload);
+
+ mKeySafeSlingerButton.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
+ PorterDuff.Mode.SRC_IN);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ mNfcPrefsButton.setVisibility(View.VISIBLE);
+ } else {
+ mNfcPrefsButton.setVisibility(View.GONE);
+ }
+
+ mFingerprintQrCode.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showQrCodeDialog();
+ }
+ });
+
+ mFingerprintShareButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ share(mDataUri, mProviderHelper, true, false);
+ }
+ });
+ mFingerprintClipboardButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ share(mDataUri, mProviderHelper, true, true);
+ }
+ });
+ mKeyShareButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ share(mDataUri, mProviderHelper, false, false);
+ }
+ });
+ mKeyClipboardButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ share(mDataUri, mProviderHelper, false, true);
+ }
+ });
+ mKeySafeSlingerButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startSafeSlinger(mDataUri);
+ }
+ });
+ mNfcHelpButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showNfcHelpDialog();
+ }
+ });
+ mNfcPrefsButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showNfcPrefs();
+ }
+ });
+ mKeyUploadButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ uploadToKeyserver();
+ }
+ });
+
+ return root;
+ }
+
+ private void startSafeSlinger(Uri dataUri) {
+ long keyId = 0;
+ try {
+ keyId = new ProviderHelper(getActivity())
+ .getCachedPublicKeyRing(dataUri)
+ .extractOrGetMasterKeyId();
+ } catch (PgpKeyNotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ }
+ Intent safeSlingerIntent = new Intent(getActivity(), SafeSlingerActivity.class);
+ safeSlingerIntent.putExtra(SafeSlingerActivity.EXTRA_MASTER_KEY_ID, keyId);
+ startActivityForResult(safeSlingerIntent, 0);
+ }
+
+ private void share(Uri dataUri, ProviderHelper providerHelper, boolean fingerprintOnly,
+ boolean toClipboard) {
+ try {
+ String content;
+ if (fingerprintOnly) {
+ byte[] data = (byte[]) providerHelper.getGenericData(
+ KeyRings.buildUnifiedKeyRingUri(dataUri),
+ Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
+ String fingerprint = KeyFormattingUtils.convertFingerprintToHex(data);
+ if (!toClipboard) {
+ content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
+ } else {
+ content = fingerprint;
+ }
+ } else {
+ Uri uri = KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri);
+ // get public keyring as ascii armored string
+ content = providerHelper.getKeyRingAsArmoredString(uri);
+ }
+
+ if (toClipboard) {
+ ClipboardReflection.copyToClipboard(getActivity(), content);
+ String message;
+ if (fingerprintOnly) {
+ message = getResources().getString(R.string.fingerprint_copied_to_clipboard);
+ } else {
+ message = getResources().getString(R.string.key_copied_to_clipboard);
+ }
+ Notify.showNotify(getActivity(), message, Notify.Style.OK);
+ } else {
+ // Android will fail with android.os.TransactionTooLargeException if key is too big
+ // see http://www.lonestarprod.com/?p=34
+ if (content.length() >= 86389) {
+ Notify.showNotify(getActivity(), R.string.key_too_big_for_sharing,
+ Notify.Style.ERROR);
+ return;
+ }
+
+ // let user choose application
+ Intent sendIntent = new Intent(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_TEXT, content);
+ sendIntent.setType("text/plain");
+ String title;
+ if (fingerprintOnly) {
+ title = getResources().getString(R.string.title_share_fingerprint_with);
+ } else {
+ title = getResources().getString(R.string.title_share_key);
+ }
+ startActivity(Intent.createChooser(sendIntent, title));
+ }
+ } catch (PgpGeneralException | IOException e) {
+ Log.e(Constants.TAG, "error processing key!", e);
+ Notify.showNotify(getActivity(), R.string.error_key_processing, Notify.Style.ERROR);
+ } catch (ProviderHelper.NotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ Notify.showNotify(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR);
+ }
+ }
+
+ private void showQrCodeDialog() {
+ Intent qrCodeIntent = new Intent(getActivity(), QrCodeViewActivity.class);
+ qrCodeIntent.setData(mDataUri);
+ startActivity(qrCodeIntent);
+ }
+
+ private void showNfcHelpDialog() {
+ ShareNfcDialogFragment dialog = ShareNfcDialogFragment.newInstance();
+ dialog.show(getActivity().getSupportFragmentManager(), "shareNfcDialog");
+ }
+
+ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ private void showNfcPrefs() {
+ Intent intentSettings = new Intent(
+ Settings.ACTION_NFCSHARING_SETTINGS);
+ startActivity(intentSettings);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ mDataUri = dataUri;
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
+ }
+
+ static final String[] UNIFIED_PROJECTION = new String[]{
+ KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET,
+ KeyRings.USER_ID, KeyRings.FINGERPRINT,
+ KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,
+
+ };
+ static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
+ static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
+ static final int INDEX_UNIFIED_USER_ID = 3;
+ static final int INDEX_UNIFIED_FINGERPRINT = 4;
+ static final int INDEX_UNIFIED_ALGORITHM = 5;
+ static final int INDEX_UNIFIED_KEY_SIZE = 6;
+ static final int INDEX_UNIFIED_CREATION = 7;
+ static final int INDEX_UNIFIED_EXPIRY = 8;
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ setContentShown(false);
+ switch (id) {
+ case LOADER_ID_UNIFIED: {
+ Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
+ return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
+ }
+
+ default:
+ return null;
+ }
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ /* TODO better error handling? May cause problems when a key is deleted,
+ * because the notification triggers faster than the activity closes.
+ */
+ // Avoid NullPointerExceptions...
+ if (data.getCount() == 0) {
+ return;
+ }
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ switch (loader.getId()) {
+ case LOADER_ID_UNIFIED: {
+ if (data.moveToFirst()) {
+
+ byte[] fingerprintBlob = data.getBlob(INDEX_UNIFIED_FINGERPRINT);
+ String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fingerprintBlob);
+ mFingerprint.setText(KeyFormattingUtils.colorizeFingerprint(fingerprint));
+
+ loadQrCode(fingerprint);
+
+ break;
+ }
+ }
+
+ }
+ setContentShown(true);
+ }
+
+ /**
+ * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
+ * We need to make sure we are no longer using it.
+ */
+ public void onLoaderReset(Loader<Cursor> loader) {
+ }
+
+ /**
+ * Load QR Code asynchronously and with a fade in animation
+ *
+ * @param fingerprint
+ */
+ private void loadQrCode(final String fingerprint) {
+ AsyncTask<Void, Void, Bitmap> loadTask =
+ new AsyncTask<Void, Void, Bitmap>() {
+ protected Bitmap doInBackground(Void... unused) {
+ String qrCodeContent = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
+ // render with minimal size
+ return QrCodeUtils.getQRCodeBitmap(qrCodeContent, 0);
+ }
+
+ protected void onPostExecute(Bitmap qrCode) {
+ // only change view, if fragment is attached to activity
+ if (ViewKeyAdvShareFragment.this.isAdded()) {
+
+ // scale the image up to our actual size. we do this in code rather
+ // than let the ImageView do this because we don't require filtering.
+ Bitmap scaled = Bitmap.createScaledBitmap(qrCode,
+ mFingerprintQrCode.getHeight(), mFingerprintQrCode.getHeight(),
+ false);
+ mFingerprintQrCode.setImageBitmap(scaled);
+
+ // simple fade-in animation
+ AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
+ anim.setDuration(200);
+ mFingerprintQrCode.startAnimation(anim);
+ }
+ }
+ };
+
+ loadTask.execute();
+ }
+
+ private void uploadToKeyserver() {
+ Intent uploadIntent = new Intent(getActivity(), UploadKeyActivity.class);
+ uploadIntent.setData(mDataUri);
+ startActivityForResult(uploadIntent, 0);
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java
new file mode 100644
index 000000000..bd00c6780
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
+import org.sufficientlysecure.keychain.util.Log;
+
+public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
+ LoaderManager.LoaderCallbacks<Cursor> {
+
+ public static final String ARG_DATA_URI = "data_uri";
+
+ private ListView mSubkeysList;
+ private SubkeysAdapter mSubkeysAdapter;
+
+ private Uri mDataUriSubkeys;
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static ViewKeyAdvSubkeysFragment newInstance(Uri dataUri) {
+ ViewKeyAdvSubkeysFragment frag = new ViewKeyAdvSubkeysFragment();
+
+ Bundle args = new Bundle();
+ args.putParcelable(ARG_DATA_URI, dataUri);
+
+ frag.setArguments(args);
+ return frag;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
+ View root = super.onCreateView(inflater, superContainer, savedInstanceState);
+ View view = inflater.inflate(R.layout.view_key_adv_subkeys_fragment, getContainer());
+
+ mSubkeysList = (ListView) view.findViewById(R.id.keys);
+
+ return root;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ mDataUriSubkeys = KeychainContract.Keys.buildKeysUri(dataUri);
+
+ // Create an empty adapter we will use to display the loaded data.
+ mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0);
+ mSubkeysList.setAdapter(mSubkeysAdapter);
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getLoaderManager().initLoader(0, null, this);
+ }
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ setContentShown(false);
+
+ return new CursorLoader(getActivity(), mDataUriSubkeys,
+ SubkeysAdapter.SUBKEYS_PROJECTION, null, null, null);
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ // Avoid NullPointerExceptions, if we get an empty result set.
+ if (data.getCount() == 0) {
+ return;
+ }
+
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ mSubkeysAdapter.swapCursor(data);
+
+ // TODO: maybe show not before both are loaded!
+ setContentShown(true);
+ }
+
+ /**
+ * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
+ * We need to make sure we are no longer using it.
+ */
+ public void onLoaderReset(Loader<Cursor> loader) {
+ mSubkeysAdapter.swapCursor(null);
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvancedActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvancedActivity.java
deleted file mode 100644
index f49f8e7cf..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvancedActivity.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2013 Bahtiar 'kalkin' Gadimov
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.util.ActionBarHelper;
-import org.sufficientlysecure.keychain.util.ExportHelper;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class ViewKeyAdvancedActivity extends ActionBarActivity {
-
- ExportHelper mExportHelper;
- ProviderHelper mProviderHelper;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mExportHelper = new ExportHelper(this);
- mProviderHelper = new ProviderHelper(this);
-
- // Inflate a "Done" custom action bar
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // "Done"
- finish();
- }
- }
- );
-
- setContentView(R.layout.view_key_advanced_activity);
-
- Uri dataUri = getIntent().getData();
- if (dataUri == null) {
- Log.e(Constants.TAG, "Data missing. Should be uri of key!");
- finish();
- return;
- }
-
- Log.i(Constants.TAG, "mDataUri: " + dataUri.toString());
-
- startFragment(savedInstanceState, dataUri);
- }
-
-
- private void startFragment(Bundle savedInstanceState, Uri dataUri) {
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- ViewKeyAdvancedFragment frag = ViewKeyAdvancedFragment.newInstance(dataUri);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.view_key_advanced_fragment, frag)
- .commitAllowingStateLoss();
- // do it immediately!
- getSupportFragmentManager().executePendingTransactions();
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvancedFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvancedFragment.java
deleted file mode 100644
index 9c37f2d94..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvancedFragment.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.pgp.WrappedSignature;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.util.Log;
-
-import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
-import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
-
-
-public class ViewKeyAdvancedFragment extends LoaderFragment implements
- LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
-
- public static final String ARG_DATA_URI = "data_uri";
-
- private ListView mSubkeysList;
- private SubkeysAdapter mSubkeysAdapter;
-
- private StickyListHeadersListView mStickyList;
- private CertListAdapter mCertsAdapter;
-
- private Uri mDataUriSubkeys;
- private Uri mDataUriCerts;
-
- private static final int LOADER_SUBKEYS = 1;
- private static final int LOADER_CERTS = 2;
-
- // These are the rows that we will retrieve.
- static final String[] CERTS_PROJECTION = new String[]{
- KeychainContract.Certs._ID,
- KeychainContract.Certs.MASTER_KEY_ID,
- KeychainContract.Certs.VERIFIED,
- KeychainContract.Certs.TYPE,
- KeychainContract.Certs.RANK,
- KeychainContract.Certs.KEY_ID_CERTIFIER,
- KeychainContract.Certs.USER_ID,
- KeychainContract.Certs.SIGNER_UID
- };
-
- // sort by our user id,
- static final String CERTS_SORT_ORDER =
- KeychainDatabase.Tables.CERTS + "." + KeychainContract.Certs.RANK + " ASC, "
- + KeychainContract.Certs.VERIFIED + " DESC, "
- + KeychainContract.Certs.TYPE + " DESC, "
- + KeychainContract.Certs.SIGNER_UID + " ASC";
-
- /**
- * Creates new instance of this fragment
- */
- public static ViewKeyAdvancedFragment newInstance(Uri dataUri) {
- ViewKeyAdvancedFragment frag = new ViewKeyAdvancedFragment();
-
- Bundle args = new Bundle();
- args.putParcelable(ARG_DATA_URI, dataUri);
-
- frag.setArguments(args);
- return frag;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
- View root = super.onCreateView(inflater, superContainer, savedInstanceState);
- View view = inflater.inflate(R.layout.view_key_advanced_fragment, getContainer());
-
- mSubkeysList = (ListView) view.findViewById(R.id.keys);
- mStickyList = (StickyListHeadersListView) view.findViewById(R.id.certs_list);
-
- return root;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
- if (dataUri == null) {
- Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
- getActivity().finish();
- return;
- }
-
- loadData(dataUri);
- }
-
- private void loadData(Uri dataUri) {
- mDataUriSubkeys = KeychainContract.Keys.buildKeysUri(dataUri);
- mDataUriCerts = KeychainContract.Certs.buildCertsUri(dataUri);
-
- mStickyList.setAreHeadersSticky(true);
- mStickyList.setDrawingListUnderStickyHeader(false);
- mStickyList.setOnItemClickListener(this);
-
- mStickyList.setEmptyView(getActivity().findViewById(R.id.empty));
-
- // Create an empty adapter we will use to display the loaded data.
- mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0);
- mSubkeysList.setAdapter(mSubkeysAdapter);
-
- mCertsAdapter = new CertListAdapter(getActivity(), null);
- mStickyList.setAdapter(mCertsAdapter);
-
- // Prepare the loaders. Either re-connect with an existing ones,
- // or start new ones.
- getLoaderManager().initLoader(LOADER_SUBKEYS, null, this);
- getLoaderManager().initLoader(LOADER_CERTS, null, this);
- }
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- setContentShown(false);
- switch (id) {
- case LOADER_SUBKEYS:
- return new CursorLoader(getActivity(), mDataUriSubkeys,
- SubkeysAdapter.SUBKEYS_PROJECTION, null, null, null);
-
- case LOADER_CERTS:
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), mDataUriCerts,
- CERTS_PROJECTION, null, null, CERTS_SORT_ORDER);
-
- default:
- return null;
- }
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Avoid NullPointerExceptions, if we get an empty result set.
- if (data.getCount() == 0) {
- return;
- }
-
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- switch (loader.getId()) {
- case LOADER_SUBKEYS:
- mSubkeysAdapter.swapCursor(data);
- break;
- case LOADER_CERTS:
- mCertsAdapter.swapCursor(data);
- mStickyList.setAdapter(mCertsAdapter);
- break;
- }
-
- // TODO: maybe show not before both are loaded!
- setContentShown(true);
- }
-
- /**
- * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
- * We need to make sure we are no longer using it.
- */
- public void onLoaderReset(Loader<Cursor> loader) {
- switch (loader.getId()) {
- case LOADER_SUBKEYS:
- mSubkeysAdapter.swapCursor(null);
- break;
- case LOADER_CERTS:
- mCertsAdapter.swapCursor(null);
- break;
- }
- }
-
- /**
- * On click on item, start key view activity
- */
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- if (view.getTag(R.id.tag_mki) != null) {
- long masterKeyId = (Long) view.getTag(R.id.tag_mki);
- long rank = (Long) view.getTag(R.id.tag_rank);
- long certifierId = (Long) view.getTag(R.id.tag_certifierId);
-
- Intent viewIntent = new Intent(getActivity(), ViewCertActivity.class);
- viewIntent.setData(KeychainContract.Certs.buildCertsSpecificUri(
- masterKeyId, rank, certifierId));
- startActivity(viewIntent);
- }
- }
-
-
- /**
- * Implements StickyListHeadersAdapter from library
- */
- private class CertListAdapter extends CursorAdapter implements StickyListHeadersAdapter {
- private LayoutInflater mInflater;
- private int mIndexMasterKeyId, mIndexUserId, mIndexRank;
- private int mIndexSignerKeyId, mIndexSignerUserId;
- private int mIndexVerified, mIndexType;
-
- public CertListAdapter(Context context, Cursor c) {
- super(context, c, 0);
-
- mInflater = LayoutInflater.from(context);
- initIndex(c);
- }
-
- @Override
- public Cursor swapCursor(Cursor newCursor) {
- initIndex(newCursor);
-
- return super.swapCursor(newCursor);
- }
-
- /**
- * Get column indexes for performance reasons just once in constructor and swapCursor. For a
- * performance comparison see http://stackoverflow.com/a/17999582
- *
- * @param cursor
- */
- private void initIndex(Cursor cursor) {
- if (cursor != null) {
- mIndexMasterKeyId = cursor.getColumnIndexOrThrow(KeychainContract.Certs.MASTER_KEY_ID);
- mIndexUserId = cursor.getColumnIndexOrThrow(KeychainContract.Certs.USER_ID);
- mIndexRank = cursor.getColumnIndexOrThrow(KeychainContract.Certs.RANK);
- mIndexType = cursor.getColumnIndexOrThrow(KeychainContract.Certs.TYPE);
- mIndexVerified = cursor.getColumnIndexOrThrow(KeychainContract.Certs.VERIFIED);
- mIndexSignerKeyId = cursor.getColumnIndexOrThrow(KeychainContract.Certs.KEY_ID_CERTIFIER);
- mIndexSignerUserId = cursor.getColumnIndexOrThrow(KeychainContract.Certs.SIGNER_UID);
- }
- }
-
- /**
- * Bind cursor data to the item list view
- * <p/>
- * NOTE: CursorAdapter already implements the ViewHolder pattern in its getView() method.
- * Thus no ViewHolder is required here.
- */
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
-
- // set name and stuff, common to both key types
- TextView wSignerKeyId = (TextView) view.findViewById(R.id.signerKeyId);
- TextView wSignerName = (TextView) view.findViewById(R.id.signerName);
- TextView wSignStatus = (TextView) view.findViewById(R.id.signStatus);
-
- String signerKeyId = KeyFormattingUtils.beautifyKeyIdWithPrefix(getActivity(), cursor.getLong(mIndexSignerKeyId));
- String[] userId = KeyRing.splitUserId(cursor.getString(mIndexSignerUserId));
- if (userId[0] != null) {
- wSignerName.setText(userId[0]);
- } else {
- wSignerName.setText(R.string.user_id_no_name);
- }
- wSignerKeyId.setText(signerKeyId);
-
- switch (cursor.getInt(mIndexType)) {
- case WrappedSignature.DEFAULT_CERTIFICATION: // 0x10
- wSignStatus.setText(R.string.cert_default);
- break;
- case WrappedSignature.NO_CERTIFICATION: // 0x11
- wSignStatus.setText(R.string.cert_none);
- break;
- case WrappedSignature.CASUAL_CERTIFICATION: // 0x12
- wSignStatus.setText(R.string.cert_casual);
- break;
- case WrappedSignature.POSITIVE_CERTIFICATION: // 0x13
- wSignStatus.setText(R.string.cert_positive);
- break;
- case WrappedSignature.CERTIFICATION_REVOCATION: // 0x30
- wSignStatus.setText(R.string.cert_revoke);
- break;
- }
-
-
- view.setTag(R.id.tag_mki, cursor.getLong(mIndexMasterKeyId));
- view.setTag(R.id.tag_rank, cursor.getLong(mIndexRank));
- view.setTag(R.id.tag_certifierId, cursor.getLong(mIndexSignerKeyId));
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.view_key_certs_item, parent, false);
- }
-
- /**
- * Creates a new header view and binds the section headers to it. It uses the ViewHolder
- * pattern. Most functionality is similar to getView() from Android's CursorAdapter.
- * <p/>
- * NOTE: The variables mDataValid and mCursor are available due to the super class
- * CursorAdapter.
- */
- @Override
- public View getHeaderView(int position, View convertView, ViewGroup parent) {
- HeaderViewHolder holder;
- if (convertView == null) {
- holder = new HeaderViewHolder();
- convertView = mInflater.inflate(R.layout.view_key_certs_header, parent, false);
- holder.text = (TextView) convertView.findViewById(R.id.stickylist_header_text);
- holder.count = (TextView) convertView.findViewById(R.id.certs_num);
- convertView.setTag(holder);
- } else {
- holder = (HeaderViewHolder) convertView.getTag();
- }
-
- if (!mDataValid) {
- // no data available at this point
- Log.d(Constants.TAG, "getHeaderView: No data available at this point!");
- return convertView;
- }
-
- if (!mCursor.moveToPosition(position)) {
- throw new IllegalStateException("couldn't move cursor to position " + position);
- }
-
- // set header text as first char in user id
- String userId = mCursor.getString(mIndexUserId);
- holder.text.setText(userId);
- holder.count.setVisibility(View.GONE);
- return convertView;
- }
-
- /**
- * Header IDs should be static, position=1 should always return the same Id that is.
- */
- @Override
- public long getHeaderId(int position) {
- if (!mDataValid) {
- // no data available at this point
- Log.d(Constants.TAG, "getHeaderView: No data available at this point!");
- return -1;
- }
-
- if (!mCursor.moveToPosition(position)) {
- throw new IllegalStateException("couldn't move cursor to position " + position);
- }
-
- // otherwise, return the first character of the name as ID
- return mCursor.getInt(mIndexRank);
-
- // sort by the first four characters (should be enough I guess?)
- // return ByteBuffer.wrap(userId.getBytes()).asLongBuffer().get(0);
- }
-
- class HeaderViewHolder {
- TextView text;
- TextView count;
- }
-
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java
new file mode 100644
index 000000000..453bfd499
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
+import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.Date;
+
+public class ViewKeyFragment extends LoaderFragment implements
+ LoaderManager.LoaderCallbacks<Cursor> {
+
+ public static final String ARG_DATA_URI = "uri";
+
+ private ListView mUserIds;
+
+ boolean mIsSecret = false;
+
+ private static final int LOADER_ID_UNIFIED = 0;
+ private static final int LOADER_ID_USER_IDS = 1;
+
+ private UserIdsAdapter mUserIdsAdapter;
+
+ private Uri mDataUri;
+
+ ProviderHelper mProviderHelper;
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static ViewKeyFragment newInstance(Uri dataUri) {
+ ViewKeyFragment frag = new ViewKeyFragment();
+ Bundle args = new Bundle();
+ args.putParcelable(ARG_DATA_URI, dataUri);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
+ View root = super.onCreateView(inflater, superContainer, savedInstanceState);
+ View view = inflater.inflate(R.layout.view_key_fragment, getContainer());
+
+ mProviderHelper = new ProviderHelper(getActivity());
+
+ mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids);
+
+ mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ showUserIdInfo(position);
+ }
+ });
+
+ return root;
+ }
+
+ private void showUserIdInfo(final int position) {
+ if (!mIsSecret) {
+ final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position);
+ final int isVerified = mUserIdsAdapter.getIsVerified(position);
+
+ DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
+ public void run() {
+ UserIdInfoDialogFragment dialogFragment =
+ UserIdInfoDialogFragment.newInstance(isRevoked, isVerified);
+
+ dialogFragment.show(getActivity().getSupportFragmentManager(), "userIdInfoDialog");
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+
+ // These are the rows that we will retrieve.
+ static final String[] UNIFIED_PROJECTION = new String[]{
+ KeychainContract.KeyRings._ID,
+ KeychainContract.KeyRings.MASTER_KEY_ID,
+ KeychainContract.KeyRings.USER_ID,
+ KeychainContract.KeyRings.IS_REVOKED,
+ KeychainContract.KeyRings.EXPIRY,
+ KeychainContract.KeyRings.VERIFIED,
+ KeychainContract.KeyRings.HAS_ANY_SECRET,
+ KeychainContract.KeyRings.FINGERPRINT,
+ KeychainContract.KeyRings.HAS_ENCRYPT
+ };
+
+ static final int INDEX_MASTER_KEY_ID = 1;
+ static final int INDEX_USER_ID = 2;
+ static final int INDEX_IS_REVOKED = 3;
+ static final int INDEX_EXPIRY = 4;
+ static final int INDEX_VERIFIED = 5;
+ static final int INDEX_HAS_ANY_SECRET = 6;
+ static final int INDEX_FINGERPRINT = 7;
+ static final int INDEX_HAS_ENCRYPT = 8;
+
+ private void loadData(Uri dataUri) {
+ mDataUri = dataUri;
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
+ }
+
+ // don't show revoked user ids here, irrelevant for average users
+ public static final String USER_IDS_WHERE = UserPackets.IS_REVOKED + " = 0";
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ setContentShown(false);
+
+ switch (id) {
+ case LOADER_ID_UNIFIED: {
+ Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
+ return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
+ }
+ case LOADER_ID_USER_IDS: {
+ Uri baseUri = UserPackets.buildUserIdsUri(mDataUri);
+ return new CursorLoader(getActivity(), baseUri,
+ UserIdsAdapter.USER_IDS_PROJECTION, USER_IDS_WHERE, null, null);
+ }
+
+ default:
+ return null;
+ }
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ /* TODO better error handling? May cause problems when a key is deleted,
+ * because the notification triggers faster than the activity closes.
+ */
+ // Avoid NullPointerExceptions...
+ if (data.getCount() == 0) {
+ return;
+ }
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ switch (loader.getId()) {
+ case LOADER_ID_UNIFIED: {
+ if (data.moveToFirst()) {
+
+ mIsSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
+ boolean hasEncrypt = data.getInt(INDEX_HAS_ENCRYPT) != 0;
+ boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
+ boolean isExpired = !data.isNull(INDEX_EXPIRY)
+ && new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date());
+ boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
+
+ // load user ids after we know if it's a secret key
+ mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, false, !mIsSecret, null);
+ mUserIds.setAdapter(mUserIdsAdapter);
+ getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
+
+ break;
+ }
+ }
+
+ case LOADER_ID_USER_IDS: {
+ mUserIdsAdapter.swapCursor(data);
+ break;
+ }
+
+ }
+ setContentShown(true);
+ }
+
+ /**
+ * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
+ * We need to make sure we are no longer using it.
+ */
+ public void onLoaderReset(Loader<Cursor> loader) {
+ switch (loader.getId()) {
+ case LOADER_ID_USER_IDS: {
+ mUserIdsAdapter.swapCursor(null);
+ break;
+ }
+ }
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
deleted file mode 100644
index f1453c40c..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.database.Cursor;
-import android.graphics.PorterDuff;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ImageView;
-import android.widget.ListView;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
-import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
-import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.ui.util.Notify;
-
-import java.util.Date;
-
-public class ViewKeyMainFragment extends LoaderFragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
-
- public static final String ARG_DATA_URI = "uri";
-
- private View mActionEdit;
- private View mActionEditDivider;
- private View mActionEncryptFiles;
- private View mActionEncryptText;
- private View mActionEncryptTextText;
- private View mActionCertify;
- private View mActionCertifyText;
- private ImageView mActionCertifyImage;
- private View mActionUpdate;
-
- private ListView mUserIds;
-
- private static final int LOADER_ID_UNIFIED = 0;
- private static final int LOADER_ID_USER_IDS = 1;
-
- // conservative attitude
- private boolean mHasEncrypt = true;
-
- private UserIdsAdapter mUserIdsAdapter;
-
- private Uri mDataUri;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
- View root = super.onCreateView(inflater, superContainer, savedInstanceState);
- View view = inflater.inflate(R.layout.view_key_main_fragment, getContainer());
-
- mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids);
- mActionEdit = view.findViewById(R.id.view_key_action_edit);
- mActionEditDivider = view.findViewById(R.id.view_key_action_edit_divider);
- mActionEncryptText = view.findViewById(R.id.view_key_action_encrypt_text);
- mActionEncryptTextText = view.findViewById(R.id.view_key_action_encrypt_text_text);
- mActionEncryptFiles = view.findViewById(R.id.view_key_action_encrypt_files);
- mActionCertify = view.findViewById(R.id.view_key_action_certify);
- mActionCertifyText = view.findViewById(R.id.view_key_action_certify_text);
- mActionCertifyImage = (ImageView) view.findViewById(R.id.view_key_action_certify_image);
- // make certify image gray, like action icons
- mActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
- PorterDuff.Mode.SRC_IN);
- mActionUpdate = view.findViewById(R.id.view_key_action_update);
-
- mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- showUserIdInfo(position);
- }
- });
-
- return root;
- }
-
- private void showUserIdInfo(final int position) {
- final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position);
- final int isVerified = mUserIdsAdapter.getIsVerified(position);
-
- DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
- public void run() {
- UserIdInfoDialogFragment dialogFragment =
- UserIdInfoDialogFragment.newInstance(isRevoked, isVerified);
-
- dialogFragment.show(getActivity().getSupportFragmentManager(), "userIdInfoDialog");
- }
- });
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
- if (dataUri == null) {
- Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
- getActivity().finish();
- return;
- }
-
- loadData(dataUri);
- }
-
- private void loadData(Uri dataUri) {
- mDataUri = dataUri;
-
- Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
-
- mActionEncryptFiles.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- encrypt(mDataUri, false);
- }
- });
- mActionEncryptText.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- encrypt(mDataUri, true);
- }
- });
- mActionCertify.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- certify(mDataUri);
- }
- });
- mActionEdit.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- editKey(mDataUri);
- }
- });
- mActionUpdate.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- try {
- updateFromKeyserver(mDataUri, new ProviderHelper(getActivity()));
- } catch (NotFoundException e) {
- Notify.showNotify(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR);
- }
- }
- });
-
- mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0);
- mUserIds.setAdapter(mUserIdsAdapter);
-
- // Prepare the loaders. Either re-connect with an existing ones,
- // or start new ones.
- getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
- getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
- }
-
- static final String[] UNIFIED_PROJECTION = new String[]{
- KeyRings._ID, KeyRings.MASTER_KEY_ID,
- KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED, KeyRings.EXPIRY, KeyRings.HAS_ENCRYPT
- };
- static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
- static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
- static final int INDEX_UNIFIED_IS_REVOKED = 3;
- static final int INDEX_UNIFIED_EXPIRY = 4;
- static final int INDEX_UNIFIED_HAS_ENCRYPT = 5;
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- setContentShown(false);
-
- switch (id) {
- case LOADER_ID_UNIFIED: {
- Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
- return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
- }
- case LOADER_ID_USER_IDS: {
- Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
- return new CursorLoader(getActivity(), baseUri,
- UserIdsAdapter.USER_IDS_PROJECTION, null, null, null);
- }
-
- default:
- return null;
- }
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- /* TODO better error handling? May cause problems when a key is deleted,
- * because the notification triggers faster than the activity closes.
- */
- // Avoid NullPointerExceptions...
- if (data.getCount() == 0) {
- return;
- }
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- switch (loader.getId()) {
- case LOADER_ID_UNIFIED: {
- if (data.moveToFirst()) {
- if (data.getInt(INDEX_UNIFIED_HAS_ANY_SECRET) != 0) {
- // edit button
- mActionEdit.setVisibility(View.VISIBLE);
- mActionEditDivider.setVisibility(View.VISIBLE);
- } else {
- // edit button
- mActionEdit.setVisibility(View.GONE);
- mActionEditDivider.setVisibility(View.GONE);
- }
-
- // If this key is revoked, it cannot be used for anything!
- if (data.getInt(INDEX_UNIFIED_IS_REVOKED) != 0) {
- mActionEdit.setEnabled(false);
- mActionCertify.setEnabled(false);
- mActionCertifyText.setEnabled(false);
- mActionEncryptText.setEnabled(false);
- mActionEncryptTextText.setEnabled(false);
- mActionEncryptFiles.setEnabled(false);
- } else {
- mActionEdit.setEnabled(true);
-
- Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000);
- if (!data.isNull(INDEX_UNIFIED_EXPIRY) && expiryDate.before(new Date())) {
- mActionCertify.setEnabled(false);
- mActionCertifyText.setEnabled(false);
- mActionEncryptText.setEnabled(false);
- mActionEncryptTextText.setEnabled(false);
- mActionEncryptFiles.setEnabled(false);
- } else {
- mActionCertify.setEnabled(true);
- mActionCertifyText.setEnabled(true);
- mActionEncryptText.setEnabled(true);
- mActionEncryptTextText.setEnabled(true);
- mActionEncryptFiles.setEnabled(true);
- }
- }
-
- mHasEncrypt = data.getInt(INDEX_UNIFIED_HAS_ENCRYPT) != 0;
-
- break;
- }
- }
-
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(data);
- break;
-
- }
- setContentShown(true);
- }
-
- /**
- * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
- * We need to make sure we are no longer using it.
- */
- public void onLoaderReset(Loader<Cursor> loader) {
- switch (loader.getId()) {
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(null);
- break;
- }
- }
-
- private void encrypt(Uri dataUri, boolean text) {
- // If there is no encryption key, don't bother.
- if (!mHasEncrypt) {
- Notify.showNotify(getActivity(), R.string.error_no_encrypt_subkey, Notify.Style.ERROR);
- return;
- }
- try {
- long keyId = new ProviderHelper(getActivity())
- .getCachedPublicKeyRing(dataUri)
- .extractOrGetMasterKeyId();
- long[] encryptionKeyIds = new long[]{keyId};
- Intent intent;
- if (text) {
- intent = new Intent(getActivity(), EncryptTextActivity.class);
- intent.setAction(EncryptTextActivity.ACTION_ENCRYPT_TEXT);
- intent.putExtra(EncryptTextActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
- } else {
- intent = new Intent(getActivity(), EncryptFilesActivity.class);
- intent.setAction(EncryptFilesActivity.ACTION_ENCRYPT_DATA);
- intent.putExtra(EncryptFilesActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
- }
- // used instead of startActivity set actionbar based on callingPackage
- startActivityForResult(intent, 0);
- } catch (PgpKeyNotFoundException e) {
- Log.e(Constants.TAG, "key not found!", e);
- }
- }
-
- private void updateFromKeyserver(Uri dataUri, ProviderHelper providerHelper)
- throws ProviderHelper.NotFoundException {
- byte[] blob = (byte[]) providerHelper.getGenericData(
- KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
- KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
- String fingerprint = KeyFormattingUtils.convertFingerprintToHex(blob);
-
- Intent queryIntent = new Intent(getActivity(), ImportKeysActivity.class);
- queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT);
- queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint);
-
- startActivityForResult(queryIntent, 0);
- }
-
- private void certify(Uri dataUri) {
- long keyId = 0;
- try {
- keyId = new ProviderHelper(getActivity())
- .getCachedPublicKeyRing(dataUri)
- .extractOrGetMasterKeyId();
- } catch (PgpKeyNotFoundException e) {
- Log.e(Constants.TAG, "key not found!", e);
- }
- Intent certifyIntent = new Intent(getActivity(), CertifyKeyActivity.class);
- certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{keyId});
- startActivityForResult(certifyIntent, 0);
- }
-
- private void editKey(Uri dataUri) {
- Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
- editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri));
- startActivityForResult(editIntent, 0);
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java
deleted file mode 100644
index aa260b654..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.annotation.TargetApi;
-import android.content.Intent;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.PorterDuff;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AlphaAnimation;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.ui.util.Notify;
-import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.IOException;
-
-
-public class ViewKeyShareFragment extends LoaderFragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
-
- public static final String ARG_DATA_URI = "uri";
-
- private TextView mFingerprint;
- private ImageView mFingerprintQrCode;
- private View mFingerprintShareButton;
- private View mFingerprintClipboardButton;
- private View mKeyShareButton;
- private View mKeyClipboardButton;
- private ImageButton mKeySafeSlingerButton;
- private View mNfcHelpButton;
- private View mNfcPrefsButton;
- private View mKeyUploadButton;
-
- ProviderHelper mProviderHelper;
-
- private static final int LOADER_ID_UNIFIED = 0;
-
- private Uri mDataUri;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
- View root = super.onCreateView(inflater, superContainer, savedInstanceState);
- View view = inflater.inflate(R.layout.view_key_share_fragment, getContainer());
-
- mProviderHelper = new ProviderHelper(ViewKeyShareFragment.this.getActivity());
-
- mFingerprint = (TextView) view.findViewById(R.id.view_key_fingerprint);
- mFingerprintQrCode = (ImageView) view.findViewById(R.id.view_key_fingerprint_qr_code_image);
- mFingerprintShareButton = view.findViewById(R.id.view_key_action_fingerprint_share);
- mFingerprintClipboardButton = view.findViewById(R.id.view_key_action_fingerprint_clipboard);
- mKeyShareButton = view.findViewById(R.id.view_key_action_key_share);
- mKeyClipboardButton = view.findViewById(R.id.view_key_action_key_clipboard);
- mKeySafeSlingerButton = (ImageButton) view.findViewById(R.id.view_key_action_key_safeslinger);
- mNfcHelpButton = view.findViewById(R.id.view_key_action_nfc_help);
- mNfcPrefsButton = view.findViewById(R.id.view_key_action_nfc_prefs);
- mKeyUploadButton = view.findViewById(R.id.view_key_action_upload);
-
- mKeySafeSlingerButton.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
- PorterDuff.Mode.SRC_IN);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- mNfcPrefsButton.setVisibility(View.VISIBLE);
- } else {
- mNfcPrefsButton.setVisibility(View.GONE);
- }
-
- mFingerprintQrCode.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showQrCodeDialog();
- }
- });
-
- mFingerprintShareButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- share(mDataUri, mProviderHelper, true, false);
- }
- });
- mFingerprintClipboardButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- share(mDataUri, mProviderHelper, true, true);
- }
- });
- mKeyShareButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- share(mDataUri, mProviderHelper, false, false);
- }
- });
- mKeyClipboardButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- share(mDataUri, mProviderHelper, false, true);
- }
- });
- mKeySafeSlingerButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startSafeSlinger(mDataUri);
- }
- });
- mNfcHelpButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showNfcHelpDialog();
- }
- });
- mNfcPrefsButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showNfcPrefs();
- }
- });
- mKeyUploadButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- uploadToKeyserver();
- }
- });
-
- return root;
- }
-
- private void startSafeSlinger(Uri dataUri) {
- long keyId = 0;
- try {
- keyId = new ProviderHelper(getActivity())
- .getCachedPublicKeyRing(dataUri)
- .extractOrGetMasterKeyId();
- } catch (PgpKeyNotFoundException e) {
- Log.e(Constants.TAG, "key not found!", e);
- }
- Intent safeSlingerIntent = new Intent(getActivity(), SafeSlingerActivity.class);
- safeSlingerIntent.putExtra(SafeSlingerActivity.EXTRA_MASTER_KEY_ID, keyId);
- startActivityForResult(safeSlingerIntent, 0);
- }
-
- private void share(Uri dataUri, ProviderHelper providerHelper, boolean fingerprintOnly,
- boolean toClipboard) {
- try {
- String content;
- if (fingerprintOnly) {
- byte[] data = (byte[]) providerHelper.getGenericData(
- KeyRings.buildUnifiedKeyRingUri(dataUri),
- Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
- String fingerprint = KeyFormattingUtils.convertFingerprintToHex(data);
- if (!toClipboard) {
- content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
- } else {
- content = fingerprint;
- }
- } else {
- Uri uri = KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri);
- // get public keyring as ascii armored string
- content = providerHelper.getKeyRingAsArmoredString(uri);
- }
-
- if (toClipboard) {
- ClipboardReflection.copyToClipboard(getActivity(), content);
- String message;
- if (fingerprintOnly) {
- message = getResources().getString(R.string.fingerprint_copied_to_clipboard);
- } else {
- message = getResources().getString(R.string.key_copied_to_clipboard);
- }
- Notify.showNotify(getActivity(), message, Notify.Style.OK);
- } else {
- // Android will fail with android.os.TransactionTooLargeException if key is too big
- // see http://www.lonestarprod.com/?p=34
- if (content.length() >= 86389) {
- Notify.showNotify(getActivity(), R.string.key_too_big_for_sharing,
- Notify.Style.ERROR);
- return;
- }
-
- // let user choose application
- Intent sendIntent = new Intent(Intent.ACTION_SEND);
- sendIntent.putExtra(Intent.EXTRA_TEXT, content);
- sendIntent.setType("text/plain");
- String title;
- if (fingerprintOnly) {
- title = getResources().getString(R.string.title_share_fingerprint_with);
- } else {
- title = getResources().getString(R.string.title_share_key);
- }
- startActivity(Intent.createChooser(sendIntent, title));
- }
- } catch (PgpGeneralException e) {
- Log.e(Constants.TAG, "error processing key!", e);
- Notify.showNotify(getActivity(), R.string.error_key_processing, Notify.Style.ERROR);
- } catch (IOException e) {
- Log.e(Constants.TAG, "error processing key!", e);
- Notify.showNotify(getActivity(), R.string.error_key_processing, Notify.Style.ERROR);
- } catch (ProviderHelper.NotFoundException e) {
- Log.e(Constants.TAG, "key not found!", e);
- Notify.showNotify(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR);
- }
- }
-
- private void showQrCodeDialog() {
- Intent qrCodeIntent = new Intent(getActivity(), QrCodeViewActivity.class);
- qrCodeIntent.setData(mDataUri);
- startActivity(qrCodeIntent);
- }
-
- private void showNfcHelpDialog() {
- ShareNfcDialogFragment dialog = ShareNfcDialogFragment.newInstance();
- dialog.show(getActivity().getSupportFragmentManager(), "shareNfcDialog");
- }
-
- @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void showNfcPrefs() {
- Intent intentSettings = new Intent(
- Settings.ACTION_NFCSHARING_SETTINGS);
- startActivity(intentSettings);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
- if (dataUri == null) {
- Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
- getActivity().finish();
- return;
- }
-
- loadData(dataUri);
- }
-
- private void loadData(Uri dataUri) {
- mDataUri = dataUri;
-
- Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
-
- // Prepare the loaders. Either re-connect with an existing ones,
- // or start new ones.
- getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
- }
-
- static final String[] UNIFIED_PROJECTION = new String[]{
- KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET,
- KeyRings.USER_ID, KeyRings.FINGERPRINT,
- KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,
-
- };
- static final int INDEX_UNIFIED_MASTER_KEY_ID = 1;
- static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
- static final int INDEX_UNIFIED_USER_ID = 3;
- static final int INDEX_UNIFIED_FINGERPRINT = 4;
- static final int INDEX_UNIFIED_ALGORITHM = 5;
- static final int INDEX_UNIFIED_KEY_SIZE = 6;
- static final int INDEX_UNIFIED_CREATION = 7;
- static final int INDEX_UNIFIED_EXPIRY = 8;
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- setContentShown(false);
- switch (id) {
- case LOADER_ID_UNIFIED: {
- Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
- return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
- }
-
- default:
- return null;
- }
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- /* TODO better error handling? May cause problems when a key is deleted,
- * because the notification triggers faster than the activity closes.
- */
- // Avoid NullPointerExceptions...
- if (data.getCount() == 0) {
- return;
- }
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- switch (loader.getId()) {
- case LOADER_ID_UNIFIED: {
- if (data.moveToFirst()) {
-
- byte[] fingerprintBlob = data.getBlob(INDEX_UNIFIED_FINGERPRINT);
- String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fingerprintBlob);
- mFingerprint.setText(KeyFormattingUtils.colorizeFingerprint(fingerprint));
-
- loadQrCode(fingerprint);
-
- break;
- }
- }
-
- }
- setContentShown(true);
- }
-
- /**
- * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
- * We need to make sure we are no longer using it.
- */
- public void onLoaderReset(Loader<Cursor> loader) {
- }
-
- /**
- * Load QR Code asynchronously and with a fade in animation
- *
- * @param fingerprint
- */
- private void loadQrCode(final String fingerprint) {
- AsyncTask<Void, Void, Bitmap> loadTask =
- new AsyncTask<Void, Void, Bitmap>() {
- protected Bitmap doInBackground(Void... unused) {
- String qrCodeContent = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
- // render with minimal size
- return QrCodeUtils.getQRCodeBitmap(qrCodeContent, 0);
- }
-
- protected void onPostExecute(Bitmap qrCode) {
- // only change view, if fragment is attached to activity
- if (ViewKeyShareFragment.this.isAdded()) {
-
- // scale the image up to our actual size. we do this in code rather
- // than let the ImageView do this because we don't require filtering.
- Bitmap scaled = Bitmap.createScaledBitmap(qrCode,
- mFingerprintQrCode.getHeight(), mFingerprintQrCode.getHeight(),
- false);
- mFingerprintQrCode.setImageBitmap(scaled);
-
- // simple fade-in animation
- AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
- anim.setDuration(200);
- mFingerprintQrCode.startAnimation(anim);
- }
- }
- };
-
- loadTask.execute();
- }
-
- private void uploadToKeyserver() {
- Intent uploadIntent = new Intent(getActivity(), UploadKeyActivity.class);
- uploadIntent.setData(mDataUri);
- startActivityForResult(uploadIntent, 0);
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
index 677646441..5483d16b8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
@@ -62,6 +62,8 @@ import java.util.List;
public class ViewKeyTrustFragment extends LoaderFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
+ public static final String ARG_DATA_URI = "uri";
+
private View mStartSearch;
private TextView mTrustReadout;
private TextView mReportHeader;
@@ -100,7 +102,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- Uri dataUri = getArguments().getParcelable(ViewKeyMainFragment.ARG_DATA_URI);
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
if (dataUri == null) {
Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
getActivity().finish();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
index f3dce5823..6ba9e26ad 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
@@ -95,8 +95,8 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
* @see org.sufficientlysecure.keychain.operations.ImportExportOperation
*/
public ArrayList<ImportKeysListEntry> getSelectedEntries() {
- ArrayList<ImportKeysListEntry> result = new ArrayList<ImportKeysListEntry>();
- ArrayList<ImportKeysListEntry> secrets = new ArrayList<ImportKeysListEntry>();
+ ArrayList<ImportKeysListEntry> result = new ArrayList<>();
+ ArrayList<ImportKeysListEntry> secrets = new ArrayList<>();
if (mData == null) {
return result;
}
@@ -175,9 +175,9 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
}
if (entry.isRevoked()) {
- KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, KeyFormattingUtils.STATE_REVOKED, true);
+ KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
} else if (entry.isExpired()) {
- KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, KeyFormattingUtils.STATE_EXPIRED, true);
+ KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
}
if (entry.isRevoked() || entry.isExpired()) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java
index 176c3ff5b..4781864dd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java
@@ -21,13 +21,13 @@ import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.keyimport.CloudSearch;
+import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.Keyserver;
import org.sufficientlysecure.keychain.operations.results.GetKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.util.Preferences;
-import org.sufficientlysecure.keychain.keyimport.CloudSearch;
-import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Preferences;
import java.util.ArrayList;
@@ -39,7 +39,7 @@ public class ImportKeysListCloudLoader
Preferences.CloudSearchPrefs mCloudPrefs;
String mServerQuery;
- private ArrayList<ImportKeysListEntry> mEntryList = new ArrayList<ImportKeysListEntry>();
+ private ArrayList<ImportKeysListEntry> mEntryList = new ArrayList<>();
private AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper;
public ImportKeysListCloudLoader(Context context, String serverQuery, Preferences.CloudSearchPrefs cloudPrefs) {
@@ -51,7 +51,7 @@ public class ImportKeysListCloudLoader
@Override
public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() {
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, null);
+ mEntryListWrapper = new AsyncTaskResultWrapper<>(mEntryList, null);
if (mServerQuery == null) {
Log.e(Constants.TAG, "mServerQuery is null!");
@@ -119,7 +119,7 @@ public class ImportKeysListCloudLoader
mEntryList.addAll(searchResult);
}
GetKeyResult getKeyResult = new GetKeyResult(GetKeyResult.RESULT_OK, null);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, getKeyResult);
+ mEntryListWrapper = new AsyncTaskResultWrapper<>(mEntryList, getKeyResult);
} catch (Keyserver.CloudSearchFailureException e) {
// convert exception to result parcel
int error = GetKeyResult.RESULT_ERROR;
@@ -140,7 +140,7 @@ public class ImportKeysListCloudLoader
OperationResult.OperationLog log = new OperationResult.OperationLog();
log.add(logType, 0);
GetKeyResult getKeyResult = new GetKeyResult(error, log);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, getKeyResult);
+ mEntryListWrapper = new AsyncTaskResultWrapper<>(mEntryList, getKeyResult);
}
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
index 41c7e0cbc..5447c5f96 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
@@ -24,9 +24,10 @@ import android.support.v4.util.LongSparseArray;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
-import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.operations.results.GetKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
@@ -34,28 +35,15 @@ import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Iterator;
public class ImportKeysListLoader
extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
- public static class NonPgpPartException extends Exception {
- private int mCount;
-
- public NonPgpPartException(int count) {
- this.mCount = count;
- }
-
- public int getCount() {
- return mCount;
- }
- }
-
final Context mContext;
final InputData mInputData;
- ArrayList<ImportKeysListEntry> mData = new ArrayList<ImportKeysListEntry>();
- LongSparseArray<ParcelableKeyRing> mParcelableRings = new LongSparseArray<ParcelableKeyRing>();
+ ArrayList<ImportKeysListEntry> mData = new ArrayList<>();
+ LongSparseArray<ParcelableKeyRing> mParcelableRings = new LongSparseArray<>();
AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper;
public ImportKeysListLoader(Context context, InputData inputData) {
@@ -72,7 +60,7 @@ public class ImportKeysListLoader
}
GetKeyResult getKeyResult = new GetKeyResult(GetKeyResult.RESULT_OK, null);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mData, getKeyResult);
+ mEntryListWrapper = new AsyncTaskResultWrapper<>(mData, getKeyResult);
if (mInputData == null) {
Log.e(Constants.TAG, "Input data is null!");
@@ -127,7 +115,7 @@ public class ImportKeysListLoader
BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
try {
// parse all keyrings
- Iterator<UncachedKeyRing> it = UncachedKeyRing.fromStream(bufferedInput);
+ IteratorWithIOThrow<UncachedKeyRing> it = UncachedKeyRing.fromStream(bufferedInput);
while (it.hasNext()) {
UncachedKeyRing ring = it.next();
ImportKeysListEntry item = new ImportKeysListEntry(getContext(), ring);
@@ -139,7 +127,7 @@ public class ImportKeysListLoader
OperationResult.OperationLog log = new OperationResult.OperationLog();
log.add(OperationResult.LogType.MSG_GET_NO_VALID_KEYS, 0);
GetKeyResult getKeyResult = new GetKeyResult(GetKeyResult.RESULT_ERROR_NO_VALID_KEYS, log);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
+ mEntryListWrapper = new AsyncTaskResultWrapper<>
(mData, getKeyResult);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java
index 80d605fb9..b8fe21941 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java
@@ -33,7 +33,7 @@ public class KeyValueSpinnerAdapter extends ArrayAdapter<String> {
static <K, V extends Comparable<? super V>> SortedSet<Map.Entry<K, V>> entriesSortedByValues(
Map<K, V> map) {
- SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
+ SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<>(
new Comparator<Map.Entry<K, V>>() {
@Override
public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java
index 9f29826ef..015775669 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java
@@ -21,13 +21,13 @@ import android.content.Context;
import android.database.Cursor;
import android.os.Parcel;
import android.support.v4.util.LongSparseArray;
+import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
-import android.support.v4.widget.CursorAdapter;
import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
@@ -44,7 +44,7 @@ public class MultiUserIdsAdapter extends CursorAdapter {
public MultiUserIdsAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
mInflater = LayoutInflater.from(context);
- mCheckStates = new ArrayList<Boolean>();
+ mCheckStates = new ArrayList<>();
}
@Override
@@ -148,7 +148,7 @@ public class MultiUserIdsAdapter extends CursorAdapter {
}
public ArrayList<CertifyAction> getSelectedCertifyActions() {
- LongSparseArray<CertifyAction> actions = new LongSparseArray<CertifyAction>();
+ LongSparseArray<CertifyAction> actions = new LongSparseArray<>();
for (int i = 0; i < mCheckStates.size(); i++) {
if (mCheckStates.get(i)) {
mCursor.moveToPosition(i);
@@ -171,7 +171,7 @@ public class MultiUserIdsAdapter extends CursorAdapter {
}
}
- ArrayList<CertifyAction> result = new ArrayList<CertifyAction>(actions.size());
+ ArrayList<CertifyAction> result = new ArrayList<>(actions.size());
for (int i = 0; i < actions.size(); i++) {
result.add(actions.valueAt(i));
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java
index 330254a8f..963e77fe9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java
@@ -27,7 +27,7 @@ import java.util.ArrayList;
public class PagerTabStripAdapter extends FragmentPagerAdapter {
protected final Activity mActivity;
- protected final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
+ protected final ArrayList<TabInfo> mTabs = new ArrayList<>();
static final class TabInfo {
public final Class<?> clss;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
index 60c130969..a836b35df 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
@@ -30,9 +30,9 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.ui.util.Highlighter;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
/**
@@ -133,11 +133,11 @@ abstract public class SelectKeyCursorAdapter extends CursorAdapter {
boolean enabled;
if (cursor.getInt(mIndexIsRevoked) != 0) {
h.statusIcon.setVisibility(View.VISIBLE);
- KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, KeyFormattingUtils.STATE_REVOKED, true);
+ KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
enabled = false;
} else if (cursor.getInt(mIndexIsExpiry) != 0) {
h.statusIcon.setVisibility(View.VISIBLE);
- KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, KeyFormattingUtils.STATE_EXPIRED, true);
+ KeyFormattingUtils.setStatusImage(mContext, h.statusIcon, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
enabled = false;
} else {
h.statusIcon.setVisibility(View.GONE);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java
index a032e96fc..ff5fbb49a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java
@@ -35,11 +35,11 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.util.Calendar;
import java.util.Date;
@@ -160,7 +160,11 @@ public class SubkeysAdapter extends CursorAdapter {
cursor.getString(INDEX_KEY_CURVE_OID)
));
- if (mSaveKeyringParcel != null && mSaveKeyringParcel.mStripSubKeys.contains(keyId)) {
+ SubkeyChange change = mSaveKeyringParcel != null
+ ? mSaveKeyringParcel.getSubkeyChange(keyId)
+ : null;
+
+ if (change != null && change.mDummyStrip) {
algorithmStr.append(", ");
final SpannableString boldStripped = new SpannableString(
context.getString(R.string.key_stripped)
@@ -268,12 +272,12 @@ public class SubkeysAdapter extends CursorAdapter {
PorterDuff.Mode.SRC_IN);
if (isRevoked) {
- vStatus.setImageResource(R.drawable.status_signature_revoked_cutout);
+ vStatus.setImageResource(R.drawable.status_signature_revoked_cutout_24px);
vStatus.setColorFilter(
mContext.getResources().getColor(R.color.bg_gray),
PorterDuff.Mode.SRC_IN);
} else if (isExpired) {
- vStatus.setImageResource(R.drawable.status_signature_expired_cutout);
+ vStatus.setImageResource(R.drawable.status_signature_expired_cutout_24px);
vStatus.setColorFilter(
mContext.getResources().getColor(R.color.bg_gray),
PorterDuff.Mode.SRC_IN);
@@ -297,7 +301,7 @@ public class SubkeysAdapter extends CursorAdapter {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- View view = mInflater.inflate(R.layout.view_key_subkey_item, null);
+ View view = mInflater.inflate(R.layout.view_key_adv_subkey_item, null);
if (mDefaultTextColor == null) {
TextView keyId = (TextView) view.findViewById(R.id.subkey_item_key_id);
mDefaultTextColor = keyId.getTextColors();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java
index 9f5d5341e..d2359a387 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java
@@ -31,8 +31,8 @@ import android.widget.TextView;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.util.Calendar;
import java.util.Date;
@@ -68,7 +68,7 @@ public class SubkeysAddedAdapter extends ArrayAdapter<SaveKeyringParcel.SubkeyAd
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
// Not recycled, inflate a new view
- convertView = mInflater.inflate(R.layout.view_key_subkey_item, null);
+ convertView = mInflater.inflate(R.layout.view_key_adv_subkey_item, null);
final ViewHolder holder = new ViewHolder();
holder.vKeyId = (TextView) convertView.findViewById(R.id.subkey_item_key_id);
holder.vKeyDetails = (TextView) convertView.findViewById(R.id.subkey_item_details);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
index 9ddfa90be..44afed351 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
@@ -33,7 +33,7 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
- private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
+ private final ArrayList<TabInfo> mTabs = new ArrayList<>();
static final class TabInfo {
public final Class<?> clss;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
index a2e1930d3..ad7c9e430 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
@@ -19,7 +19,6 @@ package org.sufficientlysecure.keychain.ui.adapter;
import android.content.Context;
import android.database.Cursor;
-import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
@@ -32,10 +31,9 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
@@ -45,14 +43,15 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
private LayoutInflater mInflater;
private final ArrayList<Boolean> mCheckStates;
private SaveKeyringParcel mSaveKeyringParcel;
+ private boolean mShowStatusImages;
public static final String[] USER_IDS_PROJECTION = new String[]{
- UserIds._ID,
- UserIds.USER_ID,
- UserIds.RANK,
- UserIds.VERIFIED,
- UserIds.IS_PRIMARY,
- UserIds.IS_REVOKED
+ UserPackets._ID,
+ UserPackets.USER_ID,
+ UserPackets.RANK,
+ UserPackets.VERIFIED,
+ UserPackets.IS_PRIMARY,
+ UserPackets.IS_REVOKED
};
private static final int INDEX_ID = 0;
private static final int INDEX_USER_ID = 1;
@@ -62,24 +61,30 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
private static final int INDEX_IS_REVOKED = 5;
public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes,
- SaveKeyringParcel saveKeyringParcel) {
+ boolean showStatusImages, SaveKeyringParcel saveKeyringParcel) {
super(context, c, flags);
mInflater = LayoutInflater.from(context);
mCheckStates = showCheckBoxes ? new ArrayList<Boolean>() : null;
mSaveKeyringParcel = saveKeyringParcel;
+ mShowStatusImages = showStatusImages;
+ }
+
+ public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes,
+ SaveKeyringParcel saveKeyringParcel) {
+ this(context, c, flags, showCheckBoxes, false, saveKeyringParcel);
}
public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes) {
- this(context, c, flags, showCheckBoxes, null);
+ this(context, c, flags, showCheckBoxes, false, null);
}
public UserIdsAdapter(Context context, Cursor c, int flags, SaveKeyringParcel saveKeyringParcel) {
- this(context, c, flags, false, saveKeyringParcel);
+ this(context, c, flags, false, false, saveKeyringParcel);
}
public UserIdsAdapter(Context context, Cursor c, int flags) {
- this(context, c, flags, false, null);
+ this(context, c, flags, false, false, null);
}
@Override
@@ -159,12 +164,17 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
vVerifiedLayout.setVisibility(View.GONE);
} else {
vEditImage.setVisibility(View.GONE);
- vVerifiedLayout.setVisibility(View.VISIBLE);
+
+ if (mShowStatusImages) {
+ vVerifiedLayout.setVisibility(View.VISIBLE);
+ } else {
+ vVerifiedLayout.setVisibility(View.GONE);
+ }
}
if (isRevoked) {
// set revocation icon (can this even be primary?)
- KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_REVOKED, true);
+ KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
// disable revoked user ids
vName.setEnabled(false);
@@ -186,13 +196,13 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
int isVerified = cursor.getInt(INDEX_VERIFIED);
switch (isVerified) {
case Certs.VERIFIED_SECRET:
- KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_VERIFIED, false);
+ KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break;
case Certs.VERIFIED_SELF:
- KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_UNVERIFIED, false);
+ KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break;
default:
- KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_INVALID, false);
+ KeyFormattingUtils.setStatusImage(mContext, vVerified, null, KeyFormattingUtils.STATE_INVALID, KeyFormattingUtils.DEFAULT_COLOR);
break;
}
}
@@ -223,7 +233,7 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
}
public ArrayList<String> getSelectedUserIds() {
- ArrayList<String> result = new ArrayList<String>();
+ ArrayList<String> result = new ArrayList<>();
for (int i = 0; i < mCheckStates.size(); i++) {
if (mCheckStates.get(i)) {
mCursor.moveToPosition(i);
@@ -265,7 +275,7 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- View view = mInflater.inflate(R.layout.view_key_user_id_item, null);
+ View view = mInflater.inflate(R.layout.view_key_adv_user_id_item, null);
// only need to do this once ever, since mShowCheckBoxes is final
view.findViewById(R.id.user_id_item_check_box).setVisibility(mCheckStates != null ? View.VISIBLE : View.GONE);
return view;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java
index 4c0e7a492..01218a4e4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java
@@ -64,7 +64,7 @@ public class UserIdsAddedAdapter extends ArrayAdapter<String> {
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
// Not recycled, inflate a new view
- convertView = mInflater.inflate(R.layout.view_key_user_id_item, null);
+ convertView = mInflater.inflate(R.layout.view_key_adv_user_id_item, null);
final ViewHolder holder = new ViewHolder();
holder.vAddress = (TextView) convertView.findViewById(R.id.user_id_item_address);
holder.vName = (TextView) convertView.findViewById(R.id.user_id_item_name);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java
index b4119a5eb..d5376cbdc 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java
@@ -145,20 +145,20 @@ public class AddSubkeyDialogFragment extends DialogFragment {
}
{
- ArrayList<Choice<Algorithm>> choices = new ArrayList<Choice<Algorithm>>();
- choices.add(new Choice<Algorithm>(Algorithm.DSA, getResources().getString(
+ ArrayList<Choice<Algorithm>> choices = new ArrayList<>();
+ choices.add(new Choice<>(Algorithm.DSA, getResources().getString(
R.string.dsa)));
if (!mWillBeMasterKey) {
- choices.add(new Choice<Algorithm>(Algorithm.ELGAMAL, getResources().getString(
+ choices.add(new Choice<>(Algorithm.ELGAMAL, getResources().getString(
R.string.elgamal)));
}
- choices.add(new Choice<Algorithm>(Algorithm.RSA, getResources().getString(
+ choices.add(new Choice<>(Algorithm.RSA, getResources().getString(
R.string.rsa)));
- choices.add(new Choice<Algorithm>(Algorithm.ECDSA, getResources().getString(
+ choices.add(new Choice<>(Algorithm.ECDSA, getResources().getString(
R.string.ecdsa)));
- choices.add(new Choice<Algorithm>(Algorithm.ECDH, getResources().getString(
+ choices.add(new Choice<>(Algorithm.ECDH, getResources().getString(
R.string.ecdh)));
- ArrayAdapter<Choice<Algorithm>> adapter = new ArrayAdapter<Choice<Algorithm>>(context,
+ ArrayAdapter<Choice<Algorithm>> adapter = new ArrayAdapter<>(context,
android.R.layout.simple_spinner_item, choices);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mAlgorithmSpinner.setAdapter(adapter);
@@ -172,20 +172,20 @@ public class AddSubkeyDialogFragment extends DialogFragment {
}
// dynamic ArrayAdapter must be created (instead of ArrayAdapter.getFromResource), because it's content may change
- ArrayAdapter<CharSequence> keySizeAdapter = new ArrayAdapter<CharSequence>(context, android.R.layout.simple_spinner_item,
+ ArrayAdapter<CharSequence> keySizeAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item,
new ArrayList<CharSequence>(Arrays.asList(getResources().getStringArray(R.array.rsa_key_size_spinner_values))));
keySizeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mKeySizeSpinner.setAdapter(keySizeAdapter);
mKeySizeSpinner.setSelection(1); // Default to 4096 for the key length
{
- ArrayList<Choice<Curve>> choices = new ArrayList<Choice<Curve>>();
+ ArrayList<Choice<Curve>> choices = new ArrayList<>();
- choices.add(new Choice<Curve>(Curve.NIST_P256, getResources().getString(
+ choices.add(new Choice<>(Curve.NIST_P256, getResources().getString(
R.string.key_curve_nist_p256)));
- choices.add(new Choice<Curve>(Curve.NIST_P384, getResources().getString(
+ choices.add(new Choice<>(Curve.NIST_P384, getResources().getString(
R.string.key_curve_nist_p384)));
- choices.add(new Choice<Curve>(Curve.NIST_P521, getResources().getString(
+ choices.add(new Choice<>(Curve.NIST_P521, getResources().getString(
R.string.key_curve_nist_p521)));
/* @see SaveKeyringParcel
@@ -197,7 +197,7 @@ public class AddSubkeyDialogFragment extends DialogFragment {
R.string.key_curve_bp_p512)));
*/
- ArrayAdapter<Choice<Curve>> adapter = new ArrayAdapter<Choice<Curve>>(context,
+ ArrayAdapter<Choice<Curve>> adapter = new ArrayAdapter<>(context,
android.R.layout.simple_spinner_item, choices);
mCurveSpinner.setAdapter(adapter);
// make NIST P-256 the default
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java
index 3eef04aa7..094c4d8a9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java
@@ -45,8 +45,8 @@ import android.widget.TextView.OnEditorActionListener;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.Log;
import java.util.regex.Matcher;
@@ -85,7 +85,7 @@ public class AddUserIdDialogFragment extends DialogFragment implements OnEditorA
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
String predefinedName = getArguments().getString(ARG_NAME);
- ArrayAdapter<String> autoCompleteEmailAdapter = new ArrayAdapter<String>
+ ArrayAdapter<String> autoCompleteEmailAdapter = new ArrayAdapter<>
(getActivity(), android.R.layout.simple_spinner_dropdown_item,
ContactHelper.getPossibleUserEmails(getActivity())
);
@@ -150,7 +150,7 @@ public class AddUserIdDialogFragment extends DialogFragment implements OnEditorA
mName.setThreshold(1); // Start working from first character
mName.setAdapter(
- new ArrayAdapter<String>
+ new ArrayAdapter<>
(getActivity(), android.R.layout.simple_spinner_dropdown_item,
ContactHelper.getPossibleUserNames(getActivity())
)
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AdvancedAppSettingsDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AdvancedAppSettingsDialogFragment.java
new file mode 100644
index 000000000..d2fa37cf7
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AdvancedAppSettingsDialogFragment.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.dialog;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.FragmentActivity;
+
+import org.sufficientlysecure.keychain.R;
+
+public class AdvancedAppSettingsDialogFragment extends DialogFragment {
+ private static final String ARG_PACKAGE_NAME = "package_name";
+ private static final String ARG_SIGNATURE = "signature";
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static AdvancedAppSettingsDialogFragment newInstance(String packageName, String digest) {
+ AdvancedAppSettingsDialogFragment frag = new AdvancedAppSettingsDialogFragment();
+ Bundle args = new Bundle();
+ args.putString(ARG_PACKAGE_NAME, packageName);
+ args.putString(ARG_SIGNATURE, digest);
+
+ frag.setArguments(args);
+ return frag;
+ }
+
+ /**
+ * Creates dialog
+ */
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final FragmentActivity activity = getActivity();
+
+ CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
+
+ alert.setTitle(R.string.api_settings_advanced);
+ alert.setCancelable(true);
+
+ alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ dismiss();
+ }
+ });
+
+ String packageName = getArguments().getString(ARG_PACKAGE_NAME);
+ String signature = getArguments().getString(ARG_SIGNATURE);
+
+ alert.setMessage(getString(R.string.api_settings_package_name) + ": " + packageName + "\n\n"
+ + getString(R.string.api_settings_package_signature) + ": " + signature);
+
+ return alert.show();
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java
index aa27e8391..d405b1dda 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CustomAlertDialogBuilder.java
@@ -26,13 +26,13 @@ public class CustomAlertDialogBuilder extends AlertDialog.Builder {
int dividerId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
View divider = dialog.findViewById(dividerId);
if (divider != null) {
- divider.setBackgroundColor(dialog.getContext().getResources().getColor(R.color.emphasis));
+ divider.setBackgroundColor(dialog.getContext().getResources().getColor(R.color.header_text));
}
int textViewId = dialog.getContext().getResources().getIdentifier("android:id/alertTitle", null, null);
TextView tv = (TextView) dialog.findViewById(textViewId);
if (tv != null) {
- tv.setTextColor(dialog.getContext().getResources().getColor(R.color.emphasis));
+ tv.setTextColor(dialog.getContext().getResources().getColor(R.color.header_text));
}
return dialog;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
index 42e21cd57..879e3f6da 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
@@ -18,6 +18,7 @@
package org.sufficientlysecure.keychain.ui.dialog;
import android.app.Dialog;
+import android.content.ContentResolver;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Build;
@@ -30,6 +31,8 @@ import android.widget.Toast;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.FileHelper;
+import java.io.File;
+
public class DeleteFileDialogFragment extends DialogFragment {
private static final String ARG_DELETE_URI = "delete_uri";
@@ -69,21 +72,38 @@ public class DeleteFileDialogFragment extends DialogFragment {
@Override
public void onClick(DialogInterface dialog, int id) {
dismiss();
+ String scheme = deleteUri.getScheme();
- // We can not securely delete Uris, so just use usual delete on them
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- if (DocumentsContract.deleteDocument(getActivity().getContentResolver(), deleteUri)) {
+ if(scheme.equals(ContentResolver.SCHEME_FILE)) {
+ if(new File(deleteUri.getPath()).delete()) {
Toast.makeText(getActivity(), R.string.file_delete_successful, Toast.LENGTH_SHORT).show();
return;
}
}
+ else if(scheme.equals(ContentResolver.SCHEME_CONTENT)) {
+ // We can not securely delete Uris, so just use usual delete on them
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if (DocumentsContract.deleteDocument(getActivity().getContentResolver(), deleteUri)) {
+ Toast.makeText(getActivity(), R.string.file_delete_successful, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ }
- if (getActivity().getContentResolver().delete(deleteUri, null, null) > 0) {
- Toast.makeText(getActivity(), R.string.file_delete_successful, Toast.LENGTH_SHORT).show();
- return;
+ if (getActivity().getContentResolver().delete(deleteUri, null, null) > 0) {
+ Toast.makeText(getActivity(), R.string.file_delete_successful, Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ // some Uri's a ContentResolver fails to delete is handled by the java.io.File's delete
+ // via the path of the Uri
+ if(new File(deleteUri.getPath()).delete()) {
+ Toast.makeText(getActivity(), R.string.file_delete_successful, Toast.LENGTH_SHORT).show();
+ return;
+ }
}
- Toast.makeText(getActivity(), getActivity().getString(R.string.error_file_delete_failed, deleteFilename), Toast.LENGTH_SHORT).show();
+ Toast.makeText(getActivity(), getActivity().getString(R.string.error_file_delete_failed,
+ deleteFilename), Toast.LENGTH_SHORT).show();
// Note: We can't delete every file...
// If possible we should find out if deletion is possible before even showing the option to do so.
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
index 1cc800b2b..7ac85781f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
@@ -37,9 +37,9 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.ui.util.Notify;
import java.io.File;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ActionBarHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ActionBarHelper.java
deleted file mode 100644
index edd12ec73..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ActionBarHelper.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * This program 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.util;
-
-import android.app.Activity;
-import android.support.v7.app.ActionBar;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.R;
-
-public class ActionBarHelper {
-
- /**
- * Sets custom view on ActionBar for Done/Cancel activities
- *
- * @param actionBar
- * @param firstText
- * @param firstDrawableId
- * @param firstOnClickListener
- * @param secondText
- * @param secondDrawableId
- * @param secondOnClickListener
- */
- public static void setTwoButtonView(ActionBar actionBar,
- int firstText, int firstDrawableId, OnClickListener firstOnClickListener,
- int secondText, int secondDrawableId, OnClickListener secondOnClickListener) {
-
- // Inflate the custom action bar view
- final LayoutInflater inflater = (LayoutInflater) actionBar.getThemedContext()
- .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
- final View customActionBarView = inflater.inflate(
- R.layout.actionbar_custom_view_done_cancel, null);
-
- TextView firstTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text));
- firstTextView.setText(firstText);
- firstTextView.setCompoundDrawablesWithIntrinsicBounds(firstDrawableId, 0, 0, 0);
- customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
- firstOnClickListener);
- TextView secondTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_cancel_text));
- secondTextView.setText(secondText);
- secondTextView.setCompoundDrawablesWithIntrinsicBounds(secondDrawableId, 0, 0, 0);
- customActionBarView.findViewById(R.id.actionbar_cancel).setOnClickListener(
- secondOnClickListener);
-
- // Show the custom action bar view and hide the normal Home icon and title.
- actionBar.setDisplayShowTitleEnabled(false);
- actionBar.setDisplayShowHomeEnabled(false);
- actionBar.setDisplayShowCustomEnabled(true);
- actionBar.setCustomView(customActionBarView, new ActionBar.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- }
-
- /**
- * Sets custom view on ActionBar for Done activities
- *
- * @param actionBar
- * @param firstText
- * @param firstOnClickListener
- */
- public static void setOneButtonView(ActionBar actionBar, int firstText, int firstDrawableId,
- OnClickListener firstOnClickListener) {
- // Inflate a "Done" custom action bar view to serve as the "Up" affordance.
- final LayoutInflater inflater = (LayoutInflater) actionBar.getThemedContext()
- .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
- final View customActionBarView = inflater
- .inflate(R.layout.actionbar_custom_view_done, null);
-
- TextView firstTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text));
- firstTextView.setText(firstText);
- firstTextView.setCompoundDrawablesWithIntrinsicBounds(firstDrawableId, 0, 0, 0);
- customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
- firstOnClickListener);
-
- // Show the custom action bar view and hide the normal Home icon and title.
- actionBar.setDisplayShowTitleEnabled(false);
- actionBar.setDisplayShowHomeEnabled(false);
- actionBar.setDisplayShowCustomEnabled(true);
- actionBar.setCustomView(customActionBarView);
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/FormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/FormattingUtils.java
index 3f84bf490..eb5c3df45 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/FormattingUtils.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/FormattingUtils.java
@@ -24,18 +24,12 @@ import android.text.style.StrikethroughSpan;
public class FormattingUtils {
- public static SpannableStringBuilder strikeOutText(CharSequence text) {
- SpannableStringBuilder sb = new SpannableStringBuilder(text);
- sb.setSpan(new StrikethroughSpan(), 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- return sb;
- }
-
public static int dpToPx(Context context, int dp) {
- return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5);
+ return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5f);
}
public static int pxToDp(Context context, int px) {
- return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5);
+ return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5f);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
index bff7d6b27..38ed88b9c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java
@@ -377,6 +377,8 @@ public class KeyFormattingUtils {
((int) digest[2] + 256) % 256};
}
+ public static final int DEFAULT_COLOR = -1;
+
public static final int STATE_REVOKED = 1;
public static final int STATE_EXPIRED = 2;
public static final int STATE_VERIFIED = 3;
@@ -393,20 +395,32 @@ public class KeyFormattingUtils {
}
public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText, int state) {
- setStatusImage(context, statusIcon, statusText, state, false);
+ setStatusImage(context, statusIcon, statusText, state, KeyFormattingUtils.DEFAULT_COLOR, false);
+ }
+
+ public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText,
+ int state, int color) {
+ setStatusImage(context, statusIcon, statusText, state, color, false);
}
/**
* Sets status image based on constant
*/
public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText,
- int state, boolean unobtrusive) {
+ int state, int color, boolean big) {
switch (state) {
/** GREEN: everything is good **/
case STATE_VERIFIED: {
- statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_verified_cutout));
- int color = R.color.android_green_light;
+ if (big) {
+ statusIcon.setImageDrawable(
+ context.getResources().getDrawable(R.drawable.status_signature_verified_cutout_96px));
+ } else {
+ statusIcon.setImageDrawable(
+ context.getResources().getDrawable(R.drawable.status_signature_verified_cutout_24px));
+ }
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_green_light;
+ }
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
if (statusText != null) {
@@ -416,8 +430,10 @@ public class KeyFormattingUtils {
}
case STATE_ENCRYPTED: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_lock_closed));
- int color = R.color.android_green_light;
+ context.getResources().getDrawable(R.drawable.status_lock_closed_24px));
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_green_light;
+ }
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
if (statusText != null) {
@@ -427,9 +443,16 @@ public class KeyFormattingUtils {
}
/** ORANGE: mostly bad... **/
case STATE_UNVERIFIED: {
- statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout));
- int color = R.color.android_orange_light;
+ if (big) {
+ statusIcon.setImageDrawable(
+ context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout_96px));
+ } else {
+ statusIcon.setImageDrawable(
+ context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout_24px));
+ }
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_orange_light;
+ }
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
if (statusText != null) {
@@ -439,8 +462,10 @@ public class KeyFormattingUtils {
}
case STATE_UNKNOWN_KEY: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout));
- int color = R.color.android_orange_light;
+ context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24px));
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_orange_light;
+ }
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
if (statusText != null) {
@@ -450,11 +475,15 @@ public class KeyFormattingUtils {
}
/** RED: really bad... **/
case STATE_REVOKED: {
- statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout));
- int color = R.color.android_red_light;
- if (unobtrusive) {
- color = R.color.bg_gray;
+ if (big) {
+ statusIcon.setImageDrawable(
+ context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout_96px));
+ } else {
+ statusIcon.setImageDrawable(
+ context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout_24px));
+ }
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_red_light;
}
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
@@ -464,11 +493,15 @@ public class KeyFormattingUtils {
break;
}
case STATE_EXPIRED: {
- statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_expired_cutout));
- int color = R.color.android_red_light;
- if (unobtrusive) {
- color = R.color.bg_gray;
+ if (big) {
+ statusIcon.setImageDrawable(
+ context.getResources().getDrawable(R.drawable.status_signature_expired_cutout_96px));
+ } else {
+ statusIcon.setImageDrawable(
+ context.getResources().getDrawable(R.drawable.status_signature_expired_cutout_24px));
+ }
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_red_light;
}
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
@@ -479,8 +512,10 @@ public class KeyFormattingUtils {
}
case STATE_NOT_ENCRYPTED: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_lock_open));
- int color = R.color.android_red_light;
+ context.getResources().getDrawable(R.drawable.status_lock_open_24px));
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_red_light;
+ }
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
if (statusText != null) {
@@ -490,8 +525,10 @@ public class KeyFormattingUtils {
}
case STATE_NOT_SIGNED: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout));
- int color = R.color.android_red_light;
+ context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24px));
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_red_light;
+ }
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
if (statusText != null) {
@@ -501,8 +538,10 @@ public class KeyFormattingUtils {
}
case STATE_INVALID: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout));
- int color = R.color.android_red_light;
+ context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24px));
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.android_red_light;
+ }
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
if (statusText != null) {
@@ -513,8 +552,10 @@ public class KeyFormattingUtils {
/** special **/
case STATE_UNAVAILABLE: {
statusIcon.setImageDrawable(
- context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout));
- int color = R.color.bg_gray;
+ context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24px));
+ if (color == KeyFormattingUtils.DEFAULT_COLOR) {
+ color = R.color.bg_gray;
+ }
statusIcon.setColorFilter(context.getResources().getColor(color),
PorterDuff.Mode.SRC_IN);
if (statusText != null) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java
index 551ac039d..6f8c477c0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java
@@ -19,18 +19,25 @@ package org.sufficientlysecure.keychain.ui.util;
import android.app.Activity;
import android.content.res.Resources;
+import android.graphics.Color;
-import com.github.johnpersano.supertoasts.SuperCardToast;
-import com.github.johnpersano.supertoasts.SuperToast;
+import com.nispok.snackbar.Snackbar;
+import com.nispok.snackbar.Snackbar.SnackbarDuration;
+import com.nispok.snackbar.SnackbarManager;
+import com.nispok.snackbar.listeners.ActionClickListener;
+
+import org.sufficientlysecure.keychain.R;
/**
- * @author danielhass
* Notify wrapper which allows a more easy use of different notification libraries
*/
public class Notify {
public static enum Style {OK, WARN, INFO, ERROR}
+ public static final int LENGTH_INDEFINITE = 0;
+ public static final int LENGTH_LONG = 3500;
+
/**
* Shows a simple in-layout notification with the CharSequence given as parameter
* @param activity
@@ -39,21 +46,94 @@ public class Notify {
*/
public static void showNotify(Activity activity, CharSequence text, Style style) {
- SuperCardToast st = new SuperCardToast(activity);
- st.setText(text);
- st.setDuration(SuperToast.Duration.MEDIUM);
- switch (style){
+ Snackbar bar = Snackbar.with(activity)
+ .text(text)
+ .duration(SnackbarDuration.LENGTH_LONG);
+
+ switch (style) {
+ case OK:
+ break;
+ case WARN:
+ bar.textColor(activity.getResources().getColor(R.color.android_orange_light));
+ break;
+ case ERROR:
+ bar.textColor(activity.getResources().getColor(R.color.android_red_light));
+ break;
+ }
+
+ SnackbarManager.show(bar);
+
+ }
+
+ public static Showable createNotify (Activity activity, int resId, int duration, Style style) {
+ final Snackbar bar = Snackbar.with(activity)
+ .text(resId);
+ if (duration == LENGTH_INDEFINITE) {
+ bar.duration(SnackbarDuration.LENGTH_INDEFINITE);
+ } else {
+ bar.duration(duration);
+ }
+
+ switch (style) {
+ case OK:
+ bar.actionColor(activity.getResources().getColor(R.color.android_green_light));
+ break;
+ case WARN:
+ bar.textColor(activity.getResources().getColor(R.color.android_orange_light));
+ break;
+ case ERROR:
+ bar.textColor(activity.getResources().getColor(R.color.android_red_light));
+ break;
+ }
+
+ return new Showable () {
+ @Override
+ public void show() {
+ SnackbarManager.show(bar);
+ }
+ };
+ }
+
+ public static Showable createNotify(Activity activity, int resId, int duration, Style style,
+ final ActionListener listener, int resIdAction) {
+ return createNotify(activity, activity.getString(resId), duration, style, listener, resIdAction);
+ }
+
+ public static Showable createNotify(Activity activity, String msg, int duration, Style style,
+ final ActionListener listener, int resIdAction) {
+ final Snackbar bar = Snackbar.with(activity)
+ .text(msg)
+ .actionLabel(resIdAction)
+ .actionListener(new ActionClickListener() {
+ @Override
+ public void onActionClicked(Snackbar snackbar) {
+ listener.onAction();
+ }
+ });
+ if (duration == LENGTH_INDEFINITE) {
+ bar.duration(SnackbarDuration.LENGTH_INDEFINITE);
+ } else {
+ bar.duration(duration);
+ }
+
+ switch (style) {
case OK:
- st.setBackground(SuperToast.Background.GREEN);
+ bar.actionColor(activity.getResources().getColor(R.color.android_green_light));
break;
case WARN:
- st.setBackground(SuperToast.Background.ORANGE);
+ bar.textColor(activity.getResources().getColor(R.color.android_orange_light));
break;
case ERROR:
- st.setBackground(SuperToast.Background.RED);
+ bar.textColor(activity.getResources().getColor(R.color.android_red_light));
break;
}
- st.show();
+
+ return new Showable () {
+ @Override
+ public void show() {
+ SnackbarManager.show(bar);
+ }
+ };
}
@@ -67,4 +147,15 @@ public class Notify {
public static void showNotify(Activity activity, int resId, Style style) throws Resources.NotFoundException {
showNotify(activity, activity.getResources().getText(resId), style);
}
+
+ public interface Showable {
+ public void show();
+
+ }
+
+ public interface ActionListener {
+ public void onAction();
+
+ }
+
} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java
index 36f38045f..b8d4ea7d2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/QrCodeUtils.java
@@ -47,7 +47,7 @@ public class QrCodeUtils {
*/
public static Bitmap getQRCodeBitmap(final String input, final int size) {
try {
- final Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
+ final Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
final BitMatrix result = new QRCodeWriter().encode(input, BarcodeFormat.QR_CODE, size,
size, hints);
@@ -59,7 +59,7 @@ public class QrCodeUtils {
for (int y = 0; y < height; y++) {
final int offset = y * width;
for (int x = 0; x < width; x++) {
- pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.WHITE;
+ pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/AspectRatioImageView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/AspectRatioImageView.java
new file mode 100644
index 000000000..0df5ba5e8
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/AspectRatioImageView.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+import org.sufficientlysecure.keychain.R;
+
+/**
+ * Maintains an aspect ratio based on either width or height. Disabled by default.
+ *
+ * from https://gist.github.com/JakeWharton/2856179
+ */
+public class AspectRatioImageView extends ImageView {
+ // NOTE: These must be kept in sync with the AspectRatioImageView attributes in attrs.xml.
+ public static final int MEASUREMENT_WIDTH = 0;
+ public static final int MEASUREMENT_HEIGHT = 1;
+
+ private static final float DEFAULT_ASPECT_RATIO = 1f;
+ private static final boolean DEFAULT_ASPECT_RATIO_ENABLED = false;
+ private static final int DEFAULT_DOMINANT_MEASUREMENT = MEASUREMENT_WIDTH;
+
+ private float aspectRatio;
+ private boolean aspectRatioEnabled;
+ private int dominantMeasurement;
+
+ public AspectRatioImageView(Context context) {
+ this(context, null);
+ }
+
+ public AspectRatioImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AspectRatioImageView);
+ aspectRatio = a.getFloat(R.styleable.AspectRatioImageView_aspectRatio, DEFAULT_ASPECT_RATIO);
+ aspectRatioEnabled = a.getBoolean(R.styleable.AspectRatioImageView_aspectRatioEnabled,
+ DEFAULT_ASPECT_RATIO_ENABLED);
+ dominantMeasurement = a.getInt(R.styleable.AspectRatioImageView_dominantMeasurement,
+ DEFAULT_DOMINANT_MEASUREMENT);
+ a.recycle();
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ if (!aspectRatioEnabled) return;
+
+ int newWidth;
+ int newHeight;
+ switch (dominantMeasurement) {
+ case MEASUREMENT_WIDTH:
+ newWidth = getMeasuredWidth();
+ newHeight = (int) (newWidth * aspectRatio);
+ break;
+
+ case MEASUREMENT_HEIGHT:
+ newHeight = getMeasuredHeight();
+ newWidth = (int) (newHeight * aspectRatio);
+ break;
+
+ default:
+ throw new IllegalStateException("Unknown measurement with ID " + dominantMeasurement);
+ }
+
+ setMeasuredDimension(newWidth, newHeight);
+ }
+
+ /**
+ * Get the aspect ratio for this image view.
+ */
+ public float getAspectRatio() {
+ return aspectRatio;
+ }
+
+ /**
+ * Set the aspect ratio for this image view. This will update the view instantly.
+ */
+ public void setAspectRatio(float aspectRatio) {
+ this.aspectRatio = aspectRatio;
+ if (aspectRatioEnabled) {
+ requestLayout();
+ }
+ }
+
+ /**
+ * Get whether or not forcing the aspect ratio is enabled.
+ */
+ public boolean getAspectRatioEnabled() {
+ return aspectRatioEnabled;
+ }
+
+ /**
+ * set whether or not forcing the aspect ratio is enabled. This will re-layout the view.
+ */
+ public void setAspectRatioEnabled(boolean aspectRatioEnabled) {
+ this.aspectRatioEnabled = aspectRatioEnabled;
+ requestLayout();
+ }
+
+ /**
+ * Get the dominant measurement for the aspect ratio.
+ */
+ public int getDominantMeasurement() {
+ return dominantMeasurement;
+ }
+
+ /**
+ * Set the dominant measurement for the aspect ratio.
+ *
+ * @see #MEASUREMENT_WIDTH
+ * @see #MEASUREMENT_HEIGHT
+ */
+ public void setDominantMeasurement(int dominantMeasurement) {
+ if (dominantMeasurement != MEASUREMENT_HEIGHT && dominantMeasurement != MEASUREMENT_WIDTH) {
+ throw new IllegalArgumentException("Invalid measurement type.");
+ }
+ this.dominantMeasurement = dominantMeasurement;
+ requestLayout();
+ }
+} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java
index 14f42eb04..6d0e6556f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java
@@ -27,9 +27,9 @@ import android.util.AttributeSet;
import android.widget.ImageView;
import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
public class CertifyKeySpinner extends KeySpinner {
@@ -86,32 +86,33 @@ public class CertifyKeySpinner extends KeySpinner {
super.onLoadFinished(loader, data);
if (loader.getId() == LOADER_ID) {
+ mIndexHasCertify = data.getColumnIndex(KeychainContract.KeyRings.HAS_CERTIFY);
+ mIndexIsRevoked = data.getColumnIndex(KeychainContract.KeyRings.IS_REVOKED);
+ mIndexIsExpired = data.getColumnIndex(KeychainContract.KeyRings.IS_EXPIRED);
+
// If there is only one choice, pick it by default
if (mAdapter.getCount() == 2) {
// preselect if key can certify
- if (data.moveToPosition(1) && !data.isNull(mIndexHasCertify)) {
+ if (data.moveToPosition(0) && !data.isNull(mIndexHasCertify)) {
setSelection(1);
}
}
- mIndexHasCertify = data.getColumnIndex(KeychainContract.KeyRings.HAS_CERTIFY);
- mIndexIsRevoked = data.getColumnIndex(KeychainContract.KeyRings.IS_REVOKED);
- mIndexIsExpired = data.getColumnIndex(KeychainContract.KeyRings.IS_EXPIRED);
}
}
@Override
boolean setStatus(Context context, Cursor cursor, ImageView statusView) {
if (cursor.getInt(mIndexIsRevoked) != 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_REVOKED, true);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
return false;
}
if (cursor.getInt(mIndexIsExpired) != 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_EXPIRED, true);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
return false;
}
// don't invalidate the "None" entry, which is also null!
if (cursor.getPosition() != 0 && cursor.isNull(mIndexHasCertify)) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_UNAVAILABLE, true);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_UNAVAILABLE, R.color.bg_gray);
return false;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
index e03a14989..f05f5f96b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
@@ -28,7 +28,6 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
-import android.text.SpannableStringBuilder;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -42,14 +41,13 @@ import com.tokenautocomplete.TokenCompleteTextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
@@ -165,7 +163,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
setAdapter(new EncryptKeyAdapter(Collections.<EncryptionKey>emptyList()));
return;
}
- ArrayList<EncryptionKey> keys = new ArrayList<EncryptionKey>();
+ ArrayList<EncryptionKey> keys = new ArrayList<>();
while (cursor.moveToNext()) {
try {
EncryptionKey key = new EncryptionKey(cursor);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java
index b456b61ab..34e7b639a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java
@@ -33,17 +33,16 @@ import org.sufficientlysecure.keychain.R;
/**
* Class representing a LinearLayout that can fold and hide it's content when pressed
* To use just add the following to your xml layout
-
- <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- custom:foldedLabel="@string/TEXT_TO_DISPLAY_WHEN_FOLDED"
- custom:unFoldedLabel="@string/TEXT_TO_DISPLAY_WHEN_UNFOLDED">
-
- <include layout="@layout/ELEMENTS_TO_BE_FOLDED"/>
-
- </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout>
-
+ * <p/>
+ * <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout
+ * android:layout_width="wrap_content"
+ * android:layout_height="wrap_content"
+ * custom:foldedLabel="@string/TEXT_TO_DISPLAY_WHEN_FOLDED"
+ * custom:unFoldedLabel="@string/TEXT_TO_DISPLAY_WHEN_UNFOLDED">
+ * <p/>
+ * <include layout="@layout/ELEMENTS_TO_BE_FOLDED"/>
+ * <p/>
+ * </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout>
*/
public class FoldableLinearLayout extends LinearLayout {
@@ -75,6 +74,7 @@ public class FoldableLinearLayout extends LinearLayout {
/**
* Load given attributes to inner variables,
+ *
* @param context
* @param attrs
*/
@@ -87,8 +87,8 @@ public class FoldableLinearLayout extends LinearLayout {
a.recycle();
}
// If any attribute isn't found then set a default one
- mFoldedLabel = (mFoldedLabel == null) ? context.getString(R.id.none) : mFoldedLabel;
- mUnFoldedLabel = (mUnFoldedLabel == null) ? context.getString(R.id.none) : mUnFoldedLabel;
+ mFoldedLabel = (mFoldedLabel == null) ? context.getString(R.string.none) : mFoldedLabel;
+ mUnFoldedLabel = (mUnFoldedLabel == null) ? context.getString(R.string.none) : mUnFoldedLabel;
}
@Override
@@ -138,7 +138,7 @@ public class FoldableLinearLayout extends LinearLayout {
private void initialiseInnerViews() {
mFoldableIcon = (ImageView) mFoldableLayout.findViewById(R.id.foldableIcon);
- mFoldableIcon.setImageResource(R.drawable.ic_action_expand);
+ mFoldableIcon.setImageResource(R.drawable.ic_expand_more_black_24dp);
mFoldableTextView = (TextView) mFoldableLayout.findViewById(R.id.foldableText);
mFoldableTextView.setText(mFoldedLabel);
@@ -151,7 +151,7 @@ public class FoldableLinearLayout extends LinearLayout {
public void onClick(View view) {
mFolded = !mFolded;
if (mFolded) {
- mFoldableIcon.setImageResource(R.drawable.ic_action_collapse);
+ mFoldableIcon.setImageResource(R.drawable.ic_expand_less_black_24dp);
mFoldableContainer.setVisibility(View.VISIBLE);
AlphaAnimation animation = new AlphaAnimation(0f, 1f);
animation.setDuration(mShortAnimationDuration);
@@ -159,12 +159,13 @@ public class FoldableLinearLayout extends LinearLayout {
mFoldableTextView.setText(mUnFoldedLabel);
} else {
- mFoldableIcon.setImageResource(R.drawable.ic_action_expand);
+ mFoldableIcon.setImageResource(R.drawable.ic_expand_more_black_24dp);
AlphaAnimation animation = new AlphaAnimation(1f, 0f);
animation.setDuration(mShortAnimationDuration);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
- public void onAnimationStart(Animation animation) { }
+ public void onAnimationStart(Animation animation) {
+ }
@Override
public void onAnimationEnd(Animation animation) {
@@ -173,7 +174,8 @@ public class FoldableLinearLayout extends LinearLayout {
}
@Override
- public void onAnimationRepeat(Animation animation) { }
+ public void onAnimationRepeat(Animation animation) {
+ }
});
mFoldableContainer.startAnimation(animation);
mFoldableTextView.setText(mFoldedLabel);
@@ -185,6 +187,7 @@ public class FoldableLinearLayout extends LinearLayout {
/**
* Adds provided child view to foldableContainer View
+ *
* @param child
*/
@Override
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java
index 7ec6ffe95..c8eceea50 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java
@@ -24,24 +24,28 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
+import android.support.v7.internal.widget.TintSpinner;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
-import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log;
-public abstract class KeySpinner extends Spinner implements LoaderManager.LoaderCallbacks<Cursor> {
+/**
+ * Use TintSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon.
+ * Related: http://stackoverflow.com/a/27713090
+ */
+public abstract class KeySpinner extends TintSpinner implements LoaderManager.LoaderCallbacks<Cursor> {
public interface OnKeyChangedListener {
public void onKeyChanged(long masterKeyId);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ListAwareSwipeRefreshLayout.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ListAwareSwipeRefreshLayout.java
index b3c3eb417..3403208d7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ListAwareSwipeRefreshLayout.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ListAwareSwipeRefreshLayout.java
@@ -20,13 +20,8 @@ package org.sufficientlysecure.keychain.ui.widget;
import android.content.Context;
import android.support.v4.widget.NoScrollableSwipeRefreshLayout;
import android.util.AttributeSet;
-import android.view.InputDevice;
-import android.view.InputDevice.MotionRange;
import android.view.MotionEvent;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.Log;
-
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
public class ListAwareSwipeRefreshLayout extends NoScrollableSwipeRefreshLayout {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java
index 59d05a62e..fe91e306e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java
@@ -84,15 +84,15 @@ public class SignKeySpinner extends KeySpinner {
@Override
boolean setStatus(Context context, Cursor cursor, ImageView statusView) {
if (cursor.getInt(mIndexIsRevoked) != 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_REVOKED, true);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_REVOKED, R.color.bg_gray);
return false;
}
if (cursor.getInt(mIndexIsExpired) != 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_EXPIRED, true);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_EXPIRED, R.color.bg_gray);
return false;
}
if (cursor.getInt(mIndexHasSign) == 0) {
- KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_UNAVAILABLE, true);
+ KeyFormattingUtils.setStatusImage(getContext(), statusView, null, KeyFormattingUtils.STATE_UNAVAILABLE, R.color.bg_gray);
return false;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SlidingTabLayout.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SlidingTabLayout.java
deleted file mode 100644
index 17471c86c..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SlidingTabLayout.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.content.Context;
-import android.graphics.Typeface;
-import android.os.Build;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.HorizontalScrollView;
-import android.widget.TextView;
-
-/**
- * Copied from http://developer.android.com/samples/SlidingTabsColors/index.html
- */
-
-/**
- * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
- * the user's scroll progress.
- * <p/>
- * To use the component, simply add it to your view hierarchy. Then in your
- * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
- * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
- * <p/>
- * The colors can be customized in two ways. The first and simplest is to provide an array of colors
- * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
- * alternative is via the {@link TabColorizer} interface which provides you complete control over
- * which color is used for any individual position.
- * <p/>
- * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
- * providing the layout ID of your custom layout.
- */
-public class SlidingTabLayout extends HorizontalScrollView {
-
- /**
- * Allows complete control over the colors drawn in the tab layout. Set with
- * {@link #setCustomTabColorizer(TabColorizer)}.
- */
- public interface TabColorizer {
-
- /**
- * @return return the color of the indicator used when {@code position} is selected.
- */
- int getIndicatorColor(int position);
-
- /**
- * @return return the color of the divider drawn to the right of {@code position}.
- */
- int getDividerColor(int position);
-
- }
-
- private static final int TITLE_OFFSET_DIPS = 24;
- private static final int TAB_VIEW_PADDING_DIPS = 16;
- private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
-
- private int mTitleOffset;
-
- private int mTabViewLayoutId;
- private int mTabViewTextViewId;
-
- private ViewPager mViewPager;
- private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
-
- private final SlidingTabStrip mTabStrip;
-
- public SlidingTabLayout(Context context) {
- this(context, null);
- }
-
- public SlidingTabLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- // Disable the Scroll Bar
- setHorizontalScrollBarEnabled(false);
- // Make sure that the Tab Strips fills this View
- setFillViewport(true);
-
- mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
-
- mTabStrip = new SlidingTabStrip(context);
- addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
- }
-
- /**
- * Set the custom {@link TabColorizer} to be used.
- * <p/>
- * If you only require simple custmisation then you can use
- * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
- * similar effects.
- */
- public void setCustomTabColorizer(TabColorizer tabColorizer) {
- mTabStrip.setCustomTabColorizer(tabColorizer);
- }
-
- /**
- * Sets the colors to be used for indicating the selected tab. These colors are treated as a
- * circular array. Providing one color will mean that all tabs are indicated with the same color.
- */
- public void setSelectedIndicatorColors(int... colors) {
- mTabStrip.setSelectedIndicatorColors(colors);
- }
-
- /**
- * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
- * Providing one color will mean that all tabs are indicated with the same color.
- */
- public void setDividerColors(int... colors) {
- mTabStrip.setDividerColors(colors);
- }
-
- /**
- * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
- * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
- * that the layout can update it's scroll position correctly.
- *
- * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
- */
- public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
- mViewPagerPageChangeListener = listener;
- }
-
- /**
- * Set the custom layout to be inflated for the tab views.
- *
- * @param layoutResId Layout id to be inflated
- * @param textViewId id of the {@link TextView} in the inflated view
- */
- public void setCustomTabView(int layoutResId, int textViewId) {
- mTabViewLayoutId = layoutResId;
- mTabViewTextViewId = textViewId;
- }
-
- /**
- * Sets the associated view pager. Note that the assumption here is that the pager content
- * (number of tabs and tab titles) does not change after this call has been made.
- */
- public void setViewPager(ViewPager viewPager) {
- mTabStrip.removeAllViews();
-
- mViewPager = viewPager;
- if (viewPager != null) {
- viewPager.setOnPageChangeListener(new InternalViewPagerListener());
- populateTabStrip();
- }
- }
-
- /**
- * Create a default view to be used for tabs. This is called if a custom tab view is not set via
- * {@link #setCustomTabView(int, int)}.
- */
- protected TextView createDefaultTabView(Context context) {
- TextView textView = new TextView(context);
- textView.setGravity(Gravity.CENTER);
- textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
- textView.setTypeface(Typeface.DEFAULT_BOLD);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- // If we're running on Honeycomb or newer, then we can use the Theme's
- // selectableItemBackground to ensure that the View has a pressed state
- TypedValue outValue = new TypedValue();
- getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
- outValue, true);
- textView.setBackgroundResource(outValue.resourceId);
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
- textView.setAllCaps(true);
- }
-
- int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
- textView.setPadding(padding, padding, padding, padding);
-
- return textView;
- }
-
- private void populateTabStrip() {
- final PagerAdapter adapter = mViewPager.getAdapter();
- final View.OnClickListener tabClickListener = new TabClickListener();
-
- for (int i = 0; i < adapter.getCount(); i++) {
- View tabView = null;
- TextView tabTitleView = null;
-
- if (mTabViewLayoutId != 0) {
- // If there is a custom tab view layout id set, try and inflate it
- tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
- false);
- tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
- }
-
- if (tabView == null) {
- tabView = createDefaultTabView(getContext());
- }
-
- if (tabTitleView == null && TextView.class.isInstance(tabView)) {
- tabTitleView = (TextView) tabView;
- }
-
- tabTitleView.setText(adapter.getPageTitle(i));
- tabView.setOnClickListener(tabClickListener);
-
- mTabStrip.addView(tabView);
- }
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- if (mViewPager != null) {
- scrollToTab(mViewPager.getCurrentItem(), 0);
- }
- }
-
- private void scrollToTab(int tabIndex, int positionOffset) {
- final int tabStripChildCount = mTabStrip.getChildCount();
- if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
- return;
- }
-
- View selectedChild = mTabStrip.getChildAt(tabIndex);
- if (selectedChild != null) {
- int targetScrollX = selectedChild.getLeft() + positionOffset;
-
- if (tabIndex > 0 || positionOffset > 0) {
- // If we're not at the first child and are mid-scroll, make sure we obey the offset
- targetScrollX -= mTitleOffset;
- }
-
- scrollTo(targetScrollX, 0);
- }
- }
-
- private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
- private int mScrollState;
-
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- int tabStripChildCount = mTabStrip.getChildCount();
- if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
- return;
- }
-
- mTabStrip.onViewPagerPageChanged(position, positionOffset);
-
- View selectedTitle = mTabStrip.getChildAt(position);
- int extraOffset = (selectedTitle != null)
- ? (int) (positionOffset * selectedTitle.getWidth())
- : 0;
- scrollToTab(position, extraOffset);
-
- if (mViewPagerPageChangeListener != null) {
- mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
- positionOffsetPixels);
- }
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
- mScrollState = state;
-
- if (mViewPagerPageChangeListener != null) {
- mViewPagerPageChangeListener.onPageScrollStateChanged(state);
- }
- }
-
- @Override
- public void onPageSelected(int position) {
- if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
- mTabStrip.onViewPagerPageChanged(position, 0f);
- scrollToTab(position, 0);
- }
-
- if (mViewPagerPageChangeListener != null) {
- mViewPagerPageChangeListener.onPageSelected(position);
- }
- }
-
- }
-
- private class TabClickListener implements View.OnClickListener {
- @Override
- public void onClick(View v) {
- for (int i = 0; i < mTabStrip.getChildCount(); i++) {
- if (v == mTabStrip.getChildAt(i)) {
- mViewPager.setCurrentItem(i);
- return;
- }
- }
- }
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SlidingTabStrip.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SlidingTabStrip.java
deleted file mode 100644
index 4c41e12c5..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SlidingTabStrip.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.R;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.View;
-import android.widget.LinearLayout;
-
-/**
- * Copied from http://developer.android.com/samples/SlidingTabsColors/index.html
- */
-class SlidingTabStrip extends LinearLayout {
-
- private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
- private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
- private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
- private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFFAA66CC;
-
- private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
- private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
- private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
-
- private final int mBottomBorderThickness;
- private final Paint mBottomBorderPaint;
-
- private final int mSelectedIndicatorThickness;
- private final Paint mSelectedIndicatorPaint;
-
- private final int mDefaultBottomBorderColor;
-
- private final Paint mDividerPaint;
- private final float mDividerHeight;
-
- private int mSelectedPosition;
- private float mSelectionOffset;
-
- private SlidingTabLayout.TabColorizer mCustomTabColorizer;
- private final SimpleTabColorizer mDefaultTabColorizer;
-
- SlidingTabStrip(Context context) {
- this(context, null);
- }
-
- SlidingTabStrip(Context context, AttributeSet attrs) {
- super(context, attrs);
- setWillNotDraw(false);
-
- final float density = getResources().getDisplayMetrics().density;
-
- TypedValue outValue = new TypedValue();
- context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
- final int themeForegroundColor = outValue.data;
-
- mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
- DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
-
- mDefaultTabColorizer = new SimpleTabColorizer();
- mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
- mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor,
- DEFAULT_DIVIDER_COLOR_ALPHA));
-
- mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
- mBottomBorderPaint = new Paint();
- mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
-
- mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
- mSelectedIndicatorPaint = new Paint();
-
- mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
- mDividerPaint = new Paint();
- mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
- }
-
- void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
- mCustomTabColorizer = customTabColorizer;
- invalidate();
- }
-
- void setSelectedIndicatorColors(int... colors) {
- // Make sure that the custom colorizer is removed
- mCustomTabColorizer = null;
- mDefaultTabColorizer.setIndicatorColors(colors);
- invalidate();
- }
-
- void setDividerColors(int... colors) {
- // Make sure that the custom colorizer is removed
- mCustomTabColorizer = null;
- mDefaultTabColorizer.setDividerColors(colors);
- invalidate();
- }
-
- void onViewPagerPageChanged(int position, float positionOffset) {
- mSelectedPosition = position;
- mSelectionOffset = positionOffset;
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- final int height = getHeight();
- final int childCount = getChildCount();
- final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
- final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
- ? mCustomTabColorizer
- : mDefaultTabColorizer;
-
- // Thick colored underline below the current selection
- if (childCount > 0) {
- View selectedTitle = getChildAt(mSelectedPosition);
- int left = selectedTitle.getLeft();
- int right = selectedTitle.getRight();
- int color = tabColorizer.getIndicatorColor(mSelectedPosition);
-
- if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
- int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
- if (color != nextColor) {
- color = blendColors(nextColor, color, mSelectionOffset);
- }
-
- // Draw the selection partway between the tabs
- View nextTitle = getChildAt(mSelectedPosition + 1);
- left = (int) (mSelectionOffset * nextTitle.getLeft() +
- (1.0f - mSelectionOffset) * left);
- right = (int) (mSelectionOffset * nextTitle.getRight() +
- (1.0f - mSelectionOffset) * right);
- }
-
- mSelectedIndicatorPaint.setColor(color);
-
- canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
- height, mSelectedIndicatorPaint);
- }
-
- // Thin underline along the entire bottom edge
- canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
-
- // Vertical separators between the titles
- int separatorTop = (height - dividerHeightPx) / 2;
- for (int i = 0; i < childCount - 1; i++) {
- View child = getChildAt(i);
- mDividerPaint.setColor(tabColorizer.getDividerColor(i));
- canvas.drawLine(child.getRight(), separatorTop, child.getRight(),
- separatorTop + dividerHeightPx, mDividerPaint);
- }
- }
-
- /**
- * Set the alpha value of the {@code color} to be the given {@code alpha} value.
- */
- private static int setColorAlpha(int color, byte alpha) {
- return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
- }
-
- /**
- * Blend {@code color1} and {@code color2} using the given ratio.
- *
- * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
- * 0.0 will return {@code color2}.
- */
- private static int blendColors(int color1, int color2, float ratio) {
- final float inverseRation = 1f - ratio;
- float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
- float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
- float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
- return Color.rgb((int) r, (int) g, (int) b);
- }
-
- private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
- private int[] mIndicatorColors;
- private int[] mDividerColors;
-
- @Override
- public final int getIndicatorColor(int position) {
- return mIndicatorColors[position % mIndicatorColors.length];
- }
-
- @Override
- public final int getDividerColor(int position) {
- return mDividerColors[position % mDividerColors.length];
- }
-
- void setIndicatorColors(int... colors) {
- mIndicatorColors = colors;
- }
-
- void setDividerColors(int... colors) {
- mDividerColors = colors;
- }
- }
-} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java
index 99db634ac..c1955f75b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java
@@ -23,7 +23,6 @@ import android.app.Activity;
import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.openpgp.PGPEncryptedData;
-import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import java.util.HashMap;
@@ -32,9 +31,9 @@ import java.util.HashMap;
public class AlgorithmNames {
Activity mActivity;
- HashMap<Integer, String> mEncryptionNames = new HashMap<Integer, String>();
- HashMap<Integer, String> mHashNames = new HashMap<Integer, String>();
- HashMap<Integer, String> mCompressionNames = new HashMap<Integer, String>();
+ HashMap<Integer, String> mEncryptionNames = new HashMap<>();
+ HashMap<Integer, String> mHashNames = new HashMap<>();
+ HashMap<Integer, String> mCompressionNames = new HashMap<>();
public AlgorithmNames(Activity context) {
super();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java
index 1c4eece6b..60bc846b2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ContactHelper.java
@@ -35,8 +35,9 @@ import android.util.Patterns;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.io.InputStream;
import java.util.ArrayList;
@@ -57,10 +58,10 @@ public class ContactHelper {
KeychainContract.KeyRings.EXPIRY,
KeychainContract.KeyRings.IS_REVOKED};
public static final String[] USER_IDS_PROJECTION = new String[]{
- KeychainContract.UserIds.USER_ID
+ UserPackets.USER_ID
};
- public static final String NON_REVOKED_SELECTION = KeychainContract.UserIds.IS_REVOKED + "=0";
+ public static final String NON_REVOKED_SELECTION = UserPackets.IS_REVOKED + "=0";
public static final String[] ID_PROJECTION = new String[]{ContactsContract.RawContacts._ID};
public static final String[] SOURCE_ID_PROJECTION = new String[]{ContactsContract.RawContacts.SOURCE_ID};
@@ -72,20 +73,20 @@ public class ContactHelper {
ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?";
public static final String ID_SELECTION = ContactsContract.RawContacts._ID + "=?";
- private static final Map<String, Bitmap> photoCache = new HashMap<String, Bitmap>();
+ private static final Map<String, Bitmap> photoCache = new HashMap<>();
public static List<String> getPossibleUserEmails(Context context) {
Set<String> accountMails = getAccountEmails(context);
accountMails.addAll(getMainProfileContactEmails(context));
// now return the Set (without duplicates) as a List
- return new ArrayList<String>(accountMails);
+ return new ArrayList<>(accountMails);
}
public static List<String> getPossibleUserNames(Context context) {
Set<String> accountMails = getAccountEmails(context);
Set<String> names = getContactNamesFromEmails(context, accountMails);
names.addAll(getMainProfileContactName(context));
- return new ArrayList<String>(names);
+ return new ArrayList<>(names);
}
/**
@@ -96,7 +97,7 @@ public class ContactHelper {
*/
private static Set<String> getAccountEmails(Context context) {
final Account[] accounts = AccountManager.get(context).getAccounts();
- final Set<String> emailSet = new HashSet<String>();
+ final Set<String> emailSet = new HashSet<>();
for (Account account : accounts) {
if (Patterns.EMAIL_ADDRESS.matcher(account.name).matches()) {
emailSet.add(account.name);
@@ -115,7 +116,7 @@ public class ContactHelper {
*/
private static Set<String> getContactNamesFromEmails(Context context, Set<String> emails) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- Set<String> names = new HashSet<String>();
+ Set<String> names = new HashSet<>();
for (String email : emails) {
ContentResolver resolver = context.getContentResolver();
Cursor profileCursor = resolver.query(
@@ -127,7 +128,7 @@ public class ContactHelper {
);
if (profileCursor == null) return null;
- Set<String> currNames = new HashSet<String>();
+ Set<String> currNames = new HashSet<>();
while (profileCursor.moveToNext()) {
String name = profileCursor.getString(1);
if (name != null) {
@@ -139,7 +140,7 @@ public class ContactHelper {
}
return names;
} else {
- return new HashSet<String>();
+ return new HashSet<>();
}
}
@@ -171,7 +172,7 @@ public class ContactHelper {
);
if (profileCursor == null) return null;
- Set<String> emails = new HashSet<String>();
+ Set<String> emails = new HashSet<>();
while (profileCursor.moveToNext()) {
String email = profileCursor.getString(0);
if (email != null) {
@@ -181,7 +182,7 @@ public class ContactHelper {
profileCursor.close();
return emails;
} else {
- return new HashSet<String>();
+ return new HashSet<>();
}
}
@@ -200,7 +201,7 @@ public class ContactHelper {
null, null, null);
if (profileCursor == null) return null;
- Set<String> names = new HashSet<String>();
+ Set<String> names = new HashSet<>();
// should only contain one entry!
while (profileCursor.moveToNext()) {
String name = profileCursor.getString(0);
@@ -209,9 +210,9 @@ public class ContactHelper {
}
}
profileCursor.close();
- return new ArrayList<String>(names);
+ return new ArrayList<>(names);
} else {
- return new ArrayList<String>();
+ return new ArrayList<>();
}
}
@@ -220,9 +221,9 @@ public class ContactHelper {
Cursor mailCursor = resolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Email.DATA},
null, null, null);
- if (mailCursor == null) return new ArrayList<String>();
+ if (mailCursor == null) return new ArrayList<>();
- Set<String> mails = new HashSet<String>();
+ Set<String> mails = new HashSet<>();
while (mailCursor.moveToNext()) {
String email = mailCursor.getString(0);
if (email != null) {
@@ -230,7 +231,7 @@ public class ContactHelper {
}
}
mailCursor.close();
- return new ArrayList<String>(mails);
+ return new ArrayList<>(mails);
}
public static List<String> getContactNames(Context context) {
@@ -238,9 +239,9 @@ public class ContactHelper {
Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,
new String[]{ContactsContract.Contacts.DISPLAY_NAME},
null, null, null);
- if (cursor == null) return new ArrayList<String>();
+ if (cursor == null) return new ArrayList<>();
- Set<String> names = new HashSet<String>();
+ Set<String> names = new HashSet<>();
while (cursor.moveToNext()) {
String name = cursor.getString(0);
if (name != null) {
@@ -248,7 +249,7 @@ public class ContactHelper {
}
}
cursor.close();
- return new ArrayList<String>(names);
+ return new ArrayList<>(names);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@@ -308,7 +309,7 @@ public class ContactHelper {
boolean isExpired = !cursor.isNull(4) && new Date(cursor.getLong(4) * 1000).before(new Date());
boolean isRevoked = cursor.getInt(5) > 0;
int rawContactId = findRawContactId(resolver, fingerprint);
- ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+ ArrayList<ContentProviderOperation> ops = new ArrayList<>();
// Do not store expired or revoked keys in contact db - and remove them if they already exist
if (isExpired || isRevoked) {
@@ -350,7 +351,7 @@ public class ContactHelper {
* @return a set of all key fingerprints currently present in the contact db
*/
private static Set<String> getRawContactFingerprints(ContentResolver resolver) {
- HashSet<String> result = new HashSet<String>();
+ HashSet<String> result = new HashSet<>();
Cursor fingerprints = resolver.query(ContactsContract.RawContacts.CONTENT_URI, SOURCE_ID_PROJECTION,
ACCOUNT_TYPE_SELECTION, new String[]{Constants.ACCOUNT_TYPE}, null);
if (fingerprints != null) {
@@ -413,7 +414,7 @@ public class ContactHelper {
int rawContactId, long masterKeyId) {
ops.add(selectByRawContactAndItemType(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI),
rawContactId, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE).build());
- Cursor ids = resolver.query(KeychainContract.UserIds.buildUserIdsUri(masterKeyId),
+ Cursor ids = resolver.query(UserPackets.buildUserIdsUri(masterKeyId),
USER_IDS_PROJECTION, NON_REVOKED_SELECTION, null, null);
if (ids != null) {
while (ids.moveToNext()) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java
index 49d4d8bf8..8334b37ec 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java
@@ -42,13 +42,13 @@ public class EmailKeyHelper {
public static void importAll(Context context, Messenger messenger, List<String> mails) {
// Collect all candidates as ImportKeysListEntry (set for deduplication)
- Set<ImportKeysListEntry> entries = new HashSet<ImportKeysListEntry>();
+ Set<ImportKeysListEntry> entries = new HashSet<>();
for (String mail : mails) {
entries.addAll(getEmailKeys(context, mail));
}
// Put them in a list and import
- ArrayList<ParcelableKeyRing> keys = new ArrayList<ParcelableKeyRing>(entries.size());
+ ArrayList<ParcelableKeyRing> keys = new ArrayList<>(entries.size());
for (ImportKeysListEntry entry : entries) {
keys.add(new ParcelableKeyRing(entry.getFingerprintHex(), entry.getKeyIdHex(), null));
}
@@ -56,7 +56,7 @@ public class EmailKeyHelper {
}
public static Set<ImportKeysListEntry> getEmailKeys(Context context, String mail) {
- Set<ImportKeysListEntry> keys = new HashSet<ImportKeysListEntry>();
+ Set<ImportKeysListEntry> keys = new HashSet<>();
// Try _hkp._tcp SRV record first
String[] mailparts = mail.split("@");
@@ -90,7 +90,7 @@ public class EmailKeyHelper {
}
public static List<ImportKeysListEntry> getEmailKeys(String mail, Keyserver keyServer) {
- Set<ImportKeysListEntry> keys = new HashSet<ImportKeysListEntry>();
+ Set<ImportKeysListEntry> keys = new HashSet<>();
try {
for (ImportKeysListEntry key : keyServer.search(mail)) {
if (key.isRevoked() || key.isExpired()) continue;
@@ -103,6 +103,6 @@ public class EmailKeyHelper {
} catch (Keyserver.QueryFailedException ignored) {
} catch (Keyserver.QueryNeedsRepairException ignored) {
}
- return new ArrayList<ImportKeysListEntry>(keys);
+ return new ArrayList<>(keys);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java
index 7492d95b2..1d78ed80e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java
@@ -24,13 +24,11 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
-import android.support.v7.app.ActionBarActivity;
-import android.widget.Toast;
+import android.support.v4.app.FragmentActivity;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.ExportResult;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
@@ -42,9 +40,9 @@ import java.io.File;
public class ExportHelper {
protected File mExportFile;
- ActionBarActivity mActivity;
+ FragmentActivity mActivity;
- public ExportHelper(ActionBarActivity activity) {
+ public ExportHelper(FragmentActivity activity) {
super();
this.mActivity = activity;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java
index f89ffd139..1f73dcb28 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java
@@ -25,16 +25,28 @@ import java.io.InputStream;
public class InputData {
private PositionAwareInputStream mInputStream;
private long mSize;
+ String mOriginalFilename;
+
+ public InputData(InputStream inputStream, long size, String originalFilename) {
+ mInputStream = new PositionAwareInputStream(inputStream);
+ mSize = size;
+ mOriginalFilename = originalFilename;
+ }
public InputData(InputStream inputStream, long size) {
mInputStream = new PositionAwareInputStream(inputStream);
mSize = size;
+ mOriginalFilename = "";
}
public InputStream getInputStream() {
return mInputStream;
}
+ public String getOriginalFilename () {
+ return mOriginalFilename;
+ }
+
public long getSize() {
return mSize;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Iso7816TLV.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Iso7816TLV.java
index 90afd3bc0..c0483ad04 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Iso7816TLV.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Iso7816TLV.java
@@ -125,7 +125,7 @@ public class Iso7816TLV {
public static Iso7816TLV[] readList(byte[] data, boolean recursive) throws IOException {
ByteBuffer buf = ByteBuffer.wrap(data);
- ArrayList<Iso7816TLV> result = new ArrayList<Iso7816TLV>();
+ ArrayList<Iso7816TLV> result = new ArrayList<>();
// read while data is available. this will fail if there is trailing data!
while (buf.hasRemaining()) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java
index 76ec9f75f..943b913d7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java
@@ -17,21 +17,6 @@
package org.sufficientlysecure.keychain.util;
-import android.content.Context;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Messenger;
-
-import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-
-import java.util.ArrayList;
-import java.util.List;
-
public class KeyUpdateHelper {
/*
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java
index b4f7c5767..8b165cd57 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java
@@ -21,9 +21,6 @@ import android.os.Bundle;
import org.sufficientlysecure.keychain.Constants;
-import java.io.IOException;
-import java.io.StreamTokenizer;
-import java.io.StringReader;
import java.util.Iterator;
import java.util.Set;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java
index 3081021cf..6f9cb277e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java
@@ -32,9 +32,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Iterator;
-import java.util.List;
/**
* When sending large data (over 1MB) through Androids Binder IPC you get
@@ -106,7 +104,6 @@ public class ParcelableFileCache<E extends Parcelable> {
throw new IOException(e);
}
- // yes this is sloppy data flow. WE WOULDN'T NEED THIS WITH TUPLE RETURN TYPES
final int numEntries = ois.readInt();
return new IteratorWithSize<E>() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java
index 65f4af880..a36af5c87 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java
@@ -172,7 +172,7 @@ public class Preferences {
}
public boolean useDefaultYubikeyPin() {
- return mSharedPreferences.getBoolean(Pref.USE_DEFAULT_YUBIKEY_PIN, true);
+ return mSharedPreferences.getBoolean(Pref.USE_DEFAULT_YUBIKEY_PIN, false);
}
public void setUseDefaultYubikeyPin(boolean useDefaultYubikeyPin) {
@@ -182,7 +182,7 @@ public class Preferences {
}
public boolean useNumKeypadForYubikeyPin() {
- return mSharedPreferences.getBoolean(Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN, false);
+ return mSharedPreferences.getBoolean(Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN, true);
}
public void setUseNumKeypadForYubikeyPin(boolean useNumKeypadForYubikeyPin) {
@@ -200,7 +200,7 @@ public class Preferences {
public String[] getKeyServers() {
String rawData = mSharedPreferences.getString(Constants.Pref.KEY_SERVERS,
Constants.Defaults.KEY_SERVERS);
- Vector<String> servers = new Vector<String>();
+ Vector<String> servers = new Vector<>();
String chunks[] = rawData.split(",");
for (String c : chunks) {
String tmp = c.trim();
@@ -281,7 +281,7 @@ public class Preferences {
case 3: {
// migrate keyserver to hkps
String[] serversArray = getKeyServers();
- ArrayList<String> servers = new ArrayList<String>(Arrays.asList(serversArray));
+ ArrayList<String> servers = new ArrayList<>(Arrays.asList(serversArray));
ListIterator<String> it = servers.listIterator();
while (it.hasNext()) {
String server = it.next();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java
index 51e58565f..120b84a3b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java
@@ -43,16 +43,18 @@ public class ShareHelper {
* Put together from some stackoverflow posts...
*/
public Intent createChooserExcluding(Intent prototype, String title, String[] activityBlacklist) {
- // Produced an empty list on Huawei U8860 with Android Version 4.0.3 and weird results on 2.3
+ // Produced an empty list on Huawei U8860 with Android Version 4.0.3
// TODO: test on 4.1, 4.2, 4.3, only tested on 4.4
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
+ // Disabled on 5.0 because using EXTRA_INITIAL_INTENTS prevents the usage based sorting
+ // introduced in 5.0: https://medium.com/@xXxXxXxXxXam/how-lollipops-share-menu-is-organized-d204888f606d
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return Intent.createChooser(prototype, title);
}
- List<LabeledIntent> targetedShareIntents = new ArrayList<LabeledIntent>();
+ List<LabeledIntent> targetedShareIntents = new ArrayList<>();
List<ResolveInfo> resInfoList = mContext.getPackageManager().queryIntentActivities(prototype, 0);
- List<ResolveInfo> resInfoListFiltered = new ArrayList<ResolveInfo>();
+ List<ResolveInfo> resInfoListFiltered = new ArrayList<>();
if (!resInfoList.isEmpty()) {
for (ResolveInfo resolveInfo : resInfoList) {
// do not add blacklisted ones
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java
index 9946d81aa..4ff14e3bb 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java
@@ -20,7 +20,6 @@ package org.sufficientlysecure.keychain.util;
import android.content.res.AssetManager;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.Log;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -50,7 +49,7 @@ public class TlsHelper {
}
}
- private static Map<String, byte[]> sStaticCA = new HashMap<String, byte[]>();
+ private static Map<String, byte[]> sStaticCA = new HashMap<>();
public static void addStaticCA(String domain, byte[] certificate) {
sStaticCA.put(domain, certificate);
@@ -120,13 +119,7 @@ public class TlsHelper {
urlConnection.setSSLSocketFactory(context.getSocketFactory());
return urlConnection;
- } catch (CertificateException e) {
- throw new TlsHelperException(e);
- } catch (NoSuchAlgorithmException e) {
- throw new TlsHelperException(e);
- } catch (KeyStoreException e) {
- throw new TlsHelperException(e);
- } catch (KeyManagementException e) {
+ } catch (CertificateException | KeyManagementException | KeyStoreException | NoSuchAlgorithmException e) {
throw new TlsHelperException(e);
}
}
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/apptheme_fastscroll_thumb_default_holo.png b/OpenKeychain/src/main/res/drawable-hdpi/apptheme_fastscroll_thumb_default_holo.png
deleted file mode 100644
index 0ddafab03..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/apptheme_fastscroll_thumb_default_holo.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/apptheme_fastscroll_thumb_pressed_holo.png b/OpenKeychain/src/main/res/drawable-hdpi/apptheme_fastscroll_thumb_pressed_holo.png
deleted file mode 100644
index c062b17f8..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/apptheme_fastscroll_thumb_pressed_holo.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/create_key_robot.png b/OpenKeychain/src/main/res/drawable-hdpi/create_key_robot.png
index acc198fc3..2d16b50cf 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/create_key_robot.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/create_key_robot.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_collapse.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_collapse.png
deleted file mode 100644
index e9d2dcb46..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_collapse.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_encrypt_file.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_encrypt_file.png
new file mode 100644
index 000000000..1e397ebed
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_encrypt_file.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_encrypt_text.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_encrypt_text.png
new file mode 100644
index 000000000..1cbd993a7
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_encrypt_text.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_expand.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_expand.png
deleted file mode 100644
index 29f4de211..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_expand.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_nfc.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_nfc.png
deleted file mode 100644
index 635633709..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_nfc.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_qr_code.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_qr_code.png
deleted file mode 100644
index ceb3b1645..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_qr_code.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_safeslinger.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_safeslinger.png
deleted file mode 100644
index 6ff9bb7b4..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_safeslinger.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_verified_cutout.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_verified_cutout.png
new file mode 100644
index 000000000..896aca575
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_verified_cutout.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_apps_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_apps_black_24dp.png
new file mode 100644
index 000000000..37931a0ad
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_apps_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png
new file mode 100644
index 000000000..5fa494878
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_check_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_check_white_24dp.png
new file mode 100644
index 000000000..f42a0e2d2
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_check_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_close_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..0fd15563a
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_close_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_cloud_search_24px.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_cloud_search_24px.png
new file mode 100644
index 000000000..6f9b343ad
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_cloud_search_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_expand_less_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_expand_less_black_24dp.png
new file mode 100644
index 000000000..35e3b426f
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_expand_less_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_expand_more_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_expand_more_black_24dp.png
new file mode 100644
index 000000000..ed993f35d
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_expand_more_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_folder_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_folder_white_24dp.png
new file mode 100644
index 000000000..9f5c75609
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_folder_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_help_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_help_black_24dp.png
new file mode 100644
index 000000000..05be749c3
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_help_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_launcher.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_launcher.png
index f5487599b..6133816d2 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/ic_launcher.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_lock_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_lock_black_24dp.png
new file mode 100644
index 000000000..0888c6173
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_lock_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_lock_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_lock_white_24dp.png
new file mode 100644
index 000000000..b94735ecb
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_lock_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png
new file mode 100644
index 000000000..3ee3e1720
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_nfc_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..1d87415c5
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png
new file mode 100644
index 000000000..164385d04
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_qrcode_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..261f4a5ab
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png
new file mode 100644
index 000000000..cd16fdd50
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_repeat_grey_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_repeat_grey_24dp.png
new file mode 100644
index 000000000..48d6ce93a
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_repeat_grey_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_repeat_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_repeat_white_24dp.png
new file mode 100644
index 000000000..612e73458
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_repeat_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_search_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_search_white_24dp.png
new file mode 100644
index 000000000..a2fc5b2e7
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_search_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_settings_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_settings_black_24dp.png
new file mode 100644
index 000000000..b16209fc1
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_settings_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_vpn_key_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_vpn_key_black_24dp.png
new file mode 100644
index 000000000..c900b8ec7
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/ic_vpn_key_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/key_flag_authenticate.png b/OpenKeychain/src/main/res/drawable-hdpi/key_flag_authenticate_24px.png
index 9d4ed6e84..9d4ed6e84 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/key_flag_authenticate.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/key_flag_authenticate_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/key_flag_certify.png b/OpenKeychain/src/main/res/drawable-hdpi/key_flag_certify_24px.png
index e76393659..e76393659 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/key_flag_certify.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/key_flag_certify_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/key_flag_encrypt.png b/OpenKeychain/src/main/res/drawable-hdpi/key_flag_encrypt_24px.png
index 3c2f8c09c..3c2f8c09c 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/key_flag_encrypt.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/key_flag_encrypt_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/key_flag_sign.png b/OpenKeychain/src/main/res/drawable-hdpi/key_flag_sign_24px.png
index 046424643..046424643 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/key_flag_sign.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/key_flag_sign_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png
deleted file mode 100644
index f74fcdd8d..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_disabled_holo_light.png
deleted file mode 100644
index 9dbad9b92..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_focused_holo_light.png
deleted file mode 100644
index 58a99014e..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_holo_light.png
deleted file mode 100644
index b1b52b23a..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_pressed_holo_light.png
deleted file mode 100644
index e5f0ddf50..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_off_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png
deleted file mode 100644
index 1d06ee46f..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_disabled_holo_light.png
deleted file mode 100644
index cd02122be..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_focused_holo_light.png
deleted file mode 100644
index 0f9718950..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_holo_light.png
deleted file mode 100644
index 8db606b56..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_pressed_holo_light.png
deleted file mode 100644
index 313698a88..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_check_on_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png
deleted file mode 100644
index 8ee0aa89c..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_disabled_holo_light.9.png
deleted file mode 100644
index 6a2a92cce..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_focused_holo_light.9.png
deleted file mode 100644
index e6ce2835c..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_normal_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_normal_holo_light.9.png
deleted file mode 100644
index 55139e939..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_normal_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_pressed_holo_light.9.png
deleted file mode 100644
index aaae193fb..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_default_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png
deleted file mode 100644
index 0dc2a75ab..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_disabled_holo_light.png
deleted file mode 100644
index 25e8e1ba5..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_focused_holo_light.png
deleted file mode 100644
index 0c22251f3..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_holo_light.png
deleted file mode 100644
index 932257123..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_pressed_holo_light.png
deleted file mode 100644
index 065e49a12..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_off_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png
deleted file mode 100644
index 82eb795b8..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_disabled_holo_light.png
deleted file mode 100644
index 6e61b5287..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_focused_holo_light.png
deleted file mode 100644
index fbee3366d..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_holo_light.png
deleted file mode 100644
index eda8002eb..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_pressed_holo_light.png
deleted file mode 100644
index 7f66e282f..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_btn_radio_on_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_activated_holo.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_activated_holo.9.png
deleted file mode 100644
index e98c2a4d2..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_activated_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_focused_holo.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_focused_holo.9.png
deleted file mode 100644
index 84d9006eb..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_longpressed_holo.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_longpressed_holo.9.png
deleted file mode 100644
index e9196aa82..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_longpressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_pressed_holo_light.9.png
deleted file mode 100644
index 895e51bdf..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_selector_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_selector_disabled_holo_light.9.png
deleted file mode 100644
index ca8e9a277..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_list_selector_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_bg_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_bg_holo_light.9.png
deleted file mode 100644
index 3f12166d2..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_bg_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_primary_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_primary_holo_light.9.png
deleted file mode 100644
index c14605dab..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_primary_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_secondary_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_secondary_holo_light.9.png
deleted file mode 100644
index 60aefe181..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progress_secondary_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo1.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo1.png
deleted file mode 100644
index b9977dedb..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo1.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo2.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo2.png
deleted file mode 100644
index 88601174a..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo2.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo3.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo3.png
deleted file mode 100644
index 6cd634a91..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo3.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo4.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo4.png
deleted file mode 100644
index 9456cf4e1..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo4.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo5.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo5.png
deleted file mode 100644
index fc6c57e16..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo5.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo6.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo6.png
deleted file mode 100644
index 3c2e03356..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo6.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo7.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo7.png
deleted file mode 100644
index 2618d0e50..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo7.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo8.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo8.png
deleted file mode 100644
index 56745c26b..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_progressbar_indeterminate_holo8.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_default_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_default_holo_light.9.png
deleted file mode 100644
index a02ebb450..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_disabled_holo_light.9.png
deleted file mode 100644
index d0d94197b..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_focused_holo_light.9.png
deleted file mode 100644
index 12c3cd5af..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_pressed_holo_light.9.png
deleted file mode 100644
index 35f8ec52a..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_spinner_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_activated_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_activated_holo_light.9.png
deleted file mode 100644
index 70691cddc..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_activated_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_default_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_default_holo_light.9.png
deleted file mode 100644
index d5ac69c23..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png
deleted file mode 100644
index b70db4e10..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_disabled_holo_light.9.png
deleted file mode 100644
index a77d66d99..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_focused_holo_light.9.png
deleted file mode 100644
index 257eba9a0..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/keychaintheme_textfield_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_lock_closed.png b/OpenKeychain/src/main/res/drawable-hdpi/status_lock_closed_24px.png
index a1b090630..a1b090630 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_lock_closed.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_lock_closed_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_lock_error.png b/OpenKeychain/src/main/res/drawable-hdpi/status_lock_error_24px.png
index e567055aa..e567055aa 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_lock_error.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_lock_error_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_lock_open.png b/OpenKeychain/src/main/res/drawable-hdpi/status_lock_open_24px.png
index 98e32eadc..98e32eadc 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_lock_open.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_lock_open_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired.png
deleted file mode 100644
index 21e8b536a..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout_24px.png
index 84ac9bec2..84ac9bec2 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout_96px.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout_96px.png
new file mode 100644
index 000000000..63546068f
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_expired_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid.png
deleted file mode 100644
index 9ae2a09ab..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout_24px.png
index 967e00e80..967e00e80 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout_96px.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout_96px.png
new file mode 100644
index 000000000..9957db288
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_invalid_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked.png
deleted file mode 100644
index 16e1d7181..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout_24px.png
index 244dd0708..244dd0708 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout_96px.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout_96px.png
new file mode 100644
index 000000000..1c3a15c07
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_revoked_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown.png
deleted file mode 100644
index 5c3ba866d..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout_24px.png
index 82cc25a4b..82cc25a4b 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout_96px.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout_96px.png
new file mode 100644
index 000000000..ce46c6317
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unknown_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified.png
deleted file mode 100644
index b8b472a5a..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout_24px.png
index e752eaeab..e752eaeab 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout_96px.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout_96px.png
new file mode 100644
index 000000000..19ee3c241
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_unverified_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified.png
deleted file mode 100644
index d8141b47b..000000000
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout_24px.png
index 08a9f464c..08a9f464c 100644
--- a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout_96px.png b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout_96px.png
new file mode 100644
index 000000000..ed3db0aca
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-hdpi/status_signature_verified_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-ldpi/ic_launcher.png b/OpenKeychain/src/main/res/drawable-ldpi/ic_launcher.png
deleted file mode 100644
index 7cd482bff..000000000
--- a/OpenKeychain/src/main/res/drawable-ldpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-ldpi/uid_mail_bad.png b/OpenKeychain/src/main/res/drawable-ldpi/uid_mail_bad.png
deleted file mode 100644
index 45467992f..000000000
--- a/OpenKeychain/src/main/res/drawable-ldpi/uid_mail_bad.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-ldpi/uid_mail_ok.png b/OpenKeychain/src/main/res/drawable-ldpi/uid_mail_ok.png
deleted file mode 100644
index c400a1820..000000000
--- a/OpenKeychain/src/main/res/drawable-ldpi/uid_mail_ok.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/apptheme_fastscroll_thumb_default_holo.png b/OpenKeychain/src/main/res/drawable-mdpi/apptheme_fastscroll_thumb_default_holo.png
deleted file mode 100644
index ebffb16a0..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/apptheme_fastscroll_thumb_default_holo.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/apptheme_fastscroll_thumb_pressed_holo.png b/OpenKeychain/src/main/res/drawable-mdpi/apptheme_fastscroll_thumb_pressed_holo.png
deleted file mode 100644
index b6739b564..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/apptheme_fastscroll_thumb_pressed_holo.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/create_key_robot.png b/OpenKeychain/src/main/res/drawable-mdpi/create_key_robot.png
index 58476bfc9..08168f357 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/create_key_robot.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/create_key_robot.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_collapse.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_collapse.png
deleted file mode 100644
index 4ac28f270..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_collapse.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_encrypt_file.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_encrypt_file.png
new file mode 100644
index 000000000..06a054160
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_encrypt_file.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_encrypt_text.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_encrypt_text.png
new file mode 100644
index 000000000..97cb03def
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_encrypt_text.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_expand.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_expand.png
deleted file mode 100644
index bb46bb315..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_expand.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_nfc.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_nfc.png
deleted file mode 100644
index da5e267d0..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_nfc.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_qr_code.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_qr_code.png
deleted file mode 100644
index 21594e62f..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_qr_code.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_safeslinger.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_safeslinger.png
deleted file mode 100644
index bfea67f33..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_safeslinger.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_verified_cutout.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_verified_cutout.png
new file mode 100644
index 000000000..0329b488f
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_verified_cutout.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_apps_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_apps_black_24dp.png
new file mode 100644
index 000000000..5b1fd7766
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_apps_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png
new file mode 100644
index 000000000..9e662f6d4
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_check_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_check_white_24dp.png
new file mode 100644
index 000000000..e91f9048b
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_check_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_close_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..e80681aeb
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_close_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_cloud_search_24px.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_cloud_search_24px.png
new file mode 100644
index 000000000..7a69993fd
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_cloud_search_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_expand_less_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_expand_less_black_24dp.png
new file mode 100644
index 000000000..a5ab2c5d3
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_expand_less_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_expand_more_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_expand_more_black_24dp.png
new file mode 100644
index 000000000..73fc3b422
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_expand_more_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_folder_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_folder_white_24dp.png
new file mode 100644
index 000000000..1c5797c9e
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_folder_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_help_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_help_black_24dp.png
new file mode 100644
index 000000000..f3743dc20
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_help_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_launcher.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_launcher.png
index 34f1420ac..d945a01de 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/ic_launcher.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_lock_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_lock_black_24dp.png
new file mode 100644
index 000000000..d18d4b667
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_lock_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_lock_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_lock_white_24dp.png
new file mode 100644
index 000000000..381b6a118
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_lock_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png
new file mode 100644
index 000000000..85cff0b91
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_nfc_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..65ae04b7c
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png
new file mode 100644
index 000000000..8d1e433a5
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_qrcode_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..5cf552b13
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png
new file mode 100644
index 000000000..235c84f1e
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_repeat_grey_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_repeat_grey_24dp.png
new file mode 100644
index 000000000..60aa53747
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_repeat_grey_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_repeat_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_repeat_white_24dp.png
new file mode 100644
index 000000000..8a2b641ca
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_repeat_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_search_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_search_white_24dp.png
new file mode 100644
index 000000000..dff1e3a8a
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_search_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_settings_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_settings_black_24dp.png
new file mode 100644
index 000000000..3405c951d
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_settings_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_vpn_key_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_vpn_key_black_24dp.png
new file mode 100644
index 000000000..5e8781731
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/ic_vpn_key_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/key_flag_authenticate.png b/OpenKeychain/src/main/res/drawable-mdpi/key_flag_authenticate_24px.png
index ed1ba24d2..ed1ba24d2 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/key_flag_authenticate.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/key_flag_authenticate_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/key_flag_certify.png b/OpenKeychain/src/main/res/drawable-mdpi/key_flag_certify_24px.png
index d54d461fa..d54d461fa 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/key_flag_certify.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/key_flag_certify_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/key_flag_encrypt.png b/OpenKeychain/src/main/res/drawable-mdpi/key_flag_encrypt_24px.png
index 81c1b3dfa..81c1b3dfa 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/key_flag_encrypt.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/key_flag_encrypt_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/key_flag_sign.png b/OpenKeychain/src/main/res/drawable-mdpi/key_flag_sign_24px.png
index 9afc43901..9afc43901 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/key_flag_sign.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/key_flag_sign_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png
deleted file mode 100644
index d7be4f996..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_disabled_holo_light.png
deleted file mode 100644
index db190430c..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_focused_holo_light.png
deleted file mode 100644
index 2c5949eb9..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_holo_light.png
deleted file mode 100644
index f5eaf804b..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_pressed_holo_light.png
deleted file mode 100644
index c237545b1..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_off_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png
deleted file mode 100644
index d5e0ef543..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_disabled_holo_light.png
deleted file mode 100644
index 20e2aab12..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_focused_holo_light.png
deleted file mode 100644
index d12f33b7d..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_holo_light.png
deleted file mode 100644
index 517ea4302..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_pressed_holo_light.png
deleted file mode 100644
index 09f2df11f..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_check_on_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png
deleted file mode 100644
index c6a653217..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_disabled_holo_light.9.png
deleted file mode 100644
index d424a0e77..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_focused_holo_light.9.png
deleted file mode 100644
index dca8db91f..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_normal_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_normal_holo_light.9.png
deleted file mode 100644
index 502f762af..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_normal_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_pressed_holo_light.9.png
deleted file mode 100644
index 693371f44..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_default_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png
deleted file mode 100644
index ef648d9df..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_disabled_holo_light.png
deleted file mode 100644
index a67375ec8..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_focused_holo_light.png
deleted file mode 100644
index aefa6e2c7..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_holo_light.png
deleted file mode 100644
index 590c37c6c..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_pressed_holo_light.png
deleted file mode 100644
index ad8341be4..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_off_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png
deleted file mode 100644
index fa981c2f4..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_disabled_holo_light.png
deleted file mode 100644
index 4583c3e1f..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_focused_holo_light.png
deleted file mode 100644
index b7421f31a..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_holo_light.png
deleted file mode 100644
index 0f3beeea6..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_pressed_holo_light.png
deleted file mode 100644
index 7d47196e4..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_btn_radio_on_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_activated_holo.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_activated_holo.9.png
deleted file mode 100644
index aa1130332..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_activated_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_focused_holo.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_focused_holo.9.png
deleted file mode 100644
index 8d1b4af83..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_longpressed_holo.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_longpressed_holo.9.png
deleted file mode 100644
index ba6538fbe..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_longpressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_pressed_holo_light.9.png
deleted file mode 100644
index 886a6ee0c..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_selector_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_selector_disabled_holo_light.9.png
deleted file mode 100644
index 42cb6463e..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_list_selector_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_bg_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_bg_holo_light.9.png
deleted file mode 100644
index 780b4b256..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_bg_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_primary_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_primary_holo_light.9.png
deleted file mode 100644
index fdb236d7c..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_primary_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_secondary_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_secondary_holo_light.9.png
deleted file mode 100644
index 64b72e8ee..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progress_secondary_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo1.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo1.png
deleted file mode 100644
index 0cff52503..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo1.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo2.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo2.png
deleted file mode 100644
index 3a290e871..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo2.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo3.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo3.png
deleted file mode 100644
index d6b4a1326..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo3.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo4.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo4.png
deleted file mode 100644
index 98061c845..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo4.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo5.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo5.png
deleted file mode 100644
index cf130fdf2..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo5.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo6.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo6.png
deleted file mode 100644
index 72d43ea01..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo6.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo7.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo7.png
deleted file mode 100644
index 6a7307dcf..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo7.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo8.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo8.png
deleted file mode 100644
index 0d3cb5fe7..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_progressbar_indeterminate_holo8.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_default_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_default_holo_light.9.png
deleted file mode 100644
index 574ea43ba..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_disabled_holo_light.9.png
deleted file mode 100644
index a78d6c082..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_focused_holo_light.9.png
deleted file mode 100644
index 33c452dcd..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_pressed_holo_light.9.png
deleted file mode 100644
index 3636d59d4..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_spinner_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_activated_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_activated_holo_light.9.png
deleted file mode 100644
index 4569d71a9..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_activated_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_default_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_default_holo_light.9.png
deleted file mode 100644
index 47302c93e..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png
deleted file mode 100644
index 0d5ea839d..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_disabled_holo_light.9.png
deleted file mode 100644
index ea6d2f74b..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_focused_holo_light.9.png
deleted file mode 100644
index 39ca1ffda..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/keychaintheme_textfield_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_lock_closed.png b/OpenKeychain/src/main/res/drawable-mdpi/status_lock_closed_24px.png
index cfc39f0e7..cfc39f0e7 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_lock_closed.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_lock_closed_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_lock_error.png b/OpenKeychain/src/main/res/drawable-mdpi/status_lock_error_24px.png
index 824dc2672..824dc2672 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_lock_error.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_lock_error_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_lock_open.png b/OpenKeychain/src/main/res/drawable-mdpi/status_lock_open_24px.png
index 9bca59ae3..9bca59ae3 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_lock_open.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_lock_open_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired.png
deleted file mode 100644
index 81a900147..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout_24px.png
index bc91094b5..bc91094b5 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout_96px.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout_96px.png
new file mode 100644
index 000000000..df385bb1b
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_expired_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid.png
deleted file mode 100644
index baa78f795..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout_24px.png
index bc2f56e2a..bc2f56e2a 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout_96px.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout_96px.png
new file mode 100644
index 000000000..aeb899599
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_invalid_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked.png
deleted file mode 100644
index 7cf985274..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout_24px.png
index 2d2593194..2d2593194 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout_96px.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout_96px.png
new file mode 100644
index 000000000..d77c5e1c1
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_revoked_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown.png
deleted file mode 100644
index 3d4665320..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout_24px.png
index 0fc74d07e..0fc74d07e 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout_96px.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout_96px.png
new file mode 100644
index 000000000..ee0661234
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unknown_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified.png
deleted file mode 100644
index 8348b32b3..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout_24px.png
index 96a2d1413..96a2d1413 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout_96px.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout_96px.png
new file mode 100644
index 000000000..1602747f1
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_unverified_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified.png
deleted file mode 100644
index 02e53ac8a..000000000
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout_24px.png
index 9f7cf837c..9f7cf837c 100644
--- a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout_96px.png b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout_96px.png
new file mode 100644
index 000000000..61c23f749
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-mdpi/status_signature_verified_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/apptheme_fastscroll_thumb_default_holo.png b/OpenKeychain/src/main/res/drawable-xhdpi/apptheme_fastscroll_thumb_default_holo.png
deleted file mode 100644
index 7c5e21eeb..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/apptheme_fastscroll_thumb_default_holo.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/apptheme_fastscroll_thumb_pressed_holo.png b/OpenKeychain/src/main/res/drawable-xhdpi/apptheme_fastscroll_thumb_pressed_holo.png
deleted file mode 100644
index 86814b45d..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/apptheme_fastscroll_thumb_pressed_holo.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/create_key_robot.png b/OpenKeychain/src/main/res/drawable-xhdpi/create_key_robot.png
index 022f2dd2e..a7d43e3b7 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/create_key_robot.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/create_key_robot.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_collapse.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_collapse.png
deleted file mode 100644
index 60ac6b066..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_collapse.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_encrypt_file.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_encrypt_file.png
new file mode 100644
index 000000000..5f528864d
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_encrypt_file.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_encrypt_text.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_encrypt_text.png
new file mode 100644
index 000000000..f8867e922
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_encrypt_text.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_expand.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_expand.png
deleted file mode 100644
index 76937f57a..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_expand.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_nfc.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_nfc.png
deleted file mode 100644
index ff569927c..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_nfc.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_qr_code.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_qr_code.png
deleted file mode 100644
index 93bdac866..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_qr_code.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_safeslinger.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_safeslinger.png
deleted file mode 100644
index 864a18d1a..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_safeslinger.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_verified_cutout.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_verified_cutout.png
new file mode 100644
index 000000000..116adf28d
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_verified_cutout.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_apps_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_apps_black_24dp.png
new file mode 100644
index 000000000..c8187799b
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_apps_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png
new file mode 100644
index 000000000..addbfc886
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_check_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_check_white_24dp.png
new file mode 100644
index 000000000..e5024472a
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_check_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_close_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..76e07f097
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_close_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_cloud_search_24px.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_cloud_search_24px.png
new file mode 100644
index 000000000..1f0db264a
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_cloud_search_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_expand_less_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_expand_less_black_24dp.png
new file mode 100644
index 000000000..47c7b52a1
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_expand_less_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_expand_more_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_expand_more_black_24dp.png
new file mode 100644
index 000000000..45d30d999
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_expand_more_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_folder_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_folder_white_24dp.png
new file mode 100644
index 000000000..e5f54cef0
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_folder_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_help_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_help_black_24dp.png
new file mode 100644
index 000000000..87095ef26
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_help_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_launcher.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_launcher.png
index 32584f3ff..825b18b38 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/ic_launcher.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_lock_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_lock_black_24dp.png
new file mode 100644
index 000000000..8856c70df
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_lock_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_lock_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_lock_white_24dp.png
new file mode 100644
index 000000000..c5e9d0b49
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_lock_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png
new file mode 100644
index 000000000..7f0ea51bf
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_nfc_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..44b9006ab
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png
new file mode 100644
index 000000000..a55d19922
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_qrcode_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..a2c6ade61
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_refresh_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_refresh_white_24dp.png
new file mode 100644
index 000000000..5f89fc257
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_refresh_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_repeat_grey_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_repeat_grey_24dp.png
new file mode 100644
index 000000000..3d0e27547
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_repeat_grey_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_repeat_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_repeat_white_24dp.png
new file mode 100644
index 000000000..729220066
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_repeat_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_search_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_search_white_24dp.png
new file mode 100644
index 000000000..043759acd
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_search_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png
new file mode 100644
index 000000000..2b775b646
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_vpn_key_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_vpn_key_black_24dp.png
new file mode 100644
index 000000000..ccbdce4ab
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/ic_vpn_key_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_authenticate.png b/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_authenticate_24px.png
index 8d36d7202..8d36d7202 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_authenticate.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_authenticate_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_certify.png b/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_certify_24px.png
index 01a74bcc0..01a74bcc0 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_certify.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_certify_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_encrypt.png b/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_encrypt_24px.png
index ff07bd0a4..ff07bd0a4 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_encrypt.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_encrypt_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_sign.png b/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_sign_24px.png
index b8002162a..b8002162a 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_sign.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/key_flag_sign_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png
deleted file mode 100644
index 0b0606462..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_disabled_holo_light.png
deleted file mode 100644
index 6a364bbe3..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_focused_holo_light.png
deleted file mode 100644
index 65d850957..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_holo_light.png
deleted file mode 100644
index a1c2005a8..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_pressed_holo_light.png
deleted file mode 100644
index 7ae2fad2b..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_off_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png
deleted file mode 100644
index 80ad53ff0..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_disabled_holo_light.png
deleted file mode 100644
index d705b4204..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_focused_holo_light.png
deleted file mode 100644
index b72dea7f8..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_holo_light.png
deleted file mode 100644
index f24991826..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_pressed_holo_light.png
deleted file mode 100644
index db233e702..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_check_on_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png
deleted file mode 100644
index 5c122118e..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_disabled_holo_light.9.png
deleted file mode 100644
index b410d238e..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_focused_holo_light.9.png
deleted file mode 100644
index e738f8218..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_normal_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_normal_holo_light.9.png
deleted file mode 100644
index 8bb32617b..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_normal_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_pressed_holo_light.9.png
deleted file mode 100644
index 06d1d1e75..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_default_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png
deleted file mode 100644
index 83af2dcc3..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_disabled_holo_light.png
deleted file mode 100644
index 1030a801a..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_focused_holo_light.png
deleted file mode 100644
index b02c9b6d1..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_holo_light.png
deleted file mode 100644
index 2360f30be..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_pressed_holo_light.png
deleted file mode 100644
index 0bbf8a326..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_off_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png
deleted file mode 100644
index 1a2ed89db..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_disabled_holo_light.png
deleted file mode 100644
index 5741490d3..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_focused_holo_light.png
deleted file mode 100644
index 306e47e71..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_holo_light.png
deleted file mode 100644
index d22876cb2..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_pressed_holo_light.png
deleted file mode 100644
index c6a6d833d..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_btn_radio_on_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_activated_holo.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_activated_holo.9.png
deleted file mode 100644
index 6a24d21e7..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_activated_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_focused_holo.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_focused_holo.9.png
deleted file mode 100644
index 430387245..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_longpressed_holo.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_longpressed_holo.9.png
deleted file mode 100644
index 22ab07906..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_longpressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_pressed_holo_light.9.png
deleted file mode 100644
index 541163853..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_selector_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_selector_disabled_holo_light.9.png
deleted file mode 100644
index c6a7d4d87..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_list_selector_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_bg_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_bg_holo_light.9.png
deleted file mode 100644
index cbd19ac4f..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_bg_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_primary_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_primary_holo_light.9.png
deleted file mode 100644
index 9e08305f5..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_primary_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_secondary_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_secondary_holo_light.9.png
deleted file mode 100644
index 95c75a6db..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progress_secondary_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo1.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo1.png
deleted file mode 100644
index 06f79cba3..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo1.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo2.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo2.png
deleted file mode 100644
index f7bae4cef..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo2.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo3.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo3.png
deleted file mode 100644
index fc5808cbf..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo3.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo4.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo4.png
deleted file mode 100644
index ef108bdf4..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo4.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo5.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo5.png
deleted file mode 100644
index f826eee36..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo5.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo6.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo6.png
deleted file mode 100644
index dfd468fe9..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo6.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo7.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo7.png
deleted file mode 100644
index 6a223873c..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo7.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo8.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo8.png
deleted file mode 100644
index 27a2832af..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_progressbar_indeterminate_holo8.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_default_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_default_holo_light.9.png
deleted file mode 100644
index 10458c01a..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_disabled_holo_light.9.png
deleted file mode 100644
index fe541269e..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_focused_holo_light.9.png
deleted file mode 100644
index e4d7abf4d..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_pressed_holo_light.9.png
deleted file mode 100644
index 9d4c6e5a2..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_spinner_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_activated_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_activated_holo_light.9.png
deleted file mode 100644
index dc19219cf..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_activated_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_default_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_default_holo_light.9.png
deleted file mode 100644
index f0ad55a66..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png
deleted file mode 100644
index 40a28cf70..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_disabled_holo_light.9.png
deleted file mode 100644
index 4ffdd869e..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_focused_holo_light.9.png
deleted file mode 100644
index b84a6fed1..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/keychaintheme_textfield_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_closed.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_closed_24px.png
index 7c6bb2d18..7c6bb2d18 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_closed.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_closed_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_error.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_error_24px.png
index da4a5d89a..da4a5d89a 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_error.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_error_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_open.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_open_24px.png
index cd02fc1e4..cd02fc1e4 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_open.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_lock_open_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired.png
deleted file mode 100644
index f5105c1ae..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout_24px.png
index 83f6fde35..83f6fde35 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout_96px.png
new file mode 100644
index 000000000..568b48c43
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_expired_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid.png
deleted file mode 100644
index 67880d6db..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout_24px.png
index 29830f5ba..29830f5ba 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout_96px.png
new file mode 100644
index 000000000..89f899212
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_invalid_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked.png
deleted file mode 100644
index 2ed67419b..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout_24px.png
index 2f7695043..2f7695043 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout_96px.png
new file mode 100644
index 000000000..3db663e2e
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_revoked_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown.png
deleted file mode 100644
index a6f1f2792..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout_24px.png
index 2ce28c7ca..2ce28c7ca 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout_96px.png
new file mode 100644
index 000000000..4e0e04375
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unknown_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified.png
deleted file mode 100644
index c25a84b4d..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout_24px.png
index 442c55eee..442c55eee 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout_96px.png
new file mode 100644
index 000000000..0b2ccc9f7
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_unverified_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified.png
deleted file mode 100644
index 6f435a85e..000000000
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout_24px.png
index 160ec7cbe..160ec7cbe 100644
--- a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout_96px.png
new file mode 100644
index 000000000..471e5e513
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xhdpi/status_signature_verified_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/apptheme_fastscroll_thumb_default_holo.png b/OpenKeychain/src/main/res/drawable-xxhdpi/apptheme_fastscroll_thumb_default_holo.png
deleted file mode 100644
index 5e4818bfc..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/apptheme_fastscroll_thumb_default_holo.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/apptheme_fastscroll_thumb_pressed_holo.png b/OpenKeychain/src/main/res/drawable-xxhdpi/apptheme_fastscroll_thumb_pressed_holo.png
deleted file mode 100644
index 7dd89e1f4..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/apptheme_fastscroll_thumb_pressed_holo.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/create_key_robot.png b/OpenKeychain/src/main/res/drawable-xxhdpi/create_key_robot.png
index 5392deafd..0e3432635 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/create_key_robot.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/create_key_robot.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_collapse.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_collapse.png
deleted file mode 100644
index 76ec594dc..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_collapse.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_encrypt_file.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_encrypt_file.png
new file mode 100644
index 000000000..c77329563
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_encrypt_file.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_encrypt_text.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_encrypt_text.png
new file mode 100644
index 000000000..15650500d
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_encrypt_text.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_expand.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_expand.png
deleted file mode 100644
index 22003198b..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_expand.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_nfc.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_nfc.png
deleted file mode 100644
index 1f96ce37b..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_nfc.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_qr_code.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_qr_code.png
deleted file mode 100644
index 7ede90609..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_qr_code.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_safeslinger.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_safeslinger.png
deleted file mode 100644
index 02efa1d24..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_safeslinger.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_verified_cutout.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_verified_cutout.png
new file mode 100644
index 000000000..49b13017c
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_verified_cutout.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_apps_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_apps_black_24dp.png
new file mode 100644
index 000000000..626543b47
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_apps_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png
new file mode 100644
index 000000000..4057cc545
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png
new file mode 100644
index 000000000..6e03d54cf
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..0eb9d8b08
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_cloud_search_24px.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_cloud_search_24px.png
new file mode 100644
index 000000000..852cdc2a6
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_cloud_search_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_expand_less_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_expand_less_black_24dp.png
new file mode 100644
index 000000000..0470e3f02
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_expand_less_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_expand_more_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_expand_more_black_24dp.png
new file mode 100644
index 000000000..aadd04af6
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_expand_more_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_folder_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_folder_white_24dp.png
new file mode 100644
index 000000000..0d1ac4876
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_folder_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_help_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_help_black_24dp.png
new file mode 100644
index 000000000..f32d7e708
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_help_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_launcher.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_launcher.png
index b2922309f..4809acc39 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_lock_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_lock_black_24dp.png
new file mode 100644
index 000000000..c49d420e0
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_lock_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_lock_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_lock_white_24dp.png
new file mode 100644
index 000000000..0dcada814
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_lock_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png
new file mode 100644
index 000000000..34ec7092f
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_nfc_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..484856b3f
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png
new file mode 100644
index 000000000..043acd808
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_play_arrow_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_qrcode_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..c4f2f57c9
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png
new file mode 100644
index 000000000..72128fe69
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_repeat_grey_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_repeat_grey_24dp.png
new file mode 100644
index 000000000..6a8906126
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_repeat_grey_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_repeat_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_repeat_white_24dp.png
new file mode 100644
index 000000000..63f8de50f
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_repeat_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png
new file mode 100644
index 000000000..0bbeab150
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png
new file mode 100644
index 000000000..47f0e0d82
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_vpn_key_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_vpn_key_black_24dp.png
new file mode 100644
index 000000000..736bde37a
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_vpn_key_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_authenticate.png b/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_authenticate_24px.png
index d786dc72f..d786dc72f 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_authenticate.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_authenticate_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_certify.png b/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_certify_24px.png
index 4bb97f992..4bb97f992 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_certify.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_certify_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_encrypt.png b/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_encrypt_24px.png
index fe0c8e41b..fe0c8e41b 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_encrypt.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_encrypt_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_sign.png b/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_sign_24px.png
index 51ab367a9..51ab367a9 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_sign.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/key_flag_sign_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png
deleted file mode 100644
index c0fdc45b0..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_disabled_holo_light.png
deleted file mode 100644
index 47a63730b..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_focused_holo_light.png
deleted file mode 100644
index 911bad8a3..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_holo_light.png
deleted file mode 100644
index 310ab257c..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_pressed_holo_light.png
deleted file mode 100644
index 773206f63..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_off_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png
deleted file mode 100644
index 456471129..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_disabled_holo_light.png
deleted file mode 100644
index 013c1f6ee..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_focused_holo_light.png
deleted file mode 100644
index e67994690..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_holo_light.png
deleted file mode 100644
index 0c5038fc0..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_pressed_holo_light.png
deleted file mode 100644
index 4b0e39517..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_check_on_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png
deleted file mode 100644
index e90491aee..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_disabled_holo_light.9.png
deleted file mode 100644
index b4c90d408..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_focused_holo_light.9.png
deleted file mode 100644
index a0ba2a3a2..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_normal_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_normal_holo_light.9.png
deleted file mode 100644
index 24daa6b8a..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_normal_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_pressed_holo_light.9.png
deleted file mode 100644
index 9c808dd2c..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_default_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png
deleted file mode 100644
index 78ab31858..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_disabled_holo_light.png
deleted file mode 100644
index 06f0cc78c..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_focused_holo_light.png
deleted file mode 100644
index 2af5bf37b..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_holo_light.png
deleted file mode 100644
index 7d6fa76cd..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_pressed_holo_light.png
deleted file mode 100644
index 9fe2ebfce..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_off_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png
deleted file mode 100644
index 01e04d15e..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_disabled_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_disabled_holo_light.png
deleted file mode 100644
index adb730439..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_focused_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_focused_holo_light.png
deleted file mode 100644
index 90c4cac28..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_holo_light.png
deleted file mode 100644
index 7860fc848..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_pressed_holo_light.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_pressed_holo_light.png
deleted file mode 100644
index 58108fc4e..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_btn_radio_on_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_activated_holo.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_activated_holo.9.png
deleted file mode 100644
index b3b0da723..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_activated_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_focused_holo.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_focused_holo.9.png
deleted file mode 100644
index 0458c7f37..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_longpressed_holo.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_longpressed_holo.9.png
deleted file mode 100644
index 82036b6b7..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_longpressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_pressed_holo_light.9.png
deleted file mode 100644
index c7b06aa6a..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_selector_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_selector_disabled_holo_light.9.png
deleted file mode 100644
index 70bc9f282..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_list_selector_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_bg_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_bg_holo_light.9.png
deleted file mode 100644
index fb146c339..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_bg_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_primary_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_primary_holo_light.9.png
deleted file mode 100644
index f89b6477b..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_primary_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_secondary_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_secondary_holo_light.9.png
deleted file mode 100644
index 30a079d6e..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progress_secondary_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo1.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo1.png
deleted file mode 100644
index ca952535f..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo1.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo2.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo2.png
deleted file mode 100644
index 88804968f..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo2.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo3.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo3.png
deleted file mode 100644
index 580a9cf9c..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo3.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo4.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo4.png
deleted file mode 100644
index 8ce77b135..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo4.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo5.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo5.png
deleted file mode 100644
index 9c17f17a2..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo5.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo6.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo6.png
deleted file mode 100644
index 2cab8426e..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo6.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo7.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo7.png
deleted file mode 100644
index 18d252948..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo7.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo8.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo8.png
deleted file mode 100644
index d0632ca2d..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_progressbar_indeterminate_holo8.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_default_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_default_holo_light.9.png
deleted file mode 100644
index f9facd05d..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_disabled_holo_light.9.png
deleted file mode 100644
index 4cef09547..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_focused_holo_light.9.png
deleted file mode 100644
index f7a9f7c55..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_pressed_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_pressed_holo_light.9.png
deleted file mode 100644
index 62ac88d40..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_spinner_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_activated_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_activated_holo_light.9.png
deleted file mode 100644
index 733255647..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_activated_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_default_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_default_holo_light.9.png
deleted file mode 100644
index 6db1dd0aa..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png
deleted file mode 100644
index d157d7d60..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_disabled_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_disabled_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_disabled_holo_light.9.png
deleted file mode 100644
index c91f7da91..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_focused_holo_light.9.png b/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_focused_holo_light.9.png
deleted file mode 100644
index 01af8180e..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/keychaintheme_textfield_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_closed.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_closed_24px.png
index 5a9664d59..5a9664d59 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_closed.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_closed_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_error.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_error_24px.png
index 608f065af..608f065af 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_error.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_error_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_open.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_open_24px.png
index ee34dd396..ee34dd396 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_open.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_lock_open_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired.png
deleted file mode 100644
index f475c9d84..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout_24px.png
index 33a3efed1..33a3efed1 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout_96px.png
new file mode 100644
index 000000000..ba7e8c2f4
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_expired_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid.png
deleted file mode 100644
index f21c2cf52..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout_24px.png
index bc39d3496..bc39d3496 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout_96px.png
new file mode 100644
index 000000000..1fbf5ceb2
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked.png
deleted file mode 100644
index be1a1d9dc..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout_24px.png
index 58929661f..58929661f 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout_96px.png
new file mode 100644
index 000000000..338c696ac
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown.png
deleted file mode 100644
index 841cfa958..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout_24px.png
index 3020357a4..3020357a4 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout_96px.png
new file mode 100644
index 000000000..2690310a6
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified.png
deleted file mode 100644
index 525d1cf6b..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout_24px.png
index 3829bb3a0..3829bb3a0 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout_96px.png
new file mode 100644
index 000000000..e559faf9d
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified.png
deleted file mode 100644
index 54eee5ba0..000000000
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified.png
+++ /dev/null
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout_24px.png
index 3548ee2b6..3548ee2b6 100644
--- a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout.png
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout_24px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout_96px.png b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout_96px.png
new file mode 100644
index 000000000..79e4ec4a9
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxhdpi/status_signature_verified_cutout_96px.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_apps_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_apps_black_24dp.png
new file mode 100644
index 000000000..d12d2e796
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_apps_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png
new file mode 100644
index 000000000..02f2f6fe8
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png
new file mode 100644
index 000000000..87892840e
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..7b2a480a0
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_expand_less_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_expand_less_black_24dp.png
new file mode 100644
index 000000000..08ae54533
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_expand_less_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_expand_more_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_expand_more_black_24dp.png
new file mode 100644
index 000000000..228b2a982
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_expand_more_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_folder_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_folder_white_24dp.png
new file mode 100644
index 000000000..7a3c198ee
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_folder_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_help_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_help_black_24dp.png
new file mode 100644
index 000000000..a4286b54c
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_help_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_launcher.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_launcher.png
index 93ea6b0f5..fab324e93 100644
--- a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_launcher.png
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_lock_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_lock_black_24dp.png
new file mode 100644
index 000000000..db080df4e
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_lock_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_lock_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_lock_white_24dp.png
new file mode 100644
index 000000000..a70c55b7e
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_lock_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png
new file mode 100644
index 000000000..9380370f4
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_nfc_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_nfc_white_24dp.png
new file mode 100644
index 000000000..c8f25bbf7
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_nfc_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png
new file mode 100644
index 000000000..7cc008475
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_qrcode_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_qrcode_white_24dp.png
new file mode 100644
index 000000000..e795f80a5
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_qrcode_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png
new file mode 100644
index 000000000..d271d8e03
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_repeat_grey_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_repeat_grey_24dp.png
new file mode 100644
index 000000000..bf33f287b
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_repeat_grey_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_repeat_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_repeat_white_24dp.png
new file mode 100644
index 000000000..f3c284330
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_repeat_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png
new file mode 100644
index 000000000..70c21baf7
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png
new file mode 100644
index 000000000..bce161d00
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_vpn_key_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_vpn_key_black_24dp.png
new file mode 100644
index 000000000..3451d9855
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_vpn_key_black_24dp.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable/apptheme_fastscroll_thumb_holo.xml b/OpenKeychain/src/main/res/drawable/apptheme_fastscroll_thumb_holo.xml
deleted file mode 100644
index e7121f083..000000000
--- a/OpenKeychain/src/main/res/drawable/apptheme_fastscroll_thumb_holo.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/apptheme_fastscroll_thumb_pressed_holo" />
- <item android:drawable="@drawable/apptheme_fastscroll_thumb_default_holo" />
-</selector>
diff --git a/OpenKeychain/src/main/res/drawable/cardview_header.xml b/OpenKeychain/src/main/res/drawable/cardview_header.xml
new file mode 100644
index 000000000..9bab96ea9
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable/cardview_header.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle" >
+
+ <size
+ android:height="1dp"
+ android:width="1000dp" />
+
+ <solid android:color="@color/bg_gray" />
+
+</shape> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/drawable/drawer_header.png b/OpenKeychain/src/main/res/drawable/drawer_header.png
new file mode 100644
index 000000000..c8fdccf8d
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable/drawer_header.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable/fab_label_background.xml b/OpenKeychain/src/main/res/drawable/fab_label_background.xml
new file mode 100644
index 000000000..0d8c05b11
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable/fab_label_background.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="@color/black_semi_transparent"/>
+ <padding
+ android:left="16dp"
+ android:top="4dp"
+ android:right="16dp"
+ android:bottom="4dp"/>
+ <corners
+ android:radius="2dp"/>
+</shape> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/drawable/first_time_1.png b/OpenKeychain/src/main/res/drawable/first_time_1.png
index 1f340df5c..1f93f2deb 100644
--- a/OpenKeychain/src/main/res/drawable/first_time_1.png
+++ b/OpenKeychain/src/main/res/drawable/first_time_1.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_activated_background_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_activated_background_holo_light.xml
deleted file mode 100644
index 60415e926..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_activated_background_holo_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_activated="true" android:drawable="@drawable/keychaintheme_list_activated_holo" />
- <item android:drawable="@android:color/transparent" />
-</selector>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_btn_check_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_btn_check_holo_light.xml
deleted file mode 100644
index 62567cb98..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_btn_check_holo_light.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Enabled states -->
-
- <item android:state_checked="true" android:state_window_focused="false"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_check_on_holo_light" />
- <item android:state_checked="false" android:state_window_focused="false"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_check_off_holo_light" />
-
- <item android:state_checked="true" android:state_pressed="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_check_on_pressed_holo_light" />
- <item android:state_checked="false" android:state_pressed="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_check_off_pressed_holo_light" />
-
- <item android:state_checked="true" android:state_focused="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_check_on_focused_holo_light" />
- <item android:state_checked="false" android:state_focused="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_check_off_focused_holo_light" />
-
- <item android:state_checked="false"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_check_off_holo_light" />
- <item android:state_checked="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_check_on_holo_light" />
-
-
- <!-- Disabled states -->
-
- <item android:state_checked="true" android:state_window_focused="false"
- android:drawable="@drawable/keychaintheme_btn_check_on_disabled_holo_light" />
- <item android:state_checked="false" android:state_window_focused="false"
- android:drawable="@drawable/keychaintheme_btn_check_off_disabled_holo_light" />
-
- <item android:state_checked="true" android:state_focused="true"
- android:drawable="@drawable/keychaintheme_btn_check_on_disabled_focused_holo_light" />
- <item android:state_checked="false" android:state_focused="true"
- android:drawable="@drawable/keychaintheme_btn_check_off_disabled_focused_holo_light" />
-
- <item android:state_checked="false" android:drawable="@drawable/keychaintheme_btn_check_off_disabled_holo_light" />
- <item android:state_checked="true" android:drawable="@drawable/keychaintheme_btn_check_on_disabled_holo_light" />
-
-</selector>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_btn_default_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_btn_default_holo_light.xml
deleted file mode 100644
index c9261f53b..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_btn_default_holo_light.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_default_normal_holo_light" />
- <item android:state_window_focused="false" android:state_enabled="false"
- android:drawable="@drawable/keychaintheme_btn_default_disabled_holo_light" />
- <item android:state_pressed="true"
- android:drawable="@drawable/keychaintheme_btn_default_pressed_holo_light" />
- <item android:state_focused="true" android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_default_focused_holo_light" />
- <item android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_default_normal_holo_light" />
- <item android:state_focused="true"
- android:drawable="@drawable/keychaintheme_btn_default_disabled_focused_holo_light" />
- <item
- android:drawable="@drawable/keychaintheme_btn_default_disabled_holo_light" />
-</selector>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_btn_radio_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_btn_radio_holo_light.xml
deleted file mode 100644
index eeba95d4f..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_btn_radio_holo_light.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:state_window_focused="false"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_radio_on_holo_light" />
- <item android:state_checked="false" android:state_window_focused="false"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_radio_off_holo_light" />
-
- <item android:state_checked="true" android:state_pressed="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_radio_on_pressed_holo_light" />
- <item android:state_checked="false" android:state_pressed="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_radio_off_pressed_holo_light" />
-
- <item android:state_checked="true" android:state_focused="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_radio_on_focused_holo_light" />
- <item android:state_checked="false" android:state_focused="true"
- android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_radio_off_focused_holo_light" />
-
- <item android:state_checked="false" android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_radio_off_holo_light" />
- <item android:state_checked="true" android:state_enabled="true"
- android:drawable="@drawable/keychaintheme_btn_radio_on_holo_light" />
-
- <!-- Disabled states -->
-
- <item android:state_checked="true" android:state_window_focused="false"
- android:drawable="@drawable/keychaintheme_btn_radio_on_disabled_holo_light" />
- <item android:state_checked="false" android:state_window_focused="false"
- android:drawable="@drawable/keychaintheme_btn_radio_off_disabled_holo_light" />
-
- <item android:state_checked="true" android:state_focused="true"
- android:drawable="@drawable/keychaintheme_btn_radio_on_disabled_focused_holo_light" />
- <item android:state_checked="false" android:state_focused="true"
- android:drawable="@drawable/keychaintheme_btn_radio_off_disabled_focused_holo_light" />
-
- <item android:state_checked="false" android:drawable="@drawable/keychaintheme_btn_radio_off_disabled_holo_light" />
- <item android:state_checked="true" android:drawable="@drawable/keychaintheme_btn_radio_on_disabled_holo_light" />
-
-</selector>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_edit_text_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_edit_text_holo_light.xml
deleted file mode 100644
index 7acab984d..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_edit_text_holo_light.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/keychaintheme_textfield_default_holo_light" />
- <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/keychaintheme_textfield_disabled_holo_light" />
- <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/keychaintheme_textfield_activated_holo_light" />
- <item android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/keychaintheme_textfield_focused_holo_light" />
- <item android:state_enabled="true" android:drawable="@drawable/keychaintheme_textfield_default_holo_light" />
- <item android:state_focused="true" android:drawable="@drawable/keychaintheme_textfield_disabled_focused_holo_light" />
- <item android:drawable="@drawable/keychaintheme_textfield_disabled_holo_light" />
-</selector> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_item_background_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_item_background_holo_light.xml
deleted file mode 100644
index b385d2f92..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_item_background_holo_light.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
- <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/keychaintheme_list_selector_disabled_holo_light" />
- <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/keychaintheme_list_selector_disabled_holo_light" />
- <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/keychaintheme_list_selector_background_transition_holo_light" />
- <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/keychaintheme_list_selector_background_transition_holo_light" />
- <item android:state_focused="true" android:drawable="@drawable/keychaintheme_list_focused_holo" />
- <item android:drawable="@android:color/transparent" />
-</selector>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_list_selector_background_transition_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_list_selector_background_transition_holo_light.xml
deleted file mode 100644
index 2a5561b22..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_list_selector_background_transition_holo_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<transition xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/keychaintheme_list_pressed_holo_light" />
- <item android:drawable="@drawable/keychaintheme_list_longpressed_holo" />
-</transition>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_list_selector_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_list_selector_holo_light.xml
deleted file mode 100644
index 17164fd1d..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_list_selector_holo_light.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_window_focused="false" android:drawable="@android:color/transparent" />
-
- <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
- <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/keychaintheme_list_selector_disabled_holo_light" />
- <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/keychaintheme_list_selector_disabled_holo_light" />
- <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/keychaintheme_list_selector_background_transition_holo_light" />
- <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/keychaintheme_list_selector_background_transition_holo_light" />
- <item android:state_focused="true" android:drawable="@drawable/keychaintheme_list_focused_holo" />
-
-</selector>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_progress_horizontal_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_progress_horizontal_holo_light.xml
deleted file mode 100644
index a99f756f6..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_progress_horizontal_holo_light.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:id="@android:id/background"
- android:drawable="@drawable/keychaintheme_progress_bg_holo_light" />
-
- <item android:id="@android:id/secondaryProgress">
- <scale android:scaleWidth="100%"
- android:drawable="@drawable/keychaintheme_progress_secondary_holo_light" />
- </item>
-
- <item android:id="@android:id/progress">
- <scale android:scaleWidth="100%"
- android:drawable="@drawable/keychaintheme_progress_primary_holo_light" />
- </item>
-
-</layer-list>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_progress_indeterminate_horizontal_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_progress_indeterminate_horizontal_holo_light.xml
deleted file mode 100644
index 79c050e47..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_progress_indeterminate_horizontal_holo_light.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<animation-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="false">
- <item android:drawable="@drawable/keychaintheme_progressbar_indeterminate_holo1" android:duration="50" />
- <item android:drawable="@drawable/keychaintheme_progressbar_indeterminate_holo2" android:duration="50" />
- <item android:drawable="@drawable/keychaintheme_progressbar_indeterminate_holo3" android:duration="50" />
- <item android:drawable="@drawable/keychaintheme_progressbar_indeterminate_holo4" android:duration="50" />
- <item android:drawable="@drawable/keychaintheme_progressbar_indeterminate_holo5" android:duration="50" />
- <item android:drawable="@drawable/keychaintheme_progressbar_indeterminate_holo6" android:duration="50" />
- <item android:drawable="@drawable/keychaintheme_progressbar_indeterminate_holo7" android:duration="50" />
- <item android:drawable="@drawable/keychaintheme_progressbar_indeterminate_holo8" android:duration="50" />
-</animation-list>
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_searchview_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_searchview_holo_light.xml
deleted file mode 100644
index e82b1c2f3..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_searchview_holo_light.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_focused="true"
- android:drawable="@drawable/keychaintheme_textfield_activated_holo_light" />
- <item android:drawable="@drawable/keychaintheme_textfield_default_holo_light" />
-</selector> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/drawable/keychaintheme_spinner_background_holo_light.xml b/OpenKeychain/src/main/res/drawable/keychaintheme_spinner_background_holo_light.xml
deleted file mode 100644
index 9fbb83f95..000000000
--- a/OpenKeychain/src/main/res/drawable/keychaintheme_spinner_background_holo_light.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false"
- android:drawable="@drawable/keychaintheme_spinner_disabled_holo_light" />
- <item android:state_pressed="true"
- android:drawable="@drawable/keychaintheme_spinner_pressed_holo_light" />
- <item android:state_pressed="false" android:state_focused="true"
- android:drawable="@drawable/keychaintheme_spinner_focused_holo_light" />
- <item android:drawable="@drawable/keychaintheme_spinner_default_holo_light" />
-</selector>
diff --git a/OpenKeychain/src/main/res/drawable/nfc.png b/OpenKeychain/src/main/res/drawable/nfc.png
new file mode 100644
index 000000000..f28b043bc
--- /dev/null
+++ b/OpenKeychain/src/main/res/drawable/nfc.png
Binary files differ
diff --git a/OpenKeychain/src/main/res/drawable/section_header.xml b/OpenKeychain/src/main/res/drawable/section_header.xml
index a4468484e..04d3d4957 100644
--- a/OpenKeychain/src/main/res/drawable/section_header.xml
+++ b/OpenKeychain/src/main/res/drawable/section_header.xml
@@ -6,6 +6,6 @@
android:height="2dp"
android:width="1000dp" />
- <solid android:color="@color/emphasis" />
+ <solid android:color="@color/header_text" />
</shape> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout-large/api_apps_list_activity.xml b/OpenKeychain/src/main/res/layout-large/api_apps_list_activity.xml
deleted file mode 100644
index af06614b9..000000000
--- a/OpenKeychain/src/main/res/layout-large/api_apps_list_activity.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
-
- <android.support.v4.widget.FixedDrawerLayout
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <include layout="@layout/drawer_list" />
-
- </android.support.v4.widget.FixedDrawerLayout>
-
- <include layout="@layout/api_apps_list_content" />
-
-</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout-large/decrypt_activity.xml b/OpenKeychain/src/main/res/layout-large/decrypt_activity.xml
deleted file mode 100644
index 06487a982..000000000
--- a/OpenKeychain/src/main/res/layout-large/decrypt_activity.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <android.support.v4.widget.FixedDrawerLayout
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <include layout="@layout/drawer_list" />
-
- </android.support.v4.widget.FixedDrawerLayout>
-
- <include layout="@layout/decrypt_content" />
-
-</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout-large/encrypt_files_activity.xml b/OpenKeychain/src/main/res/layout-large/encrypt_files_activity.xml
deleted file mode 100644
index 4b277c331..000000000
--- a/OpenKeychain/src/main/res/layout-large/encrypt_files_activity.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <android.support.v4.widget.FixedDrawerLayout
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <include layout="@layout/drawer_list" />
-
- </android.support.v4.widget.FixedDrawerLayout>
-
- <include layout="@layout/encrypt_files_content" />
-</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout-large/encrypt_text_activity.xml b/OpenKeychain/src/main/res/layout-large/encrypt_text_activity.xml
deleted file mode 100644
index 5cf838c46..000000000
--- a/OpenKeychain/src/main/res/layout-large/encrypt_text_activity.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <android.support.v4.widget.FixedDrawerLayout
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <include layout="@layout/drawer_list" />
-
- </android.support.v4.widget.FixedDrawerLayout>
-
- <include layout="@layout/encrypt_text_content" />
-</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout-large/key_list_activity.xml b/OpenKeychain/src/main/res/layout-large/key_list_activity.xml
deleted file mode 100644
index 039081cd7..000000000
--- a/OpenKeychain/src/main/res/layout-large/key_list_activity.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <android.support.v4.widget.FixedDrawerLayout
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <include layout="@layout/drawer_list" />
-
- </android.support.v4.widget.FixedDrawerLayout>
-
- <include layout="@layout/key_list_content" />
-
-</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout-v11/safe_slinger_activity.xml b/OpenKeychain/src/main/res/layout-v11/safe_slinger_activity.xml
deleted file mode 100644
index 7e4410f85..000000000
--- a/OpenKeychain/src/main/res/layout-v11/safe_slinger_activity.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <TextView
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/exchange_description"
- android:layout_weight="1"
- android:gravity="center_vertical"/>
-
- <NumberPicker
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/safe_slinger_picker"
- />
-
- </LinearLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- <LinearLayout
- android:id="@+id/safe_slinger_button"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- android:paddingRight="4dp"
- style="@style/SelectableItem"
- android:orientation="horizontal">
-
- <TextView
- android:paddingLeft="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:text="Start exchange"
- android:layout_weight="1"
- android:gravity="center_vertical" />
-
- <!-- separate ImageView required for recoloring -->
- <ImageView
- android:id="@+id/safe_slinger_button_image"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:padding="8dp"
- android:src="@drawable/ic_action_safeslinger"
- android:layout_gravity="center_vertical" />
-
- </LinearLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:layout_marginBottom="4dp"
- android:background="?android:attr/listDivider" />
-
- </LinearLayout>
-</ScrollView>
diff --git a/OpenKeychain/src/main/res/layout/actionbar_custom_view_done.xml b/OpenKeychain/src/main/res/layout/actionbar_custom_view_done.xml
deleted file mode 100644
index b219038b2..000000000
--- a/OpenKeychain/src/main/res/layout/actionbar_custom_view_done.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
- Copyright 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:dividerPadding="12dp"
- android:orientation="horizontal"
- android:showDividers="end" >
-
- <include layout="@layout/actionbar_include_done_button" />
-
-</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/actionbar_custom_view_done_cancel.xml b/OpenKeychain/src/main/res/layout/actionbar_custom_view_done_cancel.xml
deleted file mode 100644
index e9047e759..000000000
--- a/OpenKeychain/src/main/res/layout/actionbar_custom_view_done_cancel.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- Copyright 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:dividerPadding="12dp"
- android:orientation="horizontal"
- android:showDividers="middle">
-
- <include layout="@layout/actionbar_include_cancel_button" />
-
- <include layout="@layout/actionbar_include_done_button" />
-
-</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/actionbar_include_cancel_button.xml b/OpenKeychain/src/main/res/layout/actionbar_include_cancel_button.xml
deleted file mode 100644
index ec27e394a..000000000
--- a/OpenKeychain/src/main/res/layout/actionbar_include_cancel_button.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- Copyright 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/actionbar_cancel"
- style="@style/Widget.AppCompat.ActionButton"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1">
-
- <!--
- android:filterTouchesWhenObscured="true" to prevent Touch-Event Hijacking
- https://blog.lookout.com/blog/2010/12/09/android-touch-event-hijacking/
- -->
- <TextView
- android:id="@+id/actionbar_cancel_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:drawableLeft="@drawable/ic_action_cancel"
- android:drawablePadding="8dp"
- android:gravity="center_vertical"
- android:paddingRight="20dp"
- android:filterTouchesWhenObscured="true"
- style="@style/Widget.AppCompat.Light.ActionBar.TabText"
- android:text="Cancel (set in-code!)" />
-
-</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/actionbar_include_done_button.xml b/OpenKeychain/src/main/res/layout/actionbar_include_done_button.xml
deleted file mode 100644
index 2590f272c..000000000
--- a/OpenKeychain/src/main/res/layout/actionbar_include_done_button.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- Copyright 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/actionbar_done"
- style="@style/Widget.AppCompat.ActionButton"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1">
-
- <!--
- android:filterTouchesWhenObscured="true" to prevent Touch-Event Hijacking
- https://blog.lookout.com/blog/2010/12/09/android-touch-event-hijacking/
- -->
- <TextView
- android:id="@+id/actionbar_done_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:drawableLeft="@drawable/ic_action_done"
- android:drawablePadding="8dp"
- android:gravity="center_vertical"
- android:paddingRight="20dp"
- android:filterTouchesWhenObscured="true"
- style="@style/Widget.AppCompat.Light.ActionBar.TabText"
- android:text="Done (set in-code!)" />
-
-</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_account_settings_activity.xml b/OpenKeychain/src/main/res/layout/api_account_settings_activity.xml
index b2a9c11f5..d2fb291ea 100644
--- a/OpenKeychain/src/main/res/layout/api_account_settings_activity.xml
+++ b/OpenKeychain/src/main/res/layout/api_account_settings_activity.xml
@@ -1,28 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:orientation="vertical"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <ScrollView
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <LinearLayout
+ <ScrollView
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="16dp"
- android:orientation="vertical">
+ android:layout_height="match_parent">
- <fragment
- android:id="@+id/api_account_settings_fragment"
- android:name="org.sufficientlysecure.keychain.remote.ui.AccountSettingsFragment"
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ android:orientation="vertical">
- </LinearLayout>
- </ScrollView>
-</LinearLayout> \ No newline at end of file
+ <fragment
+ android:id="@+id/api_account_settings_fragment"
+ android:name="org.sufficientlysecure.keychain.remote.ui.AccountSettingsFragment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+ </ScrollView>
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_app_settings_activity.xml b/OpenKeychain/src/main/res/layout/api_app_settings_activity.xml
index dae9de1f2..6df5c84f5 100644
--- a/OpenKeychain/src/main/res/layout/api_app_settings_activity.xml
+++ b/OpenKeychain/src/main/res/layout/api_app_settings_activity.xml
@@ -1,41 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:custom="http://schemas.android.com/apk/res-auto"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
- android:orientation="vertical"
+ xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
-
- <ScrollView
+ <RelativeLayout
+ android:id="@+id/toolbar_big"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="@dimen/big_toolbar"
+ android:elevation="4dp"
+ android:background="?attr/colorPrimary"
+ android:orientation="horizontal">
- <LinearLayout
+ <ImageView
+ android:id="@+id/status_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/statusbar_height"
+ android:background="?attr/colorPrimary" />
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_below="@+id/status_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="16dp"
- android:orientation="vertical">
+ android:minHeight="?attr/actionBarSize"
+ android:background="?attr/colorPrimary"
+ android:overScrollMode="always"
+ app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
+ app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
+ tools:ignore="UnusedAttribute"
+ android:transitionGroup="false"
+ android:touchscreenBlocksFocus="false" />
- <fragment
- android:id="@+id/api_app_settings_fragment"
- android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsFragment"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- tools:layout="@layout/api_app_settings_fragment" />
+ <LinearLayout
+ android:layout_below="@+id/toolbar"
+ android:layout_marginLeft="48dp"
+ android:layout_marginRight="72dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:id="@+id/api_app_settings_app_icon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:src="@drawable/ic_launcher" />
<TextView
- style="@style/SectionHeader"
- android:layout_width="match_parent"
+ android:id="@+id/api_app_settings_app_name"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/api_settings_accounts" />
+ android:text="Name (set in-code)longlong"
+ android:textColor="@color/icons"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:paddingLeft="8dp"
+ android:layout_gravity="center_vertical" />
+ </LinearLayout>
+ </RelativeLayout>
- <FrameLayout
- android:id="@+id/api_accounts_list_fragment"
+ <LinearLayout
+ android:id="@+id/body"
+ android:layout_below="@id/toolbar_big"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" />
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ android:orientation="vertical">
- </LinearLayout>
- </ScrollView>
-</LinearLayout> \ No newline at end of file
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/api_settings_allowed_keys" />
+
+ <FrameLayout
+ android:id="@+id/api_allowed_keys_list_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" />
+
+ <TextView
+ android:id="@+id/api_accounts_label"
+ style="@style/SectionHeader"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:text="@string/api_settings_accounts" />
+
+ <FrameLayout
+ android:id="@+id/api_accounts_list_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" />
+
+ </LinearLayout>
+ </ScrollView>
+ </LinearLayout>
+
+ <com.getbase.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab"
+ android:layout_alignBottom="@id/toolbar_big"
+ android:layout_alignParentRight="true"
+ android:layout_marginRight="20dp"
+ android:layout_marginBottom="-40dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:elevation="4dp"
+ fab:fab_icon="@drawable/ic_play_arrow_white_24dp"
+ fab:fab_colorNormal="@color/fab"
+ fab:fab_colorPressed="@color/fab_pressed" />
+
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_app_settings_fragment.xml b/OpenKeychain/src/main/res/layout/api_app_settings_fragment.xml
index c5477adba..ed3e33aab 100644
--- a/OpenKeychain/src/main/res/layout/api_app_settings_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/api_app_settings_fragment.xml
@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
+ android:background="?attr/colorPrimaryDark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="4dp"
+ android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
@@ -17,7 +16,6 @@
android:id="@+id/api_app_settings_app_icon"
android:layout_width="48dp"
android:layout_height="48dp"
- android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginRight="6dp"
android:src="@drawable/ic_launcher" />
@@ -31,12 +29,14 @@
android:gravity="center_vertical"
android:orientation="vertical"
android:text="Name (set in-code)"
+ android:textColor="@color/icons"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:textColor="@color/icons"
custom:foldedLabel="@string/api_settings_show_info"
custom:unFoldedLabel="@string/api_settings_hide_info">
@@ -44,6 +44,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_settings_package_name"
+ android:textColor="@color/icons"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
@@ -51,12 +52,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="com.example"
+ android:textColor="@color/icons"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/api_settings_package_signature"
+ android:textColor="@color/icons"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
@@ -64,6 +67,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Base64 encoded hash of signature"
+ android:textColor="@color/icons"
android:textAppearance="?android:attr/textAppearanceSmall" />
</org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout>
diff --git a/OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml b/OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml
index b67da13a6..c4ea46d43 100644
--- a/OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml
+++ b/OpenKeychain/src/main/res/layout/api_apps_adapter_list_item.xml
@@ -13,16 +13,6 @@
android:layout_centerVertical="true"
android:src="@drawable/ic_launcher" />
- <TextView
- android:id="@+id/api_apps_adapter_item_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="8dp"
- android:text="Application Name"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@+id/api_apps_adapter_item_icon" />
-
<ImageView
android:id="@+id/api_apps_adapter_install_icon"
android:layout_width="wrap_content"
@@ -33,5 +23,15 @@
android:layout_alignParentEnd="true"
android:padding="8dp" />
+ <TextView
+ android:id="@+id/api_apps_adapter_item_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:text="Application Name"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_centerVertical="true"
+ android:layout_toLeftOf="@+id/api_apps_adapter_install_icon"
+ android:layout_toRightOf="@+id/api_apps_adapter_item_icon" />
</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_apps_list_activity.xml b/OpenKeychain/src/main/res/layout/api_apps_list_activity.xml
deleted file mode 100644
index df187e0a5..000000000
--- a/OpenKeychain/src/main/res/layout/api_apps_list_activity.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.FixedDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <include layout="@layout/api_apps_list_content"/>
-
- <include layout="@layout/drawer_list" />
-
-</android.support.v4.widget.FixedDrawerLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_apps_list_content.xml b/OpenKeychain/src/main/res/layout/api_apps_list_content.xml
deleted file mode 100644
index 9f9b99045..000000000
--- a/OpenKeychain/src/main/res/layout/api_apps_list_content.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/content_frame"
- android:layout_marginLeft="@dimen/drawer_content_padding"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <fragment
- android:id="@+id/crypto_consumers_list_fragment"
- android:name="org.sufficientlysecure.keychain.remote.ui.AppsListFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_remote_create_account.xml b/OpenKeychain/src/main/res/layout/api_remote_create_account.xml
index a6a39b1ad..7863f3c7f 100644
--- a/OpenKeychain/src/main/res/layout/api_remote_create_account.xml
+++ b/OpenKeychain/src/main/res/layout/api_remote_create_account.xml
@@ -1,37 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <ScrollView
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="16dp"
- android:orientation="vertical">
+ <include layout="@layout/notify_area" />
- <TextView
- android:id="@+id/api_remote_create_account_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingBottom="3dip"
- android:text="@string/api_create_account_text"
- android:textAppearance="?android:attr/textAppearanceMedium" />
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
- <fragment
- android:id="@+id/api_account_settings_fragment"
- android:name="org.sufficientlysecure.keychain.remote.ui.AccountSettingsFragment"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- tools:layout="@layout/api_app_settings_fragment" />
+ android:padding="16dp"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/api_remote_create_account_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingBottom="3dip"
+ android:text="@string/api_create_account_text"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <fragment
+ android:id="@+id/api_account_settings_fragment"
+ android:name="org.sufficientlysecure.keychain.remote.ui.AccountSettingsFragment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:layout="@layout/api_app_settings_fragment" />
- </LinearLayout>
- </ScrollView>
-</LinearLayout> \ No newline at end of file
+ </LinearLayout>
+ </ScrollView>
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_remote_error_message.xml b/OpenKeychain/src/main/res/layout/api_remote_error_message.xml
index 3d69a25b3..0bcf40407 100644
--- a/OpenKeychain/src/main/res/layout/api_remote_error_message.xml
+++ b/OpenKeychain/src/main/res/layout/api_remote_error_message.xml
@@ -1,16 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <TextView
- android:id="@+id/api_app_error_message_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="8dp"
- android:paddingBottom="0dip"
- android:text="Set in-code!"
- android:textAppearance="?android:attr/textAppearanceLarge" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
-</LinearLayout> \ No newline at end of file
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/api_app_error_message_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="8dp"
+ android:paddingBottom="0dip"
+ android:text="Set in-code!"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_remote_register_app.xml b/OpenKeychain/src/main/res/layout/api_remote_register_app.xml
index f85f3b8f7..7cb3666bf 100644
--- a/OpenKeychain/src/main/res/layout/api_remote_register_app.xml
+++ b/OpenKeychain/src/main/res/layout/api_remote_register_app.xml
@@ -1,29 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="match_parent">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="16dp"
- android:orientation="vertical">
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <TextView
- android:id="@+id/api_register_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingBottom="3dip"
- android:text="@string/api_register_text"
- android:textAppearance="?android:attr/textAppearanceLarge" />
+ <ScrollView
+ android:layout_below="@id/toolbar_include"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
- <fragment
- android:id="@+id/api_app_settings_fragment"
- android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsFragment"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- tools:layout="@layout/api_app_settings_fragment" />
+ android:padding="16dp"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/api_register_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingBottom="3dip"
+ android:text="@string/api_register_text"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <fragment
+ android:id="@+id/api_app_settings_fragment"
+ android:name="org.sufficientlysecure.keychain.remote.ui.AppSettingsHeaderFragment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:layout="@layout/api_app_settings_fragment" />
- </LinearLayout>
-</ScrollView>
+ </LinearLayout>
+ </ScrollView>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml b/OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml
index bf4d0a70d..3d3d55f3c 100644
--- a/OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml
+++ b/OpenKeychain/src/main/res/layout/api_remote_select_pub_keys.xml
@@ -1,21 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <TextView
- android:id="@+id/api_select_pub_keys_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="8dp"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <FrameLayout
- android:id="@+id/api_select_pub_keys_fragment_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical">
-</LinearLayout> \ No newline at end of file
+ <TextView
+ android:id="@+id/api_select_pub_keys_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <FrameLayout
+ android:id="@+id/api_select_pub_keys_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/certify_fingerprint_activity.xml b/OpenKeychain/src/main/res/layout/certify_fingerprint_activity.xml
new file mode 100644
index 000000000..ec91d1455
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/certify_fingerprint_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:id="@+id/content_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <FrameLayout
+ android:id="@+id/certify_fingerprint_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" />
+
+ </FrameLayout>
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/certify_fingerprint_fragment.xml b/OpenKeychain/src/main/res/layout/certify_fingerprint_fragment.xml
new file mode 100644
index 000000000..9b6b35012
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/certify_fingerprint_fragment.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_above="@+id/certify_fingerprint_buttons_divider">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="8dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/certify_fingerprint_text" />
+
+ <android.support.v7.widget.CardView
+ android:id="@+id/certify_fingerprint_card"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:cardBackgroundColor="@android:color/white"
+ app:cardUseCompatPadding="true"
+ app:cardCornerRadius="4dp"
+ android:layout_gravity="top">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ style="@style/CardViewHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/label_fingerprint" />
+
+ <TextView
+ android:id="@+id/certify_fingerprint_fingerprint"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:textSize="20sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:typeface="monospace"
+ android:gravity="center_vertical" />
+ </LinearLayout>
+
+ </android.support.v7.widget.CardView>
+
+ </LinearLayout>
+
+ </ScrollView>
+
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:id="@+id/certify_fingerprint_buttons">
+
+ <TextView
+ android:id="@+id/certify_fingerprint_button_no"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/btn_no"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:clickable="true"
+ style="?android:attr/borderlessButtonStyle"
+ android:layout_gravity="center_vertical" />
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/certify_fingerprint_button_yes"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/btn_match"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical"
+ android:clickable="true"
+ style="?android:attr/borderlessButtonStyle"
+ android:layout_gravity="center_vertical" />
+ </LinearLayout>
+
+ <View
+ android:id="@+id/certify_fingerprint_buttons_divider2"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider"
+ android:layout_alignBottom="@+id/certify_fingerprint_buttons_text"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true" />
+
+ <TextView
+ android:id="@+id/certify_fingerprint_buttons_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="24dp"
+ android:layout_marginRight="24dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/certify_fingerprint_text2"
+ android:layout_above="@+id/certify_fingerprint_buttons"
+ android:layout_centerHorizontal="true" />
+
+ <View
+ android:id="@+id/certify_fingerprint_buttons_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider"
+ android:layout_alignTop="@+id/certify_fingerprint_buttons_text"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true" />
+
+
+
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/certify_key_activity.xml b/OpenKeychain/src/main/res/layout/certify_key_activity.xml
index 2bf2c4197..fab8bc2d2 100644
--- a/OpenKeychain/src/main/res/layout/certify_key_activity.xml
+++ b/OpenKeychain/src/main/res/layout/certify_key_activity.xml
@@ -1,21 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <FrameLayout
- android:id="@+id/content_frame"
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <fragment
- android:id="@+id/multi_certify_key_fragment"
- android:name="org.sufficientlysecure.keychain.ui.CertifyKeyFragment"
+ <include layout="@layout/notify_area" />
+
+ <FrameLayout
+ android:id="@+id/content_frame"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </FrameLayout>
+ android:layout_height="match_parent">
+
+ <fragment
+ android:id="@+id/multi_certify_key_fragment"
+ android:name="org.sufficientlysecure.keychain.ui.CertifyKeyFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ </FrameLayout>
-</LinearLayout> \ No newline at end of file
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/certify_key_fragment.xml b/OpenKeychain/src/main/res/layout/certify_key_fragment.xml
index a55a8ea0c..2df3755a4 100644
--- a/OpenKeychain/src/main/res/layout/certify_key_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/certify_key_fragment.xml
@@ -95,7 +95,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
- android:src="@drawable/status_signature_verified_cutout"
+ android:src="@drawable/status_signature_verified_cutout_24px"
android:layout_gravity="center_vertical" />
</LinearLayout>
diff --git a/OpenKeychain/src/main/res/layout/create_key_activity.xml b/OpenKeychain/src/main/res/layout/create_key_activity.xml
index 0bd053c49..c42fd4d4b 100644
--- a/OpenKeychain/src/main/res/layout/create_key_activity.xml
+++ b/OpenKeychain/src/main/res/layout/create_key_activity.xml
@@ -1,15 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
<FrameLayout
- android:id="@+id/create_key_fragment_container"
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" />
+ android:layout_height="match_parent">
-</LinearLayout> \ No newline at end of file
+ <FrameLayout
+ android:id="@+id/create_key_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </FrameLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml
index 7f7b2cdce..97eba9cd1 100644
--- a/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml
@@ -86,7 +86,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/create_key_rsa"
- android:textColor="@color/android_green_dark"
+ android:textColor="@color/android_green_light"
android:textAppearance="?android:attr/textAppearanceMedium"
android:minHeight="?android:attr/listPreferredItemHeight"
android:clickable="true"
@@ -128,7 +128,7 @@
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:text="@string/create_key_final_robot_text"
- android:textColor="@color/android_green_dark"
+ android:textColor="@color/android_green_light"
android:textAppearance="?android:attr/textAppearanceMedium"
android:drawableLeft="@drawable/create_key_robot"
android:drawablePadding="8dp" />
@@ -159,7 +159,7 @@
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:clickable="true"
- style="@style/SelectableItem"
+ style="?android:attr/borderlessButtonStyle"
android:layout_gravity="center_vertical" />
<View
@@ -183,7 +183,7 @@
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:clickable="true"
- style="@style/SelectableItem"
+ style="?android:attr/borderlessButtonStyle"
android:layout_gravity="center_vertical" />
</LinearLayout>
diff --git a/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml
index d92988111..026d98004 100644
--- a/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
@@ -139,7 +139,7 @@
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:clickable="true"
- style="@style/SelectableItem"
+ style="?android:attr/borderlessButtonStyle"
android:layout_gravity="center_vertical" />
</LinearLayout>
</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/decrypt_activity.xml b/OpenKeychain/src/main/res/layout/decrypt_activity.xml
deleted file mode 100644
index bb0e463b3..000000000
--- a/OpenKeychain/src/main/res/layout/decrypt_activity.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.FixedDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <include layout="@layout/decrypt_content"/>
-
- <include layout="@layout/drawer_list" />
-
-</android.support.v4.widget.FixedDrawerLayout>
diff --git a/OpenKeychain/src/main/res/layout/decrypt_content.xml b/OpenKeychain/src/main/res/layout/decrypt_content.xml
deleted file mode 100644
index 5e7cda4f9..000000000
--- a/OpenKeychain/src/main/res/layout/decrypt_content.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/content_frame"
- android:layout_marginLeft="@dimen/drawer_content_padding"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <include layout="@layout/notify_area" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="4dp"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:orientation="vertical">
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:text="@string/section_decrypt_files" />
-
-
- <TextView
- android:id="@+id/decrypt_files"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:text="@string/btn_decrypt_files"
- android:drawableRight="@drawable/ic_action_collection"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider"
- android:layout_marginBottom="8dp" />
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="32dp"
- android:text="@string/section_decrypt_text" />
-
- <LinearLayout
- android:id="@+id/decrypt_from_clipboard"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- android:paddingRight="4dp"
- style="@style/SelectableItem"
- android:orientation="horizontal">
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingRight="4dp"
- android:gravity="center_vertical"
- android:orientation="vertical">
-
- <TextView
- android:paddingLeft="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/btn_decrypt_clipboard" />
-
- <TextView
- android:paddingLeft="8dp"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textColor="@color/tertiary_text_light"
- android:text="@string/btn_decrypt_and_verify"
- android:gravity="center_vertical" />
-
- </LinearLayout>
-
- <ImageView
- android:id="@+id/clipboard_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:padding="8dp"
- android:src="@drawable/ic_action_paste"
- android:layout_gravity="center_vertical" />
-
- </LinearLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider"
- android:layout_marginBottom="8dp" />
-
- </LinearLayout>
-
-
-</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/decrypt_files_activity.xml b/OpenKeychain/src/main/res/layout/decrypt_files_activity.xml
index 0380787db..608fce111 100644
--- a/OpenKeychain/src/main/res/layout/decrypt_files_activity.xml
+++ b/OpenKeychain/src/main/res/layout/decrypt_files_activity.xml
@@ -1,14 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <FrameLayout
- android:id="@+id/decrypt_files_fragment_container"
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:orientation="vertical">
-</LinearLayout> \ No newline at end of file
+ <include layout="@layout/notify_area" />
+
+ <FrameLayout
+ android:id="@+id/decrypt_files_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/decrypt_result_include.xml b/OpenKeychain/src/main/res/layout/decrypt_result_include.xml
index 9140ad07b..659d1c207 100644
--- a/OpenKeychain/src/main/res/layout/decrypt_result_include.xml
+++ b/OpenKeychain/src/main/res/layout/decrypt_result_include.xml
@@ -24,7 +24,7 @@
android:id="@+id/result_encryption_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/status_lock_open"
+ android:src="@drawable/status_lock_open_24px"
android:layout_gravity="center_vertical" />
<TextView
@@ -47,7 +47,7 @@
android:id="@+id/result_signature_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:src="@drawable/status_signature_unverified_cutout"
+ android:src="@drawable/status_signature_unverified_cutout_24px"
android:layout_gravity="center_vertical" />
<TextView
diff --git a/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml b/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
index e08ecb39e..b97fc9c8e 100644
--- a/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
+++ b/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml
@@ -1,14 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <FrameLayout
- android:id="@+id/decrypt_text_fragment_container"
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:orientation="vertical">
-</LinearLayout> \ No newline at end of file
+ <include layout="@layout/notify_area" />
+
+ <FrameLayout
+ android:id="@+id/decrypt_text_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/drawer_custom_header.xml b/OpenKeychain/src/main/res/layout/drawer_custom_header.xml
new file mode 100644
index 000000000..86465db98
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/drawer_custom_header.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:background="@color/primary">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/app_name"
+ android:textColor="@color/white"
+ android:layout_gravity="center_horizontal" />
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/drawer_list.xml b/OpenKeychain/src/main/res/layout/drawer_list.xml
deleted file mode 100644
index ab00c0073..000000000
--- a/OpenKeychain/src/main/res/layout/drawer_list.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- android:layout_gravity="start" tells DrawerLayout to treat
- this as a sliding drawer on the left side for left-to-right
- languages and on the right side for right-to-left languages.
- The drawer is given a fixed width in dp and extends the full height of
- the container. A solid background is used for contrast
- with the content view.
--->
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/left_drawer"
- android:layout_width="@dimen/drawer_size"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:background="@color/white"
- android:choiceMode="singleChoice"
- android:divider="@color/bg_gray"
- android:dividerHeight="1dp" />
diff --git a/OpenKeychain/src/main/res/layout/drawer_list_item.xml b/OpenKeychain/src/main/res/layout/drawer_list_item.xml
deleted file mode 100644
index 4719483da..000000000
--- a/OpenKeychain/src/main/res/layout/drawer_list_item.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:fontawesometext="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <ImageView
- android:id="@+id/drawer_item_icon"
- android:gravity="center_vertical"
- android:layout_width="30dp"
- android:layout_height="wrap_content"
- android:layout_marginLeft="8dp"
- android:layout_alignParentStart="true"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true" />
-
- <TextView
- android:id="@+id/drawer_item_text"
- android:text="Test"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:layout_marginLeft="8dp"
- android:paddingBottom="16dp"
- android:paddingRight="16dp"
- android:paddingTop="16dp"
- android:textAppearance="@android:style/TextAppearance.Medium"
- android:textColor="#111"
- android:layout_alignParentTop="true"
- android:layout_toRightOf="@id/drawer_item_icon"/>
-
-</RelativeLayout>
diff --git a/OpenKeychain/src/main/res/layout/edit_key_activity.xml b/OpenKeychain/src/main/res/layout/edit_key_activity.xml
index 7e71ccf53..c8b0e3afc 100644
--- a/OpenKeychain/src/main/res/layout/edit_key_activity.xml
+++ b/OpenKeychain/src/main/res/layout/edit_key_activity.xml
@@ -1,15 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/notify_area"/>
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <FrameLayout
- android:id="@+id/edit_key_fragment_container"
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" />
+ android:layout_height="match_parent">
-</LinearLayout> \ No newline at end of file
+ <include layout="@layout/notify_area" />
+
+ <FrameLayout
+ android:id="@+id/edit_key_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" />
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/encrypt_content_adv_settings.xml b/OpenKeychain/src/main/res/layout/encrypt_content_adv_settings.xml
index 67f7032c1..d14828ef7 100644
--- a/OpenKeychain/src/main/res/layout/encrypt_content_adv_settings.xml
+++ b/OpenKeychain/src/main/res/layout/encrypt_content_adv_settings.xml
@@ -1,24 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
<LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
<TextView
- android:id="@+id/label_fileCompression"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_weight="1"
- android:paddingRight="10dip"
- android:text="@string/label_file_compression"
- android:textAppearance="?android:attr/textAppearanceSmall"/>
+ android:id="@+id/label_fileCompression"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_weight="1"
+ android:paddingRight="10dip"
+ android:text="@string/label_file_compression"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
<Spinner
- android:id="@+id/fileCompression"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"/>
+ android:id="@+id/fileCompression"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical" />
</LinearLayout>
</merge>
diff --git a/OpenKeychain/src/main/res/layout/encrypt_decrypt_overview_fragment.xml b/OpenKeychain/src/main/res/layout/encrypt_decrypt_overview_fragment.xml
new file mode 100644
index 000000000..d62c9f32b
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/encrypt_decrypt_overview_fragment.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingTop="4dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/section_encrypt" />
+
+ <TextView
+ android:id="@+id/encrypt_files"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="@string/btn_encrypt_files"
+ android:drawableRight="@drawable/ic_action_collection"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/encrypt_text"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="@string/btn_encrypt_text"
+ android:drawableRight="@drawable/ic_action_copy"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:text="@string/section_decrypt" />
+
+ <TextView
+ android:id="@+id/decrypt_files"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="@string/btn_decrypt_files"
+ android:drawableRight="@drawable/ic_action_collection"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <LinearLayout
+ android:id="@+id/decrypt_from_clipboard"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ android:paddingRight="4dp"
+ style="@style/SelectableItem"
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingRight="4dp"
+ android:gravity="center_vertical"
+ android:orientation="vertical">
+
+ <TextView
+ android:paddingLeft="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/btn_decrypt_clipboard" />
+
+ <TextView
+ android:paddingLeft="8dp"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textColor="@color/tertiary_text_light"
+ android:text="@string/btn_decrypt_and_verify"
+ android:gravity="center_vertical" />
+
+ </LinearLayout>
+
+ <ImageView
+ android:id="@+id/clipboard_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:src="@drawable/ic_action_paste"
+ android:layout_gravity="center_vertical" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider"
+ android:layout_marginBottom="8dp" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/encrypt_files_activity.xml b/OpenKeychain/src/main/res/layout/encrypt_files_activity.xml
index cdcf4fa43..d292b1a5b 100644
--- a/OpenKeychain/src/main/res/layout/encrypt_files_activity.xml
+++ b/OpenKeychain/src/main/res/layout/encrypt_files_activity.xml
@@ -1,14 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.FixedDrawerLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/drawer_layout"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".ui.EncryptFileActivity">
+ android:orientation="vertical">
+
+ <include layout="@layout/notify_area" />
- <include layout="@layout/encrypt_files_content"/>
+ <FrameLayout
+ android:id="@+id/encrypt_pager_mode"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
- <include layout="@layout/drawer_list" />
+ <fragment
+ android:id="@+id/encrypt_file_fragment"
+ android:name="org.sufficientlysecure.keychain.ui.EncryptFilesFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
-</android.support.v4.widget.FixedDrawerLayout> \ No newline at end of file
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/encrypt_files_content.xml b/OpenKeychain/src/main/res/layout/encrypt_files_content.xml
deleted file mode 100644
index b44a2bc4d..000000000
--- a/OpenKeychain/src/main/res/layout/encrypt_files_content.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/content_frame"
- android:layout_marginLeft="@dimen/drawer_content_padding"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <include layout="@layout/notify_area" />
-
- <FrameLayout
- android:id="@+id/encrypt_pager_mode"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" />
-
- <fragment
- android:id="@+id/encrypt_file_fragment"
- android:name="org.sufficientlysecure.keychain.ui.EncryptFilesFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
-</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/encrypt_text_activity.xml b/OpenKeychain/src/main/res/layout/encrypt_text_activity.xml
index 5d5e16131..66abd03b1 100644
--- a/OpenKeychain/src/main/res/layout/encrypt_text_activity.xml
+++ b/OpenKeychain/src/main/res/layout/encrypt_text_activity.xml
@@ -1,14 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.FixedDrawerLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/drawer_layout"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".ui.EncryptTextActivity">
+ android:orientation="vertical">
+
+ <include layout="@layout/notify_area" />
- <include layout="@layout/encrypt_text_content"/>
+ <FrameLayout
+ android:id="@+id/encrypt_pager_mode"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
- <include layout="@layout/drawer_list" />
+ <fragment
+ android:id="@+id/encrypt_text_fragment"
+ android:name="org.sufficientlysecure.keychain.ui.EncryptTextFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
-</android.support.v4.widget.FixedDrawerLayout> \ No newline at end of file
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/encrypt_text_content.xml b/OpenKeychain/src/main/res/layout/encrypt_text_content.xml
deleted file mode 100644
index 809f00204..000000000
--- a/OpenKeychain/src/main/res/layout/encrypt_text_content.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/content_frame"
- android:layout_marginLeft="@dimen/drawer_content_padding"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <include layout="@layout/notify_area"/>
-
- <FrameLayout
- android:id="@+id/encrypt_pager_mode"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" />
-
- <fragment
- android:id="@+id/encrypt_text_fragment"
- android:name="org.sufficientlysecure.keychain.ui.EncryptTextFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
-</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/first_time_activity.xml b/OpenKeychain/src/main/res/layout/first_time_activity.xml
index 2d750c1a7..ba80214a6 100644
--- a/OpenKeychain/src/main/res/layout/first_time_activity.xml
+++ b/OpenKeychain/src/main/res/layout/first_time_activity.xml
@@ -4,6 +4,11 @@
android:layout_height="wrap_content"
android:paddingTop="16dp">
+ <ImageView
+ android:id="@+id/status_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/statusbar_height" />
+
<LinearLayout
android:id="@+id/first_time_buttons"
android:layout_width="match_parent"
@@ -91,6 +96,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
+ android:layout_below="@+id/status_bar"
android:layout_above="@+id/first_time_buttons">
<TextView
@@ -99,7 +105,7 @@
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/app_name"
android:drawableLeft="@drawable/ic_launcher"
- android:drawablePadding="16dp"
+ android:drawablePadding="8dp"
android:gravity="center"
android:layout_gravity="center_horizontal" />
@@ -128,5 +134,4 @@
</LinearLayout>
-
</RelativeLayout>
diff --git a/OpenKeychain/src/main/res/layout/foldable_linearlayout.xml b/OpenKeychain/src/main/res/layout/foldable_linearlayout.xml
index 13cf7c225..773a9d416 100644
--- a/OpenKeychain/src/main/res/layout/foldable_linearlayout.xml
+++ b/OpenKeychain/src/main/res/layout/foldable_linearlayout.xml
@@ -1,37 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
<LinearLayout
- android:id="@+id/foldableControl"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:clickable="true">
+ android:id="@+id/foldableControl"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:clickable="true">
<ImageView
- android:id="@+id/foldableIcon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginRight="10dp"
- android:src="@drawable/ic_action_expand"/>
+ android:id="@+id/foldableIcon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginRight="10dp"
+ android:src="@drawable/ic_expand_more_black_24dp" />
<TextView
- android:id="@+id/foldableText"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/none"
- android:layout_gravity="center_vertical"
- android:textColor="@color/emphasis"/>
+ android:id="@+id/foldableText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/none"
+ android:layout_gravity="center_vertical"
+ android:textColor="@color/header_text" />
</LinearLayout>
<LinearLayout
- android:id="@+id/foldableContainer"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:visibility="gone"/>
+ android:id="@+id/foldableContainer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone" />
</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/full_screen_dialog.xml b/OpenKeychain/src/main/res/layout/full_screen_dialog.xml
new file mode 100644
index 000000000..5eb50da07
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/full_screen_dialog.xml
@@ -0,0 +1,10 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:dividerPadding="12dp"
+ android:orientation="horizontal"
+ android:showDividers="middle">
+
+ <include layout="@layout/full_screen_dialog_done_button" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/full_screen_dialog_2.xml b/OpenKeychain/src/main/res/layout/full_screen_dialog_2.xml
new file mode 100644
index 000000000..b1d5efe76
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/full_screen_dialog_2.xml
@@ -0,0 +1,12 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:dividerPadding="12dp"
+ android:orientation="horizontal"
+ android:showDividers="middle">
+
+ <include layout="@layout/full_screen_dialog_2_cancel_button" />
+
+ <include layout="@layout/full_screen_dialog_2_done_button" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/full_screen_dialog_2_cancel_button.xml b/OpenKeychain/src/main/res/layout/full_screen_dialog_2_cancel_button.xml
new file mode 100644
index 000000000..7c2c2a62d
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/full_screen_dialog_2_cancel_button.xml
@@ -0,0 +1,27 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/actionbar_cancel"
+ style="@style/Widget.AppCompat.ActionButton"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1">
+
+ <!--
+ android:filterTouchesWhenObscured="true" to prevent Touch-Event Hijacking
+ https://blog.lookout.com/blog/2010/12/09/android-touch-event-hijacking/
+ -->
+ <TextView
+ android:id="@+id/actionbar_cancel_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:drawableLeft="@drawable/ic_close_white_24dp"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical"
+ android:paddingRight="20dp"
+ android:filterTouchesWhenObscured="true"
+ style="@style/Widget.AppCompat.Light.ActionBar.TabText"
+ android:textAllCaps="true"
+ android:textSize="14sp"
+ android:text="Cancel (set in-code!)" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/full_screen_dialog_2_done_button.xml b/OpenKeychain/src/main/res/layout/full_screen_dialog_2_done_button.xml
new file mode 100644
index 000000000..cd24a1e6d
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/full_screen_dialog_2_done_button.xml
@@ -0,0 +1,27 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/actionbar_done"
+ style="@style/Widget.AppCompat.ActionButton"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1">
+
+ <!--
+ android:filterTouchesWhenObscured="true" to prevent Touch-Event Hijacking
+ https://blog.lookout.com/blog/2010/12/09/android-touch-event-hijacking/
+ -->
+ <TextView
+ android:id="@+id/actionbar_done_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:drawableLeft="@drawable/ic_check_white_24dp"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical"
+ android:paddingRight="20dp"
+ android:filterTouchesWhenObscured="true"
+ style="@style/Widget.AppCompat.Light.ActionBar.TabText"
+ android:textAllCaps="true"
+ android:textSize="14sp"
+ android:text="Done (set in-code!)" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/full_screen_dialog_done_button.xml b/OpenKeychain/src/main/res/layout/full_screen_dialog_done_button.xml
new file mode 100644
index 000000000..49018fee1
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/full_screen_dialog_done_button.xml
@@ -0,0 +1,25 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/full_screen_dialog_done"
+ style="@style/Widget.AppCompat.ActionButton"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent">
+
+ <!--
+ android:filterTouchesWhenObscured="true" to prevent Touch-Event Hijacking
+ https://blog.lookout.com/blog/2010/12/09/android-touch-event-hijacking/
+ -->
+ <TextView
+ android:id="@+id/full_screen_dialog_done_text"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:gravity="center_vertical"
+ android:paddingRight="16dp"
+ android:paddingEnd="16dp"
+ style="@style/Widget.AppCompat.Light.ActionBar.TabText"
+ android:textAllCaps="true"
+ android:textSize="14sp"
+ android:filterTouchesWhenObscured="true"
+ android:text="Done (set in-code!)" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/full_screen_dialog_old.xml b/OpenKeychain/src/main/res/layout/full_screen_dialog_old.xml
new file mode 100644
index 000000000..ed375094f
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/full_screen_dialog_old.xml
@@ -0,0 +1,10 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:dividerPadding="12dp"
+ android:orientation="horizontal"
+ android:showDividers="end" >
+
+ <include layout="@layout/full_screen_dialog_2_done_button" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/help_activity.xml b/OpenKeychain/src/main/res/layout/help_activity.xml
index 3ad087da3..1722f03ea 100644
--- a/OpenKeychain/src/main/res/layout/help_activity.xml
+++ b/OpenKeychain/src/main/res/layout/help_activity.xml
@@ -1,17 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
+ android:layout_height="match_parent">
- <org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout
- android:id="@+id/sliding_tab_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <android.support.v4.view.ViewPager
- android:id="@+id/pager"
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:elevation="4dp">
+
+ <com.astuetz.PagerSlidingTabStrip
+ android:id="@+id/sliding_tab_layout"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="?attr/colorPrimary"
+ android:textColor="@color/tab_text"
+ app:pstsTextColorSelected="@color/tab_text_selected"
+ app:pstsIndicatorColor="@color/tab_indicator" />
+
+ <android.support.v4.view.ViewPager
+ android:id="@+id/pager"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
-</LinearLayout> \ No newline at end of file
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/import_keys_activity.xml b/OpenKeychain/src/main/res/layout/import_keys_activity.xml
index 35818e4ea..93d630437 100644
--- a/OpenKeychain/src/main/res/layout/import_keys_activity.xml
+++ b/OpenKeychain/src/main/res/layout/import_keys_activity.xml
@@ -1,68 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <FrameLayout
- android:id="@+id/import_keys_top_container"
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="64dp"
- android:orientation="vertical"
- android:background="@android:color/white" />
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <View
- android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="?android:attr/listDivider" />
+ <include layout="@layout/notify_area" />
- <View
- android:layout_width="match_parent"
- android:layout_height="16dp" />
-
- <View
- android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="?android:attr/listDivider" />
+ <FrameLayout
+ android:id="@+id/import_keys_top_container"
+ android:layout_width="match_parent"
+ android:layout_height="64dp"
+ android:orientation="vertical"
+ android:background="@android:color/white" />
- <FrameLayout
- android:id="@+id/import_keys_list_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:orientation="vertical"
- android:layout_weight="1"
- android:background="@android:color/white" />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="2dip"
+ android:background="?android:attr/listDivider" />
- <LinearLayout
- android:id="@+id/import_footer"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:background="@android:color/white">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="16dp" />
<View
android:layout_width="match_parent"
- android:layout_height="1dip"
+ android:layout_height="2dip"
android:background="?android:attr/listDivider" />
- <TextView
- android:id="@+id/import_import"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ <FrameLayout
+ android:id="@+id/import_keys_list_container"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="@string/import_import"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:drawableRight="@drawable/ic_action_download"
- android:drawablePadding="8dp"
- android:gravity="center_vertical"
- android:clickable="true"
- style="@style/SelectableItem" />
+ android:layout_height="0dp"
+ android:orientation="vertical"
+ android:layout_weight="1"
+ android:background="@android:color/white" />
+
+ <LinearLayout
+ android:id="@+id/import_footer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:background="@android:color/white">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/import_import"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/import_import"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:drawableRight="@drawable/ic_action_download"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical"
+ android:clickable="true"
+ style="@style/SelectableItem" />
+ </LinearLayout>
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_item.xml b/OpenKeychain/src/main/res/layout/import_keys_list_item.xml
index a97e81abe..bf9d33852 100644
--- a/OpenKeychain/src/main/res/layout/import_keys_list_item.xml
+++ b/OpenKeychain/src/main/res/layout/import_keys_list_item.xml
@@ -73,7 +73,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:src="@drawable/status_signature_revoked_cutout"
+ android:src="@drawable/status_signature_revoked_cutout_24px"
android:padding="16dp" />
<TextView
diff --git a/OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml
index 1cc414dab..9007d2149 100644
--- a/OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml
@@ -21,7 +21,7 @@
android:layout_height="match_parent"
android:text="@string/import_qr_code_button"
android:layout_weight="1"
- android:drawableRight="@drawable/ic_action_qr_code"
+ android:drawableRight="@drawable/ic_qrcode_white_24dp"
android:drawablePadding="8dp"
android:gravity="center_vertical" />
@@ -38,7 +38,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
- android:src="@drawable/ic_action_nfc"
+ android:src="@drawable/ic_nfc_white_24dp"
android:layout_gravity="center_vertical"
style="@style/SelectableItem" />
diff --git a/OpenKeychain/src/main/res/layout/key_list_activity.xml b/OpenKeychain/src/main/res/layout/key_list_activity.xml
deleted file mode 100644
index 03ef85381..000000000
--- a/OpenKeychain/src/main/res/layout/key_list_activity.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.FixedDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <include layout="@layout/key_list_content" />
-
- <include layout="@layout/drawer_list" />
-
-</android.support.v4.widget.FixedDrawerLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/key_list_content.xml b/OpenKeychain/src/main/res/layout/key_list_content.xml
index dd230806f..bd0239da7 100644
--- a/OpenKeychain/src/main/res/layout/key_list_content.xml
+++ b/OpenKeychain/src/main/res/layout/key_list_content.xml
@@ -1,47 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
<LinearLayout
- android:id="@+id/content_frame"
- android:layout_marginLeft="@dimen/drawer_content_padding"
android:orientation="vertical"
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <!--<LinearLayout
+ <include layout="@layout/notify_area" />
+
+ <LinearLayout
+ android:id="@+id/content_frame"
android:orientation="vertical"
- android:background="@color/holo_gray_bright"
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="match_parent">
- <Spinner
- android:id="@+id/key_list_filter_spinner"
+ <!--<LinearLayout
+ android:orientation="vertical"
+ android:background="@color/holo_gray_bright"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="12dp"
- android:layout_marginRight="12dp"
- android:layout_marginTop="4dp"
- android:layout_marginBottom="4dp" />
-
- <View
+ android:layout_height="wrap_content">
+
+ <Spinner
+ android:id="@+id/key_list_filter_spinner"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="12dp"
+ android:layout_marginRight="12dp"
+ android:layout_marginTop="4dp"
+ android:layout_marginBottom="4dp" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ </LinearLayout>-->
+
+ <fragment
+ android:id="@+id/key_list_fragment"
+ android:name="org.sufficientlysecure.keychain.ui.KeyListFragment"
android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- </LinearLayout>-->
-
- <fragment
- android:id="@+id/key_list_fragment"
- android:name="org.sufficientlysecure.keychain.ui.KeyListFragment"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+ </LinearLayout>
</LinearLayout>
-
-</LinearLayout> \ No newline at end of file
+</RelativeLayout>
diff --git a/OpenKeychain/src/main/res/layout/key_list_fragment.xml b/OpenKeychain/src/main/res/layout/key_list_fragment.xml
index 6529a88e0..3c46b4f9c 100644
--- a/OpenKeychain/src/main/res/layout/key_list_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/key_list_fragment.xml
@@ -1,41 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
-<org.sufficientlysecure.keychain.ui.widget.ListAwareSwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/key_list_swipe_container"
- android:layout_width="match_parent"
+<RelativeLayout xmlns:fab="http://schemas.android.com/apk/res-auto"
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
- android:orientation="vertical">
- <!--rebuild functionality of ListFragment -->
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_width="match_parent">
- <se.emilsjolander.stickylistheaders.StickyListHeadersListView
- android:id="@+id/key_list_list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipToPadding="false"
- android:drawSelectorOnTop="true"
- android:fastScrollEnabled="true"
- android:paddingBottom="16dp"
- android:paddingLeft="16dp"
- android:paddingRight="32dp"
- android:scrollbarStyle="outsideOverlay" />
-
- <LinearLayout
- android:id="@+id/key_list_empty"
+ <org.sufficientlysecure.keychain.ui.widget.ListAwareSwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/key_list_swipe_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <!--rebuild functionality of ListFragment -->
+ <FrameLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:orientation="vertical"
- android:visibility="visible">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent">
+
+ <se.emilsjolander.stickylistheaders.StickyListHeadersListView
+ android:id="@+id/key_list_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ android:drawSelectorOnTop="true"
+ android:fastScrollEnabled="true"
+ android:paddingBottom="16dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="32dp"
+ android:scrollbarStyle="outsideOverlay" />
+
+ <LinearLayout
+ android:id="@+id/key_list_empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:gravity="center"
- android:text="@string/key_list_empty_text1"
- android:textAppearance="?android:attr/textAppearanceLarge" />
+ android:orientation="vertical"
+ android:visibility="visible">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text="@string/key_list_empty_text1"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ </LinearLayout>
+ </FrameLayout>
+ </org.sufficientlysecure.keychain.ui.widget.ListAwareSwipeRefreshLayout>
+
+ <com.getbase.floatingactionbutton.FloatingActionsMenu
+ android:id="@+id/fab_main"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentBottom="true"
+ fab:fab_addButtonColorNormal="@color/primary"
+ fab:fab_addButtonColorPressed="@color/primary_dark"
+ fab:fab_addButtonSize="normal"
+ fab:fab_addButtonPlusIconColor="@color/icons"
+ fab:fab_expandDirection="up"
+ fab:fab_labelStyle="@style/FabMenuStyle"
+ android:layout_marginBottom="16dp"
+ android:layout_marginRight="16dp"
+ android:layout_marginEnd="16dp">
+
+ <com.getbase.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab_add_qr_code"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ fab:fab_icon="@drawable/ic_qrcode_white_24dp"
+ fab:fab_colorNormal="@color/primary"
+ fab:fab_colorPressed="@color/primary_dark"
+ fab:fab_title="Scan QR Code"
+ fab:fab_size="mini" />
+
+ <com.getbase.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab_add_cloud"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ fab:fab_icon="@drawable/ic_cloud_search_24px"
+ fab:fab_colorNormal="@color/primary"
+ fab:fab_colorPressed="@color/primary_dark"
+ fab:fab_title="Search Cloud"
+ fab:fab_size="mini" />
+
+ <com.getbase.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab_add_file"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ fab:fab_icon="@drawable/ic_folder_white_24dp"
+ fab:fab_colorNormal="@color/primary"
+ fab:fab_colorPressed="@color/primary_dark"
+ fab:fab_title="Import from File"
+ fab:fab_size="mini" />
- </LinearLayout>
- </FrameLayout>
-</org.sufficientlysecure.keychain.ui.widget.ListAwareSwipeRefreshLayout> \ No newline at end of file
+ </com.getbase.floatingactionbutton.FloatingActionsMenu>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/key_list_item.xml b/OpenKeychain/src/main/res/layout/key_list_item.xml
index df69e4237..27444a260 100644
--- a/OpenKeychain/src/main/res/layout/key_list_item.xml
+++ b/OpenKeychain/src/main/res/layout/key_list_item.xml
@@ -58,7 +58,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
- android:src="@drawable/ic_action_safeslinger"
+ android:src="@drawable/ic_repeat_grey_24dp"
android:padding="12dp"
style="@style/SelectableItem" />
@@ -69,7 +69,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:src="@drawable/status_signature_revoked_cutout"
+ android:src="@drawable/status_signature_revoked_cutout_24px"
android:padding="16dp" />
</LinearLayout>
diff --git a/OpenKeychain/src/main/res/layout/key_server_preference.xml b/OpenKeychain/src/main/res/layout/key_server_preference.xml
index 33866f746..5319a3ec0 100644
--- a/OpenKeychain/src/main/res/layout/key_server_preference.xml
+++ b/OpenKeychain/src/main/res/layout/key_server_preference.xml
@@ -1,82 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
<LinearLayout
- android:id="@+id/text_layout"
+ android:layout_below="@id/toolbar_include"
android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:orientation="horizontal" >
+ android:layout_height="fill_parent"
+ android:orientation="vertical">
<LinearLayout
- android:layout_width="0dip"
+ android:id="@+id/text_layout"
+ android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="6sp"
- android:layout_marginLeft="16sp"
- android:layout_marginRight="6sp"
- android:layout_marginTop="6sp"
- android:layout_weight="1"
- android:background="@android:drawable/menuitem_background"
- android:orientation="vertical"
- android:focusable="true" >
+ android:gravity="center_vertical"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:orientation="horizontal">
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
+ <LinearLayout
+ android:layout_width="0dip"
android:layout_height="wrap_content"
- android:focusable="true"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceLarge" />
+ android:layout_marginBottom="6sp"
+ android:layout_marginLeft="16sp"
+ android:layout_marginRight="6sp"
+ android:layout_marginTop="6sp"
+ android:layout_weight="1"
+ android:background="@android:drawable/menuitem_background"
+ android:orientation="vertical"
+ android:focusable="true">
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="true"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView
+ android:id="@+id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </LinearLayout>
- <TextView
- android:id="@+id/summary"
+ <Button
+ android:id="@+id/rotate"
+ android:layout_width="wrap_content"
+ android:layout_height="31dp"
+ android:layout_gravity="center_vertical"
+ android:layout_marginLeft="4dip"
+ android:layout_marginRight="6dip"
+ android:text="rotate"
+ android:textColor="#ffffffff"
+ android:textStyle="bold"
+ android:background="@drawable/button_rounded_blue" />
+
+ <ImageButton
+ android:id="@+id/add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ android:layout_gravity="center_vertical"
+ android:layout_margin="10dp"
+ android:src="@drawable/plus"
+ android:background="@drawable/button_rounded_green" />
</LinearLayout>
- <Button
- android:id="@+id/rotate"
- android:layout_width="wrap_content"
- android:layout_height="31dp"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="4dip"
- android:layout_marginRight="6dip"
- android:text="rotate"
- android:textColor="#ffffffff"
- android:textStyle="bold"
- android:background="@drawable/button_rounded_blue"
- />
- <ImageButton
- android:id="@+id/add"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_margin="10dp"
- android:src="@drawable/plus"
- android:background="@drawable/button_rounded_green"/>
- </LinearLayout>
- <View
- android:id="@+id/separator"
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- <ScrollView
- android:layout_width="fill_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:orientation="vertical" >
+ <View
+ android:id="@+id/separator"
+ android:layout_width="fill_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
- <LinearLayout
- android:id="@+id/editors"
+ <ScrollView
android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" />
- </ScrollView>
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:id="@+id/editors"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+ </ScrollView>
+
+ </LinearLayout>
-</LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/keyspinner_item.xml b/OpenKeychain/src/main/res/layout/keyspinner_item.xml
index b75bb808e..757dae5be 100644
--- a/OpenKeychain/src/main/res/layout/keyspinner_item.xml
+++ b/OpenKeychain/src/main/res/layout/keyspinner_item.xml
@@ -50,7 +50,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:src="@drawable/status_signature_revoked_cutout"
+ android:src="@drawable/status_signature_revoked_cutout_24px"
android:paddingLeft="16dp"
android:paddingRight="16dp" />
diff --git a/OpenKeychain/src/main/res/layout/log_display_activity.xml b/OpenKeychain/src/main/res/layout/log_display_activity.xml
index 518b56776..a243a9d2b 100644
--- a/OpenKeychain/src/main/res/layout/log_display_activity.xml
+++ b/OpenKeychain/src/main/res/layout/log_display_activity.xml
@@ -1,16 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingLeft="8dp"
- android:paddingRight="8dp">
+ android:layout_height="match_parent">
- <fragment
- android:id="@+id/list"
- android:name="org.sufficientlysecure.keychain.ui.LogDisplayFragment"
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="0.9" />
+ android:layout_height="match_parent"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp">
+
+ <fragment
+ android:id="@+id/list"
+ android:name="org.sufficientlysecure.keychain.ui.LogDisplayFragment"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.9" />
-</LinearLayout> \ No newline at end of file
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/nfc_activity.xml b/OpenKeychain/src/main/res/layout/nfc_activity.xml
index 034b74a35..9acd0676c 100644
--- a/OpenKeychain/src/main/res/layout/nfc_activity.xml
+++ b/OpenKeychain/src/main/res/layout/nfc_activity.xml
@@ -1,24 +1,35 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:paddingTop="16dp"
- android:paddingBottom="16dp">
+ android:layout_height="match_parent">
- <TextView
- android:text="@string/nfc_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Large"
- android:id="@+id/nfc_text"
- android:gravity="center"
- android:layout_gravity="center" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <ImageView
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:src="@drawable/yubikey_phone" />
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp">
-</LinearLayout>
+ <TextView
+ android:text="@string/nfc_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@android:style/TextAppearance.Large"
+ android:id="@+id/nfc_text"
+ android:gravity="center"
+ android:layout_gravity="center" />
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:src="@drawable/yubikey_phone" />
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/passphrase_wizard.xml b/OpenKeychain/src/main/res/layout/passphrase_wizard.xml
new file mode 100644
index 000000000..efc65b7c7
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/passphrase_wizard.xml
@@ -0,0 +1,11 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:id="@+id/fragmentContainer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_nfc.xml b/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_nfc.xml
new file mode 100644
index 000000000..46d430c4e
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_nfc.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="16dp">
+
+ <TextView
+ android:id="@+id/nfcText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="8dp"
+ android:text="@string/nfc_text"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:lines="2" />
+
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/imageView"
+ android:padding="16dp"
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:src="@drawable/nfc"
+ android:adjustViewBounds="true" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_passphrase.xml b/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_passphrase.xml
new file mode 100644
index 000000000..de957cc74
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_passphrase.xml
@@ -0,0 +1,117 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="16dp"
+ android:orientation="vertical"
+ tools:context="pSontag.testopenkeychain.Passphrase">
+
+
+ <TableLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TableRow android:layout_marginBottom="10dp">
+
+ <TextView
+ android:id="@+id/passphraseText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_span="2"
+ android:padding="8dp"
+ android:layout_gravity="center_vertical"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/passphrase"
+ android:layout_weight="1" />
+ </TableRow>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="8dp"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/passphrase" />
+
+ <EditText
+ android:id="@+id/passphrase"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textPassword"
+ android:padding="8dp"
+ android:layout_weight="6" />
+
+ </TableRow>
+
+ <TableRow
+ android:layout_marginTop="10dp"
+ android:layout_marginBottom="10dp">
+
+ <TextView
+ android:id="@+id/passphraseTextAgain"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="8dp"
+ android:text="@string/passphrase_again"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_weight="1" />
+
+ <EditText
+ android:id="@+id/passphraseAgain"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textPassword"
+ android:imeOptions="actionDone"
+ android:padding="8dp"
+ android:layout_weight="6" />
+
+ </TableRow>
+ </TableLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <!--<Button-->
+ <!--android:layout_width="wrap_content"-->
+ <!--android:layout_height="wrap_content"-->
+ <!--android:text="Cancel"-->
+ <!--android:onClick="cancel"-->
+ <!--android:layout_weight="1"-->
+ <!--android:textAppearance="?android:attr/textAppearanceMedium"-->
+ <!--style="?attr/alp_42447968_button_bar_button_style" />-->
+
+ <!--<View-->
+ <!--android:layout_width="1dip"-->
+ <!--android:layout_height="50dip"-->
+ <!--android:background="?android:attr/listDivider" />-->
+
+ <!--<Button-->
+ <!--android:layout_width="wrap_content"-->
+ <!--android:layout_height="wrap_content"-->
+ <!--android:text="Ok"-->
+ <!--android:onClick="savePassphrase"-->
+ <!--android:layout_weight="1"-->
+ <!--android:textAppearance="?android:attr/textAppearanceMedium"-->
+ <!--style="?attr/alp_42447968_button_bar_button_style" />-->
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+</LinearLayout>
diff --git a/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_select_methods.xml b/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_select_methods.xml
new file mode 100644
index 000000000..42baa6a0d
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/passphrase_wizard_fragment_select_methods.xml
@@ -0,0 +1,89 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="16dp"
+ tools:context="pSontag.testopenkeychain.SelectMethods">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:padding="8dp"
+ android:text="@string/title_unlock_method"
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/selectNoPassphrase"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:text="@string/noPassphrase"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:padding="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:clickable="true"
+ android:onClick="noPassphrase"
+ style="@style/SelectableItem"/>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/selectPassphrase"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:text="@string/passphrase"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:padding="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:clickable="true"
+ android:onClick="passphrase"
+ style="@style/SelectableItem"/>
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+ <TextView
+ android:id="@+id/selectLockpattern"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:text="@string/lockpattern"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:padding="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:clickable="true"
+ android:onClick="startLockpattern"
+ style="@style/SelectableItem"/>
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+ <TextView
+ android:id="@+id/selectLockpatternNFC"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:text="@string/lockpatternNFC"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:padding="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:clickable="true"
+ android:onClick="NFC"
+ style="@style/SelectableItem"/>
+
+ </LinearLayout>
+</ScrollView>
diff --git a/OpenKeychain/src/main/res/layout/preference_toolbar_activity.xml b/OpenKeychain/src/main/res/layout/preference_toolbar_activity.xml
new file mode 100644
index 000000000..f17bc30bc
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/preference_toolbar_activity.xml
@@ -0,0 +1,10 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/qr_code_activity.xml b/OpenKeychain/src/main/res/layout/qr_code_activity.xml
index 57c869db6..4ce097f40 100644
--- a/OpenKeychain/src/main/res/layout/qr_code_activity.xml
+++ b/OpenKeychain/src/main/res/layout/qr_code_activity.xml
@@ -1,14 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="match_parent">
- <ImageView
- android:id="@+id/qr_code_image"
- android:padding="32dp"
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
android:layout_height="match_parent"
- style="@style/SelectableItem" />
+ android:orientation="vertical">
+
+ <android.support.v7.widget.CardView
+ android:id="@+id/qr_code_image_layout"
+ android:transitionName="qr_code"
+ android:layout_margin="32dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ android:foreground="?android:attr/selectableItemBackground"
+ app:cardBackgroundColor="@android:color/white"
+ app:cardUseCompatPadding="true"
+ app:cardCornerRadius="4dp">
+
+ <org.sufficientlysecure.keychain.ui.widget.AspectRatioImageView
+ android:id="@+id/qr_code_image"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:aspectRatioEnabled="true" />
+ </android.support.v7.widget.CardView>
-</LinearLayout> \ No newline at end of file
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/safe_slinger_activity.xml b/OpenKeychain/src/main/res/layout/safe_slinger_activity.xml
index 39f4b7238..bafad173b 100644
--- a/OpenKeychain/src/main/res/layout/safe_slinger_activity.xml
+++ b/OpenKeychain/src/main/res/layout/safe_slinger_activity.xml
@@ -1,74 +1,86 @@
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <LinearLayout
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <ScrollView
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp">
+ android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal">
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp">
- <TextView
- android:layout_width="0dp"
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/exchange_description"
- android:layout_weight="1"/>
+ android:orientation="horizontal">
- <Spinner
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/safe_slinger_spinner"
- android:gravity="center_vertical"/>
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/exchange_description"
+ android:layout_weight="1"
+ android:gravity="center_vertical" />
- </LinearLayout>
+ <NumberPicker
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/safe_slinger_picker" />
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
+ </LinearLayout>
- <LinearLayout
- android:id="@+id/safe_slinger_button"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- android:paddingRight="4dp"
- style="@style/SelectableItem"
- android:orientation="horizontal">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
- <TextView
- android:paddingLeft="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:text="Start exchange"
- android:layout_weight="1"
- android:gravity="center_vertical" />
+ <LinearLayout
+ android:id="@+id/safe_slinger_button"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ android:paddingRight="4dp"
+ style="@style/SelectableItem"
+ android:orientation="horizontal">
- <!-- separate ImageView required for recoloring -->
- <ImageView
- android:id="@+id/safe_slinger_button_image"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:padding="8dp"
- android:src="@drawable/ic_action_safeslinger"
- android:layout_gravity="center_vertical" />
+ <TextView
+ android:paddingLeft="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:text="@string/btn_start_exchange"
+ android:layout_weight="1"
+ android:gravity="center_vertical" />
- </LinearLayout>
+ <!-- separate ImageView required for recoloring -->
+ <ImageView
+ android:id="@+id/safe_slinger_button_image"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:src="@drawable/ic_repeat_grey_24dp"
+ android:layout_gravity="center_vertical" />
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:layout_marginBottom="4dp"
- android:background="?android:attr/listDivider" />
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginBottom="4dp"
+ android:background="?android:attr/listDivider" />
+
+ </LinearLayout>
+ </ScrollView>
- </LinearLayout>
-</ScrollView>
+</RelativeLayout>
diff --git a/OpenKeychain/src/main/res/layout/select_key_item.xml b/OpenKeychain/src/main/res/layout/select_key_item.xml
index c7fa882cb..13f63d2ee 100644
--- a/OpenKeychain/src/main/res/layout/select_key_item.xml
+++ b/OpenKeychain/src/main/res/layout/select_key_item.xml
@@ -50,7 +50,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:src="@drawable/status_signature_revoked_cutout"
+ android:src="@drawable/status_signature_revoked_cutout_24px"
android:paddingLeft="16dp"
android:paddingRight="16dp" />
diff --git a/OpenKeychain/src/main/res/layout/select_public_key_activity.xml b/OpenKeychain/src/main/res/layout/select_public_key_activity.xml
index a18ce46fc..5a607e5ec 100644
--- a/OpenKeychain/src/main/res/layout/select_public_key_activity.xml
+++ b/OpenKeychain/src/main/res/layout/select_public_key_activity.xml
@@ -1,12 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_centerHorizontal="true" >
+ android:layout_height="match_parent">
- <FrameLayout
- android:id="@+id/select_public_key_fragment_container"
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <RelativeLayout
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:layout_centerHorizontal="true">
+
+ <FrameLayout
+ android:id="@+id/select_public_key_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ </RelativeLayout>
</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/toolbar_standalone.xml b/OpenKeychain/src/main/res/layout/toolbar_standalone.xml
new file mode 100644
index 000000000..950c2f2ae
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/toolbar_standalone.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/toolbar_include"
+ android:elevation="4dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <!--
+ We always have windowTranslucentStatus=true to get under the status bar.
+ Thus this ImageView is the part under the status bar!
+ -->
+ <ImageView
+ android:id="@+id/status_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/statusbar_height"
+ android:background="?attr/colorPrimary" />
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_below="@+id/status_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?attr/actionBarSize"
+ android:background="?attr/colorPrimary"
+ app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
+ app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
+ tools:ignore="UnusedAttribute" />
+
+</RelativeLayout>
diff --git a/OpenKeychain/src/main/res/layout/upload_key_activity.xml b/OpenKeychain/src/main/res/layout/upload_key_activity.xml
index 736617ba5..19e37783b 100644
--- a/OpenKeychain/src/main/res/layout/upload_key_activity.xml
+++ b/OpenKeychain/src/main/res/layout/upload_key_activity.xml
@@ -1,62 +1,72 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
- <ScrollView
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <LinearLayout
+ <include layout="@layout/notify_area" />
+
+ <ScrollView
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:orientation="vertical">
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_key_server" />
+ android:layout_height="match_parent">
- <Spinner
- android:id="@+id/upload_key_keyserver"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="4dp" />
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_actions"
- android:layout_weight="1" />
-
- <TextView
- android:id="@+id/upload_key_action_upload"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:layout_marginBottom="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="@string/btn_export_to_server"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:drawableRight="@drawable/ic_action_upload"
- android:drawablePadding="8dp"
- android:gravity="center_vertical"
- android:clickable="true"
- style="@style/SelectableItem" />
-
- </LinearLayout>
-
- </ScrollView>
-</LinearLayout> \ No newline at end of file
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:orientation="vertical">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_key_server" />
+
+ <Spinner
+ android:id="@+id/upload_key_keyserver"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="4dp" />
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_actions"
+ android:layout_weight="1" />
+
+ <TextView
+ android:id="@+id/upload_key_action_upload"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:layout_marginBottom="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/btn_export_to_server"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:drawableRight="@drawable/ic_action_upload"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical"
+ android:clickable="true"
+ style="@style/SelectableItem" />
+
+ </LinearLayout>
+
+ </ScrollView>
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/view_cert_activity.xml b/OpenKeychain/src/main/res/layout/view_cert_activity.xml
index bf65fe1cd..0a6b46a93 100644
--- a/OpenKeychain/src/main/res/layout/view_cert_activity.xml
+++ b/OpenKeychain/src/main/res/layout/view_cert_activity.xml
@@ -1,213 +1,226 @@
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
- <LinearLayout
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <ScrollView
+ android:layout_below="@id/toolbar_include"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="beforeDescendants"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp">
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_cert" />
+ android:layout_height="match_parent">
- <TableLayout
+ <!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginLeft="8dp"
- android:layout_weight="1"
- android:stretchColumns="1">
-
- <TableRow>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_key_id" />
-
- <TextView
- android:id="@+id/signee_key"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip"
- android:typeface="monospace" />
- </TableRow>
-
- <TableRow>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_user_id" />
-
- <TextView
- android:id="@+id/signee_uid"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip" />
- </TableRow>
-
- <TableRow
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_algorithm" />
-
- <TextView
- android:id="@+id/algorithm"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip" />
- </TableRow>
-
- <TableRow
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_cert_type" />
-
- <TextView
- android:id="@+id/signature_type"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip" />
- </TableRow>
-
- <TableRow
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:id="@+id/row_reason">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_revocation" />
-
- <TextView
- android:id="@+id/reason"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip" />
- </TableRow>
-
- <TableRow>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_creation" />
-
- <TextView
- android:id="@+id/creation"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip" />
- </TableRow>
-
- </TableLayout>
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_certifier_id" />
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:descendantFocusability="beforeDescendants"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_cert" />
+
+ <TableLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_weight="1"
+ android:stretchColumns="1">
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_key_id" />
+
+ <TextView
+ android:id="@+id/signee_key"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip"
+ android:typeface="monospace" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_user_id" />
+
+ <TextView
+ android:id="@+id/signee_uid"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip" />
+ </TableRow>
+
+ <TableRow
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_algorithm" />
+
+ <TextView
+ android:id="@+id/algorithm"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip" />
+ </TableRow>
+
+ <TableRow
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_cert_type" />
+
+ <TextView
+ android:id="@+id/signature_type"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip" />
+ </TableRow>
+
+ <TableRow
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/row_reason">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_revocation" />
+
+ <TextView
+ android:id="@+id/reason"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_creation" />
+
+ <TextView
+ android:id="@+id/creation"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip" />
+ </TableRow>
+
+ </TableLayout>
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_certifier_id" />
+
+ <TableLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginBottom="4dp"
+ android:layout_weight="1"
+ android:stretchColumns="1">
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:paddingRight="10dip"
+ android:text="@string/label_key_id" />
+
+ <TextView
+ android:id="@+id/signer_key_id"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip"
+ android:typeface="monospace" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ android:id="@+id/label_algorithm"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_user_id" />
+
+ <TextView
+ android:id="@+id/signer_uid"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip" />
+ </TableRow>
+
+ </TableLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/view_cert_view_cert_key"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:layout_marginBottom="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="@string/btn_view_cert_key"
+ android:layout_weight="1"
+ android:drawableRight="@drawable/ic_action_person"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ </LinearLayout>
+
+ </ScrollView>
+
+</RelativeLayout>
- <TableLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginLeft="8dp"
- android:layout_marginBottom="4dp"
- android:layout_weight="1"
- android:stretchColumns="1">
-
- <TableRow>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:paddingRight="10dip"
- android:text="@string/label_key_id" />
-
- <TextView
- android:id="@+id/signer_key_id"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="5dip"
- android:typeface="monospace" />
- </TableRow>
-
- <TableRow>
-
- <TextView
- android:id="@+id/label_algorithm"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_user_id" />
-
- <TextView
- android:id="@+id/signer_uid"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="5dip" />
- </TableRow>
-
- </TableLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- <TextView
- android:id="@+id/view_cert_view_cert_key"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:layout_marginBottom="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:text="@string/btn_view_cert_key"
- android:layout_weight="1"
- android:drawableRight="@drawable/ic_action_person"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- </LinearLayout>
-
-</ScrollView>
diff --git a/OpenKeychain/src/main/res/layout/view_key_activity.xml b/OpenKeychain/src/main/res/layout/view_key_activity.xml
index 451eb30ee..e2d153e0d 100644
--- a/OpenKeychain/src/main/res/layout/view_key_activity.xml
+++ b/OpenKeychain/src/main/res/layout/view_key_activity.xml
@@ -1,52 +1,190 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:fab="http://schemas.android.com/apk/res-auto"
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="match_parent">
- <include layout="@layout/notify_area" />
-
- <LinearLayout
- android:id="@+id/view_key_status_layout"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
+ <RelativeLayout
+ android:id="@+id/toolbar_big"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/huge_toolbar"
+ android:elevation="4dp"
+ android:background="?attr/colorPrimary"
android:orientation="horizontal">
+ <org.sufficientlysecure.keychain.ui.widget.AspectRatioImageView
+ android:id="@+id/view_key_photo"
+ app:aspectRatioEnabled="true"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/status_bar"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:src="@drawable/first_time_1" />
+
<ImageView
- android:id="@+id/view_key_status_image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ android:id="@+id/status_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/statusbar_height"
+ android:background="?attr/colorPrimary" />
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_below="@+id/status_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?attr/actionBarSize"
+ android:overScrollMode="always"
+ app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
+ app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
+ tools:ignore="UnusedAttribute"
+ android:transitionGroup="false"
+ android:touchscreenBlocksFocus="false" />
<TextView
- android:id="@+id/view_key_status_text"
+ android:id="@+id/view_key_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="48dp"
+ android:layout_marginStart="48dp"
+ android:layout_marginRight="48dp"
+ android:layout_marginEnd="48dp"
+ android:text=""
+ android:textColor="@color/icons"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:layout_above="@+id/view_key_status" />
+
+ <TextView
+ android:id="@+id/view_key_status"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="48dp"
+ android:layout_marginStart="48dp"
+ android:layout_marginRight="48dp"
+ android:layout_marginEnd="48dp"
+ android:text=""
+ android:textColor="@color/tab_text"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_above="@+id/toolbar2" />
+
+ <LinearLayout
+ android:id="@+id/toolbar2"
+ android:orientation="horizontal"
+ android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
+ android:minHeight="?attr/actionBarSize"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="8dp" />
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:layout_marginLeft="32dp"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true">
- </LinearLayout>
+ <ImageButton
+ android:id="@+id/view_key_action_encrypt_files"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:visibility="invisible"
+ style="?android:attr/borderlessButtonStyle"
+ android:src="@drawable/ic_action_encrypt_file" />
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider"
- android:visibility="gone"
- android:id="@+id/view_key_status_divider" />
+ <ImageButton
+ android:id="@+id/view_key_action_encrypt_text"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:visibility="invisible"
+ style="?android:attr/borderlessButtonStyle"
+ android:src="@drawable/ic_action_encrypt_text" />
- <org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout
- android:id="@+id/view_key_sliding_tab_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ <ImageButton
+ android:id="@+id/view_key_action_nfc"
+ android:layout_width="64dp"
+ android:layout_height="64dp"
+ android:visibility="invisible"
+ style="?android:attr/borderlessButtonStyle"
+ android:src="@drawable/ic_nfc_white_24dp" />
- <android.support.v4.view.ViewPager
- android:id="@+id/view_key_pager"
+ </LinearLayout>
+
+ <ImageView
+ android:id="@+id/view_key_status_image"
+ android:layout_width="96dp"
+ android:visibility="invisible"
+ android:src="@drawable/status_signature_unverified_cutout_96px"
+ android:layout_height="96dp"
+ android:layout_above="@id/toolbar2"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"
+ android:layout_marginRight="16dp" />
+
+ <android.support.v7.widget.CardView
+ android:id="@+id/view_key_qr_code_layout"
+ android:transitionName="qr_code"
+ android:visibility="visible"
+ android:layout_above="@id/toolbar2"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"
+ android:layout_marginRight="20dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ android:foreground="?android:attr/selectableItemBackground"
+ card_view:cardBackgroundColor="@android:color/white"
+ card_view:cardUseCompatPadding="true"
+ card_view:cardCornerRadius="4dp">
+
+ <ImageView
+ android:id="@+id/view_key_qr_code"
+ android:layout_width="96dp"
+ android:layout_height="96dp" />
+ </android.support.v7.widget.CardView>
+
+ </RelativeLayout>
+
+ <LinearLayout
+ android:id="@+id/body"
+ android:layout_below="@id/toolbar_big"
+ android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="0px"
- android:layout_weight="1"
- android:background="@android:color/white" />
+ android:layout_height="match_parent">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider"
+ android:visibility="gone"
+ android:id="@+id/view_key_status_divider" />
+
+ <FrameLayout
+ android:id="@+id/content_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <FrameLayout
+ android:id="@+id/view_key_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" />
+
+ </FrameLayout>
+ </LinearLayout>
+
+ <com.getbase.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab"
+ android:layout_alignBottom="@id/toolbar_big"
+ android:layout_alignParentRight="true"
+ android:layout_marginRight="20dp"
+ android:layout_marginBottom="-40dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible"
+ android:elevation="4dp"
+ fab:fab_icon="@drawable/ic_qrcode_white_24dp"
+ fab:fab_colorNormal="@color/fab"
+ fab:fab_colorPressed="@color/fab_pressed" />
-</LinearLayout> \ No newline at end of file
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_activity.xml b/OpenKeychain/src/main/res/layout/view_key_adv_activity.xml
new file mode 100644
index 000000000..59888c25a
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_activity.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ android:id="@+id/toolbar_include"
+ layout="@layout/toolbar_standalone" />
+
+ <LinearLayout
+ android:layout_below="@id/toolbar_include"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider"
+ android:visibility="gone"
+ android:id="@+id/view_key_status_divider" />
+
+ <com.astuetz.PagerSlidingTabStrip
+ android:id="@+id/view_key_sliding_tab_layout"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="?attr/colorPrimary"
+ android:textColor="@color/tab_text"
+ app:pstsTextColorSelected="@color/tab_text_selected"
+ app:pstsIndicatorColor="@color/tab_indicator" />
+
+ <android.support.v4.view.ViewPager
+ android:id="@+id/view_key_pager"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1"
+ android:background="@android:color/white" />
+
+ </LinearLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_certs_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_certs_fragment.xml
new file mode 100644
index 000000000..2232ea9f2
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_certs_fragment.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:descendantFocusability="beforeDescendants"
+ android:orientation="vertical">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:text="@string/section_certs" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@color/holo_gray_bright"
+ android:padding="8dp"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/certs_text"
+ android:gravity="center_horizontal" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider"
+ android:id="@+id/view_key_status_divider" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <se.emilsjolander.stickylistheaders.StickyListHeadersListView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/certs_list"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:scrollbarStyle="outsideOverlay" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/empty_certs"
+ android:id="@+id/empty"
+ android:visibility="gone"
+ android:layout_gravity="center" />
+
+ </FrameLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/view_key_certs_header.xml b/OpenKeychain/src/main/res/layout/view_key_adv_certs_header.xml
index f99c012c9..f99c012c9 100644
--- a/OpenKeychain/src/main/res/layout/view_key_certs_header.xml
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_certs_header.xml
diff --git a/OpenKeychain/src/main/res/layout/view_key_certs_item.xml b/OpenKeychain/src/main/res/layout/view_key_adv_certs_item.xml
index e84a98cdb..e84a98cdb 100644
--- a/OpenKeychain/src/main/res/layout/view_key_certs_item.xml
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_certs_item.xml
diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml
new file mode 100644
index 000000000..6d0ed3298
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml
@@ -0,0 +1,164 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:descendantFocusability="beforeDescendants"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_marginTop="8dp"
+ android:text="@string/section_user_ids"
+ android:layout_weight="1" />
+
+ <org.sufficientlysecure.keychain.ui.widget.FixedListView
+ android:id="@+id/view_key_user_ids"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginBottom="4dp"
+ android:layout_weight="1" />
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_actions"
+ android:layout_weight="1" />
+
+ <LinearLayout
+ android:id="@+id/view_key_action_certify"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ android:paddingRight="4dp"
+ style="@style/SelectableItem"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/view_key_action_certify_text"
+ android:paddingLeft="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:text="@string/key_view_action_certify"
+ android:layout_weight="1"
+ android:gravity="center_vertical" />
+
+ <ImageView
+ android:id="@+id/view_key_action_certify_image"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:src="@drawable/status_signature_verified_cutout_24px"
+ android:layout_gravity="center_vertical" />
+
+ </LinearLayout>
+
+ <View
+ android:id="@+id/view_key_action_certify_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/view_key_action_edit"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="@string/key_view_action_edit"
+ android:layout_weight="1"
+ android:drawableRight="@drawable/ic_action_edit"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:id="@+id/view_key_action_edit_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+
+ <LinearLayout
+ android:id="@+id/view_key_action_encrypt_text"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/view_key_action_encrypt_text_text"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:text="@string/key_view_action_encrypt"
+ android:layout_weight="1"
+ android:drawableRight="@drawable/ic_action_secure"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:gravity="right"
+ android:layout_marginBottom="8dp"
+ android:layout_marginTop="8dp"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/view_key_action_encrypt_files"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:text="@string/key_view_action_encrypt_files"
+ android:drawableRight="@drawable/ic_action_secure"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical"
+ style="@style/SelectableItem" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/view_key_action_update"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="@string/key_view_action_update"
+ android:layout_weight="1"
+ android:drawableRight="@drawable/ic_action_download"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ </LinearLayout>
+
+</ScrollView>
diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_share_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_share_fragment.xml
new file mode 100644
index 000000000..cd8f96e6f
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_share_fragment.xml
@@ -0,0 +1,212 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:descendantFocusability="beforeDescendants"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_marginTop="8dp"
+ android:text="@string/section_fingerprint"
+ android:layout_weight="1" />
+
+ <LinearLayout
+ android:id="@+id/view_key_action_fingerprint_share"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/view_key_fingerprint"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:text=""
+ android:layout_weight="1"
+ android:typeface="monospace"
+ android:drawableRight="@drawable/ic_action_share"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:gravity="right"
+ android:layout_marginBottom="8dp"
+ android:layout_marginTop="8dp"
+ android:background="?android:attr/listDivider" />
+
+ <ImageButton
+ android:id="@+id/view_key_action_fingerprint_clipboard"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:src="@drawable/ic_action_copy"
+ android:layout_gravity="center_vertical"
+ style="@style/SelectableItem" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <ImageView
+ android:id="@+id/view_key_fingerprint_qr_code_image"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ android:layout_gravity="center_horizontal"
+ android:layout_weight="1"
+ style="@style/SelectableItem" />
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_share_key"
+ android:layout_weight="1" />
+
+ <LinearLayout
+ android:id="@+id/view_key_action_key_share"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:orientation="horizontal">
+
+ <TextView
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:text="@string/key_view_action_share_with"
+ android:layout_weight="1"
+ android:drawableRight="@drawable/ic_action_share"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:gravity="right"
+ android:layout_marginBottom="8dp"
+ android:layout_marginTop="8dp"
+ android:background="?android:attr/listDivider" />
+
+ <ImageButton
+ android:id="@+id/view_key_action_key_clipboard"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:src="@drawable/ic_action_copy"
+ android:layout_gravity="center_vertical"
+ style="@style/SelectableItem" />
+
+ <View
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:gravity="right"
+ android:layout_marginBottom="8dp"
+ android:layout_marginTop="8dp"
+ android:background="?android:attr/listDivider" />
+
+ <ImageButton
+ android:id="@+id/view_key_action_key_safeslinger"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:src="@drawable/ic_repeat_grey_24dp"
+ android:layout_gravity="center_vertical"
+ style="@style/SelectableItem" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/view_key_action_upload"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:text="@string/key_view_action_upload"
+ android:layout_weight="1"
+ android:drawableRight="@drawable/ic_action_upload"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <LinearLayout
+ android:id="@+id/view_key_action_nfc_help"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:clickable="true"
+ style="@style/SelectableItem"
+ android:orientation="horizontal"
+ android:layout_marginBottom="8dp">
+
+ <TextView
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:text="@string/key_view_action_share_nfc"
+ android:layout_weight="1"
+ android:drawableRight="@drawable/ic_action_help"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical" />
+
+ <View
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:gravity="right"
+ android:layout_marginBottom="8dp"
+ android:layout_marginTop="8dp"
+ android:background="?android:attr/listDivider" />
+
+ <ImageButton
+ android:id="@+id/view_key_action_nfc_prefs"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:src="@drawable/ic_action_settings"
+ android:layout_gravity="center_vertical"
+ style="@style/SelectableItem" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+</ScrollView>
diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_subkey_item.xml b/OpenKeychain/src/main/res/layout/view_key_adv_subkey_item.xml
new file mode 100644
index 000000000..f41109d84
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_subkey_item.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:orientation="horizontal"
+ android:singleLine="true">
+
+ <ImageView
+ android:id="@+id/subkey_item_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:src="@drawable/status_signature_revoked_cutout_24px"
+ android:paddingLeft="8dp"
+ android:layout_centerVertical="true"
+ android:layout_alignParentStart="true" />
+
+ <FrameLayout
+ android:id="@+id/subkey_item_buttons"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true">
+
+ <ImageView
+ android:id="@+id/subkey_item_edit_image"
+ android:src="@drawable/ic_action_edit"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="8dp" />
+
+ <ImageButton
+ android:id="@+id/subkey_item_delete_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="8dp"
+ android:src="@drawable/ic_action_cancel"
+ style="@style/SelectableItem" />
+
+ </FrameLayout>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_toLeftOf="@id/subkey_item_buttons"
+ android:layout_toRightOf="@id/subkey_item_status"
+ android:layout_centerVertical="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:orientation="horizontal"
+ android:paddingBottom="2dip"
+ android:paddingTop="2dip">
+
+ <TextView
+ android:id="@+id/subkey_item_key_id"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="0x00000000"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_weight="1" />
+
+ <ImageView
+ android:id="@+id/subkey_item_ic_certify"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/key_flag_certify_24px"
+ android:layout_marginLeft="8dp"
+ android:layout_gravity="center_vertical" />
+
+ <ImageView
+ android:id="@+id/subkey_item_ic_sign"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/key_flag_sign_24px"
+ android:layout_marginLeft="8dp"
+ android:layout_gravity="center_vertical" />
+
+ <ImageView
+ android:id="@+id/subkey_item_ic_encrypt"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/key_flag_encrypt_24px"
+ android:layout_marginLeft="8dp"
+ android:layout_gravity="center_vertical" />
+
+ <ImageView
+ android:id="@+id/subkey_item_ic_authenticate"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/key_flag_authenticate_24px"
+ android:layout_marginLeft="8dp"
+ android:layout_gravity="center_vertical" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/subkey_item_details"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip"
+ android:text="RSA, 1024bit"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_weight="1" />
+
+ <TextView
+ android:id="@+id/subkey_item_expiry"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Expiry: 4/7/2016"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_gravity="right" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+</RelativeLayout>
diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml
new file mode 100644
index 000000000..62fd113f9
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:descendantFocusability="beforeDescendants"
+ android:orientation="vertical">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:text="@string/section_keys" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ListView
+ android:id="@+id/keys"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scrollbarStyle="outsideOverlay"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:layout_marginBottom="8dp" />
+ </FrameLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/view_key_user_id_item.xml b/OpenKeychain/src/main/res/layout/view_key_adv_user_id_item.xml
index 24e8e1a10..24e8e1a10 100644
--- a/OpenKeychain/src/main/res/layout/view_key_user_id_item.xml
+++ b/OpenKeychain/src/main/res/layout/view_key_adv_user_id_item.xml
diff --git a/OpenKeychain/src/main/res/layout/view_key_advanced_activity.xml b/OpenKeychain/src/main/res/layout/view_key_advanced_activity.xml
deleted file mode 100644
index a581caa0e..000000000
--- a/OpenKeychain/src/main/res/layout/view_key_advanced_activity.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <include layout="@layout/notify_area" />
-
- <FrameLayout
- android:id="@+id/content_frame"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <FrameLayout
- android:id="@+id/view_key_advanced_fragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" />
-
- </FrameLayout>
-
-</LinearLayout> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/layout/view_key_advanced_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_advanced_fragment.xml
deleted file mode 100644
index 9a2190f7e..000000000
--- a/OpenKeychain/src/main/res/layout/view_key_advanced_fragment.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<!--<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"--><!--android:layout_width="match_parent"--><!--android:layout_height="match_parent">-->
-
-<!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="beforeDescendants"
- android:orientation="vertical">
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="8dp"
- android:layout_marginLeft="16dp"
- android:layout_marginRight="16dp"
- android:text="@string/section_keys" />
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="0.4">
-
- <ListView
- android:id="@+id/keys"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:scrollbarStyle="outsideOverlay"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:layout_marginBottom="8dp" />
- </FrameLayout>
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginLeft="16dp"
- android:layout_marginRight="16dp"
- android:text="@string/section_certs" />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@color/holo_gray_bright"
- android:padding="8dp"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:text="@string/certs_text"
- android:gravity="center_horizontal" />
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider"
- android:id="@+id/view_key_status_divider" />
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="0.6">
-
- <se.emilsjolander.stickylistheaders.StickyListHeadersListView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/certs_list"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:scrollbarStyle="outsideOverlay" />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@string/empty_certs"
- android:id="@+id/empty"
- android:visibility="gone"
- android:layout_gravity="center" />
-
- </FrameLayout>
-
-</LinearLayout>
-
- <!--</ScrollView>-->
diff --git a/OpenKeychain/src/main/res/layout/view_key_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_fragment.xml
new file mode 100644
index 000000000..8e1bad3a8
--- /dev/null
+++ b/OpenKeychain/src/main/res/layout/view_key_fragment.xml
@@ -0,0 +1,47 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp">
+
+ <android.support.v7.widget.CardView
+ android:id="@+id/card_view"
+ android:layout_gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ card_view:cardBackgroundColor="@android:color/white"
+ card_view:cardElevation="2sp"
+ card_view:cardUseCompatPadding="true"
+ card_view:cardCornerRadius="4dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ style="@style/CardViewHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/section_user_ids" />
+
+ <org.sufficientlysecure.keychain.ui.widget.FixedListView
+ android:id="@+id/view_key_user_ids"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp" />
+ </LinearLayout>
+ </android.support.v7.widget.CardView>
+
+
+ </LinearLayout>
+
+</ScrollView>
diff --git a/OpenKeychain/src/main/res/layout/view_key_main_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_main_fragment.xml
deleted file mode 100644
index 691ee357d..000000000
--- a/OpenKeychain/src/main/res/layout/view_key_main_fragment.xml
+++ /dev/null
@@ -1,164 +0,0 @@
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="beforeDescendants"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp">
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_marginTop="8dp"
- android:text="@string/section_user_ids"
- android:layout_weight="1" />
-
- <org.sufficientlysecure.keychain.ui.widget.FixedListView
- android:id="@+id/view_key_user_ids"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginBottom="4dp"
- android:layout_weight="1" />
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_actions"
- android:layout_weight="1" />
-
- <LinearLayout
- android:id="@+id/view_key_action_certify"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- android:paddingRight="4dp"
- style="@style/SelectableItem"
- android:orientation="horizontal">
-
- <TextView
- android:id="@+id/view_key_action_certify_text"
- android:paddingLeft="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:text="@string/key_view_action_certify"
- android:layout_weight="1"
- android:gravity="center_vertical" />
-
- <ImageView
- android:id="@+id/view_key_action_certify_image"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:padding="8dp"
- android:src="@drawable/status_signature_verified_cutout"
- android:layout_gravity="center_vertical" />
-
- </LinearLayout>
-
- <View
- android:id="@+id/view_key_action_certify_divider"
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- <TextView
- android:id="@+id/view_key_action_edit"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:text="@string/key_view_action_edit"
- android:layout_weight="1"
- android:drawableRight="@drawable/ic_action_edit"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- <View
- android:id="@+id/view_key_action_edit_divider"
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
-
- <LinearLayout
- android:id="@+id/view_key_action_encrypt_text"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:orientation="horizontal">
-
- <TextView
- android:id="@+id/view_key_action_encrypt_text_text"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:text="@string/key_view_action_encrypt"
- android:layout_weight="1"
- android:drawableRight="@drawable/ic_action_secure"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- <View
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:gravity="right"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="8dp"
- android:background="?android:attr/listDivider" />
-
- <TextView
- android:id="@+id/view_key_action_encrypt_files"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:text="@string/key_view_action_encrypt_files"
- android:drawableRight="@drawable/ic_action_secure"
- android:drawablePadding="8dp"
- android:gravity="center_vertical"
- style="@style/SelectableItem" />
-
- </LinearLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- <TextView
- android:id="@+id/view_key_action_update"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:text="@string/key_view_action_update"
- android:layout_weight="1"
- android:drawableRight="@drawable/ic_action_download"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- </LinearLayout>
-
-</ScrollView>
diff --git a/OpenKeychain/src/main/res/layout/view_key_share_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_share_fragment.xml
deleted file mode 100644
index 9971032ce..000000000
--- a/OpenKeychain/src/main/res/layout/view_key_share_fragment.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="beforeDescendants"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp">
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_marginTop="8dp"
- android:text="@string/section_fingerprint"
- android:layout_weight="1" />
-
- <LinearLayout
- android:id="@+id/view_key_action_fingerprint_share"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:orientation="horizontal">
-
- <TextView
- android:id="@+id/view_key_fingerprint"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:text=""
- android:layout_weight="1"
- android:typeface="monospace"
- android:drawableRight="@drawable/ic_action_share"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- <View
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:gravity="right"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="8dp"
- android:background="?android:attr/listDivider" />
-
- <ImageButton
- android:id="@+id/view_key_action_fingerprint_clipboard"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:padding="8dp"
- android:src="@drawable/ic_action_copy"
- android:layout_gravity="center_vertical"
- style="@style/SelectableItem" />
-
- </LinearLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- <ImageView
- android:id="@+id/view_key_fingerprint_qr_code_image"
- android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:layout_width="200dp"
- android:layout_height="200dp"
- android:layout_gravity="center_horizontal"
- android:layout_weight="1"
- style="@style/SelectableItem" />
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_share_key"
- android:layout_weight="1" />
-
- <LinearLayout
- android:id="@+id/view_key_action_key_share"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:orientation="horizontal">
-
- <TextView
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:text="@string/key_view_action_share_with"
- android:layout_weight="1"
- android:drawableRight="@drawable/ic_action_share"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- <View
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:gravity="right"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="8dp"
- android:background="?android:attr/listDivider" />
-
- <ImageButton
- android:id="@+id/view_key_action_key_clipboard"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:padding="8dp"
- android:src="@drawable/ic_action_copy"
- android:layout_gravity="center_vertical"
- style="@style/SelectableItem" />
-
- <View
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:gravity="right"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="8dp"
- android:background="?android:attr/listDivider" />
-
- <ImageButton
- android:id="@+id/view_key_action_key_safeslinger"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:padding="8dp"
- android:src="@drawable/ic_action_safeslinger"
- android:layout_gravity="center_vertical"
- style="@style/SelectableItem" />
-
- </LinearLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- <TextView
- android:id="@+id/view_key_action_upload"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:text="@string/key_view_action_upload"
- android:layout_weight="1"
- android:drawableRight="@drawable/ic_action_upload"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="?android:attr/listDivider" />
-
- <LinearLayout
- android:id="@+id/view_key_action_nfc_help"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:clickable="true"
- style="@style/SelectableItem"
- android:orientation="horizontal"
- android:layout_marginBottom="8dp">
-
- <TextView
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:text="@string/key_view_action_share_nfc"
- android:layout_weight="1"
- android:drawableRight="@drawable/ic_action_help"
- android:drawablePadding="8dp"
- android:gravity="center_vertical" />
-
- <View
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:gravity="right"
- android:layout_marginBottom="8dp"
- android:layout_marginTop="8dp"
- android:background="?android:attr/listDivider" />
-
- <ImageButton
- android:id="@+id/view_key_action_nfc_prefs"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:padding="8dp"
- android:src="@drawable/ic_action_settings"
- android:layout_gravity="center_vertical"
- style="@style/SelectableItem" />
-
- </LinearLayout>
-
- </LinearLayout>
-
-</ScrollView>
diff --git a/OpenKeychain/src/main/res/layout/view_key_subkey_item.xml b/OpenKeychain/src/main/res/layout/view_key_subkey_item.xml
deleted file mode 100644
index b2875b9e6..000000000
--- a/OpenKeychain/src/main/res/layout/view_key_subkey_item.xml
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:orientation="horizontal"
- android:singleLine="true">
-
- <ImageView
- android:id="@+id/subkey_item_status"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:src="@drawable/status_signature_revoked_cutout"
- android:paddingLeft="8dp"
- android:layout_centerVertical="true"
- android:layout_alignParentStart="true" />
-
- <FrameLayout
- android:id="@+id/subkey_item_buttons"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_alignParentRight="true"
- android:layout_alignParentEnd="true">
-
- <ImageView
- android:id="@+id/subkey_item_edit_image"
- android:src="@drawable/ic_action_edit"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="8dp" />
-
- <ImageButton
- android:id="@+id/subkey_item_delete_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="8dp"
- android:src="@drawable/ic_action_cancel"
- style="@style/SelectableItem" />
-
- </FrameLayout>
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_toLeftOf="@id/subkey_item_buttons"
- android:layout_toRightOf="@id/subkey_item_status"
- android:layout_centerVertical="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="8dp"
- android:layout_marginRight="8dp">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:orientation="horizontal"
- android:paddingBottom="2dip"
- android:paddingTop="2dip">
-
- <TextView
- android:id="@+id/subkey_item_key_id"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="0x00000000"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_weight="1" />
-
- <ImageView
- android:id="@+id/subkey_item_ic_certify"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/key_flag_certify"
- android:layout_marginLeft="8dp"
- android:layout_gravity="center_vertical" />
-
- <ImageView
- android:id="@+id/subkey_item_ic_sign"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/key_flag_sign"
- android:layout_marginLeft="8dp"
- android:layout_gravity="center_vertical" />
-
- <ImageView
- android:id="@+id/subkey_item_ic_encrypt"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/key_flag_encrypt"
- android:layout_marginLeft="8dp"
- android:layout_gravity="center_vertical" />
-
- <ImageView
- android:id="@+id/subkey_item_ic_authenticate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/key_flag_authenticate"
- android:layout_marginLeft="8dp"
- android:layout_gravity="center_vertical" />
-
- </LinearLayout>
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <TextView
- android:id="@+id/subkey_item_details"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip"
- android:text="RSA, 1024bit"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:layout_weight="1" />
-
- <TextView
- android:id="@+id/subkey_item_expiry"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Expiry: 4/7/2016"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:layout_gravity="right" />
-
- </LinearLayout>
-
- </LinearLayout>
-
-</RelativeLayout>
diff --git a/OpenKeychain/src/main/res/menu/api_account_settings.xml b/OpenKeychain/src/main/res/menu/api_account_settings.xml
index d08fc7f42..713345ffc 100644
--- a/OpenKeychain/src/main/res/menu/api_account_settings.xml
+++ b/OpenKeychain/src/main/res/menu/api_account_settings.xml
@@ -6,9 +6,5 @@
android:id="@+id/menu_account_settings_delete"
android:title="@string/api_settings_delete_account"
app:showAsAction="never" />
- <item
- android:id="@+id/menu_account_settings_cancel"
- android:title="@string/api_settings_cancel"
- app:showAsAction="never" />
</menu> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/menu/api_app_settings.xml b/OpenKeychain/src/main/res/menu/api_app_settings.xml
index 1233e4f6e..5ac340550 100644
--- a/OpenKeychain/src/main/res/menu/api_app_settings.xml
+++ b/OpenKeychain/src/main/res/menu/api_app_settings.xml
@@ -3,9 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
- android:id="@+id/menu_api_settings_start"
- android:title="@string/api_settings_start"
- android:icon="@drawable/ic_action_play"
+ android:id="@+id/menu_api_save"
+ android:title="@string/api_settings_save"
app:showAsAction="always" />
<item
@@ -13,4 +12,9 @@
android:title="@string/api_settings_revoke"
app:showAsAction="never" />
+ <item
+ android:id="@+id/menu_api_settings_advanced"
+ android:title="@string/api_settings_advanced"
+ app:showAsAction="never" />
+
</menu> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/menu/key_list.xml b/OpenKeychain/src/main/res/menu/key_list.xml
index 716a426a0..386a9d46e 100644
--- a/OpenKeychain/src/main/res/menu/key_list.xml
+++ b/OpenKeychain/src/main/res/menu/key_list.xml
@@ -5,59 +5,42 @@
<item
android:id="@+id/menu_key_list_search"
android:title="@string/menu_search"
- android:icon="@drawable/ic_action_search"
+ android:icon="@drawable/ic_search_white_24dp"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|always" />
<item
- android:id="@+id/menu_key_list_search_cloud"
- app:showAsAction="always|withText"
- android:icon="@drawable/ic_action_search_cloud"
- android:title="@string/menu_add_keys" />
-
- <item
- android:id="@+id/menu_key_list_add"
- app:showAsAction="always|withText"
- android:icon="@drawable/ic_action_qr_code"
- android:title="@string/import_qr_code_button" />
-
- <item
android:id="@+id/menu_key_list_export"
- app:showAsAction="never"
- android:title="@string/menu_export_all_keys" />
+ android:title="@string/menu_export_all_keys"
+ app:showAsAction="never" />
<item
android:id="@+id/menu_key_list_create"
- app:showAsAction="never"
- android:title="@string/menu_create_key" />
-
- <item
- android:id="@+id/menu_key_list_import_existing_key"
- app:showAsAction="never"
- android:title="@string/menu_import_existing_key" />
+ android:title="@string/menu_create_key"
+ app:showAsAction="never" />
<item
android:id="@+id/menu_key_list_debug_cons"
- app:showAsAction="never"
android:title="Debug / Consolidate"
- android:visible="false" />
+ android:visible="false"
+ app:showAsAction="never" />
<item
android:id="@+id/menu_key_list_debug_read"
- app:showAsAction="never"
android:title="Debug / DB restore"
- android:visible="false" />
+ android:visible="false"
+ app:showAsAction="never" />
<item
android:id="@+id/menu_key_list_debug_write"
- app:showAsAction="never"
android:title="Debug / DB backup"
- android:visible="false" />
+ android:visible="false"
+ app:showAsAction="never" />
<item
android:id="@+id/menu_key_list_debug_first_time"
- app:showAsAction="never"
android:title="Debug / Show first time screen"
- android:visible="false" />
+ android:visible="false"
+ app:showAsAction="never" />
</menu>
diff --git a/OpenKeychain/src/main/res/menu/key_list_multi.xml b/OpenKeychain/src/main/res/menu/key_list_multi.xml
index 3e0f87692..7fdf4a5c1 100644
--- a/OpenKeychain/src/main/res/menu/key_list_multi.xml
+++ b/OpenKeychain/src/main/res/menu/key_list_multi.xml
@@ -4,26 +4,23 @@
<item
android:id="@+id/menu_key_list_multi_encrypt"
- android:icon="@drawable/ic_action_secure"
+ android:icon="@drawable/ic_lock_white_24dp"
android:title="@string/menu_encrypt_to" />
<item
android:id="@+id/menu_key_list_multi_export"
- android:icon="@drawable/ic_action_import_export"
android:showAsAction="never"
tools:ignore="AppCompatResource"
android:title="@string/menu_export_key" />
<item
android:id="@+id/menu_key_list_multi_delete"
- android:icon="@drawable/ic_action_discard"
android:showAsAction="never"
tools:ignore="AppCompatResource"
android:title="@string/menu_delete_key" />
<item
android:id="@+id/menu_key_list_multi_select_all"
- android:icon="@drawable/ic_action_select_all"
android:showAsAction="never"
tools:ignore="AppCompatResource"
android:title="@string/menu_select_all" />
diff --git a/OpenKeychain/src/main/res/menu/key_view.xml b/OpenKeychain/src/main/res/menu/key_view.xml
index 049c7013a..c724c46a5 100644
--- a/OpenKeychain/src/main/res/menu/key_view.xml
+++ b/OpenKeychain/src/main/res/menu/key_view.xml
@@ -3,8 +3,20 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
+ android:id="@+id/menu_key_view_edit"
+ android:icon="@drawable/ic_mode_edit_white_24dp"
+ android:visible="false"
+ app:showAsAction="always"
+ android:title="@string/key_view_action_edit" />
+
+ <item
+ android:id="@+id/menu_key_view_refresh"
+ android:icon="@drawable/ic_refresh_white_24dp"
+ app:showAsAction="always"
+ android:title="@string/key_view_action_update" />
+
+ <item
android:id="@+id/menu_key_view_export_file"
- android:icon="@drawable/ic_action_import_export"
app:showAsAction="never"
android:title="@string/menu_export_key" />
@@ -19,4 +31,10 @@
app:showAsAction="never"
android:title="@string/menu_advanced" />
+ <item
+ android:id="@+id/menu_key_view_certify_fingerprint"
+ app:showAsAction="never"
+ android:visible="false"
+ android:title="@string/menu_certify_fingerprint" />
+
</menu> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/menu/key_view2.xml b/OpenKeychain/src/main/res/menu/key_view2.xml
new file mode 100644
index 000000000..d928bee36
--- /dev/null
+++ b/OpenKeychain/src/main/res/menu/key_view2.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <item
+ android:id="@+id/menu_key_view_refresh"
+ android:icon="@drawable/ic_refresh_white_24dp"
+ app:showAsAction="always"
+ android:title="@string/key_view_action_update" />
+
+</menu> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/raw-bg/help_about.html b/OpenKeychain/src/main/res/raw-bg/help_about.html
new file mode 100644
index 000000000..2c6c5b3c4
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-bg/help_about.html
@@ -0,0 +1,57 @@
+<html>
+<head></head>
+<body>
+<p><a href="http://www.openkeychain.org">http://www.openkeychain.org</a></p>
+<p><a href="http://www.openkeychain.org">OpenKeychain</a> is an OpenPGP implementation for Android.</p>
+<p>License: GPLv3+</p>
+
+<h2>Developers</h2>
+<ul>
+<li>Dominik Schürmann (Maintainer)</li>
+<li>Art O Cathain</li>
+<li>Ash Hughes</li>
+<li>Brian C. Barnes</li>
+<li>Bahtiar 'kalkin' Gadimov</li>
+<li>Daniel Albert</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>'mar-v-in'</li>
+<li>Markus Doits</li>
+<li>Miroojin Bakshi</li>
+<li>Nikhil Peter Raj</li>
+<li>Paul Sarbinowski</li>
+<li>'Senecaso'</li>
+<li>Signe Rüsch</li>
+<li>Sreeram Boyapati</li>
+<li>Thialfihar (APG 1.x)</li>
+<li>Tim Bray</li>
+<li>Vincent Breitmoser</li>
+</ul>
+<h2>Libraries</h2>
+<ul>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Apache License v2)</li>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v7 'appcompat'</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/timbray/KeybaseLib">KeybaseLib</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/JohnPersano/SuperToasts">SuperToasts</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/splitwise/TokenAutoComplete">TokenAutoComplete</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/rtreffer/minidns">MiniDNS</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Apache License v2)</li>
+<li>
+<a href="http://code.google.com/p/zxing/">ZXing</a> (Apache License v2)</li>
+<li>
+<a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11 License)</li>
+<li>
+<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/SafeSlingerProject/exchange-android">SafeSlinger Exchange library</a> (MIT License)</li>
+</ul>
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-bg/help_changelog.html b/OpenKeychain/src/main/res/raw-bg/help_changelog.html
new file mode 100644
index 000000000..0cb7d5210
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-bg/help_changelog.html
@@ -0,0 +1,232 @@
+<html>
+<head></head>
+<body>
+
+<h2>3.1.2</h2>
+<ul>
+<li>Fix key export to files (now for real)</li>
+</ul>
+<h2>3.1.1</h2>
+<ul>
+<li>Fix key export to files (they were written partially)</li>
+<li>Fix crash on Android 2.3</li>
+</ul>
+<h2>3.1</h2>
+<ul>
+<li>Fix crash on Android 5</li>
+<li>New certify screen</li>
+<li>Secure Exchange directly from key list (SafeSlinger library)</li>
+<li>New QR Code program flow</li>
+<li>Redesigned decrypt screen</li>
+<li>New icon usage and colors</li>
+<li>Fix import of secret keys from Symantec Encryption Desktop</li>
+<li>Subkey IDs on Yubikeys are now checked correctly</li>
+</ul>
+<h2>3.0.1</h2>
+<ul>
+<li>Better handling of large key imports</li>
+<li>Improved subkey selection</li>
+</ul>
+<h2>3.0</h2>
+<ul>
+<li>Full support for Yubikey signature generation and decryption!</li>
+<li>Propose installable compatible apps in apps list</li>
+<li>New design for decryption screens</li>
+<li>Many fixes for key import, also fixes stripped keys</li>
+<li>Honor and display key authenticate flags</li>
+<li>User interface to generate custom keys</li>
+<li>Fixing user id revocation certificates</li>
+<li>New cloud search (searches over traditional keyservers and keybase.io)</li>
+<li>Support for stripping keys inside OpenKeychain</li>
+</ul>
+<h2>2.9.2</h2>
+<ul>
+<li>Fix keys broken in 2.9.1</li>
+<li>Yubikey decryption now working via API</li>
+</ul>
+<h2>2.9.1</h2>
+<ul>
+<li>Split encrypt screen into two</li>
+<li>Fix key flags handling (now supporting Mailvelope 0.7 keys)</li>
+<li>Improved passphrase handling</li>
+<li>Key sharing via SafeSlinger</li>
+<li>Yubikey: preference to allow other PINs, currently only signing via the OpenPGP API works, not inside of OpenKeychain</li>
+<li>Fix usage of stripped keys</li>
+<li>SHA256 as default for compatibility</li>
+<li>Intent API has changed, see https://github.com/open-keychain/open-keychain/wiki/Intent-API</li>
+<li>OpenPGP API now handles revoked/expired keys and returns all user ids</li>
+</ul>
+<h2>2.9</h2>
+<ul>
+<li>Fixing crashes introduced in v2.8</li>
+<li>Experimental ECC support</li>
+<li>Experimental Yubikey support (signing-only with imported keys)</li>
+</ul>
+<h2>2.8</h2>
+<ul>
+<li>So many bugs have been fixed in this release that we focus on the main new features</li>
+<li>Key edit: awesome new design, key revocation</li>
+<li>Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records</li>
+<li>New first time screen</li>
+<li>New key creation screen: autocompletion of name and email based on your personal Android accounts</li>
+<li>File encryption: awesome new design, support for encrypting multiple files</li>
+<li>New icons to show status of key (by Brennan Novak)</li>
+<li>Important bug fix: Importing of large key collections from a file is now possible</li>
+<li>Notification showing cached passphrases</li>
+<li>Keys are connected to Android's contacts</li>
+</ul>
+<p>This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar</p>
+
+<h2>2.7</h2>
+<ul>
+<li>Purple! (Dominik, Vincent)</li>
+<li>New key view design (Dominik, Vincent)</li>
+<li>New flat Android buttons (Dominik, Vincent)</li>
+<li>API fixes (Dominik)</li>
+<li>Keybase.io import (Tim Bray)</li>
+</ul>
+<h2>2.6.1</h2>
+<ul>
+<li>Some fixes for regression bugs</li>
+</ul>
+<h2>2.6</h2>
+<ul>
+<li>Key certifications (thanks to Vincent Breitmoser)</li>
+<li>Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)</li>
+<li>New design for signature verification</li>
+<li>Custom key length (thanks to Greg Witczak)</li>
+<li>Fix share-functionality from other apps</li>
+</ul>
+<h2>2.5</h2>
+<ul>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
+<li>Refactored key edit screen (thanks to Ash Hughes)</li>
+<li>New modern design for encrypt/decrypt screens</li>
+<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
+</ul>
+<h2>2.4</h2>
+<p>Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free!
+Besides several small patches, a notable number of patches are made by the following people (in alphabetical order):
+Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.</p>
+<ul>
+<li>New unified key list</li>
+<li>Colorized key fingerprint</li>
+<li>Support for keyserver ports</li>
+<li>Deactivate possibility to generate weak keys</li>
+<li>Much more internal work on the API</li>
+<li>Certify user ids</li>
+<li>Keyserver query based on machine-readable output</li>
+<li>Lock navigation drawer on tablets</li>
+<li>Suggestions for emails on creation of keys</li>
+<li>Search in public key lists</li>
+<li>And much more improvements and fixes…</li>
+</ul>
+<h2>2.3.1</h2>
+<ul>
+<li>Hotfix for crash when upgrading from old versions</li>
+</ul>
+<h2>2.3</h2>
+<ul>
+<li>Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)</li>
+<li>Fix setting expiry dates on keys (thanks to Ash Hughes)</li>
+<li>More internal fixes when editing keys (thanks to Ash Hughes)</li>
+<li>Querying keyservers directly from the import screen</li>
+<li>Fix layout and dialog style on Android 2.2-3.0</li>
+<li>Fix crash on keys with empty user ids</li>
+<li>Fix crash and empty lists when coming back from signing screen</li>
+<li>Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source</li>
+<li>Fix upload of key from signing screen</li>
+</ul>
+<h2>2.2</h2>
+<ul>
+<li>New design with navigation drawer</li>
+<li>New public key list design</li>
+<li>New public key view</li>
+<li>Bug fixes for importing of keys</li>
+<li>Key cross-certification (thanks to Ash Hughes)</li>
+<li>Handle UTF-8 passwords properly (thanks to Ash Hughes)</li>
+<li>First version with new languages (thanks to the contributors on Transifex)</li>
+<li>Sharing of keys via QR Codes fixed and improved</li>
+<li>Package signature verification for API</li>
+</ul>
+<h2>2.1.1</h2>
+<ul>
+<li>API Updates, preparation for K-9 Mail integration</li>
+</ul>
+<h2>2.1</h2>
+<ul>
+<li>Lots of bug fixes</li>
+<li>New API for developers</li>
+<li>PRNG bug fix by Google</li>
+</ul>
+<h2>2.0</h2>
+<ul>
+<li>Complete redesign</li>
+<li>Share public keys via QR codes, NFC beam</li>
+<li>Sign keys</li>
+<li>Upload keys to server</li>
+<li>Fixes import issues</li>
+<li>New AIDL API</li>
+</ul>
+<h2>1.0.8</h2>
+<ul>
+<li>Basic keyserver support</li>
+<li>App2sd</li>
+<li>More choices for passphrase cache: 1, 2, 4, 8, hours</li>
+<li>Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)</li>
+<li>Bugfixes</li>
+<li>Optimizations</li>
+</ul>
+<h2>1.0.7</h2>
+<ul>
+<li>Fixed problem with signature verification of texts with trailing newline</li>
+<li>More options for passphrase cache time to live (20, 40, 60 mins)</li>
+</ul>
+<h2>1.0.6</h2>
+<ul>
+<li>Account adding crash on Froyo fixed</li>
+<li>Secure file deletion</li>
+<li>Option to delete key file after import</li>
+<li>Stream encryption/decryption (gallery, etc.)</li>
+<li>New options (language, force v3 signatures)</li>
+<li>Interface changes</li>
+<li>Bugfixes</li>
+</ul>
+<h2>1.0.5</h2>
+<ul>
+<li>German and Italian translation</li>
+<li>Much smaller package, due to reduced BC sources</li>
+<li>New preferences GUI</li>
+<li>Layout adjustment for localization</li>
+<li>Signature bugfix</li>
+</ul>
+<h2>1.0.4</h2>
+<ul>
+<li>Fixed another crash caused by some SDK bug with query builder</li>
+</ul>
+<h2>1.0.3</h2>
+<ul>
+<li>Fixed crashes during encryption/signing and possibly key export</li>
+</ul>
+<h2>1.0.2</h2>
+<ul>
+<li>Filterable key lists</li>
+<li>Smarter pre-selection of encryption keys</li>
+<li>New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers</li>
+<li>Fixes and additional features (key preselection) for K-9 Mail, new beta build available</li>
+</ul>
+<h2>1.0.1</h2>
+<ul>
+<li>GMail account listing was broken in 1.0.0, fixed again</li>
+</ul>
+<h2>1.0.0</h2>
+<ul>
+<li>K-9 Mail integration, APG supporting beta build of K-9 Mail</li>
+<li>Support of more file managers (including ASTRO)</li>
+<li>Slovenian translation</li>
+<li>New database, much faster, less memory usage</li>
+<li>Defined Intents and content provider for other apps</li>
+<li>Bugfixes</li>
+</ul>
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-bg/help_nfc_beam.html b/OpenKeychain/src/main/res/raw-bg/help_nfc_beam.html
new file mode 100644
index 000000000..966fb554a
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-bg/help_nfc_beam.html
@@ -0,0 +1,12 @@
+<html>
+<head></head>
+<body>
+<h2>How to receive keys</h2>
+<ol>
+<li>Go to your partners keys and open the key you want to share.</li>
+<li>Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.</li>
+<li>After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the your device.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-bg/help_start.html b/OpenKeychain/src/main/res/raw-bg/help_start.html
new file mode 100644
index 000000000..92fd4a92a
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-bg/help_start.html
@@ -0,0 +1,19 @@
+<html>
+<head></head>
+<body>
+<h2>Getting started</h2>
+<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
+
+<h2>I found a bug in OpenKeychain!</h2>
+<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
+
+<h2>Contribute</h2>
+<p>If you want to help us developing OpenKeychain by contributing code <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">follow our small guide on Github</a>.</p>
+
+<h2>Translations</h2>
+<p>Help translating OpenKeychain! Everybody can participate at <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain on Transifex</a>.</p>
+
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-bg/help_wot.html b/OpenKeychain/src/main/res/raw-bg/help_wot.html
new file mode 100644
index 000000000..2a551f79c
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-bg/help_wot.html
@@ -0,0 +1,17 @@
+<html>
+<head></head>
+<body>
+<h2>Web of Trust</h2>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+
+<h2>Support in OpenKeychain</h2>
+<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
+
+<h2>Trust Model</h2>
+<p>Trust evaluation is based on the simple assumption that all keys which have secret keys available are trusted. Public keys which contain at least one user id certified by a trusted key will be marked with a green dot in the key listings. It is not (yet) possible to specify trust levels for certificates of other known public keys.</p>
+
+<h2>Certifying keys</h2>
+<p>Support for key certification is available, and user ids can be certified individually. It is not yet possible to specify the level of trust or create local and other special types of certificates.</p>
+
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-bg/nfc_beam_share.html b/OpenKeychain/src/main/res/raw-bg/nfc_beam_share.html
new file mode 100644
index 000000000..083e055c7
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-bg/nfc_beam_share.html
@@ -0,0 +1,11 @@
+<html>
+<head></head>
+<body>
+<ol>
+<li>Make sure that NFC is turned on in Settings &gt; More &gt; NFC and make sure that Android Beam is also on in the same section.</li>
+<li>Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.</li>
+<li>After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the other person’s device.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-cs/help_changelog.html b/OpenKeychain/src/main/res/raw-cs/help_changelog.html
index f90af31f0..af9e49137 100644
--- a/OpenKeychain/src/main/res/raw-cs/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-cs/help_changelog.html
@@ -14,7 +14,7 @@
<h2>3.1</h2>
<ul>
<li>Fix crash on Android 5</li>
-<li>New certify screen</li>
+<li>Nová obrazovka certifikace</li>
<li>Secure Exchange directly from key list (SafeSlinger library)</li>
<li>New QR Code program flow</li>
<li>Redesigned decrypt screen</li>
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
@@ -110,11 +110,11 @@ Besides several small patches, a notable number of patches are made by the follo
Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.</p>
<ul>
<li>New unified key list</li>
-<li>Colorized key fingerprint</li>
+<li>Obarvit otisk klíÄe</li>
<li>Support for keyserver ports</li>
<li>Deactivate possibility to generate weak keys</li>
<li>Much more internal work on the API</li>
-<li>Certify user ids</li>
+<li>Certifikovat uživatelská ID</li>
<li>Keyserver query based on machine-readable output</li>
<li>Lock navigation drawer on tablets</li>
<li>Suggestions for emails on creation of keys</li>
diff --git a/OpenKeychain/src/main/res/raw-cs/help_start.html b/OpenKeychain/src/main/res/raw-cs/help_start.html
index 58639f43a..5a665ea24 100644
--- a/OpenKeychain/src/main/res/raw-cs/help_start.html
+++ b/OpenKeychain/src/main/res/raw-cs/help_start.html
@@ -4,7 +4,7 @@
<h2>ZaÄínáme</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>Našel jsem chybu v OpenKeychain!</h2>
<p>Nahlašte prosím chybu na <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">bug trackeru OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-cs/help_wot.html b/OpenKeychain/src/main/res/raw-cs/help_wot.html
index 5b8186009..29b4fc420 100644
--- a/OpenKeychain/src/main/res/raw-cs/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-cs/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Síť důvěry</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Podpora v OpenKeychain</h2>
<p>Podpora pro síť důvÄ›ry v OpenKeychain je teprve ve svých zaÄátcích. Tento stav se bude velmi mÄ›nit v dalších verzích aplikace.</p>
diff --git a/OpenKeychain/src/main/res/raw-de/help_changelog.html b/OpenKeychain/src/main/res/raw-de/help_changelog.html
index 0979684ac..aae29a2a6 100644
--- a/OpenKeychain/src/main/res/raw-de/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-de/help_changelog.html
@@ -4,11 +4,11 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>Behoben: Schlüsselexport in Datei (Jetzt wirklich)</li>
</ul>
<h2>3.1.1</h2>
<ul>
-<li>Fix key export to files (they were written partially)</li>
+<li>Behoben: Schlüsselexport in Datei (wurde nur teilweise geschrieben)</li>
<li>Absturz auf Android 2.3 behoben</li>
</ul>
<h2>3.1</h2>
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fehler bei der Entschlüsselung symmetrischer PGP Nachrichten/Dateien behoben</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refaktorisierter Schlüsselbearbeitungsbildschirm (Dank an Ash Hughes)</li>
<li>Neues modernes Design für Verschlüsselungs-/Entschlüsselungs-Bildschirme</li>
<li>OpenPGP API Version 3 (mehrfache API-Konten, interne Fehlerbehebungen, Schlüsselsuche)</li>
diff --git a/OpenKeychain/src/main/res/raw-de/help_start.html b/OpenKeychain/src/main/res/raw-de/help_start.html
index 735961dc9..9d37a4cc6 100644
--- a/OpenKeychain/src/main/res/raw-de/help_start.html
+++ b/OpenKeychain/src/main/res/raw-de/help_start.html
@@ -4,7 +4,7 @@
<h2>Los geht's</h2>
<p>Zuerst wird ein geheimer Schlüssel benötigt. Erstelle einen über das Menü "Keys" oder importiere einen bereits existierenden geheimen Schlüssel. Anschließend kannst du die Schlüssel deiner Freunde herunterladen oder über QR-Codes oder NFC austauschen.</p>
-<p>Auf Android-Geräte mit einer kleineren Versionsnummer als 4.4 wird empfohlen den Datei-Browser <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> zu installieren. Um QR-Codes zu scannen, wird der <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> benötigt. Ein Klick auf die Links öffnet den Google Play Store oder F-Droid, von wo die Programme installiert werden können.</p>
+<p>Auf Android-Geräte mit einer kleineren Versionsnummer als 4.4 wird empfohlen den Datei-Browser <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> zu installieren.</p>
<h2>Ich habe einen Fehler in OpenKeychain gefunden!</h2>
<p>Bitte berichten Sie Bugs mithilfe des <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">Issue Trackers der OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-es/help_changelog.html b/OpenKeychain/src/main/res/raw-es/help_changelog.html
index 1c9680230..e404fecf1 100644
--- a/OpenKeychain/src/main/res/raw-es/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-es/help_changelog.html
@@ -4,7 +4,7 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>Repara la exportación de claves hacia ficheros (ahora de verdad)</li>
</ul>
<h2>3.1.1</h2>
<ul>
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Repara descifrado de mensajes/ficheros pgp simétricos</li>
+<li>Repara el descifrado de ficheros/mensajes OpenPGP simétricos</li>
<li>Pantalla de edición de clave refactorizada (gracias a Ash Hughes)</li>
<li>Nuevo diseño moderno para pantallas de cifrado/descifrado</li>
<li>API de OpenPGP version 3 (múltiples cuentas api, reparaciones internas, búsqueda de clave)</li>
diff --git a/OpenKeychain/src/main/res/raw-es/help_start.html b/OpenKeychain/src/main/res/raw-es/help_start.html
index eb56fe3f4..c3755f014 100644
--- a/OpenKeychain/src/main/res/raw-es/help_start.html
+++ b/OpenKeychain/src/main/res/raw-es/help_start.html
@@ -4,7 +4,7 @@
<h2>Primeros pasos</h2>
<p>Primero, necesita una clave personal. Cree una a través del menú en "Claves" o importe claves secretas (privadas) existentes. Después, puede descargar las claves de sus amigos o intercambiarlas mediante códigos QR o transmisión NFC.</p>
-<p>Sobre un Android inferior a la 4.4, se recomienda que instale <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> para una selección de ficheros mejorada. Para compartir mediante códigos QR instale <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Haga clic en los enlaces para abrir la Google Play Store o F-Droid para instalarlos.</p>
+<p>En Android inferior a 4.4, se recomienda que instale <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> para una selección de ficheros mejorada.</p>
<h2>¡He encontrado un bug en OpenKeychain!</h2>
<p>Por favor, informa de errores usando el <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">seguimiento de incidencias de OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-es/help_wot.html b/OpenKeychain/src/main/res/raw-es/help_wot.html
index b3b65d4b2..3af2cae10 100644
--- a/OpenKeychain/src/main/res/raw-es/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-es/help_wot.html
@@ -1,11 +1,11 @@
<html>
<head></head>
<body>
-<h2>Web of Trust</h2>
-<p>El Web of Trust (web de confianza) describe la parte de PGP que trata con la creación y catalogación de certificaciones. Proporciona mecanismos para ayudar al usuario a llevar un seguimiento de a quién pertenece una clave pública, y comparte esta información con otros. Para asegurar la privacidad de las comunicaciones cifradas, es esencial saber que la clave pública que usted cifra pertenece a la misma persona que usted piensa.</p>
+<h2>Anillo de confianza</h2>
+<p>El anillo de confianza (web of trust) describe la parte de OpenPGP que se encarga de la creación y registro de las certificaciones. Proporciona mecanismos para ayudar al usuario a llevar un seguimiento de a quién pertenece una clave pública, y compartir esta información con otros. Para asegurar la privacidad de la comunicación cifrada, es esencial saber que la clave pública con la que usted la cifra pertenece a la persona que usted cree.</p>
<h2>Soporte en OpenKeychain</h2>
-<p>Sólo hay soporte básico para Web of Trust (web de confianza) en OpenKeychain. Este es un duro trabajo que tenemos en marcha sujeto a cambios en versiones posteriores.</p>
+<p>Sólo hay soporte básico para el anillo de confianza (web of trust) en OpenKeychain. Esta es una pesada tarea que tenemos en marcha sujeta a cambios en versiones posteriores.</p>
<h2>Modelo de confianza</h2>
<p>La evaluación de la confianza está basada en la simple asunción de que todas las claves que tienen disponibles claves privadas (secretas) son de confianza. Las claves públicas que contienen al menos una identificación de usuario certificada por una clave de confianza serán marcadas con un punto verde en los listados de claves. No es posible (aún) especificar niveles de confianza para certificados de otras claves públicas conocidas.</p>
diff --git a/OpenKeychain/src/main/res/raw-et/help_changelog.html b/OpenKeychain/src/main/res/raw-et/help_changelog.html
index 4d3d293ac..0cb7d5210 100644
--- a/OpenKeychain/src/main/res/raw-et/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-et/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-et/help_start.html b/OpenKeychain/src/main/res/raw-et/help_start.html
index 4f029ab37..92fd4a92a 100644
--- a/OpenKeychain/src/main/res/raw-et/help_start.html
+++ b/OpenKeychain/src/main/res/raw-et/help_start.html
@@ -4,7 +4,7 @@
<h2>Getting started</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>I found a bug in OpenKeychain!</h2>
<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-et/help_wot.html b/OpenKeychain/src/main/res/raw-et/help_wot.html
index 29790139b..2a551f79c 100644
--- a/OpenKeychain/src/main/res/raw-et/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-et/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Web of Trust</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Support in OpenKeychain</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
diff --git a/OpenKeychain/src/main/res/raw-fi/help_changelog.html b/OpenKeychain/src/main/res/raw-fi/help_changelog.html
index 4d3d293ac..0cb7d5210 100644
--- a/OpenKeychain/src/main/res/raw-fi/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-fi/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-fi/help_start.html b/OpenKeychain/src/main/res/raw-fi/help_start.html
index 4f029ab37..92fd4a92a 100644
--- a/OpenKeychain/src/main/res/raw-fi/help_start.html
+++ b/OpenKeychain/src/main/res/raw-fi/help_start.html
@@ -4,7 +4,7 @@
<h2>Getting started</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>I found a bug in OpenKeychain!</h2>
<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-fi/help_wot.html b/OpenKeychain/src/main/res/raw-fi/help_wot.html
index 29790139b..2a551f79c 100644
--- a/OpenKeychain/src/main/res/raw-fi/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-fi/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Web of Trust</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Support in OpenKeychain</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
diff --git a/OpenKeychain/src/main/res/raw-fr/help_changelog.html b/OpenKeychain/src/main/res/raw-fr/help_changelog.html
index da2d7eada..97b42c6a6 100644
--- a/OpenKeychain/src/main/res/raw-fr/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-fr/help_changelog.html
@@ -4,7 +4,7 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>Correctif - Exportation des clefs vers des fichiers (vraiment, maintenant)</li>
</ul>
<h2>3.1.1</h2>
<ul>
@@ -54,7 +54,7 @@
<li>Correctif - Utilisation de clefs dépouillées</li>
<li>SHA256 par défaut pour la compatibilité</li>
<li>L'API des intentions a changé, voir https://github.com/open-keychain/open-keychain/wiki/Intent-API</li>
-<li>L'API d'OpenPGP gère maintenant les clefs révoquées/expirées et retourne tous les ID d'utilisateurs</li>
+<li>L'API d'OpenPGP gère maintenant les clefs révoquées/expirées et retourne tous les ID utilisateurs</li>
</ul>
<h2>2.9</h2>
<ul>
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Correctif -Déchiffrement de messages/fichiers pgp symétriques</li>
+<li>Correctif - Déchiffrement des messages/fichiers symétriques OpenPGP</li>
<li>Écran de modification des clefs remanié (merci à Ash Hughes)</li>
<li>Nouvelle conception moderne pour les écrans de chiffrement/déchiffrement</li>
<li>API OpenPGP version 3 (comptes multiples d'api, correctifs internes, recherche de clefs)</li>
@@ -114,7 +114,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
<li>Prise en charge des ports des serveurs de clefs</li>
<li>Désactiver la possibilité de générer des clefs faibles</li>
<li>Encore plus de travail interne dans l'API</li>
-<li>Certifier les ID d'utilisateurs</li>
+<li>Certifier les ID utilisateurs</li>
<li>Requêtes des serveurs de clefs basées sur des sorties assimilables par la machine</li>
<li>Verrouiller les tiroirs de navigation sur les tablettes</li>
<li>Suggestion de courriels à la création de clefs</li>
@@ -132,7 +132,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
<li>Plus de correctifs internes affectant la modifications des clefs (merci à Ash hughes)</li>
<li>Interrogation des serveurs de clefs directement depuis l'écran d'importation</li>
<li>Correctif - Mise en page et du style des fenêtres de dialogue sur Android 2.2-3.0</li>
-<li>Correctif - Plantage pour les clefs avec des ID d'utilisateur vides</li>
+<li>Correctif - Plantage pour les clefs avec des ID utilisateur vides</li>
<li>Correctif - Plantage et listes vides en revenant de l'écran de signature</li>
<li>Bouncy Castle (bibliothèque cryptographique) mise à jour de 1.47 à 1.50 et compilée depuis la source</li>
<li>Correctif - Téléversement d'une clef depuis l'écran de signature</li>
@@ -213,7 +213,7 @@ Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Pa
<li>Listes de clefs filtrables</li>
<li>Présélection plus intelligente des clefs de chiffrement</li>
<li>Nouvelle gestion des intentions pour VIEW et SEND, permet le chiffrement/déchiffrement des fichiers depuis les gestionnaires de fichiers</li>
-<li>Correctifs et fonctions additionnelles (présélection des clefs) pour K-9-Mail, nouvelle version bêta disponible</li>
+<li>Correctifs et fonctions additionnelles (présélection des clefs) pour K-9-Mail, nouvelle version bêta proposée</li>
</ul>
<h2>1.0.1</h2>
<ul>
diff --git a/OpenKeychain/src/main/res/raw-fr/help_start.html b/OpenKeychain/src/main/res/raw-fr/help_start.html
index 5440125ea..030a429e0 100644
--- a/OpenKeychain/src/main/res/raw-fr/help_start.html
+++ b/OpenKeychain/src/main/res/raw-fr/help_start.html
@@ -4,7 +4,7 @@
<h2>Commencer</h2>
<p>Vous avez d'abord besoin d'une clef personnelle. Créez-en une avec l'option du menu « Clefs » ou importez des clefs secrètes existantes. Ensuite vous pourrez télécharger les clefs de vos amis, ou les échanger par codes QR ou NFC.</p>
-<p>Sur les versions d'Android antérieures à 4.4, il vous est recommandé d'installer le<a href="market://details?id=org.openintents.filemanager">gestionnaire de fichiers OI</a> pour une sélection améliorée des fichiers. Pour le partage par codes QR, installez le <a href="market://details?id=com.google.zxing.client.android">lecteur de codes à barres</a>. Cliquer sur les liens ouvrira Google Play Store ou F-Droid pour l'installation</p>
+<p>Sur les versions d'Android antérieures à 4.4, il vous est recommandé d'installer le<a href="market://details?id=org.openintents.filemanager">gestionnaire de fichiers OI</a> pour une sélection améliorée des fichiers.</p>
<h2>J'ai trouvé un bogue dans OpenKeychain !</h2>
<p>Veuillez rapporter le bogue en utilisant le <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">gestionnaire de bogue d'OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-fr/help_wot.html b/OpenKeychain/src/main/res/raw-fr/help_wot.html
index c15e6eefd..6763b8969 100644
--- a/OpenKeychain/src/main/res/raw-fr/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-fr/help_wot.html
@@ -1,17 +1,17 @@
<html>
<head></head>
<body>
-<h2>Toile confiance</h2>
-<p>La toile de confiance décrit la partie de PGP qui s'occupe de la création et du suivi des certifications. Elle fournit des mécanismes pour aider l'utilisateur à suivre à qui appartient une clef publique, et partager cette information avec les autres. Pour assurer la confidentialité d'une communication chiffrée, il est essentiel de savoir que la clef publique vers laquelle vous chiffrez appartient à la personne à qui vous croyez qu'elle appartient.</p>
+<h2>Toile de confiance</h2>
+<p>La toile de confiance décrit la partie d'OpenPGP qui s'occupe de la création et du suivi des certifications. Elle fournit des mécanismes pour aider l'utilisateur à suivre à qui appartient une clef publique, et partager cette information avec d'autres. Pour assurer la confidentialité d'une communication chiffrée, il est essentiel de savoir que la clef publique vers laquelle vous chiffrez appartient à la personne à qui vous croyez qu'elle appartient.</p>
<h2>Prise en charge dans OpenKeychain</h2>
<p>OpenKeychain offre seulement une prise en charge de base de la toile de confiance. Un travail important est en cours et ceci pourrait changer dans les versions à venir.</p>
<h2>Modèle de confiance</h2>
-<p>L'évaluation de la confiance est fondée sur la simple supposition que toutes les clefs ayant des clefs secrètes disponibles sont de confiance. Les clefs publiques contenant au moins un ID d'utilisateur certifié par une clef de confiance seront marquées par un point vert dans le listage des clefs. Il n'est pas (encore) possible de spécifier les niveaux de confiance pour les certificats d'autres clefs publiques inconnues.</p>
+<p>L'évaluation de la confiance est fondée sur la simple supposition que toutes les clefs proposant des clefs secrètes sont de confiance. Les clefs publiques contenant au moins un ID utilisateur certifié par une clef de confiance seront marquées par un point vert dans le listage des clefs. Il n'est pas (encore) possible de spécifier les niveaux de confiance pour les certificats d'autres clefs publiques inconnues.</p>
<h2>Certifications des clefs</h2>
-<p>La prise en charge de la certification des clefs est disponible et les ID d'utilisateurs peuvent être certifiées individuellement. Il n'est pas encore possible de spécifier le niveau de confiance ou de créer des certificats locaux et d'autres types spéciaux.</p>
+<p>La prise en charge de la certification des clefs est proposée et les ID utilisateurs peuvent être certifiées individuellement. Il n'est pas encore possible de spécifier le niveau de confiance ou de créer des certificats locaux et d'autres types spéciaux.</p>
</body>
</html>
diff --git a/OpenKeychain/src/main/res/raw-is/help_changelog.html b/OpenKeychain/src/main/res/raw-is/help_changelog.html
index 4d3d293ac..0cb7d5210 100644
--- a/OpenKeychain/src/main/res/raw-is/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-is/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-is/help_start.html b/OpenKeychain/src/main/res/raw-is/help_start.html
index 4f029ab37..92fd4a92a 100644
--- a/OpenKeychain/src/main/res/raw-is/help_start.html
+++ b/OpenKeychain/src/main/res/raw-is/help_start.html
@@ -4,7 +4,7 @@
<h2>Getting started</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>I found a bug in OpenKeychain!</h2>
<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-is/help_wot.html b/OpenKeychain/src/main/res/raw-is/help_wot.html
index 29790139b..2a551f79c 100644
--- a/OpenKeychain/src/main/res/raw-is/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-is/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Web of Trust</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Support in OpenKeychain</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
diff --git a/OpenKeychain/src/main/res/raw-it/help_changelog.html b/OpenKeychain/src/main/res/raw-it/help_changelog.html
index f56362c11..bbb765bc3 100644
--- a/OpenKeychain/src/main/res/raw-it/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-it/help_changelog.html
@@ -4,23 +4,23 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>Corretta esportazione chiavi su file (ora per davvero)</li>
</ul>
<h2>3.1.1</h2>
<ul>
-<li>Fix key export to files (they were written partially)</li>
-<li>Fix crash on Android 2.3</li>
+<li>Corretta esportazione chiavi su file (la scrittura era parziale)</li>
+<li>Corretto crash su Android 2.3</li>
</ul>
<h2>3.1</h2>
<ul>
-<li>Fix crash on Android 5</li>
-<li>New certify screen</li>
-<li>Secure Exchange directly from key list (SafeSlinger library)</li>
-<li>New QR Code program flow</li>
-<li>Redesigned decrypt screen</li>
-<li>New icon usage and colors</li>
-<li>Fix import of secret keys from Symantec Encryption Desktop</li>
-<li>Subkey IDs on Yubikeys are now checked correctly</li>
+<li>Corretto crash su Android 5</li>
+<li>Nuova schermata di certificazione</li>
+<li>Scambio sicuro direttamente dalla lista delle chiavi (libreria SafeSlinger)</li>
+<li>Nuovo programma di flusso QR Code</li>
+<li>Schermata di decodifica ridisegnata</li>
+<li>Nuove icone e colori</li>
+<li>Corretta importazione di chiavi segrete da Symantec Encryption Desktop</li>
+<li>ID delle sottochiavi Yubikey sono controllati correttamente</li>
</ul>
<h2>3.0.1</h2>
<ul>
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Corretta la decodifica di messaggi PGP / file simmetrici</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactoring della schermata di modifica chiave (grazie a Ash Hughes)</li>
<li>Nuovo design moderno per le schermate di codifica / decodifica</li>
<li>OpenPGP API versione 3 (api account multipli, correzioni interne, ricerca chiavi)</li>
diff --git a/OpenKeychain/src/main/res/raw-it/help_start.html b/OpenKeychain/src/main/res/raw-it/help_start.html
index e75b209ff..ecf52eadd 100644
--- a/OpenKeychain/src/main/res/raw-it/help_start.html
+++ b/OpenKeychain/src/main/res/raw-it/help_start.html
@@ -4,7 +4,7 @@
<h2>Per iniziare</h2>
<p>In primo luogo è necessaria una chiave segreta personale. Creane una tramite il menu opzioni sotto la voce "Chiavi" o importa chiavi segrete già esistenti. Successivamente, è possibile scaricare le chiavi dei vostri amici o scambiarle con i codici QR o NFC.</p>
-<p>In Android precedente 4.4, si raccomanda di installare <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> per una migliore selezione dei file. Per condividere via Codici QR <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. I collegamenti verranno aperti in Google Play Store o F-Droid per l'installazione.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>Ho trovato un bug in OpenKeychain!</h2>
<p>Per favore riporta i bug usando il <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker di OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-it/help_wot.html b/OpenKeychain/src/main/res/raw-it/help_wot.html
index 98e3aafea..09b38199b 100644
--- a/OpenKeychain/src/main/res/raw-it/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-it/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Rete di Fiducia</h2>
-<p>La Rete di Fiducia descrive la parte del PGP che si occupa di creazione e gestione delle certificazioni. Essa fornisce meccanismi per aiutare l'utente a tenere traccia di chi appartiene una chiave pubblica, e condividere queste informazioni con gli altri; Per garantire la privacy della comunicazione crittografata, è essenziale sapere che la chiave pubblica per crittografare appartiene alla persona che si pensa.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Supporto in OpenKeychain</h2>
<p>Esiste solo un supporto di base per le Reti di Fiducia in OpenKeychain. Questo è un grosso lavoro in corso e soggetto a modifiche nei prossimi rilasci.</p>
diff --git a/OpenKeychain/src/main/res/raw-ja/help_changelog.html b/OpenKeychain/src/main/res/raw-ja/help_changelog.html
index c682d870b..f6ceaa427 100644
--- a/OpenKeychain/src/main/res/raw-ja/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-ja/help_changelog.html
@@ -4,11 +4,11 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>éµã®ãƒ•ã‚¡ã‚¤ãƒ«ã¸ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã®ä¿®æ­£ (ç¾å®Ÿçš„ã«ãªã‚Šã¾ã—ãŸ)</li>
</ul>
<h2>3.1.1</h2>
<ul>
-<li>éµã®ãƒ•ã‚¡ã‚¤ãƒ«ã¸ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã®ä¿®æ­£ (ç§ãŸã¡ã¯éƒ¨åˆ†çš„ã«ä½œæˆ)</li>
+<li>éµã®ãƒ•ã‚¡ã‚¤ãƒ«ã¸ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã®ä¿®æ­£ (部分的ã«ä¿®æ­£)</li>
<li>Android 2.3ã§ã®ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ä¿®æ­£</li>
</ul>
<h2>3.1</h2>
@@ -106,7 +106,7 @@
</ul>
<h2>2.4</h2>
<p>ã“ã®ãƒªãƒªãƒ¼ã‚¹ã«ãŠã„ã¦é©ç”¨ã—ãŸãƒªãƒƒãƒã§ãƒã‚°ã®ãªã„機能を作ã£ã¦ãã‚ŒãŸGoogle Summer of Code 2014ã®å‚加者ãŸã¡ã«æ„Ÿè¬ã‚’!
-ã¾ãŸã€ä»¥ä¸‹ã®äººé”(アルファベット順)ã®ä½œã£ã¦ãã‚ŒãŸã„ãã¤ã‚‚ã®ã®ã•ãªãƒ‘ッãƒã‚„相当数ã®ãƒ‘ッãƒã«ã‚‚:
+ã¾ãŸã€ä»¥ä¸‹ã®äººé”(アルファベット順)ã®ä½œã£ã¦ãã‚ŒãŸã„ãã¤ã‚‚ã®å°ã•ãªãƒ‘ッãƒã‚„相当数ã®ãƒ‘ッãƒã«ã‚‚:
Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.</p>
<ul>
<li>æ–°ã—ã„çµ±åˆã‚­ãƒ¼ãƒªã‚¹ãƒˆ</li>
diff --git a/OpenKeychain/src/main/res/raw-ja/help_start.html b/OpenKeychain/src/main/res/raw-ja/help_start.html
index db9841568..d9f73428a 100644
--- a/OpenKeychain/src/main/res/raw-ja/help_start.html
+++ b/OpenKeychain/src/main/res/raw-ja/help_start.html
@@ -4,7 +4,7 @@
<h2>入門</h2>
<p>最åˆã«ã‚ãªãŸã®å€‹äººç”¨éµãƒšã‚¢ãŒå¿…è¦ã«ãªã‚Šã¾ã™ã€‚メニューã®"éµ"ã§ç”Ÿæˆã™ã‚‹ã‹ã€æ—¢å­˜ã®éµãƒšã‚¢ã‚’インãƒãƒ¼ãƒˆã—ã¾ã™ã€‚ãã®å¾Œã€ã‚ãªãŸã®å‹äººã®éµã‚’ダウンロードã€ã‚‚ã—ãã¯QRコードやNFCã§äº¤æ›ã—ã¾ã™ã€‚</p>
-<p>Android 4.4 以下ã®å ´åˆã€æ‹¡å¼µã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã®é¸æŠžã®ãŸã‚ã«ã¯<a href="market://details?id=org.openintents.filemanager">OI File Manager</a>ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’推奨ã—ã¾ã™ã€‚QRコードã®å…±æœ‰ã«ã¯<a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>ã§ã™ã€‚ã“ã®ãƒªãƒ³ã‚¯ã‚’クリックã™ã‚‹ã¨ Google Play ストア㋠F-Droid ãŒé–‹ãã¾ã™ã€‚</p>
+<p>Android 4.4 未満ã®å ´åˆã€æ‹¡å¼µã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã®é¸æŠžã®ãŸã‚ã«ã¯<a href="market://details?id=org.openintents.filemanager">OI File Manager</a>ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’推奨ã—ã¾ã™ã€‚</p>
<h2>OpenKeychainã§ãƒã‚°ã‚’見付ã‘ãŸ!</h2>
<p><a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">OpenKeychainã®Issueトラッカー</a>を使ã£ã¦ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã‚’é€ã£ã¦ãã ã•ã„。</p>
diff --git a/OpenKeychain/src/main/res/raw-ja/help_wot.html b/OpenKeychain/src/main/res/raw-ja/help_wot.html
index 01b523d76..e4db99bb8 100644
--- a/OpenKeychain/src/main/res/raw-ja/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-ja/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>ä¿¡é ¼ã®è¼ª</h2>
-<p>ä¿¡é ¼ã®è¼ªã¯PGPãŒè¨¼æ˜Žã®ä½œæˆã¨ç¶­æŒã™ã‚‹ä¸€é¢ã‚’説明ã—ã¾ã™ã€‚ユーザãŒå…¬é–‹éµãŒå±žã™ã‚‹è€…ã®è¿½è·¡ã‚’維æŒã—ã€ä»–ã®ãƒ¦ãƒ¼ã‚¶ã¨ãã®æƒ…報を共有ã™ã‚‹æ‰‹åŠ©ã‘ã«ãªã‚‹ãƒ¡ã‚«ãƒ‹ã‚ºãƒ ã‚’æä¾›ã—ã¾ã™ã€‚æš—å·åŒ–通信ã®ãƒ—ライãƒã‚·ãƒ¼ã‚’確ä¿ã™ã‚‹ãŸã‚ã«ã¯ã€ã‚ãªãŸãŒæš—å·åŒ–ã—ãŸã„ã¨ã„ã†ç›¸æ‰‹ã®å…¬é–‹éµãŒå¿…è¦ãªè¦ç´ ã¨ãªã‚Šã¾ã™</p>
+<p>ä¿¡é ¼ã®è¼ªã¯OpenPGPã®ä¸€é¢ã§è¨¼æ˜Žã®ä½œæˆã¨ãã®ç¶­æŒã®ä¸€é¢ã‚’説明ã—ã¾ã™ã€‚ユーザãŒå…¬é–‹éµã«å±žã™ã‚‹è€…ã®è¿½è·¡ã‚’維æŒã—ã€ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨ãã®æƒ…報を共有ã™ã‚‹æ‰‹åŠ©ã‘ã«ãªã‚‹ãƒ¡ã‚«ãƒ‹ã‚ºãƒ ã‚’æä¾›ã—ã¾ã™ã€‚æš—å·åŒ–通信ã®ãƒ—ライãƒã‚·ãƒ¼ã‚’確ä¿ã™ã‚‹ãŸã‚ã«ã¯ã€ã‚ãªãŸãŒæš—å·åŒ–ã—ãŸã„ã¨ã„ã†ç›¸æ‰‹ã®å…¬é–‹éµãŒå¿…è¦ãªè¦ç´ ã¨ãªã‚Šã¾ã™ã€‚</p>
<h2>OpenKeychainã§ã‚µãƒãƒ¼ãƒˆ</h2>
<p>OpenKeychainã§ä¿¡é ¼ã®è¼ªã®åŸºæœ¬ã®ã¿ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¾ã™ã€‚ã¨ã¦ã‚‚é‡ã„作業を進ã‚ã¦ãŠã‚Šä»Šå¾Œã‚„ã£ã¦ãるリリースã«ãŠã„ã¦çŠ¶æ…‹ãŒå¤‰æ›´ã•ã‚Œã¦ã„ãã¾ã™ã€‚</p>
@@ -11,7 +11,7 @@
<p>ä¿¡é ¼ã®è©•ä¾¡ã¯ã‚·ãƒ³ãƒ—ルãªä»®å®šã«åŸºã¥ã„ã¦ã„ã¾ã™ã€ãã‚Œã¯ã™ã¹ã¦ã®éµã¯ç§˜å¯†éµãŒä¿¡é ¼ã§ãã‚‹ã¨ã„ã†ã‚‚ã®ã§ã™ã€‚公開éµã¯ä¿¡é ¼ã•ã‚ŒãŸéµã§æ¤œè¨¼ã•ã‚ŒãŸæœ€ä½Ž1ã¤ã®ãƒ¦ãƒ¼ã‚¶IDã‚’å«ã‚“ã§ãŠã‚Šã€ãã‚Œã¯éµãƒªã‚¹ãƒˆã«ãŠã„ã¦ã€ç·‘ã§ãƒžãƒ¼ã‚¯ã•ã‚Œã¾ã™ã€‚ãŸã ã—ãã‚Œã¯ä»–ã®æ—¢çŸ¥ã®å…¬é–‹éµã®ä¿¡é ¼ãƒ¬ãƒ™ãƒ«ã‚’特別ãªã‚‚ã®ã«ã¯(ã¾ã )ã—ã¾ã›ã‚“。</p>
<h2>éµã®æ¤œè¨¼</h2>
-<p>éµæ¤œè¨¼ã®ã‚µãƒãƒ¼ãƒˆãŒæä¾›ã•ã‚Œã¦ãŠã‚Šã€ãƒ¦ãƒ¼ã‚¶IDã¯å€‹åˆ¥ã«æ¤œè¨¼ã§ãã¾ã™ã€‚ãŸã ã—ãã‚Œã¯ä»–ã®æ—¢çŸ¥ã®å…¬é–‹éµã®ä¿¡é ¼ãƒ¬ãƒ™ãƒ«ã‚’特別ãªã‚‚ã®ã«ã¯ã¾ã ã—ãªã„ã‹ä»–ã®ç‰¹åˆ¥ãªã‚¿ã‚¤ãƒ—ã®è¨¼æ˜Žã§ã™ã€‚</p>
+<p>éµæ¤œè¨¼ã®ã‚µãƒãƒ¼ãƒˆãŒæä¾›ã•ã‚Œã¦ãŠã‚Šã€ã¾ãŸãƒ¦ãƒ¼ã‚¶IDã¯å€‹åˆ¥ã«æ¤œè¨¼ã§ãã¾ã™ã€‚ãŸã ã—ãã‚Œã¯ä»–ã®æ—¢çŸ¥ã®å…¬é–‹éµã®ä¿¡é ¼ãƒ¬ãƒ™ãƒ«ã‚’特別ãªã‚‚ã®ã«ã¯ã—ãªã„ローカルもã—ãã¯ä»–ã®ç‰¹åˆ¥ãªã‚¿ã‚¤ãƒ—ã®è¨¼æ˜Žã§ã™ã€‚</p>
</body>
</html>
diff --git a/OpenKeychain/src/main/res/raw-nl/help_about.html b/OpenKeychain/src/main/res/raw-nl/help_about.html
index 0bc9f6f70..33622b7c5 100644
--- a/OpenKeychain/src/main/res/raw-nl/help_about.html
+++ b/OpenKeychain/src/main/res/raw-nl/help_about.html
@@ -5,9 +5,9 @@
<p><a href="http://www.openkeychain.org">OpenKeychain</a> is een OpenPGP implementatie voor Android.</p>
<p>Licentie: GPLv3+</p>
-<h2>Developers</h2>
+<h2>Ontwikkelaars</h2>
<ul>
-<li>Dominik Schürmann (Maintainer)</li>
+<li>Dominik Schürmann (beheerder)</li>
<li>Art O Cathain</li>
<li>Ash Hughes</li>
<li>Brian C. Barnes</li>
@@ -35,13 +35,13 @@
<li>
<a href="http://developer.android.com/tools/support-library/index.html">Android Support Bibliotheek v7 'appcompat'</a> (Apache Licentie v2)</li>
<li>
-<a href="https://github.com/timbray/KeybaseLib">KeybaseLib</a> (Apache License v2)</li>
+<a href="https://github.com/timbray/KeybaseLib">KeybaseLib</a> (Apache-licentie v2)</li>
<li>
-<a href="https://github.com/JohnPersano/SuperToasts">SuperToasts</a> (Apache License v2)</li>
+<a href="https://github.com/JohnPersano/SuperToasts">SuperToasts</a> (Apache-licentie v2)</li>
<li>
-<a href="https://github.com/splitwise/TokenAutoComplete">TokenAutoComplete</a> (Apache License v2)</li>
+<a href="https://github.com/splitwise/TokenAutoComplete">TokenAutoComplete</a> (Apache-licentie v2)</li>
<li>
-<a href="https://github.com/rtreffer/minidns">MiniDNS</a> (Apache License v2)</li>
+<a href="https://github.com/rtreffer/minidns">MiniDNS</a> (Apache-licentie v2)</li>
<li>
<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Apache Licentie v2)</li>
<li>
@@ -51,7 +51,7 @@
<li>
<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache Licentie v2)</li>
<li>
-<a href="https://github.com/SafeSlingerProject/exchange-android">SafeSlinger Exchange library</a> (MIT License)</li>
+<a href="https://github.com/SafeSlingerProject/exchange-android">SafeSlinger Exchange library</a> (MIT-licentie)</li>
</ul>
</body>
</html>
diff --git a/OpenKeychain/src/main/res/raw-nl/help_changelog.html b/OpenKeychain/src/main/res/raw-nl/help_changelog.html
index 4d3d293ac..809ffa6e6 100644
--- a/OpenKeychain/src/main/res/raw-nl/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-nl/help_changelog.html
@@ -4,228 +4,228 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>Oplossing voor exporteren van sleutels naar bestanden (deze keer echt)</li>
</ul>
<h2>3.1.1</h2>
<ul>
-<li>Fix key export to files (they were written partially)</li>
-<li>Fix crash on Android 2.3</li>
+<li>Oplossing voor exporteren van sleutels naar bestanden (ze werden maar gedeeltelijk geschreven)</li>
+<li>Oplossing voor crash op Android 2.3</li>
</ul>
<h2>3.1</h2>
<ul>
-<li>Fix crash on Android 5</li>
-<li>New certify screen</li>
-<li>Secure Exchange directly from key list (SafeSlinger library)</li>
-<li>New QR Code program flow</li>
-<li>Redesigned decrypt screen</li>
-<li>New icon usage and colors</li>
-<li>Fix import of secret keys from Symantec Encryption Desktop</li>
-<li>Subkey IDs on Yubikeys are now checked correctly</li>
+<li>Oplossing voor crash op Android 5</li>
+<li>Nieuw certificeerscherm</li>
+<li>Veilig uitwisselen vanuit sleutellijst (SafeSlinger bibliotheek)</li>
+<li>Nieuwe QR code programma flow</li>
+<li>Nieuw design voor ontcijferingsscherm</li>
+<li>Nieuw icoon en kleuren</li>
+<li>Oplossing voor importeren van geheime sleutels van Symantec Encryption Desktop</li>
+<li>Subsleutel-ID's op Yubikeys worden nu currect gecontroleerd</li>
</ul>
<h2>3.0.1</h2>
<ul>
-<li>Better handling of large key imports</li>
-<li>Improved subkey selection</li>
+<li>Grote sleutelimportaties worden beter behandeld</li>
+<li>Subsleutelselectie verbeterd</li>
</ul>
<h2>3.0</h2>
<ul>
-<li>Full support for Yubikey signature generation and decryption!</li>
-<li>Propose installable compatible apps in apps list</li>
-<li>New design for decryption screens</li>
-<li>Many fixes for key import, also fixes stripped keys</li>
-<li>Honor and display key authenticate flags</li>
-<li>User interface to generate custom keys</li>
-<li>Fixing user id revocation certificates</li>
-<li>New cloud search (searches over traditional keyservers and keybase.io)</li>
-<li>Support for stripping keys inside OpenKeychain</li>
+<li>Volledige ondersteuning voor Yubikey ondertekeningsgeneratie en ontcijfering!</li>
+<li>Stel installeerbare compatibele apps voor in apps-lijst</li>
+<li>Nieuw design voor ontcijferingsschermen</li>
+<li>Veel oplossingen voor sleutelimporteren, lost ook gestripte sleutels op</li>
+<li>Eer en toon sleutelauthenticatievlaggen</li>
+<li>Gebruikersinterface om eigen sleutels aan te maken</li>
+<li>Oplossing voor gebruikers-ID-intrekkingscertificaten</li>
+<li>Nieuwe cloud search (zoekt op traditionele sleutelservers en keybase.io)</li>
+<li>Ondersteuning voor strippen van sleutels in OpenKeychain</li>
</ul>
<h2>2.9.2</h2>
<ul>
-<li>Fix keys broken in 2.9.1</li>
-<li>Yubikey decryption now working via API</li>
+<li>Oplossing voor gebroken sleutels in 2.9.1</li>
+<li>Yubikey ontsleuteling werkt nu via API</li>
</ul>
<h2>2.9.1</h2>
<ul>
-<li>Split encrypt screen into two</li>
-<li>Fix key flags handling (now supporting Mailvelope 0.7 keys)</li>
-<li>Improved passphrase handling</li>
-<li>Key sharing via SafeSlinger</li>
-<li>Yubikey: preference to allow other PINs, currently only signing via the OpenPGP API works, not inside of OpenKeychain</li>
-<li>Fix usage of stripped keys</li>
-<li>SHA256 as default for compatibility</li>
-<li>Intent API has changed, see https://github.com/open-keychain/open-keychain/wiki/Intent-API</li>
-<li>OpenPGP API now handles revoked/expired keys and returns all user ids</li>
+<li>Deel versleutelingsscherm in twee</li>
+<li>Oplossing voor sleutelvlaggen (ondersteunt nu Mailvelope 0.7 sleutels)</li>
+<li>Verbeterde behandeling van wachtwoorden</li>
+<li>Sleutels delen via SafeSlinger</li>
+<li>Yubikey: optie om andere PINs toe te staan, momenteel werkt enkel ondertekenen via de OpenPGP API, niet in OpenKeychain zelf</li>
+<li>Oplossing voor gestripte sleutels</li>
+<li>SHA256 als standaard voor compatibiliteit</li>
+<li>Intent API is veranderd, zie https://github.com/open-keychain/open-keychain/wiki/Intent-API</li>
+<li>OpenPGP API behandelt nu ingetrokken/verlopen sleutels en geeft alle gebruikers-ID's weer</li>
</ul>
<h2>2.9</h2>
<ul>
-<li>Fixing crashes introduced in v2.8</li>
-<li>Experimental ECC support</li>
-<li>Experimental Yubikey support (signing-only with imported keys)</li>
+<li>Oplossing voor crashes geïntroduceerd in v2.8</li>
+<li>Experimentele ondersteuning voor ECC</li>
+<li>Experimentele ondersteuning voor Yubikey (alleen ondertekenen met geïmporteerde sleutels)</li>
</ul>
<h2>2.8</h2>
<ul>
-<li>So many bugs have been fixed in this release that we focus on the main new features</li>
-<li>Key edit: awesome new design, key revocation</li>
-<li>Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records</li>
-<li>New first time screen</li>
-<li>New key creation screen: autocompletion of name and email based on your personal Android accounts</li>
-<li>File encryption: awesome new design, support for encrypting multiple files</li>
-<li>New icons to show status of key (by Brennan Novak)</li>
-<li>Important bug fix: Importing of large key collections from a file is now possible</li>
-<li>Notification showing cached passphrases</li>
-<li>Keys are connected to Android's contacts</li>
-</ul>
-<p>This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar</p>
+<li>Er zijn zoveel bugs opgelost in deze release dat we kunnen focussen op de belangrijke nieuwe mogelijkheden</li>
+<li>Sleutels wijzigen: nieuw design, sleutels intrekken</li>
+<li>Sleutels importeren: nieuw design, veilige verbindingen met sleutelservers via hkps, sleutelserver resolving via DNS SRV records</li>
+<li>Nieuw eerste gebruiksscherm</li>
+<li>Nieuw scherm voor sleutels aanmaken: automatisch aanvullen van naam en e-mailadres gebaseerd op persoonlijke Android-accounts</li>
+<li>Bestandsversleuteling: nieuw design, ondersteuning voor versleutelen van meerdere bestanden</li>
+<li>Nieuwe iconen om sleutelstatus weer te geven (door Brennan Novak)</li>
+<li>Belangrijke bugfix: importeren van grote sleutelbossen uit een bestand is nu mogelijk</li>
+<li>Melding om gecachete wachtwoorden weer te geven</li>
+<li>Sleutels worden verbonden aan Android's contacten</li>
+</ul>
+<p>Deze release zou niet mogelijk zijn zonder het werkt van Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar</p>
<h2>2.7</h2>
<ul>
-<li>Purple! (Dominik, Vincent)</li>
-<li>New key view design (Dominik, Vincent)</li>
-<li>New flat Android buttons (Dominik, Vincent)</li>
-<li>API fixes (Dominik)</li>
-<li>Keybase.io import (Tim Bray)</li>
+<li>Paars! (Dominik, Vincent)</li>
+<li>Nieuw design voor bekijken van sleutels (Dominik, Vincent)</li>
+<li>Nieuwe platte Android-knoppen (Dominik, Vincent)</li>
+<li>API-oplossingen (Dominik)</li>
+<li>Importeren uit keybase.io (Tim Bray)</li>
</ul>
<h2>2.6.1</h2>
<ul>
-<li>Some fixes for regression bugs</li>
+<li>Enkele oplossingen voor regressies</li>
</ul>
<h2>2.6</h2>
<ul>
-<li>Key certifications (thanks to Vincent Breitmoser)</li>
-<li>Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)</li>
-<li>New design for signature verification</li>
-<li>Custom key length (thanks to Greg Witczak)</li>
-<li>Fix share-functionality from other apps</li>
+<li>Sleutelcertificaties (dank aan Vincent Breitmoser)</li>
+<li>Ondersteuning voor GnuPG gedeeltelijke geheime sleutels (dank aan Vincent Breitmoser)</li>
+<li>Nieuw design voor ondertekeningsverificatie</li>
+<li>Aangepaste sleutellengte (dank aan Greg Witczak)</li>
+<li>Oplossing voor delen vanuit andere apps</li>
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
-<li>Refactored key edit screen (thanks to Ash Hughes)</li>
-<li>New modern design for encrypt/decrypt screens</li>
-<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
+<li>Oplossing voor ontcijfering van symmetrische OpenPGP berichten/bestanden</li>
+<li>Nieuw ontwerp voor sleutelbewerkingsscherm (dank aan Ash Hughes)</li>
+<li>Nieuw modern design voor versleutelings/ontcijferingsschermen</li>
+<li>OpenPGP API versie 3 (meerdere API accounts, interne fixes, zoeken naar sleutels)</li>
</ul>
<h2>2.4</h2>
-<p>Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free!
-Besides several small patches, a notable number of patches are made by the following people (in alphabetical order):
+<p>Dank aan alle deelnemers aan Google Summer of Code 2014 die deze release zo vol mogelijkheden en zonder bugs hebben gemaakt!
+Buiten verschillende kleine patches, werden een groot aantal patches gemaakt door volgende personen (alfabetisch gerangschikt):
Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.</p>
<ul>
-<li>New unified key list</li>
-<li>Colorized key fingerprint</li>
-<li>Support for keyserver ports</li>
-<li>Deactivate possibility to generate weak keys</li>
-<li>Much more internal work on the API</li>
-<li>Certify user ids</li>
-<li>Keyserver query based on machine-readable output</li>
-<li>Lock navigation drawer on tablets</li>
-<li>Suggestions for emails on creation of keys</li>
-<li>Search in public key lists</li>
-<li>And much more improvements and fixes…</li>
+<li>Nieuwe geünificeerde sleutellijst</li>
+<li>Gekleurde sleutelvingerafdruk</li>
+<li>Ondersteuning voor sleutelserver-poorten</li>
+<li>Zet mogelijkheid om zwakke sleutels aan te maken uit</li>
+<li>Veel meer intern werk aan API</li>
+<li>Certificeer gebruikers-ID's</li>
+<li>Sleutelserverzoekopdracht gebaseerd op machine-leesbare output</li>
+<li>Zet navigatiedrawer op tablets vast</li>
+<li>Suggesties voor e-mailadress bij aanmaken van sleutels</li>
+<li>Zoeken in publieke sleutellijsten</li>
+<li>En veel more verbeteringen en fixes...</li>
</ul>
<h2>2.3.1</h2>
<ul>
-<li>Hotfix for crash when upgrading from old versions</li>
+<li>Hotfix voor crash bij upgraden van oude versies</li>
</ul>
<h2>2.3</h2>
<ul>
-<li>Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)</li>
-<li>Fix setting expiry dates on keys (thanks to Ash Hughes)</li>
-<li>More internal fixes when editing keys (thanks to Ash Hughes)</li>
-<li>Querying keyservers directly from the import screen</li>
-<li>Fix layout and dialog style on Android 2.2-3.0</li>
-<li>Fix crash on keys with empty user ids</li>
-<li>Fix crash and empty lists when coming back from signing screen</li>
-<li>Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source</li>
-<li>Fix upload of key from signing screen</li>
+<li>Verwijder onnodige export van publieke sleutels bij exporteren van geheime sleutel (dank aan Ash Hughes)</li>
+<li>Oplossing voor verloopdata op sleutels (dank aan Ash Hughes)</li>
+<li>Meer interne fixes by bewerken van sleutels (dank aan Ash Hughes)</li>
+<li>Zoeken op sleutelservers rechtstreeks van importscherm</li>
+<li>Oplossing voor layout en dialoogstijl op Android 2.2-3.0</li>
+<li>Oplossing voor crash op sleutels met lege gebruikers-ID's</li>
+<li>Oplossing voor crash en lege lijsten bij terugkeren van ondertekeningsscherm</li>
+<li>Bouncy Castle (cryptografie-bibliotheek) geüpdatet van 1.47 naar 1.50 en built from source</li>
+<li>Oplossing voor uploaden van sleutel van ondertekeningsscherm</li>
</ul>
<h2>2.2</h2>
<ul>
-<li>New design with navigation drawer</li>
-<li>New public key list design</li>
-<li>New public key view</li>
-<li>Bug fixes for importing of keys</li>
-<li>Key cross-certification (thanks to Ash Hughes)</li>
-<li>Handle UTF-8 passwords properly (thanks to Ash Hughes)</li>
-<li>First version with new languages (thanks to the contributors on Transifex)</li>
-<li>Sharing of keys via QR Codes fixed and improved</li>
-<li>Package signature verification for API</li>
+<li>Nieuw design met navigatiebalk</li>
+<li>Nieuw publieke sleutellijst design</li>
+<li>Nieuwe publieke sleutel view</li>
+<li>Bugfixes voor importeren van sleutels</li>
+<li>Sleutel certificatie (dank aan Ash Hughes)</li>
+<li>Behandel UTF-8 wachtwoorden correct (dank aan Ash Hughes)</li>
+<li>Eerste versie met nieuwe talen (dank aan de medewerkers op Transifex)</li>
+<li>Delen van sleutels via QR codes opgelost en verbeterd</li>
+<li>Pakketondertekeningsverificatie voor API</li>
</ul>
<h2>2.1.1</h2>
<ul>
-<li>API Updates, preparation for K-9 Mail integration</li>
+<li>API updates, voorbereiding voor K-9 Mail integratie</li>
</ul>
<h2>2.1</h2>
<ul>
-<li>Lots of bug fixes</li>
-<li>New API for developers</li>
-<li>PRNG bug fix by Google</li>
+<li>Veel bugfixes</li>
+<li>Nieuwe API voor ontwikkelaars</li>
+<li>PRNG bug fix door Google</li>
</ul>
<h2>2.0</h2>
<ul>
-<li>Complete redesign</li>
-<li>Share public keys via QR codes, NFC beam</li>
-<li>Sign keys</li>
-<li>Upload keys to server</li>
-<li>Fixes import issues</li>
-<li>New AIDL API</li>
+<li>Volledig nieuw design</li>
+<li>Publieke sleutels delen via QR codes, NFC beam</li>
+<li>Sleutels ondertekenen</li>
+<li>Upload sleutels naar server</li>
+<li>Importeerproblemen opgelost</li>
+<li>Nieuwe AIDL API</li>
</ul>
<h2>1.0.8</h2>
<ul>
-<li>Basic keyserver support</li>
-<li>App2sd</li>
-<li>More choices for passphrase cache: 1, 2, 4, 8, hours</li>
-<li>Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)</li>
+<li>Basisondersteuning voor sleutelservers</li>
+<li>App2SD</li>
+<li>Meer keuzes voor wachtwoordcache: 1, 2, 4, 8 uur</li>
+<li>Vertalingen: Noors (bedankt, Sander Danielsen), Chinees (bedankt, Zhang Fredrick)</li>
<li>Bugfixes</li>
-<li>Optimizations</li>
+<li>Optimalisaties</li>
</ul>
<h2>1.0.7</h2>
<ul>
-<li>Fixed problem with signature verification of texts with trailing newline</li>
-<li>More options for passphrase cache time to live (20, 40, 60 mins)</li>
+<li>Probleem met ondertekeningsverificatie van text met achterlopende newline opgelost</li>
+<li>Meer opties voor wachtwoord cachetijd (20, 40, 60 min.)</li>
</ul>
<h2>1.0.6</h2>
<ul>
-<li>Account adding crash on Froyo fixed</li>
-<li>Secure file deletion</li>
-<li>Option to delete key file after import</li>
-<li>Stream encryption/decryption (gallery, etc.)</li>
-<li>New options (language, force v3 signatures)</li>
-<li>Interface changes</li>
+<li>Crash bij toevoegen van account op Froyo opgelost</li>
+<li>Veilige bestandsverwijdering</li>
+<li>Optie om sleutelbestand na importeren te verwijderen</li>
+<li>Stream versleuteling/ontcijfering (galerij, enz.)</li>
+<li>Nieuwe opties (taal, forceer v3 ondertekeningen)</li>
+<li>Wijzigingen in interface</li>
<li>Bugfixes</li>
</ul>
<h2>1.0.5</h2>
<ul>
-<li>German and Italian translation</li>
-<li>Much smaller package, due to reduced BC sources</li>
-<li>New preferences GUI</li>
-<li>Layout adjustment for localization</li>
-<li>Signature bugfix</li>
+<li>Duitse en Italiaanse vertaling</li>
+<li>Veel kleiner pakket, door verminderde BC bronnen</li>
+<li>Nieuwe GUI voor voorkeuren</li>
+<li>Layout wijzigingen voor localisatie</li>
+<li>Bugfix voor ondertekeningen</li>
</ul>
<h2>1.0.4</h2>
<ul>
-<li>Fixed another crash caused by some SDK bug with query builder</li>
+<li>Een andere crash veroorzaakt door een SDK bug met de query builder opgelost</li>
</ul>
<h2>1.0.3</h2>
<ul>
-<li>Fixed crashes during encryption/signing and possibly key export</li>
+<li>Crashes tijdens versleuteling/ondertekenen en mogelijk sleutelexportatie opgelost</li>
</ul>
<h2>1.0.2</h2>
<ul>
-<li>Filterable key lists</li>
-<li>Smarter pre-selection of encryption keys</li>
-<li>New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers</li>
-<li>Fixes and additional features (key preselection) for K-9 Mail, new beta build available</li>
+<li>Filterbare sleutellijsten</li>
+<li>Slimmere preselectie van cryptosleutels</li>
+<li>Nieuwe Intents voor VIEW en SEND, laat toe bestanden te versleutelen/ontcijferen vanuit bestandsbeheerders</li>
+<li>Oplossingen en nieuwe functies (sleutel preselectie) voor K-9 Mail, nieuwe beta build beschikbaar</li>
</ul>
<h2>1.0.1</h2>
<ul>
-<li>GMail account listing was broken in 1.0.0, fixed again</li>
+<li>Oplijsten van GMail accounts werkte niet in 1.0.0, opgelost</li>
</ul>
<h2>1.0.0</h2>
<ul>
-<li>K-9 Mail integration, APG supporting beta build of K-9 Mail</li>
-<li>Support of more file managers (including ASTRO)</li>
-<li>Slovenian translation</li>
-<li>New database, much faster, less memory usage</li>
-<li>Defined Intents and content provider for other apps</li>
+<li>K-9 Mail integratie, APG ondersteuning voor beta build van K-9 Mail</li>
+<li>Ondersteuning voor meer bestandsbeheerders (waaronder ASTRO)</li>
+<li>Sloveense vertaling</li>
+<li>Nieuwe database, veel sneller, minder geheugengebruik</li>
+<li>Intents en content provider voor andere apps gedefinieerd</li>
<li>Bugfixes</li>
</ul>
</body>
diff --git a/OpenKeychain/src/main/res/raw-nl/help_nfc_beam.html b/OpenKeychain/src/main/res/raw-nl/help_nfc_beam.html
index 7ba0a2d1a..4caf75748 100644
--- a/OpenKeychain/src/main/res/raw-nl/help_nfc_beam.html
+++ b/OpenKeychain/src/main/res/raw-nl/help_nfc_beam.html
@@ -3,10 +3,10 @@
<body>
<h2>Hoe sleutels te ontvangen</h2>
<ol>
-<li>Go to your partners keys and open the key you want to share.</li>
-<li>Houd de twee apparaten met de achterkant tegen elkaar (ze moeten elkaar bijna aanraken) en u zult een trilling voelen.</li>
-<li>Nadat het trilt zult u de inhoud op uw partners apparaat in een soort kaart zien veranderen met Star Trek warp snelheid-eruitziende animatie op de achtergrond.</li>
-<li>Druk op de kaart en de inhoud zal dan laden op het apparaat.</li>
+<li>Ga naar je partner's sleutels en open de sleutel die je wil delen.</li>
+<li>Houd de twee toestellen met de achterkant tegen elkaar (ze moeten elkaar bijna aanraken) en je zal een trilling voelen.</li>
+<li>Nadat het trilt zal je de inhoud op je partner's toestel in een soort kaart zien veranderen met Star Trek warp snelheid-eruitziende animatie op de achtergrond.</li>
+<li>Druk op de kaart en de inhoud zal dan laden op het toestel.</li>
</ol>
</body>
</html>
diff --git a/OpenKeychain/src/main/res/raw-nl/help_start.html b/OpenKeychain/src/main/res/raw-nl/help_start.html
index d159c4cf0..fda3c97b1 100644
--- a/OpenKeychain/src/main/res/raw-nl/help_start.html
+++ b/OpenKeychain/src/main/res/raw-nl/help_start.html
@@ -2,15 +2,15 @@
<head></head>
<body>
<h2>Aan de slag</h2>
-<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>Eerst heb je een persoonlijke sleutel nodig. Maak er een aan via het menu in 'Sleutels' of importeer bestaande geheime sleutels. Nadien kan je de sleutels van je vrienden downloaden of ze uitwisselen via QR codes of NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>Op Android-versies lager dan 4.4 raden we aan dat je <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> installeert voor een verbeterde bestandsselectie.</p>
<h2>Ik heb een bug in OpenKeychain gevonden!</h2>
<p>Rapporteer de bug met de <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">problemen tracker van OpenKeychain</a>.</p>
<h2>Bijdragen</h2>
-<p>Als u ons wilt helpen om OpenKeychain te ontwikkelen door code bij te dragen, <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">volg onze kleine gids op Github</a>.</p>
+<p>Als je ons wil helpen om OpenKeychain te ontwikkelen door code bij te dragen, <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">volg onze kleine gids op Github</a>.</p>
<h2>Vertalingen</h2>
<p>Help OpenKeychain te vertalen! Iedereen kan deelnemen op <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain op Transifex</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-nl/help_wot.html b/OpenKeychain/src/main/res/raw-nl/help_wot.html
index efaac3c1e..4c72a875c 100644
--- a/OpenKeychain/src/main/res/raw-nl/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-nl/help_wot.html
@@ -2,16 +2,16 @@
<head></head>
<body>
<h2>Web van Vertrouwen</h2>
-<p>het Web of Trust beschrijft het deel van PGP dat te maken heeft met aanmaken en boekhouden van certificaten. Het voorziet van mechanismes zodat de gebruiker bij kan houden van aan wie een publieke sleutel toebehoort, en deze informatie met anderen kan delen; om de privacy van versleutelde communicatie te verzekeren, is het essentiëel om te weten dat de publieke sleutel die u versleutelt, toebehoort aan de persoon aan wie u denkt dat het toebehoort.</p>
+<p>Het Web van Vertrouwen beschrijft het deel van OpenPGP dat te maken heeft met aanmaken en boekhouden van certificaten. Het voorziet van mechanismes zodat de gebruiker bij kan houden van aan wie een publieke sleutel toebehoort, en deze informatie met anderen kan delen; om de privacy van versleutelde communicatie te verzekeren, is het essentiëel om te weten dat de publieke sleutel die je versleutelt, toebehoort aan de persoon aan wie je denkt dat het toebehoort.</p>
-<h2>Support in OpenKeychain</h2>
-<p>Er is alleen basissupport voor Web van Vertrouwen in OpenKeychain. Dit is een zware 'werk in uitvoering' en onderwerp voor veranderingen in toekomstige releases.</p>
+<h2>Ondersteuning in OpenKeychain</h2>
+<p>Er is alleen basisondersteuning voor Web van Vertrouwen in OpenKeychain. Dit is een zware 'werk in uitvoering' en onderwerp voor veranderingen in toekomstige releases.</p>
-<h2>Vertrouwen Model</h2>
-<p>Vertrouwen evaluatie is gebaseerd om de simpele aanname dat alle sleutels die beschikbare geheime sleutels hebben, vertrouwd zijn. Publieke sleutels die minstens een gebruikers-id bevatten, gecertificeerd door een vertrouwde sleutel, zullen gemarkeerd worden met een groene stip in de sleutel lijsten. Het is (nog) niet mogelijk om vertrouwen niveaus voor certificaten van andere bekende publieke sleutels te specifiëren.</p>
+<h2>Vertrouwensmodel</h2>
+<p>Vertrouwensevaluatie is gebaseerd om de simpele aanname dat alle sleutels die beschikbare geheime sleutels hebben, vertrouwd zijn. Publieke sleutels die minstens een gebruikers-ID bevatten, gecertificeerd door een vertrouwde sleutel, zullen gemarkeerd worden met een groene stip in de sleutel lijsten. Het is (nog) niet mogelijk om vertrouwen niveaus voor certificaten van andere bekende publieke sleutels te specifiëren.</p>
-<h2>Sleutels certificeren</h2>
-<p>Support voor sleutelcertificatie is beschikbaar, en gebruikers-id's kunnen individueel gecertificeerd worden. Het is nog niet mogelijk om het niveau van vertrouwen te specifiëren om locale en andere speciale typen van certificaten te maken.</p>
+<h2>Bezig met certificeren van sleutels&lt;br&gt;</h2>
+<p>Ondersteuning voor sleutelcertificatie is beschikbaar, en gebruikers-ID's kunnen individueel gecertificeerd worden. Het is nog niet mogelijk om het niveau van vertrouwen te specifiëren om locale en andere speciale typen van certificaten te maken.</p>
</body>
</html>
diff --git a/OpenKeychain/src/main/res/raw-pl/help_changelog.html b/OpenKeychain/src/main/res/raw-pl/help_changelog.html
index 715e1aee6..07dcd04e2 100644
--- a/OpenKeychain/src/main/res/raw-pl/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-pl/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-pl/help_start.html b/OpenKeychain/src/main/res/raw-pl/help_start.html
index 967042b53..400a89e60 100644
--- a/OpenKeychain/src/main/res/raw-pl/help_start.html
+++ b/OpenKeychain/src/main/res/raw-pl/help_start.html
@@ -4,7 +4,7 @@
<h2>Pierwsze kroki</h2>
<p>Najpierw będziesz potrzebował osobistego klucza. Stwórz go wybierając z menu "Klucze" lub zaimportuj istniejące tajne klucze. Później możesz pobrać klucze swoich znajomych lub wymienić się używając kodów QR lub NFC.</p>
-<p>Na Androidzie niższym od wersji 4.4, zalecane jest zainstalowanie <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> w celu zapewnienia wygodniejszego wyboru plików. Aby dzielić się używając kodów QR zainstaluj <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Kliknięcie na powyższe linki przekieruje Cię do sklepu Google Play lub F-Droid w celu instalacji tych aplikacji.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>Znalazłem błąd w OpenKeychain!</h2>
<p>Zgłoś błąd korzystając z <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">systemu śledzenia błędów OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-pl/help_wot.html b/OpenKeychain/src/main/res/raw-pl/help_wot.html
index 29790139b..2a551f79c 100644
--- a/OpenKeychain/src/main/res/raw-pl/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-pl/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Web of Trust</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Support in OpenKeychain</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
diff --git a/OpenKeychain/src/main/res/raw-pt/help_changelog.html b/OpenKeychain/src/main/res/raw-pt/help_changelog.html
index 4d3d293ac..0cb7d5210 100644
--- a/OpenKeychain/src/main/res/raw-pt/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-pt/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-pt/help_start.html b/OpenKeychain/src/main/res/raw-pt/help_start.html
index 4f029ab37..92fd4a92a 100644
--- a/OpenKeychain/src/main/res/raw-pt/help_start.html
+++ b/OpenKeychain/src/main/res/raw-pt/help_start.html
@@ -4,7 +4,7 @@
<h2>Getting started</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>I found a bug in OpenKeychain!</h2>
<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-pt/help_wot.html b/OpenKeychain/src/main/res/raw-pt/help_wot.html
index 29790139b..2a551f79c 100644
--- a/OpenKeychain/src/main/res/raw-pt/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-pt/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Web of Trust</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Support in OpenKeychain</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
diff --git a/OpenKeychain/src/main/res/raw-ro/help_about.html b/OpenKeychain/src/main/res/raw-ro/help_about.html
new file mode 100644
index 000000000..2c6c5b3c4
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-ro/help_about.html
@@ -0,0 +1,57 @@
+<html>
+<head></head>
+<body>
+<p><a href="http://www.openkeychain.org">http://www.openkeychain.org</a></p>
+<p><a href="http://www.openkeychain.org">OpenKeychain</a> is an OpenPGP implementation for Android.</p>
+<p>License: GPLv3+</p>
+
+<h2>Developers</h2>
+<ul>
+<li>Dominik Schürmann (Maintainer)</li>
+<li>Art O Cathain</li>
+<li>Ash Hughes</li>
+<li>Brian C. Barnes</li>
+<li>Bahtiar 'kalkin' Gadimov</li>
+<li>Daniel Albert</li>
+<li>Daniel Hammann</li>
+<li>Daniel Haß</li>
+<li>Greg Witczak</li>
+<li>'mar-v-in'</li>
+<li>Markus Doits</li>
+<li>Miroojin Bakshi</li>
+<li>Nikhil Peter Raj</li>
+<li>Paul Sarbinowski</li>
+<li>'Senecaso'</li>
+<li>Signe Rüsch</li>
+<li>Sreeram Boyapati</li>
+<li>Thialfihar (APG 1.x)</li>
+<li>Tim Bray</li>
+<li>Vincent Breitmoser</li>
+</ul>
+<h2>Libraries</h2>
+<ul>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Apache License v2)</li>
+<li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v7 'appcompat'</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/timbray/KeybaseLib">KeybaseLib</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/JohnPersano/SuperToasts">SuperToasts</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/splitwise/TokenAutoComplete">TokenAutoComplete</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/rtreffer/minidns">MiniDNS</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Apache License v2)</li>
+<li>
+<a href="http://code.google.com/p/zxing/">ZXing</a> (Apache License v2)</li>
+<li>
+<a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11 License)</li>
+<li>
+<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
+<li>
+<a href="https://github.com/SafeSlingerProject/exchange-android">SafeSlinger Exchange library</a> (MIT License)</li>
+</ul>
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-ro/help_changelog.html b/OpenKeychain/src/main/res/raw-ro/help_changelog.html
new file mode 100644
index 000000000..0cb7d5210
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-ro/help_changelog.html
@@ -0,0 +1,232 @@
+<html>
+<head></head>
+<body>
+
+<h2>3.1.2</h2>
+<ul>
+<li>Fix key export to files (now for real)</li>
+</ul>
+<h2>3.1.1</h2>
+<ul>
+<li>Fix key export to files (they were written partially)</li>
+<li>Fix crash on Android 2.3</li>
+</ul>
+<h2>3.1</h2>
+<ul>
+<li>Fix crash on Android 5</li>
+<li>New certify screen</li>
+<li>Secure Exchange directly from key list (SafeSlinger library)</li>
+<li>New QR Code program flow</li>
+<li>Redesigned decrypt screen</li>
+<li>New icon usage and colors</li>
+<li>Fix import of secret keys from Symantec Encryption Desktop</li>
+<li>Subkey IDs on Yubikeys are now checked correctly</li>
+</ul>
+<h2>3.0.1</h2>
+<ul>
+<li>Better handling of large key imports</li>
+<li>Improved subkey selection</li>
+</ul>
+<h2>3.0</h2>
+<ul>
+<li>Full support for Yubikey signature generation and decryption!</li>
+<li>Propose installable compatible apps in apps list</li>
+<li>New design for decryption screens</li>
+<li>Many fixes for key import, also fixes stripped keys</li>
+<li>Honor and display key authenticate flags</li>
+<li>User interface to generate custom keys</li>
+<li>Fixing user id revocation certificates</li>
+<li>New cloud search (searches over traditional keyservers and keybase.io)</li>
+<li>Support for stripping keys inside OpenKeychain</li>
+</ul>
+<h2>2.9.2</h2>
+<ul>
+<li>Fix keys broken in 2.9.1</li>
+<li>Yubikey decryption now working via API</li>
+</ul>
+<h2>2.9.1</h2>
+<ul>
+<li>Split encrypt screen into two</li>
+<li>Fix key flags handling (now supporting Mailvelope 0.7 keys)</li>
+<li>Improved passphrase handling</li>
+<li>Key sharing via SafeSlinger</li>
+<li>Yubikey: preference to allow other PINs, currently only signing via the OpenPGP API works, not inside of OpenKeychain</li>
+<li>Fix usage of stripped keys</li>
+<li>SHA256 as default for compatibility</li>
+<li>Intent API has changed, see https://github.com/open-keychain/open-keychain/wiki/Intent-API</li>
+<li>OpenPGP API now handles revoked/expired keys and returns all user ids</li>
+</ul>
+<h2>2.9</h2>
+<ul>
+<li>Fixing crashes introduced in v2.8</li>
+<li>Experimental ECC support</li>
+<li>Experimental Yubikey support (signing-only with imported keys)</li>
+</ul>
+<h2>2.8</h2>
+<ul>
+<li>So many bugs have been fixed in this release that we focus on the main new features</li>
+<li>Key edit: awesome new design, key revocation</li>
+<li>Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records</li>
+<li>New first time screen</li>
+<li>New key creation screen: autocompletion of name and email based on your personal Android accounts</li>
+<li>File encryption: awesome new design, support for encrypting multiple files</li>
+<li>New icons to show status of key (by Brennan Novak)</li>
+<li>Important bug fix: Importing of large key collections from a file is now possible</li>
+<li>Notification showing cached passphrases</li>
+<li>Keys are connected to Android's contacts</li>
+</ul>
+<p>This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar</p>
+
+<h2>2.7</h2>
+<ul>
+<li>Purple! (Dominik, Vincent)</li>
+<li>New key view design (Dominik, Vincent)</li>
+<li>New flat Android buttons (Dominik, Vincent)</li>
+<li>API fixes (Dominik)</li>
+<li>Keybase.io import (Tim Bray)</li>
+</ul>
+<h2>2.6.1</h2>
+<ul>
+<li>Some fixes for regression bugs</li>
+</ul>
+<h2>2.6</h2>
+<ul>
+<li>Key certifications (thanks to Vincent Breitmoser)</li>
+<li>Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)</li>
+<li>New design for signature verification</li>
+<li>Custom key length (thanks to Greg Witczak)</li>
+<li>Fix share-functionality from other apps</li>
+</ul>
+<h2>2.5</h2>
+<ul>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
+<li>Refactored key edit screen (thanks to Ash Hughes)</li>
+<li>New modern design for encrypt/decrypt screens</li>
+<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
+</ul>
+<h2>2.4</h2>
+<p>Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free!
+Besides several small patches, a notable number of patches are made by the following people (in alphabetical order):
+Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.</p>
+<ul>
+<li>New unified key list</li>
+<li>Colorized key fingerprint</li>
+<li>Support for keyserver ports</li>
+<li>Deactivate possibility to generate weak keys</li>
+<li>Much more internal work on the API</li>
+<li>Certify user ids</li>
+<li>Keyserver query based on machine-readable output</li>
+<li>Lock navigation drawer on tablets</li>
+<li>Suggestions for emails on creation of keys</li>
+<li>Search in public key lists</li>
+<li>And much more improvements and fixes…</li>
+</ul>
+<h2>2.3.1</h2>
+<ul>
+<li>Hotfix for crash when upgrading from old versions</li>
+</ul>
+<h2>2.3</h2>
+<ul>
+<li>Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)</li>
+<li>Fix setting expiry dates on keys (thanks to Ash Hughes)</li>
+<li>More internal fixes when editing keys (thanks to Ash Hughes)</li>
+<li>Querying keyservers directly from the import screen</li>
+<li>Fix layout and dialog style on Android 2.2-3.0</li>
+<li>Fix crash on keys with empty user ids</li>
+<li>Fix crash and empty lists when coming back from signing screen</li>
+<li>Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source</li>
+<li>Fix upload of key from signing screen</li>
+</ul>
+<h2>2.2</h2>
+<ul>
+<li>New design with navigation drawer</li>
+<li>New public key list design</li>
+<li>New public key view</li>
+<li>Bug fixes for importing of keys</li>
+<li>Key cross-certification (thanks to Ash Hughes)</li>
+<li>Handle UTF-8 passwords properly (thanks to Ash Hughes)</li>
+<li>First version with new languages (thanks to the contributors on Transifex)</li>
+<li>Sharing of keys via QR Codes fixed and improved</li>
+<li>Package signature verification for API</li>
+</ul>
+<h2>2.1.1</h2>
+<ul>
+<li>API Updates, preparation for K-9 Mail integration</li>
+</ul>
+<h2>2.1</h2>
+<ul>
+<li>Lots of bug fixes</li>
+<li>New API for developers</li>
+<li>PRNG bug fix by Google</li>
+</ul>
+<h2>2.0</h2>
+<ul>
+<li>Complete redesign</li>
+<li>Share public keys via QR codes, NFC beam</li>
+<li>Sign keys</li>
+<li>Upload keys to server</li>
+<li>Fixes import issues</li>
+<li>New AIDL API</li>
+</ul>
+<h2>1.0.8</h2>
+<ul>
+<li>Basic keyserver support</li>
+<li>App2sd</li>
+<li>More choices for passphrase cache: 1, 2, 4, 8, hours</li>
+<li>Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)</li>
+<li>Bugfixes</li>
+<li>Optimizations</li>
+</ul>
+<h2>1.0.7</h2>
+<ul>
+<li>Fixed problem with signature verification of texts with trailing newline</li>
+<li>More options for passphrase cache time to live (20, 40, 60 mins)</li>
+</ul>
+<h2>1.0.6</h2>
+<ul>
+<li>Account adding crash on Froyo fixed</li>
+<li>Secure file deletion</li>
+<li>Option to delete key file after import</li>
+<li>Stream encryption/decryption (gallery, etc.)</li>
+<li>New options (language, force v3 signatures)</li>
+<li>Interface changes</li>
+<li>Bugfixes</li>
+</ul>
+<h2>1.0.5</h2>
+<ul>
+<li>German and Italian translation</li>
+<li>Much smaller package, due to reduced BC sources</li>
+<li>New preferences GUI</li>
+<li>Layout adjustment for localization</li>
+<li>Signature bugfix</li>
+</ul>
+<h2>1.0.4</h2>
+<ul>
+<li>Fixed another crash caused by some SDK bug with query builder</li>
+</ul>
+<h2>1.0.3</h2>
+<ul>
+<li>Fixed crashes during encryption/signing and possibly key export</li>
+</ul>
+<h2>1.0.2</h2>
+<ul>
+<li>Filterable key lists</li>
+<li>Smarter pre-selection of encryption keys</li>
+<li>New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers</li>
+<li>Fixes and additional features (key preselection) for K-9 Mail, new beta build available</li>
+</ul>
+<h2>1.0.1</h2>
+<ul>
+<li>GMail account listing was broken in 1.0.0, fixed again</li>
+</ul>
+<h2>1.0.0</h2>
+<ul>
+<li>K-9 Mail integration, APG supporting beta build of K-9 Mail</li>
+<li>Support of more file managers (including ASTRO)</li>
+<li>Slovenian translation</li>
+<li>New database, much faster, less memory usage</li>
+<li>Defined Intents and content provider for other apps</li>
+<li>Bugfixes</li>
+</ul>
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-ro/help_nfc_beam.html b/OpenKeychain/src/main/res/raw-ro/help_nfc_beam.html
new file mode 100644
index 000000000..966fb554a
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-ro/help_nfc_beam.html
@@ -0,0 +1,12 @@
+<html>
+<head></head>
+<body>
+<h2>How to receive keys</h2>
+<ol>
+<li>Go to your partners keys and open the key you want to share.</li>
+<li>Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.</li>
+<li>After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the your device.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-ro/help_start.html b/OpenKeychain/src/main/res/raw-ro/help_start.html
new file mode 100644
index 000000000..92fd4a92a
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-ro/help_start.html
@@ -0,0 +1,19 @@
+<html>
+<head></head>
+<body>
+<h2>Getting started</h2>
+<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
+
+<h2>I found a bug in OpenKeychain!</h2>
+<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
+
+<h2>Contribute</h2>
+<p>If you want to help us developing OpenKeychain by contributing code <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">follow our small guide on Github</a>.</p>
+
+<h2>Translations</h2>
+<p>Help translating OpenKeychain! Everybody can participate at <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain on Transifex</a>.</p>
+
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-ro/help_wot.html b/OpenKeychain/src/main/res/raw-ro/help_wot.html
new file mode 100644
index 000000000..2a551f79c
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-ro/help_wot.html
@@ -0,0 +1,17 @@
+<html>
+<head></head>
+<body>
+<h2>Web of Trust</h2>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+
+<h2>Support in OpenKeychain</h2>
+<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
+
+<h2>Trust Model</h2>
+<p>Trust evaluation is based on the simple assumption that all keys which have secret keys available are trusted. Public keys which contain at least one user id certified by a trusted key will be marked with a green dot in the key listings. It is not (yet) possible to specify trust levels for certificates of other known public keys.</p>
+
+<h2>Certifying keys</h2>
+<p>Support for key certification is available, and user ids can be certified individually. It is not yet possible to specify the level of trust or create local and other special types of certificates.</p>
+
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-ro/nfc_beam_share.html b/OpenKeychain/src/main/res/raw-ro/nfc_beam_share.html
new file mode 100644
index 000000000..083e055c7
--- /dev/null
+++ b/OpenKeychain/src/main/res/raw-ro/nfc_beam_share.html
@@ -0,0 +1,11 @@
+<html>
+<head></head>
+<body>
+<ol>
+<li>Make sure that NFC is turned on in Settings &gt; More &gt; NFC and make sure that Android Beam is also on in the same section.</li>
+<li>Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.</li>
+<li>After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the other person’s device.</li>
+</ol>
+</body>
+</html>
diff --git a/OpenKeychain/src/main/res/raw-ru/help_changelog.html b/OpenKeychain/src/main/res/raw-ru/help_changelog.html
index 4d3d293ac..0cb7d5210 100644
--- a/OpenKeychain/src/main/res/raw-ru/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-ru/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-ru/help_start.html b/OpenKeychain/src/main/res/raw-ru/help_start.html
index a9c200abb..ef91a4131 100644
--- a/OpenKeychain/src/main/res/raw-ru/help_start.html
+++ b/OpenKeychain/src/main/res/raw-ru/help_start.html
@@ -4,7 +4,7 @@
<h2>ПриÑтупаÑ</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>Я нашел ошибку в OpenKeychain!</h2>
<p>ПожалуйÑта, Ñообщайте о возникших проблемах и найденных ошибках в разделе <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">Решение проблем OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-ru/help_wot.html b/OpenKeychain/src/main/res/raw-ru/help_wot.html
index 53c862cbc..4da6c9a82 100644
--- a/OpenKeychain/src/main/res/raw-ru/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-ru/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Сеть Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ (WoT)</h2>
-<p>Сеть Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ (The Web of Trust) предоÑтавлÑет механизм, Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð½Ð¾Ñти ключа именно тому пользователю, который в нём указан. ОÑнова Ñтой модели ÑтроитÑÑ Ð½Ð° знакомÑтве людей и Ñертификации Ñвоей подпиÑью ключей Ñвоих знакомых. Ðе менее важно раÑпроÑтранение Ñтой информации Ñреди других пользователей WoT.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Поддержка в OpenKeychain</h2>
<p>Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ñ€ÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ‹ только базовые возможноÑти WoT. Работа в Ñамом разгаре и в будущих верÑиÑÑ… OpenKeychain будут поÑвлÑÑ‚ÑŒÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ возможноÑти.</p>
diff --git a/OpenKeychain/src/main/res/raw-sl/help_changelog.html b/OpenKeychain/src/main/res/raw-sl/help_changelog.html
index ed1f88cad..943ba79f1 100644
--- a/OpenKeychain/src/main/res/raw-sl/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-sl/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Popravek deÅ¡ifriranja simetriÄno Å¡ifriranih sporoÄil pgp</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Popravki kode za okno 'uredi kljuÄ' (hvala, Ash Hughes)</li>
<li>Nova, sodobna podoba za okno 'šifriranje/dešifriranje'</li>
<li>API OpenPGP, verzija 3 (podpora za veÄ api raÄunov, interni popravki, iskanje kljuÄev)</li>
diff --git a/OpenKeychain/src/main/res/raw-sl/help_start.html b/OpenKeychain/src/main/res/raw-sl/help_start.html
index 276377723..2d0b763e0 100644
--- a/OpenKeychain/src/main/res/raw-sl/help_start.html
+++ b/OpenKeychain/src/main/res/raw-sl/help_start.html
@@ -4,7 +4,7 @@
<h2>Kako zaÄeti</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>NaÅ¡el sem 'hroÅ¡Äa' v aplikaciji OpenKeychain!</h2>
<p>Za poroÄanje o 'hroÅ¡Äih' uporabite <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">sledilnik težav za OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-sl/help_wot.html b/OpenKeychain/src/main/res/raw-sl/help_wot.html
index 62cdf8094..224110e18 100644
--- a/OpenKeychain/src/main/res/raw-sl/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-sl/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Omrežje zaupanja</h2>
-<p>Omrežje zaupanja je del PGP-ja, ki se dotika ustvarjanja, urejanja in hranjenja kljuÄev. Ponuja nam orodja za vodenje evidence kljuÄev in njihovih lastnikov, ter deljenje teh informacij z drugimi. Za zagotavljanje zasebnosti Å¡ifrirane komunikacije je bistvenega pomena, da vemo, da kljuÄ s katerim Å¡ifriramo doloÄeno vsebino resniÄno pripada osebi, ki ji je ta vsebina namenjena.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Podpora v OpenKeychain</h2>
<p>OpenKeychain ponuja zgolj osnovno podporo za 'Omrežje zaupanja'. V prihodnjih razliÄicah bomo to podporo Å¡e nadgrajevali in izboljÅ¡evali.</p>
diff --git a/OpenKeychain/src/main/res/raw-sr/help_changelog.html b/OpenKeychain/src/main/res/raw-sr/help_changelog.html
index 5cd99d2fd..599498336 100644
--- a/OpenKeychain/src/main/res/raw-sr/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-sr/help_changelog.html
@@ -4,7 +4,7 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>Поправка извоза кључева у фајлове (Ñада заиÑта)</li>
</ul>
<h2>3.1.1</h2>
<ul>
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Поправка дешифровања Ñиметричних пгп порука/фајлова</li>
+<li>Поправка дешифровања Ñиметричних ОпенПГП порука/фајлова</li>
<li>Прерађен екран уређивања кључа (захваљујући Ешу ХјуџеÑу)</li>
<li>Ðови модерни дизајн за екране шифровања/дешифровања</li>
<li>ОпенПГП ÐПИ издање 3 (вишеÑтруки ÐПИ налози, унутрашње поправке, потрага кључа)</li>
diff --git a/OpenKeychain/src/main/res/raw-sr/help_start.html b/OpenKeychain/src/main/res/raw-sr/help_start.html
index 020f21137..a2f337a2f 100644
--- a/OpenKeychain/src/main/res/raw-sr/help_start.html
+++ b/OpenKeychain/src/main/res/raw-sr/help_start.html
@@ -4,7 +4,7 @@
<h2>Први кораци</h2>
<p>Ðајпре требате лични кључ. Ðаправите један преко менија у „Кључеви“ или увезите поÑтојеће тајне кључеве. Ðакон тога, можете да преузмете пријатељеве кључеве или да их размените преко бар-кодова или ÐФЦ-а.</p>
-<p>За Ðндроид Ñтарији од 4.4 препоручује Ñе да инÑталирате <a href="market://details?id=org.openintents.filemanager">ОИ Менаџер фајлова</a> за побољшани избор фаjлова. Да биÑте делили преко бар-кодова инÑталирајте <a href="market://details?id=com.google.zxing.client.android">Скенер бар-кода</a>. Кликом на везе отворићете Гуглову Продавницу или Ф-Дроид за инÑталацију.</p>
+<p>За Ðндроид Ñтарији од 4.4 препоручује Ñе да инÑталирате <a href="market://details?id=org.openintents.filemanager">ОИ Менаџер фајлова</a> за побољшани избор фаjлова.</p>
<h2>Пронађох грешку у Отвореном кључарнику!</h2>
<p>Пријавите грешку на <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">пратиоцу проблема за Отворени кључарник</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-sr/help_wot.html b/OpenKeychain/src/main/res/raw-sr/help_wot.html
index 91a75bd3c..713b3e331 100644
--- a/OpenKeychain/src/main/res/raw-sr/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-sr/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Веб Поверења</h2>
-<p>Веб поверења опиÑује део ПГП-а који Ñе бави прављењем и књиговодÑтвом Ñертификата. Пружа механизме који помажу кориÑнику у праћењу коме јавни кључ припада и дељењу ове информације Ñа оÑталима; да би Ñе оÑигурала приватноÑÑ‚ шифроване комуникације, нужно је знати да јавни кључ на који шифрујете припада оÑоби којој и миÑлите да припада.</p>
+<p>Веб Поверења опиÑује део ОпенПГП-а који Ñе бави прављењем и Ñпремањем Ñертификата. Пружа механизме који помажу кориÑнику у праћењу коме јавни кључ припада и дељењу ове информације Ñа оÑталима; да би Ñе оÑигурала приватноÑÑ‚ шифроване комуникације, нужно је знати да јавни кључ на који шифрујете припада оÑоби којој и миÑлите да припада.</p>
<h2>Подршка у Отвореном кључарнику</h2>
<p>ПоÑтоји Ñамо оÑновна подршка за Веб поверења у Отвореном кључарнику. Ово је велики поÑао у току и подложан променама у наредним издањима.</p>
diff --git a/OpenKeychain/src/main/res/raw-sv/help_changelog.html b/OpenKeychain/src/main/res/raw-sv/help_changelog.html
index 4d3d293ac..30ab97733 100644
--- a/OpenKeychain/src/main/res/raw-sv/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-sv/help_changelog.html
@@ -4,28 +4,28 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>Fixade nyckelexport till filer (nu på riktigt)</li>
</ul>
<h2>3.1.1</h2>
<ul>
<li>Fix key export to files (they were written partially)</li>
-<li>Fix crash on Android 2.3</li>
+<li>Fixade krasch på Android 2.3</li>
</ul>
<h2>3.1</h2>
<ul>
-<li>Fix crash on Android 5</li>
-<li>New certify screen</li>
+<li>Fixade krasch på Android 5</li>
+<li>Ny certifieringsskärm</li>
<li>Secure Exchange directly from key list (SafeSlinger library)</li>
<li>New QR Code program flow</li>
-<li>Redesigned decrypt screen</li>
-<li>New icon usage and colors</li>
-<li>Fix import of secret keys from Symantec Encryption Desktop</li>
+<li>Omdesignad dekrypteringsskärm</li>
+<li>Nya ikoner och färger</li>
+<li>Fixade import av privata nycklar från Symantec Encryption Desktop</li>
<li>Subkey IDs on Yubikeys are now checked correctly</li>
</ul>
<h2>3.0.1</h2>
<ul>
-<li>Better handling of large key imports</li>
-<li>Improved subkey selection</li>
+<li>Bättre hantering av import av stora nycklar</li>
+<li>Förbättade markeringen av undernycklar</li>
</ul>
<h2>3.0</h2>
<ul>
@@ -58,32 +58,32 @@
</ul>
<h2>2.9</h2>
<ul>
-<li>Fixing crashes introduced in v2.8</li>
-<li>Experimental ECC support</li>
-<li>Experimental Yubikey support (signing-only with imported keys)</li>
+<li>Fixar krascher som uppstod i v2.8</li>
+<li>Experimentellt stöd för ECC</li>
+<li>Experimentellt stöd för Yubikey (endast signering med importerade nycklar)</li>
</ul>
<h2>2.8</h2>
<ul>
<li>So many bugs have been fixed in this release that we focus on the main new features</li>
-<li>Key edit: awesome new design, key revocation</li>
+<li>Nyckelredigering: ny design, nyckelåterkallelse</li>
<li>Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records</li>
-<li>New first time screen</li>
+<li>Ny första gången-skärm</li>
<li>New key creation screen: autocompletion of name and email based on your personal Android accounts</li>
-<li>File encryption: awesome new design, support for encrypting multiple files</li>
-<li>New icons to show status of key (by Brennan Novak)</li>
+<li>Filkryptering: ny design, stöd för att kryptera flera filer</li>
+<li>Nya ikoner för att visa nyckelstatus (av Brennan Novak)</li>
<li>Important bug fix: Importing of large key collections from a file is now possible</li>
-<li>Notification showing cached passphrases</li>
-<li>Keys are connected to Android's contacts</li>
+<li>Notis visar cachace lösenordsfraser</li>
+<li>Nycklar är anslutna till Androids kontakter</li>
</ul>
<p>This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar</p>
<h2>2.7</h2>
<ul>
-<li>Purple! (Dominik, Vincent)</li>
-<li>New key view design (Dominik, Vincent)</li>
-<li>New flat Android buttons (Dominik, Vincent)</li>
-<li>API fixes (Dominik)</li>
-<li>Keybase.io import (Tim Bray)</li>
+<li>Lila! (Dominik, Vincent)</li>
+<li>Ny design av nyckelvy (Dominik, Vincent)</li>
+<li>Nya platta Android-knappar (Dominik, Vincent)</li>
+<li>API-fixar (Dominik)</li>
+<li>Import från Keybase.io (Tim Bray)</li>
</ul>
<h2>2.6.1</h2>
<ul>
@@ -93,15 +93,15 @@
<ul>
<li>Key certifications (thanks to Vincent Breitmoser)</li>
<li>Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)</li>
-<li>New design for signature verification</li>
-<li>Custom key length (thanks to Greg Witczak)</li>
+<li>Ny design för verifiering av signaturer</li>
+<li>Anpassad nyckellängd (tack vare Greg Witczak)</li>
<li>Fix share-functionality from other apps</li>
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
-<li>New modern design for encrypt/decrypt screens</li>
+<li>Ny modern design för kryptera-/dekryptera-skärmar</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
</ul>
<h2>2.4</h2>
@@ -110,11 +110,11 @@ Besides several small patches, a notable number of patches are made by the follo
Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.</p>
<ul>
<li>New unified key list</li>
-<li>Colorized key fingerprint</li>
+<li>Färglagda nyckelfingeravtryck</li>
<li>Support for keyserver ports</li>
<li>Deactivate possibility to generate weak keys</li>
<li>Much more internal work on the API</li>
-<li>Certify user ids</li>
+<li>Certifiera användar-ID:n</li>
<li>Keyserver query based on machine-readable output</li>
<li>Lock navigation drawer on tablets</li>
<li>Suggestions for emails on creation of keys</li>
diff --git a/OpenKeychain/src/main/res/raw-sv/help_nfc_beam.html b/OpenKeychain/src/main/res/raw-sv/help_nfc_beam.html
index 966fb554a..4e940a398 100644
--- a/OpenKeychain/src/main/res/raw-sv/help_nfc_beam.html
+++ b/OpenKeychain/src/main/res/raw-sv/help_nfc_beam.html
@@ -1,12 +1,12 @@
<html>
<head></head>
<body>
-<h2>How to receive keys</h2>
+<h2>Hur man tar emot nycklar</h2>
<ol>
<li>Go to your partners keys and open the key you want to share.</li>
-<li>Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.</li>
-<li>After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
-<li>Tap the card and the content will then load on the your device.</li>
+<li>Håll de två enheternas baksidor mot varandra (de måste nästan vidröras) och du känner av en vibration.</li>
+<li>Efter vibrationen kommer du att se innehållet på din partners enhet omvandlas till ett kortliknande föremål och en animation i bakgrunden som ser ut som Star Treks warp speed.</li>
+<li>Tryck på kortet och innehållet kommer att laddas på den andra personens enhet.</li>
</ol>
</body>
</html>
diff --git a/OpenKeychain/src/main/res/raw-sv/help_start.html b/OpenKeychain/src/main/res/raw-sv/help_start.html
index e7220f5e1..da1d90308 100644
--- a/OpenKeychain/src/main/res/raw-sv/help_start.html
+++ b/OpenKeychain/src/main/res/raw-sv/help_start.html
@@ -2,15 +2,15 @@
<head></head>
<body>
<h2>Kom igång</h2>
-<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
+<p>Först behöver du en personlig nyckel. Skapa en via menyn i "Nycklar" eller importera en befintlig privat nyckel. Efteråt så kan du ladda ner dina vänners nycklar eller utbyta dem via QR-koder eller NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>I Android lägre än 4.4 rekommenderas det att du installerar <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> för förbättrad filurval.</p>
<h2>Jag hittade en bugg i OpenKeychain!</h2>
-<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
+<p>Rapporterar buggen med <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">felrapporteringssystemen av OpenKeychain</a>.</p>
<h2>Bidra</h2>
-<p>If you want to help us developing OpenKeychain by contributing code <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">follow our small guide on Github</a>.</p>
+<p>Om du vill hjälpa oss att utveckla OpenKeychain genom att bidra med kod <a href="https://github.com/openpgp-keychain/openpgp-keychain#contribute-code">, följ vår korta guide på Github</a>.</p>
<h2>Översättningar</h2>
<p>Hjälp till med att översätta OpenKeychain! Alla kan delta i <a href="https://www.transifex.com/projects/p/openpgp-keychain/">OpenKeychain på Transifex</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-sv/help_wot.html b/OpenKeychain/src/main/res/raw-sv/help_wot.html
index efada7bd8..68a2e3997 100644
--- a/OpenKeychain/src/main/res/raw-sv/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-sv/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Tillitsnät</h2>
-<p>Tillitsnätet beskriver den del av PGP som handlar om hur man skapar och bokför certifieringar. Det gör det möjligt för användaren att hålla reda på vem en publik nyckel tillhör, och dela denna information med andra; för att försäkra sig om integriteten i krypterad kommunikation är det avgörande att veta att den publika nyckel du krypterar till tillhör den person du tror att den gör.</p>
+<p>Tillitsnätet beskriver den del av OpenPGP som handlar om hur man skapar och bokför certifieringar. Det gör det möjligt för användaren att hålla reda på vem en publik nyckel tillhör, och dela denna information med andra; för att försäkra sig om integriteten i krypterad kommunikation är det avgörande att veta att den publika nyckel du krypterar till tillhör den person du tror att den gör.</p>
<h2>Stöd i OpenKeychain</h2>
<p>Endast grundläggande stöd för tillitsnät finns i OpenKeychain. Arbetet med funktionen pågår och den kan komma att ändras i kommande versioner.</p>
diff --git a/OpenKeychain/src/main/res/raw-sv/nfc_beam_share.html b/OpenKeychain/src/main/res/raw-sv/nfc_beam_share.html
index 083e055c7..b88771e70 100644
--- a/OpenKeychain/src/main/res/raw-sv/nfc_beam_share.html
+++ b/OpenKeychain/src/main/res/raw-sv/nfc_beam_share.html
@@ -2,10 +2,10 @@
<head></head>
<body>
<ol>
-<li>Make sure that NFC is turned on in Settings &gt; More &gt; NFC and make sure that Android Beam is also on in the same section.</li>
-<li>Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.</li>
-<li>After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
-<li>Tap the card and the content will then load on the other person’s device.</li>
+<li>Se till att NFC är påslaget i Inställningar &gt; Mer &gt; NFC och se även till att Android Beam är på i samma avdelning.</li>
+<li>Håll de två enheternas baksidor mot varandra (de måste nästan vidröras) och du känner av en vibration.</li>
+<li>Efter vibrationen kommer du att se innehållet på din enhet omvandlas till ett kortliknande föremål och en animation i bakgrunden som ser ut som Star Treks warp speed.</li>
+<li>Tryck på kortet och innehållet kommer att laddas på den andra personens enhet.</li>
</ol>
</body>
</html>
diff --git a/OpenKeychain/src/main/res/raw-tr/help_changelog.html b/OpenKeychain/src/main/res/raw-tr/help_changelog.html
index a7a8030c8..cb5cdaf36 100644
--- a/OpenKeychain/src/main/res/raw-tr/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-tr/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-tr/help_start.html b/OpenKeychain/src/main/res/raw-tr/help_start.html
index 93674e794..bbcd0326c 100644
--- a/OpenKeychain/src/main/res/raw-tr/help_start.html
+++ b/OpenKeychain/src/main/res/raw-tr/help_start.html
@@ -4,7 +4,7 @@
<h2>BaÅŸlarken</h2>
<p>Öncelikle kişisel bir anahtara ihtiyacınız var. "Anahtarlar" içindeki menüden bir tane oluşturabilir veya var olan gizli anahtarınızı içe aktarabilirsiniz. Daha sonra arkadaşlarınızın anahtarlarını indirebilir ya da QR Kodları veya NFC aracılığıyla değiş tokuş edebilirsiniz.</p>
-<p>Android 4.4 altındaki sürümlere gelişmiş dosya seçimi için <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> yüklenmesi önerilir. QR Kodları ile paylaşmak için <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a> yükleyin. Bağlantılara tıkladığınızda yükleme için Google Play Store veya F-Droid açılır.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>OpenKeychain'de bir bug buldum!</h2>
<p>Lütfen bulduğunuz hataları <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">OpenKeychain sorun izleyici</a> kullanarak rapor edin.</p>
diff --git a/OpenKeychain/src/main/res/raw-tr/help_wot.html b/OpenKeychain/src/main/res/raw-tr/help_wot.html
index f80c1274f..f2282908b 100644
--- a/OpenKeychain/src/main/res/raw-tr/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-tr/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Web of Trust</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>OpenKeychain DesteÄŸi</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
diff --git a/OpenKeychain/src/main/res/raw-uk/help_changelog.html b/OpenKeychain/src/main/res/raw-uk/help_changelog.html
index 4d3d293ac..0cb7d5210 100644
--- a/OpenKeychain/src/main/res/raw-uk/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-uk/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-uk/help_start.html b/OpenKeychain/src/main/res/raw-uk/help_start.html
index f2d2fe6f7..19197f6df 100644
--- a/OpenKeychain/src/main/res/raw-uk/help_start.html
+++ b/OpenKeychain/src/main/res/raw-uk/help_start.html
@@ -4,7 +4,7 @@
<h2>ПриÑтупаючи до роботи</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>Я знайшов помилку в OpenPGP Keychain!</h2>
<p>Будь лаÑка, повідомте про ваду за допомогою <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">відÑтежувача проблем OpenPGP Keychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw-uk/help_wot.html b/OpenKeychain/src/main/res/raw-uk/help_wot.html
index e1296472e..669aa0649 100644
--- a/OpenKeychain/src/main/res/raw-uk/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-uk/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Мережа довіри</h2>
-<p>Мережа довіри - The Web of Trust - надає механізм Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ð½Ð°Ð»ÐµÐ¶Ð½Ð¾ÑÑ‚Ñ– ключа Ñаме тому кориÑтувачеві, Ñкий в ньому зазначений. ОÑнова цієї моделі будуєтьÑÑ Ð½Ð° знайомÑтві людей та Ñертифікації Ñвоїм підпиÑом ключів Ñвоїх знайомих. Ðе менш важливо Ð¿Ð¾ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ñ†Ñ–Ñ”Ñ— інформації Ñеред інших кориÑтувачів WoT.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Підтримка у OpenKeychain</h2>
<p>Ðаразі реалізовані тільки базові можливоÑÑ‚Ñ– WoT. Робота в Ñамому розпалі, Ñ– в майбутніх верÑÑ–ÑÑ… OpenKeychain будуть з'ÑвлÑтиÑÑ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ñ– можливоÑÑ‚Ñ–.</p>
diff --git a/OpenKeychain/src/main/res/raw-zh-rTW/help_about.html b/OpenKeychain/src/main/res/raw-zh-rTW/help_about.html
index 6c95c4afe..37b3a2ec6 100644
--- a/OpenKeychain/src/main/res/raw-zh-rTW/help_about.html
+++ b/OpenKeychain/src/main/res/raw-zh-rTW/help_about.html
@@ -7,7 +7,7 @@
<h2>銘è¬</h2>
<ul>
-<li>Dominik Schürmann (Maintainer)</li>
+<li>Dominik Schürmann (維護人)</li>
<li>Art O Cathain</li>
<li>Ash Hughes</li>
<li>Brian C. Barnes</li>
@@ -31,27 +31,27 @@
<h2>函å¼åº«</h2>
<ul>
<li>
-<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Apache License v2)</li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v4</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v7 'appcompat'</a> (Apache License v2)</li>
+<a href="http://developer.android.com/tools/support-library/index.html">Android Support Library v7 'appcompat'</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="https://github.com/timbray/KeybaseLib">KeybaseLib</a> (Apache License v2)</li>
+<a href="https://github.com/timbray/KeybaseLib">KeybaseLib</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="https://github.com/JohnPersano/SuperToasts">SuperToasts</a> (Apache License v2)</li>
+<a href="https://github.com/JohnPersano/SuperToasts">SuperToasts</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="https://github.com/splitwise/TokenAutoComplete">TokenAutoComplete</a> (Apache License v2)</li>
+<a href="https://github.com/splitwise/TokenAutoComplete">TokenAutoComplete</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="https://github.com/rtreffer/minidns">MiniDNS</a> (Apache License v2)</li>
+<a href="https://github.com/rtreffer/minidns">MiniDNS</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Apache License v2)</li>
+<a href="https://github.com/emilsjolander/StickyListHeaders">StickyListHeaders</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="http://code.google.com/p/zxing/">ZXing</a> (Apache License v2)</li>
+<a href="http://code.google.com/p/zxing/">ZXing</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11 License)</li>
+<a href="http://rtyley.github.com/spongycastle/">SpongyCastle</a> (MIT X11授權æ¢æ¬¾)</li>
<li>
-<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache License v2)</li>
+<a href="https://github.com/dschuermann/html-textview">HtmlTextView</a> (Apache授權æ¢æ¬¾ v2)</li>
<li>
-<a href="https://github.com/SafeSlingerProject/exchange-android">SafeSlinger Exchange library</a> (MIT License)</li>
+<a href="https://github.com/SafeSlingerProject/exchange-android">SafeSlinger Exchange library</a> (MIT授權æ¢æ¬¾)</li>
</ul>
</body>
</html>
diff --git a/OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.html b/OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.html
index 4d3d293ac..bf28ea2e0 100644
--- a/OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.html
@@ -4,22 +4,22 @@
<h2>3.1.2</h2>
<ul>
-<li>Fix key export to files (now for real)</li>
+<li>修正ã€åŒ¯å‡ºé‡‘鑰到檔案〞功能(這次是真的了)</li>
</ul>
<h2>3.1.1</h2>
<ul>
-<li>Fix key export to files (they were written partially)</li>
-<li>Fix crash on Android 2.3</li>
+<li>修正ã€åŒ¯å‡ºé‡‘鑰到檔案〞功能(部分完æˆ)</li>
+<li>修正在Android 2.3上的崩潰</li>
</ul>
<h2>3.1</h2>
<ul>
-<li>Fix crash on Android 5</li>
-<li>New certify screen</li>
-<li>Secure Exchange directly from key list (SafeSlinger library)</li>
+<li>修正在Android 5上的崩潰</li>
+<li>æ–°çš„èªè­‰ç•«é¢</li>
+<li>ç›´æŽ¥åœ¨é‡‘é‘°æ¸…å–®é€²è¡Œå®‰å…¨çš„é‡‘é‘°äº¤æ› (使用SafeSlinger程å¼åº«)</li>
<li>New QR Code program flow</li>
-<li>Redesigned decrypt screen</li>
+<li>é‡æ–°è¨­è¨ˆçš„解密畫é¢</li>
<li>New icon usage and colors</li>
-<li>Fix import of secret keys from Symantec Encryption Desktop</li>
+<li>修正從Symantec Encryption Desktop匯入密鑰的å•é¡Œ</li>
<li>Subkey IDs on Yubikeys are now checked correctly</li>
</ul>
<h2>3.0.1</h2>
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-zh-rTW/help_start.html b/OpenKeychain/src/main/res/raw-zh-rTW/help_start.html
index ce6e388a8..44835cc46 100644
--- a/OpenKeychain/src/main/res/raw-zh-rTW/help_start.html
+++ b/OpenKeychain/src/main/res/raw-zh-rTW/help_start.html
@@ -4,7 +4,7 @@
<h2>快速上手</h2>
<p>首先你需è¦ä¸€æ”¯å€‹äººé‡‘鑰,通éŽé¸å–®ä¾†å»ºç«‹ä¸€æ”¯é‡‘鑰或是匯入ç¾æœ‰ç§é‘°ã€‚接下來,你å¯ä»¥ä¸‹è¼‰ä½ æœ‹å‹çš„金鑰,或是通éŽQRæ¢ç¢¼å’ŒNFC進行交æ›ã€‚</p>
-<p>Android 4.4以下的è£ç½®å¯ä»¥ä¸‹è¼‰<a href="market://details?id=org.openintents.filemanager">OI File Manager檔案總管</a>來é¸æ“‡å’ŒåŠ å¯†æª”案,è¦é€šéŽQRæ¢ç¢¼åˆ†äº«éœ€è¦å…ˆå®‰è£<a href="market://details?id=com.google.zxing.client.android">æ¢ç¢¼æŽƒæ器</a>。點é¸é€£çµé–‹å•ŸGoogle Play商店或F-Droid進行安è£ã€‚</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>我在OpenKeychain發ç¾å•é¡Œï¼</h2>
<p>請通éŽ<a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">OpenKeychainå•é¡Œè¿½è¹¤</a>回報å•é¡Œã€‚</p>
diff --git a/OpenKeychain/src/main/res/raw-zh-rTW/help_wot.html b/OpenKeychain/src/main/res/raw-zh-rTW/help_wot.html
index 3674f22c2..0db0d354f 100644
--- a/OpenKeychain/src/main/res/raw-zh-rTW/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-zh-rTW/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>信任網</h2>
-<p>信任網æ述了PGP建立與紀錄èªè­‰çš„部分,它æ供使用者追蹤公鑰所有人並與他人分享此一資訊的機制。為了確ä¿åŠ å¯†é€šè¨Šçš„éš±ç§ï¼Œä½ å¿…須確èªç”¨ä¾†åŠ å¯†çš„公鑰屬於你所期望的å°è±¡ã€‚</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>OpenKeychain的支æ´ç‹€æ³</h2>
<p>ç›®å‰OpenKeychainå°ä¿¡ä»»ç¶²åªæœ‰åŸºæœ¬ç¨‹åº¦çš„支æ´ã€‚這是一件大工程,有任何進展將隨時發佈。</p>
diff --git a/OpenKeychain/src/main/res/raw-zh/help_changelog.html b/OpenKeychain/src/main/res/raw-zh/help_changelog.html
index 728d85c11..7bba18be8 100644
--- a/OpenKeychain/src/main/res/raw-zh/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw-zh/help_changelog.html
@@ -99,7 +99,7 @@
</ul>
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw-zh/help_start.html b/OpenKeychain/src/main/res/raw-zh/help_start.html
index 357f937c9..1290e109a 100644
--- a/OpenKeychain/src/main/res/raw-zh/help_start.html
+++ b/OpenKeychain/src/main/res/raw-zh/help_start.html
@@ -4,7 +4,7 @@
<h2>快速上手指å—</h2>
<p>首先你需è¦ä¸€ä¸ªä¸ªäººå¯†é’¥ã€‚å¯ä»¥é€šè¿‡èœå•åˆ›å»ºä¸€ä¸ªå¯†é’¥æˆ–者导入已有密钥。之åŽä½ å°±å¯ä»¥ä»Žç½‘络下载朋å‹çš„密钥或者通过二维ç å’ŒNFC功能交æ¢å¯†é’¥ã€‚</p>
-<p>安å“4.4一下版本å¯ä»¥é€šè¿‡è¯¥é“¾æŽ¥<a href="market://details?id=org.openintents.filemanager">下载OI File Manager文件管ç†å™¨</a> æ¥é€‰æ‹©å’ŒåŠ å¯†æ–‡ä»¶ã€‚使用二维ç åŠŸèƒ½å¯ä»¥ä¸‹è½½<a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. 点击链接å¯ä»¥ä»Žè°·æ­Œå•†åº—下载安装.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>我在OpenKeychain發ç¾å•é¡Œï¼</h2>
<p>請利用 <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">OpenKeychain 項目回報系統</a>回報å•é¡Œã€‚</p>
diff --git a/OpenKeychain/src/main/res/raw-zh/help_wot.html b/OpenKeychain/src/main/res/raw-zh/help_wot.html
index 29790139b..2a551f79c 100644
--- a/OpenKeychain/src/main/res/raw-zh/help_wot.html
+++ b/OpenKeychain/src/main/res/raw-zh/help_wot.html
@@ -2,7 +2,7 @@
<head></head>
<body>
<h2>Web of Trust</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Support in OpenKeychain</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
diff --git a/OpenKeychain/src/main/res/raw/help_changelog.html b/OpenKeychain/src/main/res/raw/help_changelog.html
index 3a1970565..2cc93bc38 100644
--- a/OpenKeychain/src/main/res/raw/help_changelog.html
+++ b/OpenKeychain/src/main/res/raw/help_changelog.html
@@ -114,7 +114,7 @@ And don't add newlines before or after p tags because of transifex -->
<h2>2.5</h2>
<ul>
-<li>Fix decryption of symmetric pgp messages/files</li>
+<li>Fix decryption of symmetric OpenPGP messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
diff --git a/OpenKeychain/src/main/res/raw/help_start.html b/OpenKeychain/src/main/res/raw/help_start.html
index d54780491..75fe9de26 100644
--- a/OpenKeychain/src/main/res/raw/help_start.html
+++ b/OpenKeychain/src/main/res/raw/help_start.html
@@ -8,7 +8,7 @@ And don't add newlines before or after p tags because of transifex -->
<h2>Getting started</h2>
<p>First you need a personal key. Create one via the menu in "Keys" or import existing secret keys. Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.</p>
-<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection. To share via QR Codes install <a href="market://details?id=com.google.zxing.client.android">Barcode Scanner</a>. Clicking on the links will open Google Play Store or F-Droid for installation.</p>
+<p>On Android lower 4.4, it is recommended that you install <a href="market://details?id=org.openintents.filemanager">OI File Manager</a> for enhanced file selection.</p>
<h2>I found a bug in OpenKeychain!</h2>
<p>Please report the bug using the <a href="https://github.com/openpgp-keychain/openpgp-keychain/issues">issue tracker of OpenKeychain</a>.</p>
diff --git a/OpenKeychain/src/main/res/raw/help_wot.html b/OpenKeychain/src/main/res/raw/help_wot.html
index 0ed8e586d..d2ce4a7ae 100644
--- a/OpenKeychain/src/main/res/raw/help_wot.html
+++ b/OpenKeychain/src/main/res/raw/help_wot.html
@@ -6,7 +6,7 @@ And don't add newlines before or after p tags because of transifex -->
</head>
<body>
<h2>Web of Trust</h2>
-<p>The Web of Trust describes the part of PGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
+<p>The Web of Trust describes the part of OpenPGP which deals with creation and bookkeeping of certifications. It provides mechanisms to help the user keep track of who a public key belongs to, and share this information with others; To ensure the privacy of encrypted communication, it is essential to know that the public key you encrypt to belongs to the person you think it does.</p>
<h2>Support in OpenKeychain</h2>
<p>There is only basic support for Web of Trust in OpenKeychain. This is a heavy work in progress and subject to changes in upcoming releases.</p>
diff --git a/OpenKeychain/src/main/res/values-bg/strings.xml b/OpenKeychain/src/main/res/values-bg/strings.xml
new file mode 100644
index 000000000..ef0a0ce94
--- /dev/null
+++ b/OpenKeychain/src/main/res/values-bg/strings.xml
@@ -0,0 +1,66 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+ <!--GENERAL: Please put all strings inside quotes as described in example 1 on
+ http://developer.android.com/guide/topics/resources/string-resource.html (scroll down to "Escaping apostrophes and quotes").-->
+ <!--title-->
+ <!--section-->
+ <!--button-->
+ <!--menu-->
+ <!--label-->
+ <!--choice-->
+ <!--key flags-->
+ <!--sentences-->
+ <!--errors
+ no punctuation, all lowercase,
+ they will be put after "error_message", e.g. "Error: file not found"-->
+ <!--errors without preceeding Error:-->
+ <!--results shown after decryption/verification-->
+ <!--Add keys-->
+ <!--progress dialogs, usually ending in '…'-->
+ <!--action strings-->
+ <!--key bit length selections-->
+ <!--elliptic curve names-->
+ <!--not in for now, see SaveKeyringParcel
+ <string name="key_curve_bp_p256">"Brainpool P-256"</string>
+ <string name="key_curve_bp_p384">"Brainpool P-384"</string>
+ <string name="key_curve_bp_p512">"Brainpool P-512"</string>-->
+ <!--compression-->
+ <!--Help-->
+ <!--Import-->
+ <!--Generic result toast-->
+ <!--Import result toast-->
+ <!--Delete result toast-->
+ <!--Certify result toast-->
+ <!--Intent labels-->
+ <!--Remote API-->
+ <!--Share-->
+ <!--Key list-->
+ <!--Key view-->
+ <!--Edit key-->
+ <!--Create key-->
+ <!--View key-->
+ <!--Navigation Drawer-->
+ <!--hints-->
+ <!--certs-->
+ <!--LogType log messages. Errors should have _ERROR_ in their name and end with a !-->
+ <!--Import Public log entries-->
+ <!--Import Secret log entries-->
+ <!--Keyring Canonicalization log entries-->
+ <!--Keyring merging log entries-->
+ <!--createSecretKeyRing-->
+ <!--modifySecretKeyRing-->
+ <!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
+ <!--Other messages used in OperationLogs-->
+ <!--Messages for DecryptVerify operation-->
+ <!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
+ <!--PassphraseCache-->
+ <!--First Time-->
+ <!--unsorted-->
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+</resources>
diff --git a/OpenKeychain/src/main/res/values-cs/strings.xml b/OpenKeychain/src/main/res/values-cs/strings.xml
index 4243ee68b..cbf0eb0b8 100644
--- a/OpenKeychain/src/main/res/values-cs/strings.xml
+++ b/OpenKeychain/src/main/res/values-cs/strings.xml
@@ -9,12 +9,12 @@
<string name="title_encrypt_text">Zašifrovat text</string>
<string name="title_encrypt_files">Zašifrovat soubory</string>
<string name="title_decrypt">Rozšifrovat</string>
- <string name="title_authentication">Heslo</string>
+ <string name="title_unlock">Odemknout klíÄ</string>
<string name="title_add_subkey">PÅ™idat podklíÄ</string>
<string name="title_edit_key">Editovat klíÄ</string>
- <string name="title_preferences">Možnosti</string>
+ <string name="title_preferences">Nastavení</string>
+ <string name="title_cloud_search_preferences">Nastavení vyhledávání v cloudu</string>
<string name="title_api_registered_apps">Aplikace</string>
- <string name="title_key_server_preference">Nastavení keyservrů</string>
<string name="title_change_passphrase">Změnit heslo</string>
<string name="title_share_fingerprint_with">Sdílet otisk s...</string>
<string name="title_share_key">Sdílet klÃ­Ä s...</string>
@@ -33,6 +33,7 @@
<string name="title_help">Nápověda</string>
<string name="title_log_display">Log</string>
<string name="title_create_key">VytvoÅ™it klíÄ</string>
+ <string name="title_exchange_keys">VymÄ›nit klíÄe</string>
<string name="title_advanced_key_info">Další informace ke klíÄi</string>
<!--section-->
<string name="section_user_ids">Identity</string>
@@ -41,6 +42,8 @@
<string name="section_general">Obecné</string>
<string name="section_defaults">Výchozí hodnoty</string>
<string name="section_advanced">PokroÄilé</string>
+ <string name="section_passphrase_cache">Cache hesel</string>
+ <string name="section_certify">Certifikovat</string>
<string name="section_actions">Akce</string>
<string name="section_share_key">KlíÄ</string>
<string name="section_certification_key">KlÃ­Ä použitý pro certifikaci</string>
@@ -70,7 +73,6 @@
<string name="btn_create_key">VytvoÅ™it klíÄ</string>
<string name="btn_add_files">Přidat soubor(y)</string>
<string name="btn_add_share_decrypted_text">Sdílet dešifrovaný text</string>
- <string name="btn_decrypt_clipboard">Dešifrovat ze schránky</string>
<string name="btn_decrypt_and_verify">a ověřit podpisy</string>
<string name="btn_decrypt_files">Dešifrovat soubory</string>
<!--menu-->
@@ -102,8 +104,9 @@
<string name="label_file_ascii_armor">Povolit ASCII armor</string>
<string name="label_write_version_header">Dát ostatním vědět, že používáte OpenKeychain</string>
<string name="label_write_version_header_summary">Zapisovat \'OpenKeychain v2.7\' do OpenPGP podpisů, Å¡ifrovaného textu a exportovaných klíÄů</string>
- <string name="label_use_default_yubikey_pin">Použít výchozí Yubikey PIN</string>
- <string name="label_label_use_default_yubikey_pin_summary">Používá základní PIN (123456) pro přístup k Yubikey přes NFC</string>
+ <string name="label_use_default_yubikey_pin">Použít výchozí YubiKey PIN</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Použít numerickou klávesnici pro YubiKey PIN</string>
+ <string name="label_label_use_default_yubikey_pin_summary">Používá základní PIN (123456) pro přístup k YubiKey přes NFC</string>
<string name="label_asymmetric_from">Podepsáno:</string>
<string name="label_to">Zašifrovat pro:</string>
<string name="label_delete_after_encryption">Smazat soubor po zašifrování</string>
@@ -111,6 +114,8 @@
<string name="label_encryption_algorithm">Šifrovací algoritmus</string>
<string name="label_hash_algorithm">Hashovací algoritmus</string>
<string name="label_symmetric">Zašifrovat heslem</string>
+ <string name="label_passphrase_cache_ttl">Čas vypršení pro cache</string>
+ <string name="label_passphrase_cache_subs">Pamatovat si heslo podle podklíÄe</string>
<string name="label_message_compression">Komprimovat zprávu</string>
<string name="label_file_compression">Komprimovat soubor</string>
<string name="label_keyservers">Keyservery</string>
@@ -127,6 +132,7 @@
<string name="label_send_key">Synchronizovat s cloudem</string>
<string name="label_fingerprint">Otisk</string>
<string name="expiry_date_dialog_title">Nastavit datum expirace</string>
+ <string name="label_first_keyserver_is_used">(Výchozí je první keyserver)</string>
<string name="label_preferred">upřednostněno</string>
<string name="user_id_no_name">&lt;beze jména&gt;</string>
<string name="none">&lt;žádný&gt;</string>
@@ -183,7 +189,9 @@
<string name="passphrase_must_not_be_empty">Prosím zadejte heslo.</string>
<string name="passphrase_for_symmetric_encryption">Symetrická šifra.</string>
<string name="passphrase_for">Zadejte heslo pro \'%s\'</string>
- <string name="yubikey_pin">Zadejte PIN pro přístup k Yubikey pro \'%s\'</string>
+ <string name="pin_for">Zadat PIN pro \'%s\'</string>
+ <string name="yubikey_pin_for">Zadejte PIN pro přístup k YubiKey pro \'%s\'</string>
+ <string name="nfc_text">Přidržte YubiKey u zadní strany vašeho přístroje.</string>
<string name="file_delete_confirmation">Chcete opravdu smazat\n%s?</string>
<string name="file_delete_successful">Úspěšně smazáno.</string>
<string name="no_file_selected">Nejprve vyberte soubor.</string>
@@ -192,7 +200,14 @@
<string name="enter_passphrase_twice">Heslo zadejte dvakrát.</string>
<string name="select_encryption_key">Vyberte alespoň jeden Å¡ifrovací klíÄ.</string>
<string name="select_encryption_or_signature_key">Vyberte alespoň jeden Å¡ifrovací nebo podpisový klíÄ.</string>
+ <string name="specify_file_to_encrypt_to">Prosím specifikujte do kterého souboru zaÅ¡ifrovat.\nVAROVÃNÃ: Pokud soubor již existuje, bude pÅ™epsán.</string>
+ <string name="specify_file_to_decrypt_to">Prosím specifikujte do kterého souboru rozÅ¡ifrovat.\nVAROVÃNÃ: Pokud soubor již existuje, bude pÅ™epsán.</string>
+ <string name="specify_file_to_export_to">Prosím specifikujte do kterého souboru exportovat.\nVAROVÃNÃ: Pokud soubor již existuje, bude pÅ™epsán.</string>
+ <string name="key_deletion_confirmation_multi">Opravdu si pÅ™ejete smazat vÅ¡echny vybrané veÅ™ejné klíÄe?\nToto nebude možné vzít zpÄ›t!</string>
+ <string name="secret_key_deletion_confirmation">Opravdu chcete smazat TAJNà klÃ­Ä \'%s\'?\nTuto operaci nelze vzít zpÄ›t!</string>
+ <string name="public_key_deletetion_confirmation">Opravdu chcete smazat veÅ™ejný klÃ­Ä \'%s\'?\nToto nelze vzít zpÄ›t!</string>
<string name="also_export_secret_keys">Zárověň exportovat tajný klíÄ</string>
+ <string name="reinstall_openkeychain">Narazili jste na známou chybu v Androidu. PÅ™einstalujte prosím OpenKeychain pokud chcete své propojit kontakty s klíÄi.</string>
<string name="key_exported">ÚspěšnÄ› exportován 1 klíÄ.</string>
<string name="keys_exported">ÚspěšnÄ› exportován %d klíÄ.</string>
<string name="no_keys_exported">Žádný klÃ¡Ä pro export.</string>
@@ -225,16 +240,22 @@
<string name="error_jelly_bean_needed">Musíte mít Android 4.1 abyste mohli používat Androidí NFC Beam technologii!</string>
<string name="error_nfc_needed">NFC není na vašem zařízení k dispozici!</string>
<string name="error_nothing_import">Žádný klÃ­Ä nenalezen!</string>
+ <string name="error_contacts_key_id_missing">Příjem ID klíÄe od kontatktu selhal!</string>
<string name="error_generic_report_bug">Nastala obecná chyba, prosím vytvořte nový bug report pro OpenKeychain.</string>
<!--results shown after decryption/verification-->
<string name="decrypt_result_no_signature">Nepodepsáno</string>
<string name="decrypt_result_invalid_signature">Špatný podpis!</string>
+ <string name="decrypt_result_signature_uncertified">Kým podepsáno (neověřen!)</string>
<string name="decrypt_result_signature_certified">Podepsáno</string>
+ <string name="decrypt_result_signature_expired_key">KlÃ­Ä neplatný!</string>
+ <string name="decrypt_result_signature_revoked_key">KlÃ­Ä byl revokován!</string>
<string name="decrypt_result_signature_missing_key">Neznámý veÅ™ejný klíÄ</string>
<string name="decrypt_result_encrypted">Zašifrováno</string>
<string name="decrypt_result_not_encrypted">Nezašifrováno</string>
<string name="decrypt_result_action_show">Zobrazit</string>
<string name="decrypt_result_action_Lookup">Vyhledat</string>
+ <string name="decrypt_invalid_text">Podpis neplatný, platnost klíÄe vyprÅ¡ela nebo byl zruÅ¡en. Nemůžete si být jistí tím, kdo text napsal. Jste si jistí, že chcete i pÅ™esto zprávu zobrazit?</string>
+ <string name="decrypt_invalid_button">Beru na vědomí, zobraz to!</string>
<!--Add keys-->
<string name="add_keys_my_key">Můj klíÄ:</string>
<!--progress dialogs, usually ending in '…'-->
@@ -255,6 +276,7 @@
<string name="progress_modify">modifikuji klíÄenku...</string>
<string name="progress_modify_unlock">odemykám klíÄenku...</string>
<string name="progress_modify_adduid">pÅ™idávám uživatelské IDÄka...</string>
+ <string name="progress_modify_adduat">přidávám uživatelovy atributy...</string>
<string name="progress_modify_revokeuid">revokuji uživatelská IDÄka...</string>
<string name="progress_modify_primaryuid">měním primární uživatelské ID...</string>
<string name="progress_modify_subkeychange">modifikuji podklíÄe...</string>
@@ -285,6 +307,7 @@
<string name="progress_deleting">mažu klíÄe...</string>
<!--action strings-->
<string name="hint_keyserver_search_hint">Jméno/Email/ID klíÄe</string>
+ <string name="hint_cloud_search_hint">Jméno/Email/Důkaz/KlíÄ...</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@@ -327,8 +350,12 @@
<string name="import_qr_code_too_short_fingerprint">Fingerprint je příliš krátký (&lt; 16 znaků)</string>
<string name="import_qr_code_button">Naskenovat QR kód</string>
<!--Generic result toast-->
- <string name="view_log">Zobrazit log</string>
<!--Import result toast-->
+ <plurals name="import_keys_added_and_updated_1">
+ <item quantity="one">KlÃ­Ä ÃºspěšnÄ› importován</item>
+ <item quantity="few">ÚspěšnÄ› importováno %1$d klíÄe</item>
+ <item quantity="other">ÚspěšnÄ› importováno %1$d klíÄů</item>
+ </plurals>
<plurals name="import_error">
<item quantity="one">Import selhal!</item>
<item quantity="few">Import %d klíÄů selhal!</item>
@@ -337,6 +364,8 @@
<string name="import_error_nothing">Nic k importu</string>
<string name="import_error_nothing_cancelled">Import zrušen.</string>
<!--Delete result toast-->
+ <string name="delete_nothing">Nic ke smazání.</string>
+ <string name="delete_cancelled">Operace smazání zrušena.</string>
<!--Certify result toast-->
<!--Intent labels-->
<string name="intent_decrypt_file">Dešifrovat soubor pomocí OpenKeychain</string>
@@ -359,7 +388,6 @@
<string name="api_settings_delete_account">Smazat úÄet</string>
<string name="api_settings_package_name">Jméno balíÄku</string>
<string name="api_settings_package_signature">SHA-256 z podpisu balíÄku</string>
- <string name="api_settings_accounts">ÚÄty</string>
<string name="api_settings_settings">Nastavení</string>
<string name="api_settings_key">KlÃ­Ä ÃºÄtu:</string>
<string name="api_settings_accounts_empty">Žádné úÄty nejsou specifikovány pro tuto appku.</string>
@@ -380,6 +408,9 @@
<item quantity="few">%d klíÄe vybrány.</item>
<item quantity="other">%d klíÄů vybráno.</item>
</plurals>
+ <string name="key_list_empty_text1">Žádný klÃ­Ä nenalezen!</string>
+ <string name="key_list_filter_show_all">Zobrazit vÅ¡echny klíÄe</string>
+ <string name="key_list_filter_show_certified">Zobrazit puze ověřené klíÄe</string>
<!--Key view-->
<string name="key_view_action_edit">Editovat klíÄ</string>
<string name="key_view_action_encrypt">Zašifrovat text</string>
@@ -395,6 +426,10 @@
<string name="key_view_tab_certs">Certifikáty</string>
<string name="user_id_info_revoked_title">Zneplatněno</string>
<string name="user_id_info_revoked_text">Tato identity byla zneplatnÄ›na vlastníkem klíÄe. KlÃ­Ä již není platný.</string>
+ <string name="user_id_info_certified_title">Ověřeno</string>
+ <string name="user_id_info_certified_text">Tato identita byla vámi ověřena</string>
+ <string name="user_id_info_uncertified_title">Neověřeno</string>
+ <string name="user_id_info_uncertified_text">Tato identita nebyla jeÅ¡tÄ› ověřena. Nemůžete si být jisti, že identita skuteÄnÄ› odpovídá konkrétní osobÄ›.</string>
<string name="user_id_info_invalid_title">Neplatná</string>
<string name="user_id_info_invalid_text">S touto identitou je něco v nepořádku!</string>
<!--Edit key-->
@@ -411,22 +446,31 @@
</string-array>
<string name="edit_key_edit_user_id_revoked">Tato identity byla zneplatněna. Toto není možné vzít zpět.</string>
<string name="edit_key_edit_subkey_title">Vyberte akci!</string>
+ <string-array name="edit_key_edit_subkey">
+ <item>Změnit expiraci</item>
+ <item>Zneplatnit podklíÄ</item>
+ <item>Strip podklíÄ</item>
+ </string-array>
<string name="edit_key_new_subkey">nový podklíÄ</string>
+ <string name="edit_key_select_flag">Prosím vyberte alespoň jeden příznak!</string>
+ <string name="edit_key_error_add_identity">Přidejte alespoň jednu identitu!</string>
+ <string name="edit_key_error_add_subkey">PÅ™idejte alespoň jeden podklíÄ!</string>
<!--Create key-->
<string name="create_key_upload">Aktualizovat klÃ­Ä na keyserver</string>
<string name="create_key_empty">Toto pole je vyžadováno</string>
<string name="create_key_passphrases_not_equal">Heslo nesouhlasí</string>
<string name="create_key_final_text">Zadali jste následující identitu:</string>
+ <string name="create_key_final_robot_text">VytvoÅ™ení klíÄe může chvíli trvat, mezitím si dejte tÅ™eba šálek dobré kávy...</string>
+ <string name="create_key_rsa">(3 podklíÄe, RSA, 4096 bit)</string>
+ <string name="create_key_custom">(uživatelská konfigurace klíÄe)</string>
<string name="create_key_text">Zadejte své celé jméno, emailovou adresu a zvolte heslo.</string>
<string name="create_key_hint_full_name">Celé jméno, např. Jan Novák</string>
+ <string name="create_key_edit">ZmÄ›nit konfiguraci klíÄe</string>
<!--View key-->
<string name="view_key_revoked">Tento klÃ­Ä byl zneplatnÄ›n!</string>
<string name="view_key_expired">Tento klÃ­Ä vyexpiroval!</string>
<!--Navigation Drawer-->
<string name="nav_keys">KlíÄe</string>
- <string name="nav_encrypt_text">Zašifrovat text</string>
- <string name="nav_encrypt_files">Zašifrovat soubory</string>
- <string name="nav_decrypt">Rozšifrovat</string>
<string name="nav_apps">Aplikace</string>
<string name="drawer_open">Otevřít navigaÄní panel</string>
<string name="drawer_close">Zavří navigaÄní panel</string>
@@ -456,21 +500,27 @@
<!--createSecretKeyRing-->
<string name="msg_cr">Generuji nový hlavní klíÄ</string>
<string name="msg_cr_error_no_keysize">Nebyla specifikována eliptická křivka! Toto je chyba v programování a je třeba ji nahlásit!</string>
- <string name="msg_cr_error_internal_pgp">Vnitřní chyba PGP!</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Upravuji klíÄenku %s</string>
<string name="msg_mf_uid_error_empty">Uživatelské ID nesmí být prázdné!</string>
<!--Consolidate-->
<string name="msg_con_error_db">Chyba otevírání databáze!</string>
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_not_found">KlÃ­Ä nenalezen!</string>
<!--Messages for DecryptVerify operation-->
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<string name="msg_acc_saved">ÚÄet uložen</string>
<!--PassphraseCache-->
<string name="passp_cache_notif_click_to_clear">Kliknout pro vymazání naÄtených hesel</string>
<string name="passp_cache_notif_clear">Smazat cache</string>
<string name="passp_cache_notif_pwd">Heslo</string>
+ <!--First Time-->
+ <string name="first_time_text1">Převezměte opět kontrolu nad svým soukromím s OpenKeychain!</string>
+ <string name="first_time_create_key">VytvoÅ™it vlastní klíÄ</string>
+ <string name="first_time_skip">PÅ™eskoÄit nastavení</string>
<!--unsorted-->
<string name="section_cert">Detaily certifikátu</string>
<string name="label_user_id">Identita</string>
@@ -490,8 +540,8 @@
<string name="error_no_encrypt_subkey">Není dostupný Å¡ifrovací podklíÄ!</string>
<string name="contact_show_key">Zobrazit klÃ­Ä (%s)</string>
<string name="swipe_to_update">Potáhnout dolů pro aktualizaci z keyserveru</string>
- <!--First Time-->
- <string name="first_time_text1">Převezměte opět kontrolu nad svým soukromím s OpenKeychain!</string>
- <string name="first_time_create_key">VytvoÅ™it vlastní klíÄ</string>
- <string name="first_time_skip">PÅ™eskoÄit nastavení</string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml
index 3bb5eb9bb..e6416b28b 100644
--- a/OpenKeychain/src/main/res/values-de/strings.xml
+++ b/OpenKeychain/src/main/res/values-de/strings.xml
@@ -9,7 +9,7 @@
<string name="title_encrypt_text">Text Verschlüsseln</string>
<string name="title_encrypt_files">Dateien verschlüsseln</string>
<string name="title_decrypt">Entschlüsseln</string>
- <string name="title_authentication">Passwort</string>
+ <string name="title_unlock">Schlüssel entsperren</string>
<string name="title_add_subkey">Unterschlüssel hinzufügen</string>
<string name="title_edit_key">Schlüssel bearbeiten</string>
<string name="title_preferences">Einstellungen</string>
@@ -36,6 +36,7 @@
<string name="title_create_key">Schlüssel erzeugen</string>
<string name="title_exchange_keys">Schlüssel austauschen</string>
<string name="title_advanced_key_info">Erweiterte Schlüsselinformation</string>
+ <string name="title_keys">Schlüssel</string>
<!--section-->
<string name="section_user_ids">Identitäten</string>
<string name="section_keys">Unterschlüssel</string>
@@ -55,6 +56,8 @@
<string name="section_decrypt_files">Dateien</string>
<string name="section_decrypt_text">Text</string>
<string name="section_certs">Zertifikate</string>
+ <string name="section_encrypt">Verschlüsseln</string>
+ <string name="section_decrypt">Entschlüsseln</string>
<!--button-->
<string name="btn_decrypt_verify_file">Datei entschlüsseln, verifizieren und speichern</string>
<string name="btn_decrypt_verify_message">Entschlüsseln und verifizieren</string>
@@ -74,9 +77,11 @@
<string name="btn_create_key">Schlüssel erzeugen</string>
<string name="btn_add_files">Datei(en) hinzufügen</string>
<string name="btn_add_share_decrypted_text">Entschlüsselten Text teilen</string>
- <string name="btn_decrypt_clipboard">Aus Zwischenablage entschlüsseln</string>
+ <string name="btn_decrypt_clipboard">Text aus Zwischenablage entschlüsseln</string>
<string name="btn_decrypt_and_verify">und Signaturen überprüfen</string>
<string name="btn_decrypt_files">Dateien entschlüsseln</string>
+ <string name="btn_encrypt_files">Dateien verschlüsseln</string>
+ <string name="btn_encrypt_text">Text verschlüsseln</string>
<!--menu-->
<string name="menu_preferences">Einstellungen</string>
<string name="menu_help">Hilfe</string>
@@ -90,6 +95,7 @@
<string name="menu_encrypt_to">Verschlüsseln nach…</string>
<string name="menu_select_all">Alles auswählen</string>
<string name="menu_add_keys">Schlüssel hinzufügen</string>
+ <string name="menu_search_cloud">Cloud durchsuchen</string>
<string name="menu_export_all_keys">Alle Schlüssel exportieren</string>
<string name="menu_advanced">Erweiterte Infos anzeigen</string>
<!--label-->
@@ -106,9 +112,9 @@
<string name="label_file_ascii_armor">Aktiviere ASCII Armor</string>
<string name="label_write_version_header">Lass andere wissen dass du OpenKeychain nutzt</string>
<string name="label_write_version_header_summary">Fügt \'OpenKeychain v2.7\' zu OpenPGP-Signaturen, Daten und exportierten Schlüsseln hinzu</string>
- <string name="label_use_default_yubikey_pin">Standard Yubikey PIN verwenden</string>
- <string name="label_use_num_keypad_for_yubikey_pin">Zifferntastatur für Yubikey PIN verwenden</string>
- <string name="label_label_use_default_yubikey_pin_summary">Verwendet Standard PIN (123456) um auf Yubikeys via NFC zuzugreifen</string>
+ <string name="label_use_default_yubikey_pin">Standard-YubiKey-PIN verwenden</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Zifferntastatur für YubiKey PIN verwenden</string>
+ <string name="label_label_use_default_yubikey_pin_summary">Verwendet Standard-PIN (123456) zum Zugriff auf YubiKeys über NFC</string>
<string name="label_asymmetric_from">Signiert von:</string>
<string name="label_to">Verschlüsselt an:</string>
<string name="label_delete_after_encryption">Datei nach Verschlüsselung löschen</string>
@@ -189,7 +195,9 @@
<string name="passphrase_must_not_be_empty">Bitte ein Passwort eingeben.</string>
<string name="passphrase_for_symmetric_encryption">Symmetrische Verschlüsselung.</string>
<string name="passphrase_for">Passwort für \'%s\' eingeben</string>
- <string name="yubikey_pin">PIN für Zugriff auf Yubikey für \'%s\' eingeben</string>
+ <string name="pin_for">PIN für \'%s\' eingeben</string>
+ <string name="yubikey_pin_for">PIN für Zugriff auf Yubikey für \'%s\' eingeben</string>
+ <string name="nfc_text">Halten Sie den YubiKey gegen die Rückseite Ihres Geräts.</string>
<string name="file_delete_confirmation">%s wirklich löschen?</string>
<string name="file_delete_successful">Erfolgreich gelöscht.</string>
<string name="no_file_selected">Zuerst eine Datei auswählen.</string>
@@ -257,6 +265,7 @@
<string name="decrypt_result_not_encrypted">Nicht Verschlüsselt</string>
<string name="decrypt_result_action_show">Anzeigen</string>
<string name="decrypt_result_action_Lookup">Nachschlagen</string>
+ <string name="decrypt_invalid_text">Der Schlüssel ist entweder ungültig oder wurde zurückgezogen/ist abgelaufen. Sie können den Verfasser der Nachricht nicht eindeutig identifizieren. Wollen Sie die Nachricht trotzdem anzeigen?</string>
<string name="decrypt_invalid_button">Ich verstehe das Risiko, Nachricht anzeigen!</string>
<!--Add keys-->
<string name="add_keys_my_key">Mein Schlüssel:</string>
@@ -278,6 +287,7 @@
<string name="progress_modify">Schlüsselbund wird verändert...</string>
<string name="progress_modify_unlock">Schlüsselbund wird entsperrt...</string>
<string name="progress_modify_adduid">User-ID wird hinzugefügt...</string>
+ <string name="progress_modify_adduat">Benutzerattribute werden hinzugefügt...</string>
<string name="progress_modify_revokeuid">User-IDs werden widerrufen...</string>
<string name="progress_modify_primaryuid">Primäre User-ID wird geändert...</string>
<string name="progress_modify_subkeychange">Unterschlüssel werden verändert...</string>
@@ -306,8 +316,8 @@
<string name="progress_verifying_integrity">Integrität wird überprüft…</string>
<string name="progress_deleting_securely">\'%s\' wird sicher gelöscht…</string>
<string name="progress_deleting">Lösche Schlüssel</string>
- <string name="progress_con_saving">Zusammenführung: Speiche in Cache...</string>
- <string name="progress_con_reimport">Zusammenführung: Reimportiere...</string>
+ <string name="progress_con_saving">Zusammenführung: Im Cache speichern...</string>
+ <string name="progress_con_reimport">Zusammenführung: Neuimportierung...</string>
<!--action strings-->
<string name="hint_keyserver_search_hint">Name/Email/Schlüssel ID...</string>
<string name="hint_cloud_search_hint">Name/Email/Nachweis/Schlüssel...</string>
@@ -352,8 +362,9 @@
<string name="import_qr_code_wrong">Falsch formatierter QR-Code! Bitte erneut versuchen!</string>
<string name="import_qr_code_too_short_fingerprint">Der Fingerabdruck ist zu kurz (&lt; 16 Zeichen)</string>
<string name="import_qr_code_button">QR-Code scannen</string>
+ <string name="import_qr_code_text">Plazieren sie ihre Kamera über dem QR Code!</string>
<!--Generic result toast-->
- <string name="view_log">Log ansehen</string>
+ <string name="view_log">Details</string>
<string name="with_warnings">, mit Warnungen</string>
<string name="with_cancelled">. bis abgebrochen wurde</string>
<!--Import result toast-->
@@ -388,9 +399,33 @@
<item quantity="one">Der Schlüssel wurde erfolgreich gelöscht.</item>
<item quantity="other">%1$d Schlüssel wurden erfolgreich gelöscht</item>
</plurals>
+ <plurals name="delete_ok_but_fail_2">
+ <item quantity="one">, aber das Löschen eines Schlüssels%2$s ist fehlgeschlagen.</item>
+ <item quantity="other">, aber das Löschen von %1$d Schlüsseln%2$s ist fehlgeschlagen.</item>
+ </plurals>
+ <plurals name="delete_ok">
+ <item quantity="one">Erfolgreich gelöscht key%2$s.</item>
+ <item quantity="other">Erfolgreich gelöscht %1$d keys%2$s.</item>
+ </plurals>
+ <plurals name="delete_fail">
+ <item quantity="one">Fehler beim Löschen eines Schlüssels%2$s.</item>
+ <item quantity="other">Fehler beim Löschen von %1$d Schlüsseln.</item>
+ </plurals>
<string name="delete_nothing">Nichts zu löschen.</string>
<string name="delete_cancelled">Löschen abgebrochen.</string>
<!--Certify result toast-->
+ <plurals name="certify_keys_ok">
+ <item quantity="one">Schlüssel%2$s erfolgreich beglaubigt.</item>
+ <item quantity="other">%1$d Schlüssel%2$s erfolgreich beglaubigt.</item>
+ </plurals>
+ <plurals name="certify_keys_with_errors">
+ <item quantity="one">Beglaubigung fehlgeschlagen!</item>
+ <item quantity="other">Beglaubigung für %d Schlüssel fehlgeschlagen!</item>
+ </plurals>
+ <plurals name="certify_error">
+ <item quantity="one">Beglaubigung fehlgeschlagen!</item>
+ <item quantity="other">Beglaubigung von %d Schlüsseln ist fehlgeschlagen!</item>
+ </plurals>
<!--Intent labels-->
<string name="intent_decrypt_file">Datei entschlüsseln mit OpenKeychain</string>
<string name="intent_import_key">Schlüssel importieren mit OpenKeychain</string>
@@ -413,10 +448,14 @@
<string name="api_settings_delete_account">Account löschen</string>
<string name="api_settings_package_name">Paketname</string>
<string name="api_settings_package_signature">SHA-256 der Paketsignatur</string>
- <string name="api_settings_accounts">Konten</string>
+ <string name="api_settings_accounts">Konten (veraltete API)</string>
+ <string name="api_settings_advanced">Erweiterte Informationen</string>
+ <string name="api_settings_allowed_keys">Erlaubte Schlüssel</string>
<string name="api_settings_settings">Einstellungen</string>
<string name="api_settings_key">Account Schlüssel:</string>
<string name="api_settings_accounts_empty">Keine Konten mit dieser Anwendung verknüpft.</string>
+ <string name="api_create_account_text">Für diesen Account ist kein Schlüssel hinterlegt. Bitte wähle einen deiner existierenden Schlüssel aus oder erstelle einen neuen.\nApps können nur hier ausgewählte Schlüssel nutzen.</string>
+ <string name="api_update_account_text">Der Schlüssel für diesen Account wurde gelöscht. Bitte wähle einen anderen aus!\nApps können nur hier ausgewählte Schlüssel nutzen.</string>
<string name="api_register_text">Folgende Anwendung möchte Nachrichten ver-/entschlüsseln und in Ihrem Namen signieren. Zugriff erlauben?\n\nVORSICHT: Sollten Sie nicht wissen warum dieses Fenster erscheint, sollten Sie den Zugriff verbieten! Sie können Zugriffe später über das Menü \'Apps\' widerrufen.</string>
<string name="api_register_allow">Zugriff erlauben</string>
<string name="api_register_disallow">Zugriff verbieten</string>
@@ -455,6 +494,7 @@
<string name="user_id_info_certified_title">Beglaubigt</string>
<string name="user_id_info_certified_text">Diese Identität wurde von Ihnen beglaubigt.</string>
<string name="user_id_info_uncertified_title">Nicht beglaubigt</string>
+ <string name="user_id_info_uncertified_text">Diese Identität wurde noch nicht beglaubigt. Sie können nicht sicher sein, ob diese Identität wirklich zu einer bestimmten Person gehört.</string>
<string name="user_id_info_invalid_title">Ungültig</string>
<string name="user_id_info_invalid_text">Irgend etwas ist mit dieser Identität nicht in Ordnung!</string>
<!--Edit key-->
@@ -496,9 +536,7 @@
<string name="view_key_expired">Dieser Schlüssel ist nicht mehr gültig!</string>
<!--Navigation Drawer-->
<string name="nav_keys">Schlüssel</string>
- <string name="nav_encrypt_text">Text Verschlüsseln</string>
- <string name="nav_encrypt_files">Dateien Verschlüsseln</string>
- <string name="nav_decrypt">Entschlüsseln</string>
+ <string name="nav_encrypt_decrypt">Verschlüsseln/Entschlüsseln</string>
<string name="nav_apps">Apps</string>
<string name="drawer_open">Menü öffnen</string>
<string name="drawer_close">Menü schließen</string>
@@ -519,6 +557,7 @@
<string name="msg_internal_error">Interner Fehler!</string>
<string name="msg_cancelled">Vorgang abgebrochen.</string>
<!--Import Public log entries-->
+ <string name="msg_ip_apply_batch">Eingabeoperationen werden angewendet.</string>
<string name="msg_ip_bad_type_secret">Es wurde versucht einen geheimen Schlüsselbund als Öffentlich zu importieren. Das ist ein Fehler, bitte reiche einen Bericht ein.</string>
<string name="msg_ip_delete_old_fail">Kein alter Schlüssel gelöscht (Einen neuen erzeugen?)</string>
<string name="msg_ip_delete_old_ok">Alte Schlüssel aus der Datenbank löschen</string>
@@ -551,6 +590,7 @@
<string name="msg_ip_master_flags_xxxa">Haupt-Attribute: authentifizieren</string>
<string name="msg_ip_master_flags_xxxx">Haupt-Attribute: Keine</string>
<string name="msg_ip_merge_public">Füge importierte Daten in existierend öffentlichen Schlüsselbund ein</string>
+ <string name="msg_ip_merge_secret">Importierte Daten werden in vorhandenen öffentlichen Schlüsselbund eingefügt</string>
<string name="msg_ip_subkey">Unterschlüssel %s wird bearbeitet</string>
<string name="msg_ip_subkey_expired">Unterschlüssel am %s abgelaufen</string>
<string name="msg_ip_subkey_expires">Unterschlüssel läuft am %s ab</string>
@@ -585,30 +625,63 @@
<item quantity="one">Ignoriere eine Beglaubigung, ausgestellt von unbekanntm öffentlichen Schlüssel</item>
<item quantity="other">Ignoriere %s Beglaubigungen, ausgestellt von unbekannten öffentlichen Schlüsseln</item>
</plurals>
+ <string name="msg_ip_uid_classifying_zero">Benutzerkennungen werden klassifiziert (keine vertrauenswürdigen Schlüssel verfügbar)</string>
+ <plurals name="msg_ip_uid_classifying">
+ <item quantity="one">Benutzerkennungen werden klassifiziert (ein vertrauenswürdiger Schlüssel wird verwendet)</item>
+ <item quantity="other">Benutzerkennungen werden klassifiziert (%s vertrauenswürdige Schlüssel werden verwendet)</item>
+ </plurals>
+ <string name="msg_ip_uid_reorder">Benutzerkennungen werden neu geordnet</string>
+ <string name="msg_ip_uid_processing">Benutzerkennung %s wird verarbeitet</string>
+ <string name="msg_ip_uid_revoked">Nutzer ID wiederrufen</string>
+ <string name="msg_ip_uat_processing_image">Bilder werden verarbeitet</string>
+ <string name="msg_ip_uat_processing_unknown">Unbekannte Benutzerattribute werden verarbeitet</string>
+ <string name="msg_ip_uat_cert_bad">Ungültiges Zertifikat gefunden!</string>
+ <string name="msg_ip_uat_cert_error">Fehler beim Verarbeiten des Zertifikates!</string>
+ <string name="msg_ip_uat_cert_nonrevoke">Besitzt bereits eine nicht widerrufbare Beglaubigung, überspringe.</string>
+ <string name="msg_ip_uat_cert_old">Beglaubgigung ist älter als Vorherige, überspringe.</string>
+ <string name="msg_ip_uat_cert_new">Beglaubigung ist aktueller, ersetze Vorherhige.</string>
+ <string name="msg_ip_uat_cert_good">Korrekte Beglaubigung von %1$s gefunden</string>
+ <string name="msg_ip_uat_cert_good_revoke">Korrekten Zertifikatswiderruf von %1$s gefunden</string>
+ <plurals name="msg_ip_uat_certs_unknown">
+ <item quantity="one">Ignoriere eine Beglaubigung, ausgestellt von einem unbekannten Schlüssel</item>
+ <item quantity="other">Ignoriere %s Beglaubigungen, ausgestellt von unbekannten öffentlichen Schlüsseln</item>
+ </plurals>
+ <string name="msg_ip_uat_classifying">Klassifiziere Benutzerattribute</string>
+ <string name="msg_ip_uat_revoked">Benutzerattribut wurde widerrufen</string>
<string name="msg_is_bad_type_public">Es wurde versucht einen öffentlichen Schlüsselbund als Geheim zu importieren. Das ist ein Fehler, bitte reiche einen Bericht ein.</string>
+ <string name="msg_is_bad_type_uncanon">Es wurde versucht, einen Schlüsselbund ohne Anpassung zu importieren. Dies ist ein Fehler, bitte reiche einen Bericht ein.</string>
<!--Import Secret log entries-->
<string name="msg_is">Importiere geheimen Schlüssel %s</string>
<string name="msg_is_db_exception">Datenbankfehler!</string>
<string name="msg_is_importing_subkeys">Geheime Unterschlüssel werden bearbeitet</string>
<string name="msg_is_error_io_exc">Fehler bei Kordierung des Schlüsselbunds</string>
+ <string name="msg_is_merge_public">Importierte Daten werden in vorhandenen öffentlichen Schlüsselbund eingefügt</string>
+ <string name="msg_is_merge_secret">Importierte Daten werden in vorhandenen öffentlichen Schlüsselbund eingefügt</string>
+ <string name="msg_is_merge_special">Eigenbeglaubigungsdaten aus öffentlichem Schlüsselbund werden eingefügt</string>
<string name="msg_is_pubring_generate">Generiere öffentlichen Schlüsselbund aus geheimem Schlüsselbund</string>
<string name="msg_is_subkey_nonexistent">Unterschlüssel %s in privatem Schlüssel nicht verfügbar.</string>
<string name="msg_is_subkey_ok">Geheimen Unterschlüssel %s als verfügbar markiert</string>
<string name="msg_is_subkey_empty">Geheimen Unterschlüssel %s als verfügbar markiert, ohne Passphrase</string>
+ <string name="msg_is_subkey_pin">Geheimen Unterschlüssel %s als verfügbar markiert, mit PIN</string>
<string name="msg_is_subkey_stripped">Privater Unterschlüssel %s als gekürzt markiert</string>
<string name="msg_is_subkey_divert">Privater Unterschlüssel %s als \'Umleiten zu Smartcard/NFC\' markiert</string>
<string name="msg_is_success_identical">Schlüsselbund enthält keine neuen Daten, es gibt nichts zu tun.</string>
<string name="msg_is_success">Geheimer Schlüsselbund erfolgreich importiert</string>
<!--Keyring Canonicalization log entries-->
+ <string name="msg_kc_public">Öffentlicher Schlüsselbund %s wird in vorschriftsgemäße Form gebracht</string>
+ <string name="msg_kc_secret">Geheimer Schlüsselbund %s wird in vorschriftsgemäße Form gebracht</string>
<string name="msg_kc_error_v3">Dies ist ein OpenPGP Schlüssel der Version 3, welche hinfällig sind und nicht weiter unterstützt werden!</string>
<string name="msg_kc_error_no_uid">Schlüsselbund hat keine gültigen Benutzerkennungen!</string>
<string name="msg_kc_error_master_algo">Der Hauptschlüssel verwendet einen unbekannten (%s) Algorithmus!</string>
+ <string name="msg_kc_error_dup_key">Unterschlüssel %s kommt zweimal im Schlüsselbund vor. Schlüsselbund ist fehlerhaft, wird nicht importiert!</string>
<string name="msg_kc_master">Verarbeite Hauptschlüssel</string>
- <string name="msg_kc_revoke_bad_err">Entferne fehlerhaftes Schlüsselbund Widerrufszertifikat</string>
- <string name="msg_kc_revoke_bad_local">Entferne Schlüsselbund Widerrufszertifikat mit \"Lokal\" Attribut</string>
- <string name="msg_kc_revoke_bad_time">Entferne Schlüsselbund Widerrufszertifikat mit zukünftigem Zeitstempel</string>
- <string name="msg_kc_revoke_bad_type">Entferne Hauptschlüsselbeglaubigung unbekannter Art (%s)</string>
- <string name="msg_kc_revoke_bad">Entferne fehlerhaftes Schlüsselbund Widerrufszertifikat</string>
+ <string name="msg_kc_master_bad_type">Hauptschlüsselbeglaubigung unbekannter Art wird entfernt (%s)</string>
+ <string name="msg_kc_master_bad_local">Hauptschlüsselbeglaubigung mit \'Lokal\'-Attribut wird entfernt</string>
+ <string name="msg_kc_master_bad_err">Fehlerhafte Hauptschlüsselbeglaubigung wird entfernt</string>
+ <string name="msg_kc_master_bad_time">Schlüsselbund-Widerrufszertifikat mit zukünftigem Zeitstempel wird entfernt</string>
+ <string name="msg_kc_master_bad_type_uid"> Benutzerkennungsbeglaubigung an falscher Position wird entfernt</string>
+ <string name="msg_kc_master_bad">Fehlerhafte Hauptschlüsselbeglaubigung wird entfernt</string>
+ <string name="msg_kc_master_local">Hauptschlüsselbeglaubigung mit \'Lokal\'-Attribut wird entfernt</string>
<string name="msg_kc_revoke_dup">Entferne redundantes Schlüsselbund Widerrufszertifikat</string>
<string name="msg_kc_sub">Verarbeite Unterschlüssel %s</string>
<string name="msg_kc_sub_bad">Entferne ungültige Unterschlüssel Zwischenbeglaubigung</string>
@@ -626,25 +699,64 @@
<string name="msg_kc_sub_revoke_bad">Entferne fehlerhaftes Unterschlüssel Widerrufszertifikat</string>
<string name="msg_kc_sub_revoke_dup">Entferne redundantes Unterschlüssel Widerrufszertifikat</string>
<string name="msg_kc_sub_unknown_algo">Unterschlüssel verwendet unbekannten Algorithmus, wird nicht importiert...</string>
+ <string name="msg_kc_sub_algo_bad_encrpyt">Der Unterschlüssel soll für die Verschlüsselung genutzt werden, der zu verwendende Algorithmus unterstützt dies jedoch nicht.</string>
+ <string name="msg_kc_sub_algo_bad_sign">Der Unterschlüssel soll zum Unterschreiben genutzt werden, der zu verwendende Algorithmus unterstützt dies jedoch nicht.</string>
+ <string name="msg_kc_success">Schlüsselbund wurde erfolgreich in vorschriftsgemäße Form gebracht, keine Änderungen</string>
+ <plurals name="msg_kc_success_bad">
+ <item quantity="one">Schlüsselbund wurde erfolgreich in vorschriftsgemäße Form gebracht, eine fehlerhafte Beglaubigung entfernt</item>
+ <item quantity="other">Schlüsselbund wurde erfolgreich in vorschriftsgemäße Form gebracht, %d fehlerhafte Beglaubigungen entfernt</item>
+ </plurals>
+ <string name="msg_kc_success_bad_and_red">Schlüsselbund wurde erfolgreich in vorschriftsgemäße Form gebracht, %1$s fehlerhafte und %2$s redundante Beglaubigungen entfernt</string>
+ <plurals name="msg_kc_success_redundant">
+ <item quantity="one">Schlüsselbund wurde erfolgreich in vorschriftsgemäße Form gebracht, eine redundante Beglaubigung entfernt</item>
+ <item quantity="other">Schlüsselbund wurde erfolgreich in vorschriftsgemäße Form gebracht, %d redundante Beglaubigungen entfernt</item>
+ </plurals>
+ <string name="msg_kc_uid_bad_err">Fehlerhafte Eigenbeglaubigung für Benutzerkennung \'%s\' wird entfernt</string>
+ <string name="msg_kc_uid_bad_local">Benutzerkennungsbeglaubigung mit \'Lokal\'-Attribut wird entfernt</string>
+ <string name="msg_kc_uid_bad_time">Benutzerkennung mit zukünftigem Zeitstempel wird entfernt</string>
+ <string name="msg_kc_uid_bad_type">Benutzerkennungsbeglaubigung unbekannter Art wird entfernt (%s)</string>
+ <string name="msg_kc_uid_bad">Fehlerhafte Eigenbeglaubigung für Benutzerkennung \'%s\' wird entfernt</string>
+ <string name="msg_kc_uid_cert_dup">Abgelaufene Eigenbeglaubigung für Benutzerkennung \'%s\' wird entfernt</string>
+ <string name="msg_kc_uid_foreign">Fremde Benutzerkennungsbeglaubigung von \'%s\' wird entfernt</string>
+ <string name="msg_kc_uid_revoke_dup">Redundantes Widerrufszertifikat für Benutzerkennung \'%s\' wird entfernt</string>
+ <string name="msg_kc_uid_revoke_old">Abgelaufenes Widerrufszertifikat für Benutzerkennung \'%s\' wird entfernt</string>
+ <string name="msg_kc_uid_no_cert">Keine gültige Eigenbeglaubigung für Benutzerkennung \'%s\' gefunden, wird vom Bund entfernt</string>
+ <string name="msg_kc_uid_remove">Ungültige Benutzerkennung \'%s\' wird entfernt</string>
+ <string name="msg_kc_uid_dup">Doppelte Benutzerkennung \'%s\' wird entfernt. Der geheime Schlüssel enthielt zwei davon. Hieraus könnten fehlende Beglaubigungen resultieren!</string>
<string name="msg_kc_uid_warn_encoding">Benutzerkennung nicht als UTF-8 bestätigt!</string>
+ <string name="msg_kc_uat_jpeg">Das Benutzerattribut JPEG wird verarbeitet</string>
+ <string name="msg_kc_uat_unknown">Ein unbekanntes Benutzerattribut wird verarbeitet</string>
+ <string name="msg_kc_uat_bad_err">Entferne fehlerhafte Eigenbeglaubigung für Benutzerattribut</string>
+ <string name="msg_kc_uat_bad_local">Entferne Benutzerattributsbeglaubigung mit \'Lokal\'-Attribut</string>
+ <string name="msg_kc_uat_bad_time">Entferne fehlerhaftes Benutzerattribute mit zukünftigem Zeitstempel</string>
+ <string name="msg_kc_uat_bad_type">Entferne Benutzerattributbeglaubigung unbekannter Art (%s)</string>
+ <string name="msg_kc_uat_bad">Entferne fehlerhafte Eigenbeglaubigung für Benutzerattribut</string>
+ <string name="msg_kc_uat_cert_dup">Entferne abgelaufene Eigenbeglaubigung für Benutzerattribut</string>
+ <string name="msg_kc_uat_foreign">Entferne fremdes Benutzerattributszertifikat von</string>
+ <string name="msg_kc_uat_revoke_dup">Entferne redundantes Widerrufszertifikat für Benutzerkennung</string>
+ <string name="msg_kc_uat_revoke_old">Entferne abgelaufenes Widerrufszertifikat für Benutzerkennung</string>
+ <string name="msg_kc_uat_no_cert">Keine gültigen Eigenbeglaubigungen für das Benutzerattribut gefunden, entferne vom Ring</string>
+ <string name="msg_kc_uat_remove">Ungültiges Benutzerattribut wird entfernt</string>
+ <string name="msg_kc_uat_warn_encoding">Benutzerkennung nicht als UTF-8 bestätigt!</string>
<!--Keyring merging log entries-->
<string name="msg_mg_error_secret_dummy">Neuer öffentlicher Unterschlüssel gefunden, aber Erstellung von geheimen Unterschlüsseldummys wird nicht unterstützt!</string>
<string name="msg_mg_error_heterogeneous">Versucht Schlüsselbunde mit unterschiedlichen Fingerabdrücken zusammenzufügen!</string>
<string name="msg_mg_error_encode">Schwerer Fehler bei Kodierung der Signatur!</string>
<string name="msg_mg_public">Vereine in öffentlichen Schlüsselbund %s </string>
- <string name="msg_mg_secret">Vereine in geheimen Schlüsselring %s</string>
+ <string name="msg_mg_secret">Wird in geheimen Schlüsselbund %s eingefügt</string>
<string name="msg_mg_new_subkey">Neuer Unterschlüssel %s wird hinzugefügt</string>
<string name="msg_mg_found_new">%s neue Beglaubigungen in Schlüsselbund gefunden</string>
<string name="msg_mg_unchanged">Nichts zum zusammenführen</string>
<!--createSecretKeyRing-->
<string name="msg_cr">Neuer Masterschlüssel wird erzeugt</string>
<string name="msg_cr_error_no_master">Keine Hauptschlüsseloptionen definiert!</string>
+ <string name="msg_cr_error_no_user_id">Schlüsselbund muss mit mindestens einer Benutzerkennung erstellt werden!</string>
<string name="msg_cr_error_no_certify">Hauptschlüssel benötigt das Attribut beglaubigen!</string>
<string name="msg_cr_error_null_expiry">Ablaufdatum kann bei Schlüsselerstellung nicht \'gleiche wie vorher\' sein. Das ist ein Programmierfehler, bitte reiche einen Fehlerbericht ein.</string>
<string name="msg_cr_error_keysize_512">Schlüsselgröße muss größer/gleich 512 sein!</string>
<string name="msg_cr_error_no_curve">Keine Schlüsselgröße angegeben. Das ist ein Progammierfehler, bitte reiche einen Fehlerbericht ein!</string>
<string name="msg_cr_error_no_keysize">Keine Elliptische Kurve angegeben. Das ist ein Progammierfehler, bitte reiche einen Fehlerbericht ein!</string>
- <string name="msg_cr_error_internal_pgp">Interner PGP Fehler!</string>
+ <string name="msg_cr_error_internal_pgp">Interner OpenPGP Fehler!</string>
<string name="msg_cr_error_unknown_algo">Unbekannter Algorithmus ausgewählt. Das ist ein Progammierfehler, bitte reiche einen Fehlerbericht ein!</string>
<string name="msg_cr_error_flags_dsa">Falsche Schlüsselattribute gewählt, DSA kann nicht zum verschlüsseln verwendet werden!</string>
<string name="msg_cr_error_flags_elgamal">Falsche Schlüsselattribute gewählt, ElGamal kann nicht zum signieren verwendet werden!</string>
@@ -658,15 +770,19 @@
<string name="msg_mf_error_integrity">Interner Fehler, Integritätsprüfung fehlgeschlagen!</string>
<string name="msg_mf_error_master_none">Keine Hauptbeglaubigung zum arbeiten gefunden! (Alle widerrufen?)</string>
<string name="msg_mf_error_noexist_primary">Falsche primäre Benutzerkennung festgelegt!</string>
+ <string name="msg_mf_error_noexist_revoke">Falsche Benutzerkennung für Widerruf definiert!</string>
+ <string name="msg_mf_error_revoked_primary">Widerrufene Benutzerkennungen können keine Primäre sein!</string>
<string name="msg_mf_error_null_expiry">Ablaufdatum kann bei Unterschlüsselerstellung nicht \'gleiche wie vorher\' sein. Das ist ein Programmierfehler, bitte reiche einen Fehlerbericht ein.</string>
<string name="msg_mf_error_passphrase_master">Schwerer Fehler beim Entschlüsseln des Hauptschlüssels! Dies ist wahrscheinlich ein Programmierfehler, bitte reiche einen Fehlerbericht ein.</string>
- <string name="msg_mf_error_pgp">Interner PGP-Fehler!</string>
+ <string name="msg_mf_error_pgp">Interner OpenPGP Fehler!</string>
<string name="msg_mf_error_sig">Signaturfehler!</string>
<string name="msg_mf_master">Verändere Hauptbeglaubigungen</string>
- <string name="msg_mf_passphrase">Speichere Passwort für Schlüsselbund zwischen...</string>
+ <string name="msg_mf_passphrase">Passwort für Schlüsselbund wird geändert</string>
<string name="msg_mf_passphrase_key">Erneute Verschlüsselung des Unterschlüssels %s mit neuem Passwort</string>
<string name="msg_mf_passphrase_empty_retry">Setzen des neuen Passworts fehlgeschlagen, versuche es nochmal mit leerem altem Passwort</string>
<string name="msg_mf_passphrase_fail">Passwort für Unterschlüssel konnte nicht geändert werden! (Hat er ein anderes als die anderen Schlüssel?)</string>
+ <string name="msg_mf_primary_replace_old">Beglaubigung von vorheriger primärer Benutzerkennung wird ersetzt</string>
+ <string name="msg_mf_primary_new">Neue Beglaubigung für neue primäre Benutzerkennung wird erzeugt</string>
<string name="msg_mf_subkey_change">Unterschlüssel %s wird geändert</string>
<string name="msg_mf_error_subkey_missing">Versuch mit fehlendem Unterschlüssel %s zu arbeiten!</string>
<string name="msg_mf_subkey_new">Füge neuen Unterschlüssel vom Typ %s hinzu</string>
@@ -676,15 +792,20 @@
<string name="msg_mf_subkey_strip">Kürze Unterschlüssel %s</string>
<string name="msg_mf_success">Schlüsselbund erfolgreich verändert</string>
<string name="msg_mf_uid_add">Benutzerkennung %s wird hinzugefügt</string>
+ <string name="msg_mf_uid_primary">Primäre Benutzerkenung wird auf %s geändert</string>
+ <string name="msg_mf_uid_revoke">Benutzerkennung %s wird widerrufen</string>
<string name="msg_mf_uid_error_empty">Benutzerkennung darf nicht leer sein!</string>
+ <string name="msg_mf_uat_error_empty">Benutzerattribut darf nicht leer sein!</string>
+ <string name="msg_mf_uat_add_image">Benutzerattribut vom Typ Bild wird hinzugefügt</string>
+ <string name="msg_mf_uat_add_unknown">Benutzerattribut unbekannter Art wird hinzugefügt</string>
<string name="msg_mf_unlock_error">Fehler beim entsperren des Schlüsselbunds</string>
<string name="msg_mf_unlock">Schlüsselbund wird entsperrt</string>
<!--Consolidate-->
- <string name="msg_con">Führe Datenbank zusammen</string>
- <string name="msg_con_error_bad_state">Zusammenführung wurde gestartet, während keine Datenbank zwischengespeichert war! Dies ist wahrscheinlich ein Programmierfehler, bitte reiche einen Fehlerbericht ein!</string>
- <string name="msg_con_error_concurrent">Zusammenführung abgebrochen, läuft bereits in einem anderen Prozess!</string>
- <string name="msg_con_save_secret">Geheime Schlüsselringe werden gespeichert</string>
- <string name="msg_con_save_public">Öffentliche Schlüsselringe werden gespeichert</string>
+ <string name="msg_con">Datenbank wird zusammengeführt</string>
+ <string name="msg_con_error_bad_state">Zusammenführung wurde gestartet während keine Datenbank zwischengespeichert war! Dies ist wahrscheinlich ein Programmierfehler, bitte reichen Sie einen Fehlerbericht ein!</string>
+ <string name="msg_con_error_concurrent">Zusammenführung abgebrochen, läuft bereits auf einem anderen Thread!</string>
+ <string name="msg_con_save_secret">Geheime Schlüsselbünde werden gespeichert</string>
+ <string name="msg_con_save_public">Öffentliche Schlüsselbünde werden gespeichert</string>
<string name="msg_con_db_clear">Datenbank wird geleert</string>
<string name="msg_con_success">Datenbank erfolgreich zusammengeführt!</string>
<string name="msg_con_critical_in">Beginne kritische Phase!</string>
@@ -696,6 +817,8 @@
<string name="msg_con_error_io_secret">Ein-/Ausgabefehler beim Schreiben von geheimen Schlüsseln in den Cache!</string>
<string name="msg_con_error_public">Fehler beim reimportieren der öffentlichen Schlüssel!</string>
<string name="msg_con_error_secret">Fehler beim reimportieren der geheimen Schlüssel!</string>
+ <string name="msg_con_recover">Zusammenführungsvorgang wird fortgesetzt</string>
+ <string name="msg_con_recover_unknown">Zusammenführungsvorgang aus unbekanntem Zustand wird fortgesetzt</string>
<plurals name="msg_con_reimport_public">
<item quantity="one">Wiederimport eines öffentlichen Schlüssels </item>
<item quantity="other">Reimport von %d öffentlichen Schlüsseln</item>
@@ -708,6 +831,17 @@
<string name="msg_con_reimport_secret_skip">Keine geheimen Schlüssel für reimport, überspringe...</string>
<string name="msg_con_warn_delete_public">Fehler beim Löschen der Öffentlichen Cache-Datei</string>
<string name="msg_con_warn_delete_secret">Fehler beim Löschen der Geheimen Cache-Datei</string>
+ <!--Edit Key (higher level than modify)-->
+ <string name="msg_ed">Schlüsselvorgang wird durchgeführt</string>
+ <string name="msg_ed_caching_new">Neues Passwort wird zwischengespeichert</string>
+ <string name="msg_ed_error_key_not_found">Schlüssel nicht gefunden!</string>
+ <string name="msg_ed_fetching">Zu ändernder Schlüssel wird abgerufen (%s)</string>
+ <string name="msg_ed_success">Schlüsselvorgang erfolgreich</string>
+ <!--Promote key-->
+ <string name="msg_pr_error_already_secret">Der Schlüssel ist bereits ein geheimer Schlüssel!</string>
+ <string name="msg_pr_error_key_not_found">Schlüssel nicht gefunden!</string>
+ <string name="msg_pr_fetching">Zu ändernder Schlüssel wird abgerufen (%s)</string>
+ <string name="msg_pr_success">Schlüssel erfolgreich eingebracht</string>
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_divert">Bearbeiten von NFC Schlüsseln wird (noch) nicht unterstützt!</string>
<string name="msg_ek_error_dummy">Kann Schlüsselbund nicht mit gekürztem Hauptschlüssel bearbeiten!</string>
@@ -716,11 +850,13 @@
<string name="msg_dc_askip_no_key">Daten mit unbekanntem Schlüssel verschlüsselt, überspringe...</string>
<string name="msg_dc_askip_not_allowed">Daten mit nicht zugelassenem Schlüssel verschlüsselt, überspringe...</string>
<string name="msg_dc_asym">Block asymmetrisch verschlüsselter Daten für Schlüssel %s gefunden</string>
+ <string name="msg_dc_charset">Ein Zeichensatz-Header wurde gefunden: \'%s\'</string>
<string name="msg_dc_clear_data">Verarbeite Klartextdaten</string>
<string name="msg_dc_clear_decompress">Entpacke komprimierte Daten</string>
<string name="msg_dc_clear_meta_file">Dateiname: %s</string>
<string name="msg_dc_clear_meta_mime">MIME-Typ: %s</string>
<string name="msg_dc_clear_meta_size">Dateigröße: %s</string>
+ <string name="msg_dc_clear_meta_size_unknown">Dateigröße ist unbekannt</string>
<string name="msg_dc_clear_meta_time">Änderungszeit: %s</string>
<string name="msg_dc_clear_signature_bad">Signaturprüfung NICHT OK!</string>
<string name="msg_dc_clear_signature_check">Überprüfe Signaturdaten</string>
@@ -734,7 +870,7 @@
<string name="msg_dc_error_io">Ein-/Ausgabefehler während Vorgang aufgetreten!</string>
<string name="msg_dc_error_no_data">Keine verschlüsselten Daten in Datenstrom gefunden!</string>
<string name="msg_dc_error_no_key">Keine verschlüsselten Daten mit bekanntem geheimen Schlüssel in Datenstrom gefunden!</string>
- <string name="msg_dc_error_pgp_exception">PGP Ausnahme während des Vorgangs aufgetreten!</string>
+ <string name="msg_dc_error_pgp_exception">Es ist ein OpenPGP-Ausnahmefehler während des Vorgangs aufgetreten!</string>
<string name="msg_dc_integrity_check_ok">Integritätsprüfung OK!</string>
<string name="msg_dc_ok_meta_only">Es wurden nur Metadaten angefragt, überspringe Entschlüsselung</string>
<string name="msg_dc_ok">OK</string>
@@ -745,36 +881,58 @@
<string name="msg_dc">Starte Entschlüsselungsvorgang...</string>
<string name="msg_dc_sym_skip">Symmetrische Daten nicht erlaubt, überspringe...</string>
<string name="msg_dc_sym">Block symmetrisch verschlüsselter Daten gefunden</string>
+ <string name="msg_dc_trail_asym">Anhängende, asymmetrisch verschlüsselte Daten für Schlüssel %s gefunden</string>
+ <string name="msg_dc_trail_sym">Anhang gefunden, symmetrisch verschlüsselte Daten</string>
+ <string name="msg_dc_trail_unknown">Anhängende Daten unbekannter Art gefunden</string>
<string name="msg_dc_unlocking">Geheimer Schlüssel wird entsperrt</string>
<!--Messages for SignEncrypt operation-->
- <string name="msg_se_asymmetric">Bereite öffentliche Schlüssel für Verschlüsselung vor</string>
- <string name="msg_se_clearsign_only">Signieren von Klartexteingaben wird nicht Unterstützt!</string>
- <string name="msg_se_compressing">Bereite Kompression vor</string>
- <string name="msg_se_encrypting">Daten werden verschlüsselt</string>
- <string name="msg_se_error_bad_passphrase">Falsches Passwort!</string>
- <string name="msg_se_error_io">Ein-/Ausgabefehler während Vorgang aufgetreten!</string>
- <string name="msg_se_error_key_sign">Gewählter Signaturschlüssel kann keine Daten signieren!</string>
- <string name="msg_se_error_sign_key">Fehler bei Abruf des Signaturschlüssels!</string>
- <string name="msg_se_error_nfc">NFC-Datenfehler!</string>
- <string name="msg_se_error_no_passphrase">Kein Passwort bereitgestellt!</string>
- <string name="msg_se_error_pgp">Interner PGP-Fehler!</string>
- <string name="msg_se_error_sig">PGP Signaturausnahme aufgetreten!</string>
- <string name="msg_se_error_unlock">Unbekannter Fehler bei Schlüsselentsperrung!</string>
- <string name="msg_se_key_ok">Verschlüssele für Schlüssel: %s</string>
- <string name="msg_se_key_unknown">Fehlender Schlüssel für Verschlüsselung: %s</string>
- <string name="msg_se_key_warn">Falscher Schlüssel für Verschlüsselung: %s</string>
- <string name="msg_se_ok">Signierungs-/Verschlüsselungsvorgang erfolgreich!</string>
- <string name="msg_se_pending_nfc">NFC Token benötigt, verlange Benutzereingabe...</string>
- <string name="msg_se_pending_passphrase">Passwort benötigt, verlange Benutezreingabe...</string>
- <string name="msg_se_signing">Signiere Daten (ohne Verschlüsselung)</string>
- <string name="msg_se_sigcrypting">Verschlüssele Daten mit Signatur</string>
- <string name="msg_se">Starte Signier- und/oder Verschlüsselungsvorgang</string>
- <string name="msg_se_symmetric">Bereite symmetrische Verschlüsselung vor</string>
+ <string name="msg_se">Starte Signier-/Verschlüsselungsvorgang</string>
+ <string name="msg_se_error_no_input">Keine Eingabe gegeben!</string>
+ <string name="msg_se_error_input_uri_not_found">Fehler beim öffnen der Uri zum lesen!</string>
+ <string name="msg_se_success">Signier-/Verschlüsselungsvorgang erfolgreich!</string>
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_pse_asymmetric">Bereite öffentliche Schlüssel für Verschlüsselung vor</string>
+ <string name="msg_pse_clearsign_only">Signieren von Klartexteingaben wird nicht unterstützt!</string>
+ <string name="msg_pse_compressing">Bereite Kompression vor</string>
+ <string name="msg_pse_encrypting">Daten werden verschlüsselt</string>
+ <string name="msg_pse_error_bad_passphrase">Falsches Passwort!</string>
+ <string name="msg_pse_error_hash_algo">Angeforderter Hash-Algorithmus wird von diesem Schlüssel nicht unterstützt!</string>
+ <string name="msg_pse_error_io">Ein-/Ausgabefehler während Vorgang aufgetreten!</string>
+ <string name="msg_pse_error_key_sign">Gewählter Signaturschlüssel kann keine Daten signieren!</string>
+ <string name="msg_pse_error_sign_key">Fehler bei Abruf des Signaturschlüssels!</string>
+ <string name="msg_pse_error_nfc">NFC-Datenfehler!</string>
+ <string name="msg_pse_error_no_passphrase">Kein Passwort bereitgestellt!</string>
+ <string name="msg_pse_error_pgp">Interner OpenPGP Fehler!</string>
+ <string name="msg_pse_error_sig">OpenPGP-Signaturfehler aufgetreten!</string>
+ <string name="msg_pse_error_unlock">Unbekannter Fehler bei Schlüsselentsperrung!</string>
+ <string name="msg_pse_key_ok">Verschlüssele für Schlüssel: %s</string>
+ <string name="msg_pse_key_unknown">Fehlender Schlüssel für Verschlüsselung: %s</string>
+ <string name="msg_pse_key_warn">Falscher Schlüssel für Verschlüsselung: %s</string>
+ <string name="msg_pse_ok">Signierungs-/Verschlüsselungsvorgang erfolgreich!</string>
+ <string name="msg_pse_pending_nfc">NFC Token benötigt, verlange Benutzereingabe...</string>
+ <string name="msg_pse_pending_passphrase">Passwort benötigt, verlange Benutzereingabe...</string>
+ <string name="msg_pse_signing">Signiere Daten (ohne Verschlüsselung)</string>
+ <string name="msg_pse_signing_cleartext">Erstelle Klartextsignatur</string>
+ <string name="msg_pse_signing_detached">Separate Signatur wird erstellt</string>
+ <string name="msg_pse_sigcrypting">Verschlüssele Daten mit Signatur</string>
+ <string name="msg_pse">Starte Signier- und/oder Verschlüsselungsvorgang</string>
+ <string name="msg_pse_symmetric">Bereite symmetrische Verschlüsselung vor</string>
<string name="msg_crt_certifying">Zertifizierungen werden erzeugt</string>
+ <string name="msg_crt_certify_all">Alle Benutzerkennungen für Schlüssel %s werden beglaubigt</string>
+ <plurals name="msg_crt_certify_some">
+ <item quantity="one">Eine Benutzerkennung für Schlüssel %2$s wird beglaubigt</item>
+ <item quantity="other">%1$d Benutzerkennungen für Schlüssel %2$s werden beglaubigt</item>
+ </plurals>
+ <string name="msg_crt_error_self">Auf diese Art und Weise kann keine Eigenbeglaubigung ausgestellt werden!</string>
<string name="msg_crt_error_master_not_found">Hauptschlüssel nicht gefunden!</string>
<string name="msg_crt_error_nothing">Keine beglaubigten Schlüssel!</string>
+ <string name="msg_crt_error_unlock">Fehler beim Entsperren des Hauptschlüssels!</string>
+ <string name="msg_crt_error_divert">Beglaubigung mit NFC wird (noch) nicht unterstützt!</string>
<string name="msg_crt">Schlüsselbund wird beglaubigt</string>
+ <string name="msg_crt_master_fetch">Beglaubigender Hauptschlüssel wird abgerfufen</string>
+ <string name="msg_crt_save">Beglaubigter Schlüssel %s wird gespeichert</string>
<string name="msg_crt_saving">Schlüsselbunde werden gespeichert</string>
+ <string name="msg_crt_unlock">Hauptschlüssel wird entsperrt</string>
<string name="msg_crt_success">Identitäten erfolgreich beglaubigt</string>
<string name="msg_crt_warn_not_found">Schlüssel nicht gefunden!</string>
<string name="msg_crt_warn_cert_failed">Erzeugen des Zertifikates fehlgeschlagen!</string>
@@ -784,15 +942,35 @@
<item quantity="one">Schlüssel wird importiert</item>
<item quantity="other">%d Schlüssel werden importiert</item>
</plurals>
+ <string name="msg_import_fetch_error_decode">Fehler beim Dekodieren des abgerufenen Schlüsselbundes!</string>
+ <string name="msg_import_fetch_error">Schlüssel konnte nicht abgerufen werden! (Netzwerkprobleme?)</string>
+ <string name="msg_import_fetch_keybase">Empfange von keybase.io: %s</string>
+ <string name="msg_import_fetch_keyserver_error">Konnte Schlüssel nicht von Keybase empfangen!</string>
+ <string name="msg_import_fetch_keyserver">Von einem Schlüsselserver abrufen: %s</string>
+ <string name="msg_import_fetch_keyserver_ok">Schlüsselabruf erfolgreich</string>
<string name="msg_import_keyserver">Schlüsselserver %s wird verwendet</string>
+ <string name="msg_import_fingerprint_error">Fingerabdruck des abgerufenen Schlüssels entspricht nicht dem Erwarteten!</string>
+ <string name="msg_import_fingerprint_ok">Fingerabdrucktest in Ordnung</string>
+ <string name="msg_import_merge">Abgerufene Daten werden eingefügt</string>
<string name="msg_import_error">Importieren fehlgeschlagen!</string>
+ <string name="msg_import_error_io">Der Import ist aufgrund eines Eingabe/Ausgabe-Fehlers fehlgeschlagen!</string>
<string name="msg_import_partial">Importvorgang erfolgreich, mit Fehlern!</string>
+ <string name="msg_import_success">Importvorgang erfolgreich!</string>
+ <plurals name="msg_export">
+ <item quantity="one">Ein Schlüssel wird exportiert</item>
+ <item quantity="other">%d Schlüssel werden exportiert</item>
+ </plurals>
<string name="msg_export_all">Exportiere alle Schlüssel</string>
<string name="msg_export_public">Exportiere öffentlichen Schlüssel %s</string>
<string name="msg_export_secret">Exportiere privaten Schlüssel %s</string>
<string name="msg_export_error_no_file">Kein Dateiname angegeben!</string>
+ <string name="msg_export_error_fopen">Fehler beim Öffnen der Datei !</string>
+ <string name="msg_export_error_no_uri">Keine URI angegeben!</string>
+ <string name="msg_export_error_uri_open">Fehler beim Öffnen des URI-Streams!</string>
+ <string name="msg_export_error_storage">Speicher ist nicht Schreibbereit !</string>
<string name="msg_export_error_db">Datenbankfehler!</string>
<string name="msg_export_error_io">Eingabe/Ausgabe Fehler!</string>
+ <string name="msg_export_error_key">Fehlber bei der Vorverarbeitung der Schlüsseldaten!</string>
<string name="msg_export_success">Exportvorgang erfolgreich!</string>
<string name="msg_del_error_empty">Nichts zu löschen!</string>
<string name="msg_del_error_multi_secret">Geheime Schlüssel können nur einzeln gelöscht werden!</string>
@@ -802,16 +980,26 @@
</plurals>
<string name="msg_del_key">Lösche Schlüssel %s</string>
<string name="msg_del_key_fail">Fehler beim Löschen von Schlüssel %s</string>
+ <string name="msg_del_consolidate">Datenbank wird nach Löschung des geheimen Schlüssels zusammengeführt</string>
<plurals name="msg_del_ok">
<item quantity="one">Schlüssel erfolgreich gelöscht</item>
<item quantity="other">%d Schlüssel erfolgreich gelöscht</item>
</plurals>
+ <plurals name="msg_del_fail">
+ <item quantity="one">Fehler beim Löschen eines Schlüssels</item>
+ <item quantity="other">Fehler beim Löschen von %d Schlüsseln</item>
+ </plurals>
<string name="msg_acc_saved">Konto gespeichert</string>
<string name="msg_download_success">Erfolgreich heruntergeladen!</string>
+ <string name="msg_download_no_valid_keys">Keine gültigen Schlüssel in der Datei/Zwischenablage gefunden!</string>
+ <string name="msg_download_no_pgp_parts">NOCH ZU MACHEN: Plurale!</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">Ein Teil der geladenen Datei ist ein gültiges OpenPGP Objekt aber kein OpenPGP Schlüssel</item>
<item quantity="other">Teile der geladenen Dateien sind gültige OpenPGP Objekte aber keine OpenPGP Schlüssel</item>
</plurals>
+ <string name="msg_download_query_too_short">Suchanfrage zu kurz. Bitte verfeinern Sie Ihre Suchanfrage!</string>
+ <string name="msg_download_too_many_responses">Schlüsselsuchanfrage lieferte zu viele Kandidaten. Bitte verfeinern Sie Ihre Anfrage!</string>
+ <string name="msg_download_query_too_short_or_too_many_responses">Entweder keine oder zu viele Schlüssel wurden gefunden. Bitte verbessern Sie Ihre Anfrage!</string>
<string name="msg_download_query_failed">Beim suchen der Schlüssel ist ein Fehler aufgetreten.</string>
<!--PassphraseCache-->
<string name="passp_cache_notif_click_to_clear">Klicken um Passworte aus Zwischenspeicher zu leeren</string>
@@ -819,6 +1007,11 @@
<string name="passp_cache_notif_keys">Zwischengespeicherte Passworte:</string>
<string name="passp_cache_notif_clear">Cache löschen</string>
<string name="passp_cache_notif_pwd">Passwort</string>
+ <!--First Time-->
+ <string name="first_time_text1">Hol dir deine Privatsphäre mit OpenKeychain zurück!</string>
+ <string name="first_time_create_key">Erzeuge meinen Schlüssel</string>
+ <string name="first_time_import_key">Von Datei importieren</string>
+ <string name="first_time_skip">Setup überspringen</string>
<!--unsorted-->
<string name="section_certifier_id">Beglaubiger</string>
<string name="section_cert">Zertifikatdetails</string>
@@ -847,9 +1040,32 @@
<string name="error_no_file_selected">Mindestens eine Datei zum Verschlüsseln auswählen!</string>
<string name="error_multi_not_supported">Das speichern von mehreren Dateien wird nicht unterstützt. Dies ist eine Einschränkung der aktuellen Android Version.</string>
<string name="key_colon">Schlüssel:</string>
- <!--First Time-->
- <string name="first_time_text1">Hol dir deine Privatsphäre mit OpenKeychain zurück!</string>
- <string name="first_time_create_key">Erzeuge meinen Schlüssel</string>
- <string name="first_time_import_key">Von Datei importieren</string>
- <string name="first_time_skip">Setup überspringen</string>
+ <string name="btn_start_exchange">Austausch starten</string>
+ <string name="user_id_none"><![CDATA[<kein>]]></string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <string name="title_unlock_method">Wähle eine Entsperrmethode</string>
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <string name="enter_passphrase">Passwort eingeben</string>
+ <string name="passphrase">Passwort</string>
+ <string name="noPassphrase">Kein Passwort</string>
+ <string name="no_passphrase_set">Kein Passwort gesetzt</string>
+ <string name="passphrases_match">Die Passwörter stimmten nicht überein.</string>
+ <string name="passphrase_saved">Passwort gespeichert</string>
+ <string name="passphrase_invalid">Falsches Passwort</string>
+ <string name="missing_passphrase">Fehlendes Passwort</string>
+ <string name="passphrase_again">Wiederholen</string>
+ <string name="lockpattern">Entsperrcode</string>
+ <string name="lockpatternNFC">NFc + Entsperrcode</string>
+ <string name="unlock_method">Entsperrmethode</string>
+ <string name="set_passphrase">Passwort setzen</string>
+ <string name="draw_lockpattern">Zeichne Entsperrcode</string>
+ <string name="nfc_title">NFC</string>
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+ <string name="nfc_wrong_tag">Falscher Tag. Bitte versuche es erneut.</string>
+ <string name="enable_nfc">Aktiviere NFC in deinen Einstellungen.</string>
+ <string name="no_nfc_support">Dieses Gerät unterstützt kein NFC</string>
+ <string name="nfc_write_succesful">Erfolgreich auf den NFC Tag geschrieben</string>
+ <string name="unlocked">Entsperrt</string>
+ <string name="nfc_settings">Einstellungen</string>
</resources>
diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml
index d95f5bfb4..e2c657f3e 100644
--- a/OpenKeychain/src/main/res/values-es/strings.xml
+++ b/OpenKeychain/src/main/res/values-es/strings.xml
@@ -9,13 +9,13 @@
<string name="title_encrypt_text">Cifrar texto</string>
<string name="title_encrypt_files">Cifrar ficheros</string>
<string name="title_decrypt">Descifrar</string>
- <string name="title_authentication">Frase de contraseña</string>
+ <string name="title_unlock">Desbloquear clave</string>
<string name="title_add_subkey">Añadir subclave</string>
<string name="title_edit_key"> Editar clave</string>
- <string name="title_preferences"> Preferencias</string>
+ <string name="title_preferences">Configuración</string>
<string name="title_cloud_search_preferences">Preferencias de búsqueda en la nube</string>
<string name="title_api_registered_apps">Aplicaciones</string>
- <string name="title_key_server_preference">Prioridad del servidor de claves</string>
+ <string name="title_key_server_preference">Servidores de claves</string>
<string name="title_change_passphrase">Cambiar frase de contraseña</string>
<string name="title_share_fingerprint_with">Compartir huella de validación de clave con...</string>
<string name="title_share_key">Compartir clave con...</string>
@@ -36,6 +36,7 @@
<string name="title_create_key">Crear clave</string>
<string name="title_exchange_keys">Intercambiar claves</string>
<string name="title_advanced_key_info">Información avanzada de clave</string>
+ <string name="title_keys">Claves</string>
<!--section-->
<string name="section_user_ids">Identificaciones</string>
<string name="section_keys">Subclaves</string>
@@ -55,6 +56,8 @@
<string name="section_decrypt_files">Ficheros</string>
<string name="section_decrypt_text">Texto</string>
<string name="section_certs">Certificados</string>
+ <string name="section_encrypt">Cifrar</string>
+ <string name="section_decrypt">Descifrar</string>
<!--button-->
<string name="btn_decrypt_verify_file">Descifrar, verificar, y guardar fichero</string>
<string name="btn_decrypt_verify_message">Descifrar y verificar mensaje</string>
@@ -74,9 +77,11 @@
<string name="btn_create_key">Crear clave</string>
<string name="btn_add_files">Añadir fichero(s)</string>
<string name="btn_add_share_decrypted_text">Compartir texto descifrado</string>
- <string name="btn_decrypt_clipboard">Descifrar desde el portapapeles</string>
+ <string name="btn_decrypt_clipboard">Descifrar texto desde el portapapeles</string>
<string name="btn_decrypt_and_verify">y verificar firmas</string>
<string name="btn_decrypt_files">Descifrar ficheros</string>
+ <string name="btn_encrypt_files">Cifrar ficheros</string>
+ <string name="btn_encrypt_text">Cifrar texto</string>
<!--menu-->
<string name="menu_preferences">Ajustes</string>
<string name="menu_help">Ayuda</string>
@@ -90,6 +95,7 @@
<string name="menu_encrypt_to">Cifrar hacia...</string>
<string name="menu_select_all">Seleccionar todo</string>
<string name="menu_add_keys">Añadir claves</string>
+ <string name="menu_search_cloud">Buscar en la nube</string>
<string name="menu_export_all_keys">Exportar todas las claves</string>
<string name="menu_advanced">Mostrar información avanzada</string>
<!--label-->
@@ -106,9 +112,9 @@
<string name="label_file_ascii_armor">Habilitar armadura ASCII</string>
<string name="label_write_version_header">Permitir conocer a otros que usted está usando OpenKeychain</string>
<string name="label_write_version_header_summary">Escribe \'OpenKeychain v2.7\' en las firmas OpenPGP, texto cifrado, y claves exportadas</string>
- <string name="label_use_default_yubikey_pin">Usar el PIN por defecto de Yubikey</string>
- <string name="label_use_num_keypad_for_yubikey_pin">Usar el teclado numérico para el PIN de Yubikey</string>
- <string name="label_label_use_default_yubikey_pin_summary">Usa el PIN predeterminado (123456) para acceder a las Yubikeys sobre NFC</string>
+ <string name="label_use_default_yubikey_pin">Utilizar PIN predeterminado de la YubiKey</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Utilizar teclado numérico para el PIN de la YubiKey</string>
+ <string name="label_label_use_default_yubikey_pin_summary">Utiliza el PIN predeterminado (123456) para acceder a las YubiKeys sobre NFC</string>
<string name="label_asymmetric_from">Firmado por:</string>
<string name="label_to">Cifrar hacia:</string>
<string name="label_delete_after_encryption">Eliminar fichero después del cifrado</string>
@@ -189,7 +195,9 @@
<string name="passphrase_must_not_be_empty">Por favor, introduce una frase de contraseña.</string>
<string name="passphrase_for_symmetric_encryption">Cifrado simétrico.</string>
<string name="passphrase_for">Introducir la frase de contraseña para \'%s\'</string>
- <string name="yubikey_pin">Introduzca el PIN de acceso a Yubikey para \'%s\'</string>
+ <string name="pin_for">Introduzca el PIN para \'%s\'</string>
+ <string name="yubikey_pin_for">Introduzca el PIN para acceder a la YubiKey para \'%s\'</string>
+ <string name="nfc_text">Sostenga la YubiKey contra el reverso de su dispositivo.</string>
<string name="file_delete_confirmation">¿Está seguro de que quiere eliminar\n%s?</string>
<string name="file_delete_successful">Borrado satisfactoriamente.</string>
<string name="no_file_selected">Selecciona un archivo antes.</string>
@@ -279,6 +287,7 @@
<string name="progress_modify">modificando juego de claves...</string>
<string name="progress_modify_unlock">desbloqueando juego de claves...</string>
<string name="progress_modify_adduid">añadiendo identificaciones de usuario...</string>
+ <string name="progress_modify_adduat">añadiendo atributos de usuario...</string>
<string name="progress_modify_revokeuid">revocando identificaciones de usuario...</string>
<string name="progress_modify_primaryuid">cambiando identificación principal de usuario...</string>
<string name="progress_modify_subkeychange">modificando subclaves...</string>
@@ -339,7 +348,7 @@
<!--Help-->
<string name="help_tab_start">Comenzar</string>
<string name="help_tab_faq">FAQ</string>
- <string name="help_tab_wot">Web of Trust</string>
+ <string name="help_tab_wot">Anillo de confianza</string>
<string name="help_tab_nfc_beam">NFC Beam</string>
<string name="help_tab_changelog">Registro de cambios</string>
<string name="help_tab_about">A cerca de</string>
@@ -353,8 +362,9 @@
<string name="import_qr_code_wrong">¡El código QR está deformado! ¡Por favor, prueba de nuevo!</string>
<string name="import_qr_code_too_short_fingerprint">La huella de validación (fingerprint) de clave es demasiado corta (&lt; 16 caracteres)</string>
<string name="import_qr_code_button">Escanear código QR</string>
+ <string name="import_qr_code_text">¡Sitúe su cámara sobre el código QR!</string>
<!--Generic result toast-->
- <string name="view_log">Ver registro (log)</string>
+ <string name="view_log">Detalles</string>
<string name="with_warnings">, con advertencias</string>
<string name="with_cancelled">, hasta que sea cancelado</string>
<!--Import result toast-->
@@ -438,7 +448,9 @@
<string name="api_settings_delete_account">Borrar cuenta</string>
<string name="api_settings_package_name">Nombre de paquete</string>
<string name="api_settings_package_signature">SHA-256 de firma de paquete</string>
- <string name="api_settings_accounts">Cuentas</string>
+ <string name="api_settings_accounts">Cuentas (API desechada)</string>
+ <string name="api_settings_advanced">Información avanzada</string>
+ <string name="api_settings_allowed_keys">Claves permitidas</string>
<string name="api_settings_settings">Configuración</string>
<string name="api_settings_key">Clave de la cuenta:</string>
<string name="api_settings_accounts_empty">No hay cuentas adjuntas a esta aplicación</string>
@@ -524,9 +536,7 @@
<string name="view_key_expired">¡Esta clave ha expirado!</string>
<!--Navigation Drawer-->
<string name="nav_keys">Claves</string>
- <string name="nav_encrypt_text">Cifrar texto</string>
- <string name="nav_encrypt_files">Cifrar ficheros</string>
- <string name="nav_decrypt">Descifrar</string>
+ <string name="nav_encrypt_decrypt">Cifrar/Descifrar</string>
<string name="nav_apps">Aplicaciones</string>
<string name="drawer_open">Abrir el Navigation Drawer</string>
<string name="drawer_close">Cerrar el Navigation Drawer</string>
@@ -623,6 +633,21 @@
<string name="msg_ip_uid_reorder">Re-ordenando identificaciones de usuario</string>
<string name="msg_ip_uid_processing">Procesando identificación de usuario %s</string>
<string name="msg_ip_uid_revoked">La identificación de usuario está revocada</string>
+ <string name="msg_ip_uat_processing_image">Procesando atributo de usuario de tipo imagen</string>
+ <string name="msg_ip_uat_processing_unknown">Procesando atributo de usuario de tipo desconocido</string>
+ <string name="msg_ip_uat_cert_bad">¡Se encontró un certificado defectuoso!</string>
+ <string name="msg_ip_uat_cert_error">¡Error procesando certificado!</string>
+ <string name="msg_ip_uat_cert_nonrevoke">Ya tiene un certificado no revocable, omitiendo.</string>
+ <string name="msg_ip_uat_cert_old">El certificado es más antiguo que el anterior, omitiendo.</string>
+ <string name="msg_ip_uat_cert_new">El certificado es más reciente, reemplazando el anterior.</string>
+ <string name="msg_ip_uat_cert_good">Hallado certificado correcto por %1$s</string>
+ <string name="msg_ip_uat_cert_good_revoke">Hallada revocación de certificado correcta por %1$s </string>
+ <plurals name="msg_ip_uat_certs_unknown">
+ <item quantity="one">Ignorando un certificado publicado por una clave pública desconocida</item>
+ <item quantity="other">Ignorando %s certificados publicados por claves públicas desconocidas</item>
+ </plurals>
+ <string name="msg_ip_uat_classifying">Clasificando atributos de usuario</string>
+ <string name="msg_ip_uat_revoked">El atributo de usuario está revocado</string>
<string name="msg_is_bad_type_public">Se intentó importar un juego de claves (keyring) público como secreto. Esto es un fallo, por favor ¡consigne un informe!</string>
<string name="msg_is_bad_type_uncanon">Se intentó importar un juego de claves sin canonicalización. ¡Esto es un fallo, por favor rellene un informe!</string>
<!--Import Secret log entries-->
@@ -637,6 +662,7 @@
<string name="msg_is_subkey_nonexistent">La subclave %s no está disponible en la clave secreta (privada)</string>
<string name="msg_is_subkey_ok">Subclave secreta (privada) %s marcada como disponible</string>
<string name="msg_is_subkey_empty">Subclave secreta (privada) %s marcada como disponible, con frase-contraseña vacía</string>
+ <string name="msg_is_subkey_pin">Subclave secreta %s marcada como disponible, con PIN</string>
<string name="msg_is_subkey_stripped">Subclave secreta (privada) %s marcada como desnuda</string>
<string name="msg_is_subkey_divert">Se marcó la subclave secreta (privada) %s como \'desviar a smartcard/NFC\'</string>
<string name="msg_is_success_identical">El juego de claves no contiene nuevos datos, no hay nada que hacer</string>
@@ -649,13 +675,16 @@
<string name="msg_kc_error_master_algo">¡La clave maestra usa un algoritmo (%s) desconocido!</string>
<string name="msg_kc_error_dup_key">La subclave %s aparece dos veces en el juego de claves (keyring). El juego de claves está mal formado, ¡no se va a importar!</string>
<string name="msg_kc_master">Procesando clave maestra</string>
- <string name="msg_kc_revoke_bad_err">Eliminando certificado defectuoso de revocación de juego de claves</string>
- <string name="msg_kc_revoke_bad_local">Eliminando certificado de revocación de juego de claves, con distintivo \"local\"</string>
- <string name="msg_kc_revoke_bad_time">Eliminando certificado de revocación de juego de claves, con marca de tiempo futura</string>
- <string name="msg_kc_revoke_bad_type">Eliminando certificado de clave maestra, de tipo desconocido (%s)</string>
- <string name="msg_kc_revoke_bad_type_uid">Eliminando certificado de identificación de usuario en posición incorrecta</string>
- <string name="msg_kc_revoke_bad">Eliminando certificado defectuoso de revocación de juego de claves</string>
+ <string name="msg_kc_master_bad_type">Eliminando certificado de clave maestra de tipo desconocido (%s)</string>
+ <string name="msg_kc_master_bad_local">Eliminando certificado de clave maestra con distintivo \"local\"</string>
+ <string name="msg_kc_master_bad_err">Eliminando certificado de clave maestra defectuoso</string>
+ <string name="msg_kc_master_bad_time">Eliminando certificado de revocación de juego de claves con marca de tiempo en el futuro</string>
+ <string name="msg_kc_master_bad_type_uid">Eliminando certificado de identificación de usuario en posición incorrecta</string>
+ <string name="msg_kc_master_bad">Eliminando certificado de clave maestra defectuoso</string>
+ <string name="msg_kc_master_local">Eliminando certificado de clave maestra con distitivo \"local\"</string>
<string name="msg_kc_revoke_dup">Eliminando certificado redundante de revocación de juego de claves </string>
+ <string name="msg_kc_notation_dup">Eliminando certificado de notación redundante</string>
+ <string name="msg_kc_notation_empty">Eliminando certificado de notación vacía</string>
<string name="msg_kc_sub">Procesando subclave %s</string>
<string name="msg_kc_sub_bad">Eliminando certificado no válido de vinculación de subclave</string>
<string name="msg_kc_sub_bad_err">Eliminando certificado defectuoso de vinculación de subclave</string>
@@ -695,8 +724,23 @@
<string name="msg_kc_uid_revoke_old">Eliminando certificado de revocación caducado para la identificación de usuario \'%s\'</string>
<string name="msg_kc_uid_no_cert">No se encontró auto-certificado válido para la identificación de usuario \'%s\', eliminándola del juego de claves</string>
<string name="msg_kc_uid_remove">Eliminando identificación de usuario \'%s\' no válida</string>
- <string name="msg_kc_uid_dup">Eliminando identificación de usuario duplicada \'%s\'. La clave secreta (privada) contenía dos de ellas. ¡Esto puede dar lugar a certificados perdidos!</string>
+ <string name="msg_kc_uid_dup">Eliminando identificaciones de usuario duplicadas \'%s\'. El juego de claves contenía dos de ellas. ¡Esto puede resultar en certificados perdidos!</string>
<string name="msg_kc_uid_warn_encoding">¡La identificación de usuario no se verifica como UTF-8!</string>
+ <string name="msg_kc_uat_jpeg">Procesando atributo de usuario del tipo JPEG</string>
+ <string name="msg_kc_uat_unknown">Procesando atributo de usuario de tipo desconocido</string>
+ <string name="msg_kc_uat_bad_err">Eliminando auto certificados defectuosos para el atributo de usuario</string>
+ <string name="msg_kc_uat_bad_local">Eliminando certificado de atributo de usuario con indicativo \'local\'</string>
+ <string name="msg_kc_uat_bad_time">Eliminando atributo de usuario con marca de tiempo futura</string>
+ <string name="msg_kc_uat_bad_type">Eliminando certificado de atributo de usuario de tipo desconocido (%s)</string>
+ <string name="msg_kc_uat_bad">Eliminando auto certificado defectuoso para el atributo de usuario</string>
+ <string name="msg_kc_uat_cert_dup">Eliminando auto certificado desactualizado para el atributo de usuario</string>
+ <string name="msg_kc_uat_dup">Eliminando atributo de usuario duplicado. El juego de claves contenía dos de ellos. ¡Esto puede resultar en certificados perdidos!</string>
+ <string name="msg_kc_uat_foreign">Eliminando atributo de usuario ajeno certificado por</string>
+ <string name="msg_kc_uat_revoke_dup">Eliminando certificado de revocación redundante para el atributo de usuario</string>
+ <string name="msg_kc_uat_revoke_old">Eliminando certificado de revocación desactualizado para el atributo de usuario</string>
+ <string name="msg_kc_uat_no_cert">No se encontró auto certificado válido para el atributo de usuario, eliminándolo del juego de claves</string>
+ <string name="msg_kc_uat_remove">Eliminando atributo de usuario no válido</string>
+ <string name="msg_kc_uat_warn_encoding">¡La identificación de usuario no se verifica con formato UTF-8!</string>
<!--Keyring merging log entries-->
<string name="msg_mg_error_secret_dummy">Nueva subclave pública encontrada, ¡pero la generación de subclaves secretas (privadas) ficticias no está soportada!</string>
<string name="msg_mg_error_heterogeneous">¡Se intentaron fusionar juegos de claves con diferentes huellas de validación!</string>
@@ -715,7 +759,7 @@
<string name="msg_cr_error_keysize_512">¡El tamaño de la clave debe ser mayor o igual de 512!</string>
<string name="msg_cr_error_no_curve">¡No se especificó tamaño de clave! ¡Esto es un error de programación, por favor consigne un informe de fallo!</string>
<string name="msg_cr_error_no_keysize">¡No se especificó curva elíptica! ¡Esto es un error de programación, por favor consigne un informe de fallo!</string>
- <string name="msg_cr_error_internal_pgp">¡Error PGP interno!</string>
+ <string name="msg_cr_error_internal_pgp">¡Error OpenPGP interno!</string>
<string name="msg_cr_error_unknown_algo">¡Se seleccionó un algoritmo desconocido! ¡Esto es un error de programación, por favor consigne un informe de errores!</string>
<string name="msg_cr_error_flags_dsa">¡Se seleccionaron indicativos de clave defectuosa, DSA no puede usarse para cifrado!</string>
<string name="msg_cr_error_flags_elgamal">¡Se seleccionaron indicativos de clave defectuosa, ElGamal no puede usarse para firmado!</string>
@@ -723,6 +767,7 @@
<string name="msg_cr_error_flags_ecdh">¡Seleccionados indicativos de clave defectuosa, ECDH no puede usarse para firmado!</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Modificando el juego de claves %s</string>
+ <string name="msg_mf_error_divert_serial">¡El número de serie de una clave con indicativo desviar-a-tarjeta debe ser de 16 bytes! ¡Esto es un error de programación, por favor consigne un informe de error!</string>
<string name="msg_mf_error_encode">¡Excepción en la codificación!</string>
<string name="msg_mf_error_fingerprint">¡La actual huella de validación de clave no coincide con la esperada!</string>
<string name="msg_mf_error_keyid">No hay identificación de clave. Esto es un error interno, por favor ¡consigne un informe de error!</string>
@@ -730,13 +775,16 @@
<string name="msg_mf_error_master_none">¡No se encontró certificado maestro sobre el que operar! (¿Todos revocados?)</string>
<string name="msg_mf_error_noexist_primary">¡Se especificó una identificación de usuario principal errónea!</string>
<string name="msg_mf_error_noexist_revoke">¡Se especificó una identificación de usuario errónea para revocación!</string>
+ <string name="msg_mf_error_restricted">¡Se intentó efectuar una operación restringida sin frase-contraseña! ¡Este es un error de programación, por favor consigne un informe de error!</string>
<string name="msg_mf_error_revoked_primary">¡Las identificaciones de usuario revocadas no pueden ser las principales!</string>
<string name="msg_mf_error_null_expiry">El periodo hasta la expiración no puede ser \"el mismo que antes\" al crear subclave. Esto es un error de programación, por favor ¡rellene un informe de fallo!</string>
<string name="msg_mf_error_passphrase_master">¡Error fatal descrifrando la clave maestra! Probablemente esto se daba a un error de programación, por favor ¡rellene un informe de fallo!</string>
- <string name="msg_mf_error_pgp">¡Error interno de PGP!</string>
+ <string name="msg_mf_error_pgp">¡Error OpenPGP interno!</string>
<string name="msg_mf_error_sig">¡Excepción con la firma!</string>
<string name="msg_mf_master">Modificando certificaciones maestras</string>
- <string name="msg_mf_passphrase">Cambiando frase-contraseña para el juego de claves (keyring)...</string>
+ <string name="msg_mf_notation_empty">Añadiendo paquete de notación vacío</string>
+ <string name="msg_mf_notation_pin">Añadiendo paquete de notación de PIN</string>
+ <string name="msg_mf_passphrase">Cambiando la frase-contraseña para el juego de claves</string>
<string name="msg_mf_passphrase_key">Re-cifrando subclave %s con nueva frase-contraseña</string>
<string name="msg_mf_passphrase_empty_retry">Fallo al establecer nueva frase-contraseña, intentándolo de nuevo con una antigua frase-contraseña vacía</string>
<string name="msg_mf_passphrase_fail">¡La frase contraseña para la subclave no pudo cambiarse! (¿Tiene la subclave una diferente de la de las otras claves?)</string>
@@ -754,6 +802,9 @@
<string name="msg_mf_uid_primary">Cambiando identificación de usuario primaria a %s</string>
<string name="msg_mf_uid_revoke">Revocando la identificación de usuario %s</string>
<string name="msg_mf_uid_error_empty">¡La identificación de usuario no debe estar vacía!</string>
+ <string name="msg_mf_uat_error_empty">¡El atributo de usuario no debe estar vacío!</string>
+ <string name="msg_mf_uat_add_image">Añadiendo atributo de usuario de tipo imagen</string>
+ <string name="msg_mf_uat_add_unknown">Añadiendo atributo de usuario de tipo desconocido</string>
<string name="msg_mf_unlock_error">¡Error desbloqueando juego de claves!</string>
<string name="msg_mf_unlock">Desbloqueando juego de claves (keyring)</string>
<!--Consolidate-->
@@ -774,6 +825,7 @@
<string name="msg_con_error_public">¡Error al reimportar claves públicas!</string>
<string name="msg_con_error_secret">¡Error reimportando claves secretas (privadas)!</string>
<string name="msg_con_recover">Retomando el proceso de consolidación</string>
+ <string name="msg_con_recursive">Omitiendo consolidación recursiva</string>
<string name="msg_con_recover_unknown">Retomando el proceso de consolidación desde un estado desconocido</string>
<plurals name="msg_con_reimport_public">
<item quantity="one">Reimportando una clave pública</item>
@@ -787,6 +839,19 @@
<string name="msg_con_reimport_secret_skip">No hay claves públicas a reimportar, omitiendo...</string>
<string name="msg_con_warn_delete_public">Excepción borrando fichero de caché de claves públicas</string>
<string name="msg_con_warn_delete_secret">Excepción al borrar fichero de caché de claves secretas (privadas)</string>
+ <!--Edit Key (higher level than modify)-->
+ <string name="msg_ed">Realizando operación en la clave</string>
+ <string name="msg_ed_caching_new">Guardar en caché nueva frase-contraseña</string>
+ <string name="msg_ed_error_no_parcel">¡SaveKeyringParcel ausente! (esto es un fallo, por favor notifíquelo)</string>
+ <string name="msg_ed_error_key_not_found">¡Clave no encontrada!</string>
+ <string name="msg_ed_fetching">Descargando clave a modificar (%s)</string>
+ <string name="msg_ed_success">Operación en la clave completada</string>
+ <!--Promote key-->
+ <string name="msg_pr">Promover clave pública a clave secreta (privada)</string>
+ <string name="msg_pr_error_already_secret">¡La clave ya es una clave secreta (privada)!</string>
+ <string name="msg_pr_error_key_not_found">¡Clave no encontrada!</string>
+ <string name="msg_pr_fetching">Descargar clave para modificar (%s)</string>
+ <string name="msg_pr_success">La clave se promovió con éxito</string>
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_divert">¡La edición de claves NFC (aún) no está soportada!</string>
<string name="msg_ek_error_dummy">¡No se pudo editar el juego de claves (keyring) con la clave maestra desnuda!</string>
@@ -795,11 +860,13 @@
<string name="msg_dc_askip_no_key">Datos no cifrados con clave conocida, omitiendo...</string>
<string name="msg_dc_askip_not_allowed">Datos no cifrados con clave permitida, omitiendo...</string>
<string name="msg_dc_asym">Se encontró un bloque de datos cifrados asimétricamente para la clave %s</string>
+ <string name="msg_dc_charset">Se encontró cabecera de juego de caracteres: \'%s\'</string>
<string name="msg_dc_clear_data">Procesando datos literales</string>
<string name="msg_dc_clear_decompress">Desempaquetando datos comprimidos</string>
<string name="msg_dc_clear_meta_file">Nombre de fichero: %s</string>
<string name="msg_dc_clear_meta_mime">Tipo MIME: %s</string>
<string name="msg_dc_clear_meta_size">Tamaño de fichero: %s</string>
+ <string name="msg_dc_clear_meta_size_unknown">Tamaño de fichero desconocido</string>
<string name="msg_dc_clear_meta_time">Hora de la modificación: %s</string>
<string name="msg_dc_clear_signature_bad">¡Comprobación de firma NO CORRECTA!</string>
<string name="msg_dc_clear_signature_check">Verificando datos de firma</string>
@@ -809,11 +876,12 @@
<string name="msg_dc_error_bad_passphrase">Error al desbloquear clave, ¡frase-contraseña errónea!</string>
<string name="msg_dc_error_extract_key">¡Error desconocido al desbloquear clave!</string>
<string name="msg_dc_error_integrity_check">¡Error de comprobación de integridad!</string>
+ <string name="msg_dc_error_integrity_missing">¡Verificación de integridad ausente! Esto puede ocurrir porque la aplicación de cifrado no está actualizada, o debido a un ataque desactualización.</string>
<string name="msg_dc_error_invalid_siglist">¡No se encontraron datos de firma válidos!</string>
<string name="msg_dc_error_io">¡Se encontró Excepción de E/S durante la operación!</string>
<string name="msg_dc_error_no_data">¡No se encontraron datos cifrados en el flujo de datos (`stream`)!</string>
<string name="msg_dc_error_no_key">¡No se encontraron datos cifrados con clave secreta (privada) conocida en el flujo de datos (`stream`)!</string>
- <string name="msg_dc_error_pgp_exception">¡Se encontró una Excepción PGP durante la operación!</string>
+ <string name="msg_dc_error_pgp_exception">¡Se encontró una excepción OpenPGP durante la operación!</string>
<string name="msg_dc_integrity_check_ok">¡Comprobación de integridad CORRECTA!</string>
<string name="msg_dc_ok_meta_only">Sólo fueron solicitados los metadatos, omitiendo descifrado</string>
<string name="msg_dc_ok">CORRECTO</string>
@@ -829,35 +897,49 @@
<string name="msg_dc_trail_unknown">Se encontró huella, datos de tipo desconocido</string>
<string name="msg_dc_unlocking">Desbloqueando clave secreta (privada)</string>
<!--Messages for SignEncrypt operation-->
- <string name="msg_se_asymmetric">Preparando claves públicas para cifrado</string>
- <string name="msg_se_clearsign_only">¡No está soportado el firmado de la entrada de texto no cifrado (`cleartext`)!</string>
- <string name="msg_se_compressing">Preparando compresión</string>
- <string name="msg_se_encrypting">Cifrando datos</string>
- <string name="msg_se_error_bad_passphrase">¡Frase-contraseña errónea!</string>
- <string name="msg_se_error_io">¡Se encontró Excepción de E/S durante la operación!</string>
- <string name="msg_se_error_key_sign">¡La clave de firmado seleccionada no puede firmar datos!</string>
- <string name="msg_se_error_sign_key">¡Error descargando clave de firmado!</string>
- <string name="msg_se_error_nfc">¡Error de datos NFC!</string>
- <string name="msg_se_error_no_passphrase">¡No se proporcionó frase-contraseña!</string>
- <string name="msg_se_error_pgp">¡Error interno de PGP!</string>
- <string name="msg_se_error_sig">¡Se encontró excepción de firma PGP!</string>
- <string name="msg_se_error_unlock">¡Error desconocido desbloqueando clave!</string>
- <string name="msg_se_key_ok">Cifrando para la clave: %s</string>
- <string name="msg_se_key_unknown">Clave para cifrado perdida: %s</string>
- <string name="msg_se_key_warn">Clave para cifrado errónea: %s</string>
- <string name="msg_se_ok">¡Operación de firmado/cifrado completada!</string>
- <string name="msg_se_pending_nfc">Se requiere credencial NFC, solicitando su introducción por el usuario...</string>
- <string name="msg_se_pending_passphrase">Se requiere frase-contraseña, solicitando que el usuario la introduzca...</string>
- <string name="msg_se_signing">Firmando datos (sin cifrado)</string>
- <string name="msg_se_sigcrypting">Cifrando datos con firma</string>
- <string name="msg_se">Iniciando operación de firmado y/o cifrado</string>
- <string name="msg_se_symmetric">Preparando cifrado simétrico</string>
+ <string name="msg_se">Iniciando operación de firmado/cifrado</string>
+ <string name="msg_se_input_bytes">Procesando entrada de matriz de bytes</string>
+ <string name="msg_se_input_uri">Procesando entrada de URI</string>
+ <string name="msg_se_error_no_input">¡No se proporcionó entrada!</string>
+ <string name="msg_se_error_input_uri_not_found">¡Error al abrir URI para lectura!</string>
+ <string name="msg_se_error_output_uri_not_found">¡Error al abrir URI para escritura!</string>
+ <string name="msg_se_error_too_many_inputs">¡Se especificaron más entradas que salidas! Probablemente esto es un error de programación, ¡por favor informe!</string>
+ <string name="msg_se_warn_output_left">Se dejaron las salidas pero no las entradas. Probablemente esto es un error de programación, ¡por favor informe!</string>
+ <string name="msg_se_success">Operación de firmado/cifrado completada</string>
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_pse_asymmetric">Preparando claves públicas para cifrado</string>
+ <string name="msg_pse_clearsign_only">¡El fimado de texto sin cifrar (cleartext) no está soportado!</string>
+ <string name="msg_pse_compressing">Preparando compresión</string>
+ <string name="msg_pse_encrypting">Cifrando datos</string>
+ <string name="msg_pse_error_bad_passphrase">¡Frase-contraseña errónea!</string>
+ <string name="msg_pse_error_hash_algo">¡El algoritmo de identificación criptográfica (hash) solicitado no está soportado por esta clave!</string>
+ <string name="msg_pse_error_io">¡Se encontró una excepción de E/S durante la operación!</string>
+ <string name="msg_pse_error_key_sign">¡La clave de firmado seleccionada no puede firmar datos!</string>
+ <string name="msg_pse_error_sign_key">¡Error al descargar clave de firmado!</string>
+ <string name="msg_pse_error_nfc">¡Error de datos NFC!</string>
+ <string name="msg_pse_error_no_passphrase">¡No se proporcionó frase-contraseña!</string>
+ <string name="msg_pse_error_pgp">¡Error interno de OpenPGP!</string>
+ <string name="msg_pse_error_sig">¡Se encontró una excepción de firma OpenPGP!</string>
+ <string name="msg_pse_error_unlock">¡Error desconocido al desbloquear clave!</string>
+ <string name="msg_pse_key_ok">Cifrando para la clave: %s</string>
+ <string name="msg_pse_key_unknown">Clave para cifrado ausente: %s</string>
+ <string name="msg_pse_key_warn">Clave para cifrado errónea: %s</string>
+ <string name="msg_pse_ok">¡Operación de firmado/cifrado completada!</string>
+ <string name="msg_pse_pending_nfc">Se requiere credencial NFC, solicitando su introducción al usuario...</string>
+ <string name="msg_pse_pending_passphrase">Se requiere frase-contraseña, solicitando su introducción al usuario.</string>
+ <string name="msg_pse_signing">Firmando datos (sin cifrado)</string>
+ <string name="msg_pse_signing_cleartext">Creando firma de texto sin cifrar (cleartext)</string>
+ <string name="msg_pse_signing_detached">Creando firma desacoplada</string>
+ <string name="msg_pse_sigcrypting">Cifrando datos con firma</string>
+ <string name="msg_pse">Iniciando operación de firmado y/o cifrado</string>
+ <string name="msg_pse_symmetric">Preparando cifrado simétrico</string>
<string name="msg_crt_certifying">Generando certificaciones</string>
<string name="msg_crt_certify_all">Certificando todas las identificaciones de usuario para la clave %s</string>
<plurals name="msg_crt_certify_some">
<item quantity="one">Certificando una identificación de usuario para la clave %2$s</item>
<item quantity="other">Certificando %1$d identificaciones de usuario para la clave %2$s</item>
</plurals>
+ <string name="msg_crt_error_self">¡No se puede emitir un auto-certificado como este!</string>
<string name="msg_crt_error_master_not_found">¡Clave maestra no encontrada!</string>
<string name="msg_crt_error_nothing">¡No se certificaron claves!</string>
<string name="msg_crt_error_unlock">¡Error desbloqueando clave maestra!</string>
@@ -887,6 +969,7 @@
<string name="msg_import_fingerprint_ok">Comprobación de la huella de validación correcta</string>
<string name="msg_import_merge">Incorporando datos descargados</string>
<string name="msg_import_error">¡La operación de importación falló!</string>
+ <string name="msg_import_error_io">¡Fallo en la operación de importación debido a un error de e/s!</string>
<string name="msg_import_partial">¡Operación de importado completada, con errores!</string>
<string name="msg_import_success">¡Operación de importado exitosa!</string>
<plurals name="msg_export">
@@ -903,6 +986,7 @@
<string name="msg_export_error_storage">¡El almacenamiento no está listo para escritura!</string>
<string name="msg_export_error_db">¡Error de base de datos!</string>
<string name="msg_export_error_io">¡Error de entrada/salida!</string>
+ <string name="msg_export_error_key">¡Error al preprocesar los datos de la clave!</string>
<string name="msg_export_success">Operación de exportado exitosa</string>
<string name="msg_del_error_empty">¡No hay nada que borrar!</string>
<string name="msg_del_error_multi_secret">¡Las claves secretas (privadas) sólo se pueden borrar individualmente!</string>
@@ -939,6 +1023,11 @@
<string name="passp_cache_notif_keys">Frases-contraseña almacenadas en caché:</string>
<string name="passp_cache_notif_clear">Limpiar caché</string>
<string name="passp_cache_notif_pwd">Frase-contraseña</string>
+ <!--First Time-->
+ <string name="first_time_text1">¡Recupere su privacidad con OpenKeychain!</string>
+ <string name="first_time_create_key">Crear mi clave</string>
+ <string name="first_time_import_key">Importar desde fichero</string>
+ <string name="first_time_skip">Omitir configuración</string>
<!--unsorted-->
<string name="section_certifier_id">Certificador</string>
<string name="section_cert">Detalles del certificado</string>
@@ -969,9 +1058,32 @@
<string name="error_multi_not_supported">El guardado de múltiples ficheros no está soportado. Esto es una limitación de su Android actual.</string>
<string name="key_colon">Clave:</string>
<string name="exchange_description">Para iniciar un intercambio de claves, en el lado derecho elija el número de participantes, y luego pulse el botón \"Iniciar intercambio\".\n\nSe le formularán dos preguntas más para asegurar que sólo están en el intercambio los participantes debidos, y que sus huellas de validación son correctas.</string>
- <!--First Time-->
- <string name="first_time_text1">¡Recupere su privacidad con OpenKeychain!</string>
- <string name="first_time_create_key">Crear mi clave</string>
- <string name="first_time_import_key">Importar desde fichero</string>
- <string name="first_time_skip">Omitir configuración</string>
+ <string name="btn_start_exchange">Comenzar intercambio</string>
+ <string name="user_id_none"><![CDATA[<ninguno>]]></string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <string name="title_unlock_method">Escoja un método de desbloqueo</string>
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <string name="enter_passphrase">Introduzca frase-contraseña</string>
+ <string name="passphrase">Frase-contraseña</string>
+ <string name="noPassphrase">Sin frase-contraseña</string>
+ <string name="no_passphrase_set">No se estableció frase-contraseña</string>
+ <string name="passphrases_match">Las frases-contraseña no coinciden</string>
+ <string name="passphrase_saved">Frase-contraseña guardada</string>
+ <string name="passphrase_invalid">Frase-contraseña no válida</string>
+ <string name="missing_passphrase">Frase-contraseña ausente</string>
+ <string name="passphrase_again">De nuevo</string>
+ <string name="lockpattern">Patrón de bloqueo</string>
+ <string name="lockpatternNFC">NFC + patrón de bloqueo</string>
+ <string name="unlock_method">Método de desbloqueo</string>
+ <string name="set_passphrase">Establecer frase-contraseña</string>
+ <string name="draw_lockpattern">Dibujar patrón de bloqueo</string>
+ <string name="nfc_title">NFC</string>
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+ <string name="nfc_wrong_tag">Etiqueta incorrecta. Por favor inténtelo de nuevo.</string>
+ <string name="enable_nfc">Por favor active NFC en su configuración</string>
+ <string name="no_nfc_support">Este dispositivo no soporta NFC</string>
+ <string name="nfc_write_succesful">Se escribió con éxito en la etiqueta NFC</string>
+ <string name="unlocked">Desbloqueado</string>
+ <string name="nfc_settings">Configuración</string>
</resources>
diff --git a/OpenKeychain/src/main/res/values-et/strings.xml b/OpenKeychain/src/main/res/values-et/strings.xml
index 985035f34..992d1db91 100644
--- a/OpenKeychain/src/main/res/values-et/strings.xml
+++ b/OpenKeychain/src/main/res/values-et/strings.xml
@@ -4,10 +4,7 @@
http://developer.android.com/guide/topics/resources/string-resource.html (scroll down to "Escaping apostrophes and quotes").-->
<!--title-->
<string name="title_decrypt">Dekrüpteeri</string>
- <string name="title_authentication">Salasõne</string>
<string name="title_edit_key">Muuda võtit</string>
- <string name="title_preferences">Seaded</string>
- <string name="title_key_server_preference">Võtmeserveri seaded</string>
<string name="title_import_keys">Impordi võtmeid</string>
<string name="title_export_key">Ekspordi võti</string>
<string name="title_export_keys">Ekspordi võtmed</string>
@@ -107,10 +104,17 @@
<!--createSecretKeyRing-->
<!--modifySecretKeyRing-->
<!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<!--Messages for DecryptVerify operation-->
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<!--PassphraseCache-->
- <!--unsorted-->
<!--First Time-->
+ <!--unsorted-->
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-fi/strings.xml b/OpenKeychain/src/main/res/values-fi/strings.xml
index 460c5462e..468d7b835 100644
--- a/OpenKeychain/src/main/res/values-fi/strings.xml
+++ b/OpenKeychain/src/main/res/values-fi/strings.xml
@@ -3,13 +3,191 @@
<!--GENERAL: Please put all strings inside quotes as described in example 1 on
http://developer.android.com/guide/topics/resources/string-resource.html (scroll down to "Escaping apostrophes and quotes").-->
<!--title-->
+ <string name="title_select_recipients">Valitse Avaimet</string>
+ <string name="title_select_secret_key">Valitse Oma Avain</string>
+ <string name="title_encrypt_text">Salaa Tekstiä</string>
+ <string name="title_encrypt_files">Salaa Tiedostoja</string>
+ <string name="title_decrypt">Pura Salaus</string>
+ <string name="title_unlock">Avaa Avain</string>
+ <string name="title_add_subkey">Lisää aliavain</string>
+ <string name="title_edit_key">Muokkaa avainta</string>
+ <string name="title_preferences">Asetukset</string>
+ <string name="title_cloud_search_preferences">Pilvihaun Asetukset</string>
+ <string name="title_api_registered_apps">Sovellukset</string>
+ <string name="title_change_passphrase">Vaihda Salasana</string>
+ <string name="title_share_fingerprint_with">Jaa sormenjälki...</string>
+ <string name="title_share_key">Jaa avain...</string>
+ <string name="title_share_file">Jaa tiedosto...</string>
+ <string name="title_share_message">Jaa viesti...</string>
+ <string name="title_encrypt_to_file">Salaa Tiedostoon</string>
+ <string name="title_decrypt_to_file">Pura Tiedostoon</string>
+ <string name="title_import_keys">Tuo Avaimia</string>
+ <string name="title_add_keys">Lisää Avaimia</string>
+ <string name="title_export_key">Vie Avain</string>
+ <string name="title_export_keys">Vie Avaimia</string>
+ <string name="title_key_not_found">Avainta Ei Löydy</string>
+ <string name="title_send_key">Lähetä Avainpalvelimelle</string>
+ <string name="title_certify_key">Varmenna Identiteetit</string>
+ <string name="title_key_details">Avaimen Tiedot</string>
+ <string name="title_help">Apua</string>
+ <string name="title_log_display">Loki</string>
+ <string name="title_create_key">Luo Avain</string>
+ <string name="title_exchange_keys">Vaihda Avaimia</string>
+ <string name="title_advanced_key_info">Lisätietoa Avaimesta</string>
<!--section-->
+ <string name="section_user_ids">Identiteetit</string>
+ <string name="section_keys">Aliavaimet</string>
+ <string name="section_cloud_search">Pilvihaku</string>
+ <string name="section_general">Yleistä</string>
+ <string name="section_defaults">Vakiot</string>
+ <string name="section_advanced">Lisäasetukset</string>
+ <string name="section_passphrase_cache">Salasanavälimuisti</string>
+ <string name="section_certify">Varmenna</string>
+ <string name="section_actions">Toiminteet</string>
+ <string name="section_share_key">Avain</string>
+ <string name="section_certification_key">Varmentamiseen käytetty Avaimesi</string>
+ <string name="section_upload_key">Synkronoi Avain</string>
+ <string name="section_key_server">Avainpalvelin</string>
+ <string name="section_fingerprint">Sormenjälki</string>
+ <string name="section_key_to_certify">Varmennettava avain</string>
+ <string name="section_decrypt_files">Tiedostot</string>
+ <string name="section_decrypt_text">Teksti</string>
+ <string name="section_certs">Varmenteet</string>
<!--button-->
+ <string name="btn_decrypt_verify_file">Pura, todenna ja tallenna tiedosto</string>
+ <string name="btn_decrypt_verify_message">Pura ja todenna viesti</string>
+ <string name="btn_encrypt_file">Salaa ja tallenna tiedosto</string>
+ <string name="btn_encrypt_share_file">Salaa ja jaa tiedosto</string>
+ <string name="btn_save">Tallenna</string>
+ <string name="btn_do_not_save">Peruuta</string>
+ <string name="btn_delete">Poista</string>
+ <string name="btn_no_date">Ei umpeutumisaikaa</string>
+ <string name="btn_okay">OK</string>
+ <string name="btn_export_to_server">Lataa Avainpalvelimelle</string>
+ <string name="btn_next">Seuraava</string>
+ <string name="btn_back">Takaisin</string>
+ <string name="btn_lookup_key">Etsi avain</string>
+ <string name="btn_share_encrypted_signed">Salaa ja jaa viesti</string>
+ <string name="btn_view_cert_key">Näytä varmennusavain</string>
+ <string name="btn_create_key">Luo avain</string>
+ <string name="btn_add_files">Lisää tiedosto(ja)</string>
+ <string name="btn_add_share_decrypted_text">Jaa purettu teksti</string>
+ <string name="btn_decrypt_and_verify">ja varmenna allekirjoitukset</string>
+ <string name="btn_decrypt_files">Pura tiedostoja</string>
<!--menu-->
+ <string name="menu_preferences">Asetukset</string>
+ <string name="menu_help">Apua</string>
+ <string name="menu_export_key">Vie tiedostoon</string>
+ <string name="menu_delete_key">Poista avain</string>
+ <string name="menu_create_key">Luo minun avaimeni</string>
+ <string name="menu_import_existing_key">Tuo tiedostosta</string>
+ <string name="menu_search">Etsi</string>
+ <string name="menu_beam_preferences">Beam asetukset</string>
+ <string name="menu_key_edit_cancel">Peruuta</string>
+ <string name="menu_encrypt_to">Salaa...</string>
+ <string name="menu_select_all">Valitse kaikki</string>
+ <string name="menu_add_keys">Lisää avaimia</string>
+ <string name="menu_search_cloud">Etsi pilvestä</string>
+ <string name="menu_export_all_keys">Vie kaikki avaimet</string>
+ <string name="menu_advanced">Näytä lisäinformaatio</string>
<!--label-->
+ <string name="label_message">Viesti</string>
+ <string name="label_file">Tiedosto</string>
+ <string name="label_files">Tiedosto(t)</string>
+ <string name="label_file_colon">Tiedosto:</string>
+ <string name="label_no_passphrase">Ei salasanaa</string>
+ <string name="label_passphrase">Salasana</string>
+ <string name="label_unlock">Avataan...</string>
+ <string name="label_passphrase_again">Toista salasana</string>
+ <string name="label_algorithm">Algoritmi</string>
+ <string name="label_ascii_armor">Tiedosto ASCII Armor</string>
+ <string name="label_file_ascii_armor">Käytä ASCII Armoria</string>
+ <string name="label_write_version_header">Anna muiden tietää että käytät OpenKeychainia</string>
+ <string name="label_write_version_header_summary">Kirjoittaa \'OpenKeychain v2.7\' OpenPGP-allekirjoituksiin, kryptattuun tekstiin sekä vietyihin avaimiin</string>
+ <string name="label_use_default_yubikey_pin">Käytä vakiota YubiKey PIN:iä</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Käytä numeerista näppäimistöä YuniKey PIN:iin</string>
+ <string name="label_label_use_default_yubikey_pin_summary">Käyttää vakio-PIN:iä (123456) käyttääkseen YubiKeyssejä NFC kautta</string>
+ <string name="label_asymmetric_from">Allekirjoittaja:</string>
+ <string name="label_to">Salaa:</string>
+ <string name="label_delete_after_encryption">Poista tiedosto salauksen jälkeen</string>
+ <string name="label_delete_after_decryption">Poista salauksen purkamisen jälkeen</string>
+ <string name="label_encryption_algorithm">Salausalgoritmi</string>
+ <string name="label_hash_algorithm">Tiivistealgoritmi</string>
+ <string name="label_symmetric">Salaa salasanalla</string>
+ <string name="label_passphrase_cache_ttl">Välimuistiaika</string>
+ <string name="label_passphrase_cache_subs">Väliaikaistalleta salasanat aliavaimen mukaan</string>
+ <string name="label_message_compression">Viestin pakkaus</string>
+ <string name="label_file_compression">Tiedoston pakkaus</string>
+ <string name="label_keyservers">Avainpalvelimet</string>
+ <string name="label_key_id">Avaimen ID</string>
+ <string name="label_creation">Luontiaika</string>
+ <string name="label_expiry">Umpeutumisaika</string>
+ <string name="label_usage">Käyttö</string>
+ <string name="label_key_size">Avaimen Koko</string>
+ <string name="label_ecc_curve">Elliptinen Käyrä</string>
+ <string name="label_main_user_id">Pääidentiteetti</string>
+ <string name="label_name">Nimi</string>
+ <string name="label_comment">Kommentti</string>
+ <string name="label_email">Email</string>
+ <string name="label_send_key">Synkronoi pilveen</string>
+ <string name="label_fingerprint">Sormenjälki</string>
+ <string name="expiry_date_dialog_title">Aseta umpeutumispäivämäärä</string>
+ <string name="label_first_keyserver_is_used">(Ensimmäinen avainpalvelin listalla on ensisijainen)</string>
+ <string name="label_preferred">ensisijainen</string>
+ <string name="user_id_no_name">&lt;ei nimeä&gt;</string>
+ <string name="none">&lt;ei mitään&gt;</string>
+ <string name="no_key">&lt;ei avainta&gt;</string>
+ <string name="can_encrypt">voi salata</string>
+ <string name="can_sign">voi allekirjoittaa</string>
+ <string name="can_certify">voi varmentaa</string>
+ <string name="can_certify_not">ei voi varmentaa</string>
+ <string name="expired">umpeutunut</string>
+ <string name="revoked">peruutettu</string>
+ <plurals name="n_keys">
+ <item quantity="one">1 avain</item>
+ <item quantity="other">%d avainta</item>
+ </plurals>
+ <plurals name="n_keyservers">
+ <item quantity="one">%d avainpalvelin</item>
+ <item quantity="other">%d avainpalvelinta</item>
+ </plurals>
+ <string name="secret_key">Salainen Avain:</string>
<!--choice-->
+ <string name="choice_none">Ei mitään</string>
+ <string name="choice_15secs">15 sek.</string>
+ <string name="choice_1min">1 min</string>
+ <string name="choice_3mins">3 min.</string>
+ <string name="choice_5mins">5 min.</string>
+ <string name="choice_10mins">10 min.</string>
+ <string name="choice_20mins">20 min.</string>
+ <string name="choice_40mins">40 min.</string>
+ <string name="choice_1hour">1 tunti</string>
+ <string name="choice_2hours">2 tuntia</string>
+ <string name="choice_4hours">4 tuntia</string>
+ <string name="choice_8hours">8 tuntia</string>
+ <string name="choice_forever">aina</string>
+ <string name="dsa">DSA</string>
+ <string name="elgamal">ElGamal</string>
+ <string name="rsa">RSA</string>
+ <string name="ecdh">ECDH</string>
+ <string name="ecdsa">ECDSA</string>
+ <string name="filemanager_title_open">Avaa...</string>
+ <string name="warning">Varoitus</string>
+ <string name="error">Virhe</string>
+ <string name="error_message">Virhe: %s</string>
<!--key flags-->
+ <string name="flag_certify">Varmenna</string>
+ <string name="flag_sign">Allekirjoita</string>
+ <string name="flag_encrypt">Salaa</string>
+ <string name="flag_authenticate">Autentikoi</string>
<!--sentences-->
+ <string name="wrong_passphrase">Väärä salasana.</string>
+ <string name="no_filemanager_installed">Yhteensopivaa tiedostonhallintaa ei ole asennettu.</string>
+ <string name="passphrases_do_not_match">Salasanat eivät vastaa toisiaan.</string>
+ <string name="passphrase_must_not_be_empty">Syötä salasana.</string>
+ <string name="passphrase_for_symmetric_encryption">Symmetrinen salaus.</string>
+ <string name="passphrase_for">Syötä salasana \'%s\':lle</string>
+ <string name="pin_for">Syötä PIN \'%s\':lle</string>
<!--errors
no punctuation, all lowercase,
they will be put after "error_message", e.g. "Error: file not found"-->
@@ -50,10 +228,17 @@
<!--createSecretKeyRing-->
<!--modifySecretKeyRing-->
<!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<!--Messages for DecryptVerify operation-->
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<!--PassphraseCache-->
- <!--unsorted-->
<!--First Time-->
+ <!--unsorted-->
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml
index d107bb756..6d0733625 100644
--- a/OpenKeychain/src/main/res/values-fr/strings.xml
+++ b/OpenKeychain/src/main/res/values-fr/strings.xml
@@ -9,13 +9,13 @@
<string name="title_encrypt_text">Chiffrer un texte</string>
<string name="title_encrypt_files">Chiffrer des fichiers</string>
<string name="title_decrypt">Déchiffrer</string>
- <string name="title_authentication">Phrase de passe</string>
+ <string name="title_unlock">Déverrouiller la clef</string>
<string name="title_add_subkey">Ajouter une sous-clef</string>
<string name="title_edit_key">Modifier une clef</string>
- <string name="title_preferences">Préférences</string>
+ <string name="title_preferences">Paramètres</string>
<string name="title_cloud_search_preferences">Préférences de recherche nuagique</string>
<string name="title_api_registered_apps">Applis</string>
- <string name="title_key_server_preference">Préférences du serveur de clefs</string>
+ <string name="title_key_server_preference">Serveurs de clefs</string>
<string name="title_change_passphrase">Modifier la phrase de passe</string>
<string name="title_share_fingerprint_with">Partager l\'empreinte avec...</string>
<string name="title_share_key">Partager la clef avec...</string>
@@ -36,6 +36,7 @@
<string name="title_create_key">Créer une clef</string>
<string name="title_exchange_keys">Échanger des clefs</string>
<string name="title_advanced_key_info">Infos avancées sur les clefs</string>
+ <string name="title_keys">Clefs</string>
<!--section-->
<string name="section_user_ids">identités</string>
<string name="section_keys">Sous-clefs</string>
@@ -55,6 +56,8 @@
<string name="section_decrypt_files">Fichiers</string>
<string name="section_decrypt_text">Texte</string>
<string name="section_certs">Certificats</string>
+ <string name="section_encrypt">Chiffrer</string>
+ <string name="section_decrypt">Déchiffrer</string>
<!--button-->
<string name="btn_decrypt_verify_file">Déchiffrer, vérifier et enregistrer le fichier</string>
<string name="btn_decrypt_verify_message">Déchiffrer et enregistrer le message</string>
@@ -74,9 +77,11 @@
<string name="btn_create_key">Créer la clef</string>
<string name="btn_add_files">Ajouter un/des fichier(s)</string>
<string name="btn_add_share_decrypted_text">Partager le texte déchiffrer</string>
- <string name="btn_decrypt_clipboard">Déchiffrer à partir du presse-papiers</string>
+ <string name="btn_decrypt_clipboard">Déchiffrer du texte à partir du presse-papiers</string>
<string name="btn_decrypt_and_verify">et vérifier les signatures</string>
<string name="btn_decrypt_files">Déchiffrer les fichiers</string>
+ <string name="btn_encrypt_files">Chiffrer des fichiers</string>
+ <string name="btn_encrypt_text">Chiffrer du texte</string>
<!--menu-->
<string name="menu_preferences">Paramètres</string>
<string name="menu_help">Aide</string>
@@ -90,6 +95,7 @@
<string name="menu_encrypt_to">Chiffrer vers...</string>
<string name="menu_select_all">Tout sélectionner</string>
<string name="menu_add_keys">Ajouter des clefs</string>
+ <string name="menu_search_cloud">Rechercher dans le nuage</string>
<string name="menu_export_all_keys">Exporter toutes les clefs</string>
<string name="menu_advanced">Afficher les infos avancées</string>
<!--label-->
@@ -189,7 +195,9 @@
<string name="passphrase_must_not_be_empty">Veuillez saisir une phrase de passe</string>
<string name="passphrase_for_symmetric_encryption">Chriffrement symétrique.</string>
<string name="passphrase_for">Saisir une phrase de passe pour « %s »</string>
- <string name="yubikey_pin">Saisir le NIP pour accéder à la Yubikey pour « %s »</string>
+ <string name="pin_for">Saisir le NIP pour « %s »</string>
+ <string name="yubikey_pin_for">Saisir le NIP pour accéder à la Yubikey pour « %s »</string>
+ <string name="nfc_text">Tenez la YubiKey contre le dos de votre appareil.</string>
<string name="file_delete_confirmation">Êtes-vous certain de vouloir supprimer\n%s?</string>
<string name="file_delete_successful">Supprimé avec succès.</string>
<string name="no_file_selected">Choisir d\'abord un fichier.</string>
@@ -241,7 +249,7 @@
<string name="error_could_not_extract_private_key">impossible d\'extraire la clef privée</string>
<!--errors without preceeding Error:-->
<string name="error_jelly_bean_needed">Il vous faut Android 4.1 pour utiliser la fonction Beam NFC d\'Android !</string>
- <string name="error_nfc_needed">La NFC n\'est pas disponible sur votre appareil !</string>
+ <string name="error_nfc_needed">La NFC n\'est pas proposée sur votre appareil !</string>
<string name="error_nothing_import">Aucune clef trouvée !</string>
<string name="error_contacts_key_id_missing">Échec lors de la récupération de l\'ID de clef à partir des contacts !</string>
<string name="error_generic_report_bug">Une erreur générique est survenue, veuillez créer un nouveau rapport de bogue pour OpenKeychain.</string>
@@ -278,9 +286,10 @@
<string name="progress_generating_ecdh">génération d\'une nouvelle clef ECDH... </string>
<string name="progress_modify">modification du trousseau...</string>
<string name="progress_modify_unlock">déverrouillage du trousseau...</string>
- <string name="progress_modify_adduid">ajout des ID d\'utilisateur...</string>
- <string name="progress_modify_revokeuid">révocation des ID d\'utilisateur...</string>
- <string name="progress_modify_primaryuid">changement de l\'ID d\'utilisateur principal...</string>
+ <string name="progress_modify_adduid">ajout des ID utilisateurs...</string>
+ <string name="progress_modify_adduat">ajout des attributs utilisateur...</string>
+ <string name="progress_modify_revokeuid">révocation des ID utilisateurs...</string>
+ <string name="progress_modify_primaryuid">changement de l\'ID utilisateur principal...</string>
<string name="progress_modify_subkeychange">modification des sous-clefs...</string>
<string name="progress_modify_subkeyrevoke">révocation des sous-clefs...</string>
<string name="progress_modify_subkeystrip">dépouillement des sous-clefs...</string>
@@ -353,8 +362,9 @@
<string name="import_qr_code_wrong">Code QR incorrecte ! Veuillez réessayer !</string>
<string name="import_qr_code_too_short_fingerprint">L\'empreinte est trop courte (&lt; 16 caractères)</string>
<string name="import_qr_code_button">Balayer le code QR</string>
+ <string name="import_qr_code_text">Placez votre appareil photo au-dessus du code QR !</string>
<!--Generic result toast-->
- <string name="view_log">Consulter le journal</string>
+ <string name="view_log">Détails</string>
<string name="with_warnings">, avec des avertissements</string>
<string name="with_cancelled">, jusqu\'à l\'annulation</string>
<!--Import result toast-->
@@ -438,7 +448,9 @@
<string name="api_settings_delete_account">Supprimer le compte</string>
<string name="api_settings_package_name">Nom du paquet</string>
<string name="api_settings_package_signature">SHA-256 de la signature du paquet</string>
- <string name="api_settings_accounts">Comptes</string>
+ <string name="api_settings_accounts">Comptes (API dépréciée)</string>
+ <string name="api_settings_advanced">Informations avancées</string>
+ <string name="api_settings_allowed_keys">Clefs autorisées</string>
<string name="api_settings_settings">Paramètres</string>
<string name="api_settings_key">Clef du compte :</string>
<string name="api_settings_accounts_empty">Aucun compte n\'est attaché à cette appli.</string>
@@ -524,9 +536,7 @@
<string name="view_key_expired">Cette clef est expirée !</string>
<!--Navigation Drawer-->
<string name="nav_keys">Clefs</string>
- <string name="nav_encrypt_text">Chiffrer un texte</string>
- <string name="nav_encrypt_files">Chiffrer des fichiers</string>
- <string name="nav_decrypt">Déchiffrer</string>
+ <string name="nav_encrypt_decrypt">Chiffrer/déchiffrer</string>
<string name="nav_apps">Applis</string>
<string name="drawer_open">Ouvrir le tiroir de navigation</string>
<string name="drawer_close">Fermer le tiroir de navigation</string>
@@ -552,7 +562,7 @@
<string name="msg_ip_delete_old_fail">Aucune ancienne clef de supprimée (création d\'une nouvelle ?)</string>
<string name="msg_ip_delete_old_ok">L\'ancienne clef a été supprimée de la base de données</string>
<string name="msg_ip_encode_fail">Échec de l\'opération causé par une erreur d\'encodage</string>
- <string name="msg_ip_error_io_exc">Échec de l\'opération causé par une erreur d\'e/s</string>
+ <string name="msg_ip_error_io_exc">Échec de l\'opération causé par une erreur d\'E/S</string>
<string name="msg_ip_error_op_exc">Échec de l\'opération causé par une erreur de base de données</string>
<string name="msg_ip_error_remote_ex">Échec de l\'opération causé par une erreur interne</string>
<string name="msg_ip">Importation du trousseau public %s</string>
@@ -615,14 +625,29 @@
<item quantity="one">Un certificat ignoré provenant d\'une clef publique inconnue</item>
<item quantity="other">%s certificats ignorés provenant de clefs publiques inconnues</item>
</plurals>
- <string name="msg_ip_uid_classifying_zero">Classification des ID d\'utilisateurs (aucune clef de confiance disponible)</string>
+ <string name="msg_ip_uid_classifying_zero">Classification des ID utilisateurs (aucune clef de confiance proposée)</string>
<plurals name="msg_ip_uid_classifying">
- <item quantity="one">Classification des ID d\'utilisateurs (en utilisant une clef de confiance)</item>
- <item quantity="other">Classification des ID d\'utilisateurs (en utilisant %s clefs de confiance)</item>
+ <item quantity="one">Classification des ID utilisateurs (en utilisant une clef de confiance)</item>
+ <item quantity="other">Classification des ID utilisateurs (en utilisant %s clefs de confiance)</item>
</plurals>
- <string name="msg_ip_uid_reorder">Réorganisation des ID d\'utilisateurs</string>
- <string name="msg_ip_uid_processing">Traitement de l\'ID d\'utilisateur %s</string>
- <string name="msg_ip_uid_revoked">L\'ID d\'utilisateur est révoqué</string>
+ <string name="msg_ip_uid_reorder">Réorganisation des ID utilisateurs</string>
+ <string name="msg_ip_uid_processing">Traitement de l\'ID utilisateur %s</string>
+ <string name="msg_ip_uid_revoked">L\'ID utilisateur est révoqué</string>
+ <string name="msg_ip_uat_processing_image">Traitement de l\'attribut utilisateur de type image</string>
+ <string name="msg_ip_uat_processing_unknown">Traitement de l\'attribut utilisateur de type inconnu</string>
+ <string name="msg_ip_uat_cert_bad">Mauvais certificat rencontré !</string>
+ <string name="msg_ip_uat_cert_error">Erreur lors du traitement du certificat !</string>
+ <string name="msg_ip_uat_cert_nonrevoke">A déjà un certificat non-révocable, étape ignorée.</string>
+ <string name="msg_ip_uat_cert_old">Le certificat est plus ancien que le précédent, étape ignorée.</string>
+ <string name="msg_ip_uat_cert_new">Le certificat est plus récent, remplacement du précédent.</string>
+ <string name="msg_ip_uat_cert_good">Un bon certificat par %1$s a été trouvé</string>
+ <string name="msg_ip_uat_cert_good_revoke">Une révocation d\'un bon certificat par %1$s a été trouvée</string>
+ <plurals name="msg_ip_uat_certs_unknown">
+ <item quantity="one">Un certificat provenant d\'une clef publique inconnue est ignoré</item>
+ <item quantity="other">%s certificats provenant de clefs publiques inconnues sont ignorés</item>
+ </plurals>
+ <string name="msg_ip_uat_classifying">Organisation des attributs utilisateur</string>
+ <string name="msg_ip_uat_revoked">L\'attribut utilisateur est révoqué</string>
<string name="msg_is_bad_type_public">Tentative d\'importer le trousseau public comme secret. Ceci est un bogue, veuillez remplir un rapport !</string>
<string name="msg_is_bad_type_uncanon">Tentative d\'importer un trousseau sans canonicalisation. Ceci est un bogue, veuillez remplir un rapport !</string>
<!--Import Secret log entries-->
@@ -637,6 +662,7 @@
<string name="msg_is_subkey_nonexistent">La sous-clef %s n\'est pas disponible dans la clef secrète</string>
<string name="msg_is_subkey_ok">Marquer la sous-clef secrète %s comme disponible</string>
<string name="msg_is_subkey_empty">Marquer la sous-clef secrète %s comme disponible, avec une phrase de passe vide</string>
+ <string name="msg_is_subkey_pin">La sous-clef secrète %s a été marquée comme disponible, avec un NIP</string>
<string name="msg_is_subkey_stripped">Marquer la sous-clef secrète %s comme dépouillée</string>
<string name="msg_is_subkey_divert">Marquer la sous-clef secrète %s comme « dévier vers la carte intelligente/la NFC »</string>
<string name="msg_is_success_identical">Le trousseau ne contient pas de nouvelle donnée, rien à faire</string>
@@ -645,17 +671,20 @@
<string name="msg_kc_public">Canonicalisation du trousseau public %s</string>
<string name="msg_kc_secret">Canonicalisation du trousseau secret %s</string>
<string name="msg_kc_error_v3">Ceci est une clef OpenPGP version 3, qui a été déprécié et n\'est plus pris en charge !</string>
- <string name="msg_kc_error_no_uid">Le trousseau n\'a pas d\'ID d\'utilisateur valide !</string>
+ <string name="msg_kc_error_no_uid">Le trousseau n\'a pas d\'ID utilisateur valide !</string>
<string name="msg_kc_error_master_algo">La clef maîtresse utilise un algorithme (%s) inconnu ! </string>
<string name="msg_kc_error_dup_key">La sous-clef %s se présente deux fois dans le trousseau. Le trousseau est mal formé, pas d\'importation ! </string>
<string name="msg_kc_master">Traitement de la clef maîtresse</string>
- <string name="msg_kc_revoke_bad_err">Suppression du mauvais certificat de révocation du trousseau</string>
- <string name="msg_kc_revoke_bad_local">Suppression du certificat de révocation du trousseau ayant le drapeau « local »</string>
- <string name="msg_kc_revoke_bad_time">Suppression du certificat de révocation du trousseau ayant une estampille temporelle dans le futur</string>
- <string name="msg_kc_revoke_bad_type">Suppression du certificat de clef maîtresse de type inconnu (%s)</string>
- <string name="msg_kc_revoke_bad_type_uid">Suppression du certificat de l\'ID d\'utilisateur en mauvaise position</string>
- <string name="msg_kc_revoke_bad">Suppression du mauvais certificat de révocation du trousseau</string>
+ <string name="msg_kc_master_bad_type">Suppression du certificat de clef maîtresse de type inconnu (%s)</string>
+ <string name="msg_kc_master_bad_local">Suppression du certificat clef maîtresse ayant le drapeau « local »</string>
+ <string name="msg_kc_master_bad_err">Suppression du mauvais certificat de clef maîtresse</string>
+ <string name="msg_kc_master_bad_time">Suppression du certificat de révocation du trousseau ayant une estampille temporelle dans le futur</string>
+ <string name="msg_kc_master_bad_type_uid">Suppression du certificat de l\'ID utilisateur en mauvaise position</string>
+ <string name="msg_kc_master_bad">Suppression du mauvais certificat de clef maîtresse</string>
+ <string name="msg_kc_master_local">Suppression du certificat de clef maîtresse ayant le drapeau « local »</string>
<string name="msg_kc_revoke_dup"> Suppression du certificat redondant de révocation du trousseau</string>
+ <string name="msg_kc_notation_dup">Suppression du certificat de notation redondant</string>
+ <string name="msg_kc_notation_empty">Suppression du certificat de notation vide</string>
<string name="msg_kc_sub">Traitement de la sous-clef %s</string>
<string name="msg_kc_sub_bad">Suppression du certificat invalide de liaison de la sous-clef</string>
<string name="msg_kc_sub_bad_err">Suppression du mauvais certificat de liaison de la sous-clef</string>
@@ -685,18 +714,33 @@
<item quantity="other">Canonicalisation du trousseau réussie, %d certificats redondants supprimés</item>
</plurals>
<string name="msg_kc_uid_bad_err">Suppression du mauvais auto-certificat pour l\'ID utilisateur « %s »</string>
- <string name="msg_kc_uid_bad_local">Suppression du certificat d\'ID d\'utilisateur ayant le drapeau « local »</string>
- <string name="msg_kc_uid_bad_time">Suppression de l\'ID d\'utilisateur ayant une estampille temporelle dans le futur</string>
- <string name="msg_kc_uid_bad_type">Suppression du certificat d\'ID d\'utilisateur de type inconnu (%s)</string>
+ <string name="msg_kc_uid_bad_local">Suppression du certificat d\'ID utilisateur ayant le drapeau « local »</string>
+ <string name="msg_kc_uid_bad_time">Suppression de l\'ID utilisateur ayant une estampille temporelle dans le futur</string>
+ <string name="msg_kc_uid_bad_type">Suppression du certificat d\'ID utilisateur de type inconnu (%s)</string>
<string name="msg_kc_uid_bad">Suppression du mauvais auto-certificat pour l\'ID utilisateur « %s »</string>
- <string name="msg_kc_uid_cert_dup">Suppression de l\'auto-certificat périmé pour l\'ID d\'utilisateur « %s »</string>
- <string name="msg_kc_uid_foreign">Suppression du certificat d\'ID d\'utilisateur étranger par « %s »</string>
- <string name="msg_kc_uid_revoke_dup">Suppression du certificat de révocation redondant pour l\'ID d\'utilisateur « %s »</string>
- <string name="msg_kc_uid_revoke_old">Suppression du certificat de révocation périmé pour l\'ID d\'utilisateur « %s »</string>
- <string name="msg_kc_uid_no_cert">Aucun auto-certificat valide trouvé pour l\'ID d\'utilisateur « %s », qui est maintenant enlevé du trousseau</string>
- <string name="msg_kc_uid_remove">Suppression de l\'ID d\'utilisateur invalide « %s »</string>
- <string name="msg_kc_uid_dup">Suppression de l\'ID d\'utilisateur en double « %s ». La clef secrète en contenait deux. Ceci pourrait entraîner des certificats manquants !</string>
- <string name="msg_kc_uid_warn_encoding">L\'ID d\'utilisateur ne passe pas le test UTF-8 !</string>
+ <string name="msg_kc_uid_cert_dup">Suppression de l\'auto-certificat périmé pour l\'ID utilisateur « %s »</string>
+ <string name="msg_kc_uid_foreign">Suppression du certificat d\'ID utilisateur étranger par « %s »</string>
+ <string name="msg_kc_uid_revoke_dup">Suppression du certificat de révocation redondant pour l\'ID utilisateur « %s »</string>
+ <string name="msg_kc_uid_revoke_old">Suppression du certificat de révocation périmé pour l\'ID utilisateur « %s »</string>
+ <string name="msg_kc_uid_no_cert">Aucun auto-certificat valide trouvé pour l\'ID utilisateur « %s », qui est maintenant enlevé du trousseau</string>
+ <string name="msg_kc_uid_remove">Suppression de l\'ID utilisateur invalide « %s »</string>
+ <string name="msg_kc_uid_dup">Suppression de l\'ID d\'utilisateur en double « %s ». Le trousseau en contenait deux. Ceci pourrait entraîner des certificats manquants !</string>
+ <string name="msg_kc_uid_warn_encoding">L\'ID utilisateur ne passe pas le test UTF-8 !</string>
+ <string name="msg_kc_uat_jpeg">Traitement de l\'attribut utilisateur de type JPEG</string>
+ <string name="msg_kc_uat_unknown">Traitement de l\'attribut utilisateur de type inconnu</string>
+ <string name="msg_kc_uat_bad_err">Suppression du mauvais auto-certificat pour l\'attribut utilisateur</string>
+ <string name="msg_kc_uat_bad_local">Suppression de l\'attribut utilisateur ayant le drapeau « local »</string>
+ <string name="msg_kc_uat_bad_time">Suppression de l\'attribut utilisateur ayant une estampille temporelle dans le futur</string>
+ <string name="msg_kc_uat_bad_type">Suppression du certificat d\'attribut utilisateur de type inconnu (%s)</string>
+ <string name="msg_kc_uat_bad">Suppression du mauvais auto-certificat pour l\'attribut utilisateur</string>
+ <string name="msg_kc_uat_cert_dup">Suppression de l\'auto-certificat périmé pour l\'attribut utilisateur</string>
+ <string name="msg_kc_uat_dup">Suppression de l\'attribut utilisateur en double. Le trousseau en contenait deux. Ceci pourrait entraîner des certificats manquants !</string>
+ <string name="msg_kc_uat_foreign">Suppression du certificat étranger d\'attribut utilisateur par</string>
+ <string name="msg_kc_uat_revoke_dup">Suppression du certificat de révocation redondant pour l\'attribut utilisateur</string>
+ <string name="msg_kc_uat_revoke_old">Suppression de l\'auto-certificat périmé pour l\'attribut utilisateur</string>
+ <string name="msg_kc_uat_no_cert">Aucun auto-certificat valide trouvé pour l\'attribut utilisateur, qui est maintenant enlevé du trousseau</string>
+ <string name="msg_kc_uat_remove">Suppression de l\'attribut utilisateur invalide</string>
+ <string name="msg_kc_uat_warn_encoding">L\'ID utilisateur ne passe pas le test UTF-8 !</string>
<!--Keyring merging log entries-->
<string name="msg_mg_error_secret_dummy">Une nouvelle sous-clef publique a été trouvée, mais la génération de sous-clef secrète factice n\'est pas prise en charge !</string>
<string name="msg_mg_error_heterogeneous">Il a été tenté de fusionner des trousseaux avec des empreintes différentes !</string>
@@ -709,13 +753,13 @@
<!--createSecretKeyRing-->
<string name="msg_cr">Génération d\'une nouvelle clef maîtresse</string>
<string name="msg_cr_error_no_master">Aucune option de clef maîtresse n\'a été spécifiée !</string>
- <string name="msg_cr_error_no_user_id">Les trousseaux doivent être créés avec au moins un ID d\'utilisateur !</string>
+ <string name="msg_cr_error_no_user_id">Les trousseaux doivent être créés avec au moins un ID utilisateur !</string>
<string name="msg_cr_error_no_certify">La clef maîtresse doit avoir le drapeau « certifié » !</string>
<string name="msg_cr_error_null_expiry">L\'expiration ne peut pas être « pareille qu\'avant » à la création de la clef. Ceci est une erreur du programme, veuillez remplir un rapport de bogue !</string>
<string name="msg_cr_error_keysize_512">La taille de la clef doit être supérieure ou égale à 512 !</string>
<string name="msg_cr_error_no_curve">Aucune taille de clef n\'a été spécifiée ! Ceci est une erreur de programmation, veuillez remplir un rapport de bogue !</string>
<string name="msg_cr_error_no_keysize">Aucune courbe elliptique n\'a été spécifiée ! Ceci est une erreur de programmation, veuillez remplir un rapport de bogue !</string>
- <string name="msg_cr_error_internal_pgp">Erreur interne PGP !</string>
+ <string name="msg_cr_error_internal_pgp">Erreur interne OpenPGP !</string>
<string name="msg_cr_error_unknown_algo">L\'algorithme choisi est inconnu ! Ceci est une erreur de programmation, veuillez remplir un rapport de bogue !</string>
<string name="msg_cr_error_flags_dsa">Les drapeaux de clef choisis sont incorrects, DSA ne peut pas être utilisé pour le chiffrement ! </string>
<string name="msg_cr_error_flags_elgamal">Les drapeaux de clef choisis sont incorrects, ElGamal ne peut pas être utilisé pour le chiffrement ! </string>
@@ -723,25 +767,29 @@
<string name="msg_cr_error_flags_ecdh">Les drapeaux de clef choisis sont incorrects, ECDH ne peut pas être utilisé pour le chiffrement ! </string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Modification du trousseau %s</string>
+ <string name="msg_mf_error_divert_serial">Le numéro de série d\'une clef diriger-vers-la-carte doit avoir 16 bytes ! Ceci est une erreur de programmation, veuillez remplir un rapport de bogue !</string>
<string name="msg_mf_error_encode">Exception d\'encodage !</string>
<string name="msg_mf_error_fingerprint">L\'empreinte de clef effective ne correspond pas à celle attendue !</string>
<string name="msg_mf_error_keyid">Aucune ID de clef. Ceci est une erreur interne, veuillez remplir un rapport de bogue !</string>
<string name="msg_mf_error_integrity">Erreur interne, le contrôle d\'intégrité a échoué !</string>
<string name="msg_mf_error_master_none">Aucun certificat maître sur lequel se basé n\'a été trouvé ! (Tous révoqués ?)</string>
- <string name="msg_mf_error_noexist_primary">Mauvais ID d\'utilisateur principal spécifié !</string>
- <string name="msg_mf_error_noexist_revoke">Mauvais ID d\'utilisateur spécifié pour la révocation !</string>
- <string name="msg_mf_error_revoked_primary">Les ID d\'utilisateurs révoqués ne peuvent pas être principaux !</string>
+ <string name="msg_mf_error_noexist_primary">Mauvais ID utilisateur principal spécifié !</string>
+ <string name="msg_mf_error_noexist_revoke">Mauvais ID utilisateur spécifié pour la révocation !</string>
+ <string name="msg_mf_error_restricted">Tentative d\'exécution d\'une opération restreinte sans phrase de passe ! Ceci est une erreur de programmation, veuillez remplir un rapport de bogue !</string>
+ <string name="msg_mf_error_revoked_primary">Les ID utilisateurs révoqués ne peuvent pas être principaux !</string>
<string name="msg_mf_error_null_expiry">L\'expiration ne peut pas être « pareille qu\'avant » lors de la création de sous-clefs. Ceci est une erreur de programmation, veuillez remplir un rapport de bogue !</string>
<string name="msg_mf_error_passphrase_master">Erreur fatale lors du déchiffrement de la clef maîtresse ! Ceci est probablement une erreur de programmation, veuillez remplir un rapport de bogue !</string>
- <string name="msg_mf_error_pgp">Erreur interne de PGP !</string>
+ <string name="msg_mf_error_pgp">Erreur interne OpenPGP !</string>
<string name="msg_mf_error_sig">Exception de signature !</string>
<string name="msg_mf_master">Modification des certifications maîtresses</string>
- <string name="msg_mf_passphrase">Changement de la phrase de passe pour le trousseau...</string>
+ <string name="msg_mf_notation_empty">Ajout d\'un paquet de notation vide</string>
+ <string name="msg_mf_notation_pin">Ajout d\'un paquet de notation NIP</string>
+ <string name="msg_mf_passphrase">Changement de la phrase de passe pour le trousseau</string>
<string name="msg_mf_passphrase_key">Rechiffrement de la sous-clef %s avec la nouvelle phrase de passe</string>
<string name="msg_mf_passphrase_empty_retry">Échec lors de la définition de la nouvelle phrase de passe, nouvel essai avec une ancienne phrase de passe vide</string>
<string name="msg_mf_passphrase_fail">La phrase de passe de la sous-clef n\'a pas pu être changée ! (Est-elle différente des autres clefs ?)</string>
- <string name="msg_mf_primary_replace_old">Remplacement du certificat de l\'ID d\'utilisateur principal précédent</string>
- <string name="msg_mf_primary_new">Génération d\'un nouveau certificat pour le nouvel ID d\'utilisateur principal</string>
+ <string name="msg_mf_primary_replace_old">Remplacement du certificat de l\'ID utilisateur principal précédent</string>
+ <string name="msg_mf_primary_new">Génération d\'un nouveau certificat pour le nouvel ID utilisateur principal</string>
<string name="msg_mf_subkey_change">Modification de la sous-clef %s</string>
<string name="msg_mf_error_subkey_missing">Une action a été tentée sur la sous-clef manquante %s !</string>
<string name="msg_mf_subkey_new">Ajout d\'une nouvelle sous-clef de type %s</string>
@@ -750,10 +798,13 @@
<string name="msg_mf_subkey_revoke">Révocation de la sous-clef %s</string>
<string name="msg_mf_subkey_strip">Dépouillement de la sous-clef %s</string>
<string name="msg_mf_success">Trousseau modifié avec succès</string>
- <string name="msg_mf_uid_add">Ajout de l\'ID d\'utilisateur %s</string>
- <string name="msg_mf_uid_primary">Changement de l\'ID d\'utilisateur principal en %s</string>
- <string name="msg_mf_uid_revoke">Révocation de l\'ID d\'utilisateur %s</string>
- <string name="msg_mf_uid_error_empty">L\'ID d\'utilisateur ne peut pas être vide !</string>
+ <string name="msg_mf_uid_add">Ajout de l\'ID utilisateur %s</string>
+ <string name="msg_mf_uid_primary">Changement de l\'ID utilisateur principal en %s</string>
+ <string name="msg_mf_uid_revoke">Révocation de l\'ID utilisateur %s</string>
+ <string name="msg_mf_uid_error_empty">L\'ID utilisateur ne peut pas être vide !</string>
+ <string name="msg_mf_uat_error_empty">L\'attribut utilisateur ne peut pas être vide !</string>
+ <string name="msg_mf_uat_add_image">Ajout de l\'attribut utilisateur de type image</string>
+ <string name="msg_mf_uat_add_unknown">Ajout de l\'attribut utilisateur de type inconnu</string>
<string name="msg_mf_unlock_error">Erreur lors du déverrouillage du trousseau !</string>
<string name="msg_mf_unlock">Déverrouillage du trousseau</string>
<!--Consolidate-->
@@ -774,6 +825,7 @@
<string name="msg_con_error_public">Erreur lors de la réimportation des clefs publiques !</string>
<string name="msg_con_error_secret">Erreur lors de la réimportation des clefs secrètes !</string>
<string name="msg_con_recover">Reprise du processus de consolidation</string>
+ <string name="msg_con_recursive">Consolidation récursive ignorée</string>
<string name="msg_con_recover_unknown">Reprise du processus de consolidation à partir d\'un état inconnu</string>
<plurals name="msg_con_reimport_public">
<item quantity="one">Réimportation d\'une clef publique</item>
@@ -787,6 +839,19 @@
<string name="msg_con_reimport_secret_skip">Aucune clef secrète à réimporter, étape ignorée...</string>
<string name="msg_con_warn_delete_public">Une exception a eu lieu lors de la suppression du fichier de cache public</string>
<string name="msg_con_warn_delete_secret">Une exception a eu lieu lors de la suppression du fichier de cache secret</string>
+ <!--Edit Key (higher level than modify)-->
+ <string name="msg_ed">Exécution de l\'opération sur la clef</string>
+ <string name="msg_ed_caching_new">Mise en cache de la nouvelle phrase de passe</string>
+ <string name="msg_ed_error_no_parcel">SaveKeyringParcel absent ! (Ceci est un bogue, veuillez le rapporter)</string>
+ <string name="msg_ed_error_key_not_found">Clef introuvable !</string>
+ <string name="msg_ed_fetching">Obtention de la clef à modifier (%s)</string>
+ <string name="msg_ed_success">Opération sur la clef réussie</string>
+ <!--Promote key-->
+ <string name="msg_pr">Promotion de la clef publique en clef secrète</string>
+ <string name="msg_pr_error_already_secret">La clef est déjà une clef secrète !</string>
+ <string name="msg_pr_error_key_not_found">Clef introuvable !</string>
+ <string name="msg_pr_fetching">Obtention de la clef à modifier (%s)</string>
+ <string name="msg_pr_success">Clef promue avec succès</string>
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_divert">La modification des clefs NFC n\'est pas (encore) prise en charge !</string>
<string name="msg_ek_error_dummy">Impossible de modifier un trousseau avec une clef maîtresse dépouillée !</string>
@@ -795,11 +860,13 @@
<string name="msg_dc_askip_no_key">Les données ne sont pas chiffrées avec un clef connue, étape ignorée...</string>
<string name="msg_dc_askip_not_allowed">Les données ne sont pas chiffrées avec un clef autorisée, étape ignorée...</string>
<string name="msg_dc_asym">Un bloc de données chiffrées asymétriquement a été trouvé pour la clef %s</string>
+ <string name="msg_dc_charset">En-tête de jeu de caractère trouvé : « %s »</string>
<string name="msg_dc_clear_data">Traitement des données littérales</string>
<string name="msg_dc_clear_decompress">Extraction des données compressées</string>
<string name="msg_dc_clear_meta_file">Nom de fichier : %s</string>
<string name="msg_dc_clear_meta_mime">Type MIME : %s</string>
<string name="msg_dc_clear_meta_size">Taille de fichier : %s</string>
+ <string name="msg_dc_clear_meta_size_unknown">La taille de fichier est inconnue</string>
<string name="msg_dc_clear_meta_time">Heure de modification : %s</string>
<string name="msg_dc_clear_signature_bad">La vérification de la signature n\'est PAS CORRECTE !</string>
<string name="msg_dc_clear_signature_check">Vérification des données de signature</string>
@@ -809,11 +876,12 @@
<string name="msg_dc_error_bad_passphrase">Erreur lors du déverrouillage de la clef, phrase de passe erronée !</string>
<string name="msg_dc_error_extract_key">Erreur inconnue lors du déverrouillage de la clef !</string>
<string name="msg_dc_error_integrity_check">Erreur de vérification de l\'intégrité !</string>
+ <string name="msg_dc_error_integrity_missing">Vérification de l\'intégrité absente ! Ceci peut arriver car l\'application n\'est pas à jour, ou à cause d\'une attaque par mise à niveau inférieur.</string>
<string name="msg_dc_error_invalid_siglist">Aucune donnée de signature valide trouvée !</string>
<string name="msg_dc_error_io">Une exception E/S a été rencontrée durant l\'opération !</string>
<string name="msg_dc_error_no_data">Aucune donnée chiffrée n\'a été trouvée dans le flux !</string>
<string name="msg_dc_error_no_key">Aucune donnée chiffrée avec une clef secrète connue n\'a été trouvée dans le flux !</string>
- <string name="msg_dc_error_pgp_exception">Une exception PGP a été rencontrée durant l\'opération !</string>
+ <string name="msg_dc_error_pgp_exception">Une exception OpenPGP a été rencontrée durant l\'opération !</string>
<string name="msg_dc_integrity_check_ok">Vérification de l\'intégrité OK !</string>
<string name="msg_dc_ok_meta_only">Seules les métadonnées ont été demandées, déchiffrement ignoré</string>
<string name="msg_dc_ok">OK</string>
@@ -829,35 +897,49 @@
<string name="msg_dc_trail_unknown">Des données traînantes de type inconnu ont été rencontrées</string>
<string name="msg_dc_unlocking">Déverrouillage de la clef secrète</string>
<!--Messages for SignEncrypt operation-->
- <string name="msg_se_asymmetric">Préparation de la clef secrète pour le chiffrement</string>
- <string name="msg_se_clearsign_only">La signature d\'entrée de texte en clair n\'est pas prise en charge !</string>
- <string name="msg_se_compressing">Préparation de la compression</string>
- <string name="msg_se_encrypting">Chiffrement des données</string>
- <string name="msg_se_error_bad_passphrase">Phrase de passe erronée !</string>
- <string name="msg_se_error_io">Exception E/S rencontrée durant l\'opération !</string>
- <string name="msg_se_error_key_sign">La clef de signature choisie ne peut pas signer les données !</string>
- <string name="msg_se_error_sign_key">Erreur lors de la récupération de la clef de signature !</string>
- <string name="msg_se_error_nfc">Erreur de données NFC !</string>
- <string name="msg_se_error_no_passphrase">Aucune phrase de passe fournie !</string>
- <string name="msg_se_error_pgp">Erreur interne PGP !</string>
- <string name="msg_se_error_sig">Une exception de signature PGP a été rencontrée !</string>
- <string name="msg_se_error_unlock">Erreur inconnue lors du déverrouillage de la clef !</string>
- <string name="msg_se_key_ok">Chiffrement pour la clef : %s</string>
- <string name="msg_se_key_unknown">Clef manquante pour le chiffrement : %s</string>
- <string name="msg_se_key_warn">Clef erronée pour le chiffrement : %s</string>
- <string name="msg_se_ok">Opération de signature/chiffrement réussie !</string>
- <string name="msg_se_pending_nfc">Jeton NFC exigé, demande de saisie à l\'utilisateur...</string>
- <string name="msg_se_pending_passphrase">Phrase de passe exigée, demande de saisie à l\'utilisateur...</string>
- <string name="msg_se_signing">Signature des données (sans chiffrement)</string>
- <string name="msg_se_sigcrypting">Chiffrement des données avec signature</string>
- <string name="msg_se">Début de l\'opération de signature et/ou de chiffrement</string>
- <string name="msg_se_symmetric">Préparation du chiffrement symétrique</string>
+ <string name="msg_se">Début de l\'opération de signature/chiffrement</string>
+ <string name="msg_se_input_bytes">Traitement de l\'entrée du tableau de bytes</string>
+ <string name="msg_se_input_uri">Traitement de l\'entrée de l\'URI</string>
+ <string name="msg_se_error_no_input">Aucune entrée donnée !</string>
+ <string name="msg_se_error_input_uri_not_found">Erreur lors de l\'ouverture de l\'URI en lecture !</string>
+ <string name="msg_se_error_output_uri_not_found">Erreur lors de l\'ouverture de l\'URI en écriture !</string>
+ <string name="msg_se_error_too_many_inputs">Plus d\'entrées spécifiées que de sorties ! Ceci est probablement une erreur de programmation, veuillez remplir un rapport de bogue !</string>
+ <string name="msg_se_warn_output_left">Il reste des sorties mais pas d\'entrée. Ceci est probablement une erreur de programmation, veuillez remplir un rapport de bogue !</string>
+ <string name="msg_se_success">Opération de signature/chiffrement réussie</string>
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_pse_asymmetric">Préparation des clefs publiques pour le chiffrement</string>
+ <string name="msg_pse_clearsign_only">La signature de texte en clair n\'est pas prise en charge !</string>
+ <string name="msg_pse_compressing">Préparation de la compression</string>
+ <string name="msg_pse_encrypting">Chiffrement des données</string>
+ <string name="msg_pse_error_bad_passphrase">Phrase de passe erronée !</string>
+ <string name="msg_pse_error_hash_algo">L’algorithme de hachage demandé n\'est pas pris en charge par cette clef ! </string>
+ <string name="msg_pse_error_io">Une exception E/S a été rencontrée durant l\'opération !</string>
+ <string name="msg_pse_error_key_sign">La clef de signature choisie ne peut pas signer les données !</string>
+ <string name="msg_pse_error_sign_key">Erreur lors de la récupération de la clef de signature !</string>
+ <string name="msg_pse_error_nfc">Erreur de données NFC !</string>
+ <string name="msg_pse_error_no_passphrase">Aucune phrase de passe fournie !</string>
+ <string name="msg_pse_error_pgp">Erreur interne OpenPGP !</string>
+ <string name="msg_pse_error_sig">Une exception de signature OpenPGP a été rencontrée !</string>
+ <string name="msg_pse_error_unlock">Erreur inconnue lors du déverrouillage de la clef !</string>
+ <string name="msg_pse_key_ok">Chiffrement pour la clef : %s</string>
+ <string name="msg_pse_key_unknown">Clef manquante pour le chiffrement : %s</string>
+ <string name="msg_pse_key_warn">Clef erronée pour le chiffrement : %s</string>
+ <string name="msg_pse_ok">Opération de signature/chiffrement réussie !</string>
+ <string name="msg_pse_pending_nfc">Jeton NFC exigé, demande de saisie à l\'utilisateur...</string>
+ <string name="msg_pse_pending_passphrase">Phrase de passe exigée, demande de saisie à l\'utilisateur...</string>
+ <string name="msg_pse_signing">Signature des données (sans chiffrement)</string>
+ <string name="msg_pse_signing_cleartext">Création d\'une signature de texte en clair</string>
+ <string name="msg_pse_signing_detached">Création d\'une signature détachée</string>
+ <string name="msg_pse_sigcrypting">Chiffrement des données avec signature</string>
+ <string name="msg_pse">Début de l\'opération de signature et/ou de chiffrement</string>
+ <string name="msg_pse_symmetric">Préparation du chiffrement symétrique</string>
<string name="msg_crt_certifying">Générations des certifications</string>
- <string name="msg_crt_certify_all">Certification de tous les ID d\'utilisateurs pour la clef %s</string>
+ <string name="msg_crt_certify_all">Certification de tous les ID utilisateurs pour la clef %s</string>
<plurals name="msg_crt_certify_some">
- <item quantity="one">Certification d\'un ID d\'utilisateur pour la clef %2$s</item>
- <item quantity="other">Certification de %1$d ID d\'utilisateurs pour la clef %2$s</item>
+ <item quantity="one">Certification d\'un ID utilisateur pour la clef %2$s</item>
+ <item quantity="other">Certification de %1$d ID utilisateurs pour la clef %2$s</item>
</plurals>
+ <string name="msg_crt_error_self">Un auto-certificat ne peut pas être délivré ainsi !</string>
<string name="msg_crt_error_master_not_found">Clef maîtresse introuvable !</string>
<string name="msg_crt_error_nothing">Aucune clef certifiée !</string>
<string name="msg_crt_error_unlock">Erreur lors du déverrouillage de la clef maîtresse !</string>
@@ -887,6 +969,7 @@
<string name="msg_import_fingerprint_ok">Vérification de l\'empreinte OK !</string>
<string name="msg_import_merge">Fusion des données récupérées</string>
<string name="msg_import_error">Échec lors de l\'opération d\'importation !</string>
+ <string name="msg_import_error_io">Échec de l\'opération causé par une erreur d\'E/S !</string>
<string name="msg_import_partial">Opération d\'importation réussie, avec des erreurs !</string>
<string name="msg_import_success">Opération d\'importation réussie !</string>
<plurals name="msg_export">
@@ -903,6 +986,7 @@
<string name="msg_export_error_storage">Le stockage n\'est pas prêt pour l\'écriture !</string>
<string name="msg_export_error_db">Erreur de base de données !</string>
<string name="msg_export_error_io">Erreur d\'entrée/sortie !</string>
+ <string name="msg_export_error_key">Erreur lors du prétraitement des données de la clef !</string>
<string name="msg_export_success">Opération d\'exportation réussie !</string>
<string name="msg_del_error_empty">Rien à supprimer !</string>
<string name="msg_del_error_multi_secret">Les clefs secrètes ne peuvent être supprimées qu\'individuellement !</string>
@@ -939,6 +1023,11 @@
<string name="passp_cache_notif_keys">Phrases de passe mises en cache :</string>
<string name="passp_cache_notif_clear">Effacer le cache</string>
<string name="passp_cache_notif_pwd">Phrase de passe</string>
+ <!--First Time-->
+ <string name="first_time_text1">Reprenez le contrôle de votre confidentialité avec OpenKeychain |</string>
+ <string name="first_time_create_key">Créer ma clef</string>
+ <string name="first_time_import_key">Importer depuis un fichier</string>
+ <string name="first_time_skip">Ignorer le paramétrage</string>
<!--unsorted-->
<string name="section_certifier_id">Certificateur</string>
<string name="section_cert">Détails du certificat</string>
@@ -961,7 +1050,7 @@
<string name="title_view_cert">Voir les détails du certificat</string>
<string name="unknown_algorithm">inconnu</string>
<string name="can_sign_not">impossible de signer</string>
- <string name="error_no_encrypt_subkey">Aucune sous-clef de chiffrement n\'est disponible !</string>
+ <string name="error_no_encrypt_subkey">Aucune sous-clef de chiffrement n\'est proposée !</string>
<string name="info_no_manual_account_creation">Ne pas créer de comptes-OpenKeychain manuellement.\nPour plus d\'informations, consultez l\'Aide.</string>
<string name="contact_show_key">Montrer la clef (%s)</string>
<string name="swipe_to_update">Glisser vers le bas pour mettre à jour à partir du serveur de clefs</string>
@@ -969,9 +1058,31 @@
<string name="error_multi_not_supported">L\'enregistrement des fichiers multiples n\'est pas pris en charge. Ceci est actuellement une limitation d\'Android.</string>
<string name="key_colon">Clef :</string>
<string name="exchange_description">Pour démarrer un échange de clef, choisir le nombre de participants du côté droit, puis cliquer sur le bouton « Démarrer l\'échange ».\n\Deux questions de plus seront posées pour s\'assurer que seuls les bons participants sont dans l\'échange et que les empreintes sont correctes.</string>
- <!--First Time-->
- <string name="first_time_text1">Reprenez le contrôle de votre confidentialité avec OpenKeychain |</string>
- <string name="first_time_create_key">Créer ma clef</string>
- <string name="first_time_import_key">Importer depuis un fichier</string>
- <string name="first_time_skip">Ignorer le paramétrage</string>
+ <string name="user_id_none"><![CDATA[<none>]]></string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <string name="title_unlock_method">Choisir une méthode de déverrouillage</string>
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <string name="enter_passphrase">Saisir la phrase de passe</string>
+ <string name="passphrase">Phrase de passe</string>
+ <string name="noPassphrase">Aucune phrase de passe</string>
+ <string name="no_passphrase_set">Aucune phrase de passe définie</string>
+ <string name="passphrases_match">Les phrases de passe ne correspondent pas</string>
+ <string name="passphrase_saved">Phrase de passe enregistrée</string>
+ <string name="passphrase_invalid">Phrase de passe invalide</string>
+ <string name="missing_passphrase">Phrase de passe manquante</string>
+ <string name="passphrase_again">De nouveau</string>
+ <string name="lockpattern">Schéma de verrouillage</string>
+ <string name="lockpatternNFC">NFC + schéma de verrouillage</string>
+ <string name="unlock_method">Méthode de déverrouillage</string>
+ <string name="set_passphrase">Définir la phrase de passe</string>
+ <string name="draw_lockpattern">Dessiner le schéma de verrouillage</string>
+ <string name="nfc_title">NFC</string>
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+ <string name="nfc_wrong_tag">Mauvaise balise. Veuillez ressayer.</string>
+ <string name="enable_nfc">Veuillez activer la NFC dans vos paramètres</string>
+ <string name="no_nfc_support">Cet appareil ne prends pas en charge la NFC</string>
+ <string name="nfc_write_succesful">Écrit avec succès sur la balise NFC</string>
+ <string name="unlocked">Déverrouillé</string>
+ <string name="nfc_settings">Paramètres</string>
</resources>
diff --git a/OpenKeychain/src/main/res/values-is/strings.xml b/OpenKeychain/src/main/res/values-is/strings.xml
index 460c5462e..ef0a0ce94 100644
--- a/OpenKeychain/src/main/res/values-is/strings.xml
+++ b/OpenKeychain/src/main/res/values-is/strings.xml
@@ -50,10 +50,17 @@
<!--createSecretKeyRing-->
<!--modifySecretKeyRing-->
<!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<!--Messages for DecryptVerify operation-->
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<!--PassphraseCache-->
- <!--unsorted-->
<!--First Time-->
+ <!--unsorted-->
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml
index ceab689ab..4c73ebc72 100644
--- a/OpenKeychain/src/main/res/values-it/strings.xml
+++ b/OpenKeychain/src/main/res/values-it/strings.xml
@@ -5,17 +5,14 @@
<string name="app_name">OpenKeychain</string>
<!--title-->
<string name="title_select_recipients">Seleziona chiavi</string>
- <string name="title_select_secret_key">Seleziona la Tua Chiave</string>
- <string name="title_encrypt_text">Testo Cifrato</string>
- <string name="title_encrypt_files">File Cifrati</string>
+ <string name="title_select_secret_key">Seleziona la tua chiave</string>
+ <string name="title_encrypt_text">Testo cifrato</string>
+ <string name="title_encrypt_files">File cifrati</string>
<string name="title_decrypt">Decodifica</string>
- <string name="title_authentication">Frase di accesso</string>
<string name="title_add_subkey">Aggiungi Sottochiave</string>
<string name="title_edit_key">Modifica Chiave</string>
- <string name="title_preferences">Preferenze</string>
<string name="title_cloud_search_preferences">Preferenze di ricerca</string>
<string name="title_api_registered_apps">Apps</string>
- <string name="title_key_server_preference">Preferenze Server delle Chiavi</string>
<string name="title_change_passphrase">Cambia Frase Di Accesso</string>
<string name="title_share_fingerprint_with">Condivi impronta con...</string>
<string name="title_share_key">Condividi chiave con...</string>
@@ -34,6 +31,8 @@
<string name="title_help">Aiuto</string>
<string name="title_log_display">Registro</string>
<string name="title_create_key">Crea Chiave</string>
+ <string name="title_exchange_keys">Scambia le chiavi</string>
+ <string name="title_advanced_key_info">Informazioni avanzate sulla chiave</string>
<!--section-->
<string name="section_user_ids">Identità</string>
<string name="section_keys">Sottochiavi</string>
@@ -52,6 +51,7 @@
<string name="section_key_to_certify">Chiave da certificare</string>
<string name="section_decrypt_files">Files</string>
<string name="section_decrypt_text">Testo</string>
+ <string name="section_certs">Certificati</string>
<!--button-->
<string name="btn_decrypt_verify_file">Decodifica, verifica e salva su file</string>
<string name="btn_decrypt_verify_message">Decodifica e verifica messaggio</string>
@@ -71,7 +71,6 @@
<string name="btn_create_key">Crea chiave</string>
<string name="btn_add_files">Aggiungi file(s)</string>
<string name="btn_add_share_decrypted_text">Condividi testo decifrato</string>
- <string name="btn_decrypt_clipboard">Decifra dalla lavagna</string>
<string name="btn_decrypt_and_verify">e verifica le firme</string>
<string name="btn_decrypt_files">Decifra files</string>
<!--menu-->
@@ -80,6 +79,7 @@
<string name="menu_export_key">Esporta su un file</string>
<string name="menu_delete_key">Cancella chiave</string>
<string name="menu_create_key">Crea mia chiave</string>
+ <string name="menu_import_existing_key">Importa da file</string>
<string name="menu_search">Cerca</string>
<string name="menu_beam_preferences">Impostazioni Beam</string>
<string name="menu_key_edit_cancel">Annulla</string>
@@ -102,9 +102,8 @@
<string name="label_file_ascii_armor">Abilita Armatura ASCII</string>
<string name="label_write_version_header">Fai sapere agli altri che utilizzi OpenKeychain</string>
<string name="label_write_version_header_summary">Scrive \'OpenKeychain v2.7\' nelle firme OpenPGP, testi cifrati e chiavi esportate</string>
- <string name="label_use_default_yubikey_pin">Utilizza PIN Yubikey</string>
- <string name="label_use_num_keypad_for_yubikey_pin">Usa tastierino numerico per PIN Yubikey</string>
- <string name="label_label_use_default_yubikey_pin_summary">Utilizza il PIN base (123456) per accedere a Yubikeys tramite NFC</string>
+ <string name="label_use_default_yubikey_pin">Utilizza il PIN predefinito di YubiKey</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Utilizza la tastiera numerica per il PIN di YubiKey</string>
<string name="label_asymmetric_from">Firmato da:</string>
<string name="label_to">Codifica per:</string>
<string name="label_delete_after_encryption">Elimina file dopo la codifica</string>
@@ -126,6 +125,7 @@
<string name="label_name">Nome</string>
<string name="label_comment">Commento</string>
<string name="label_email">Email</string>
+ <string name="label_send_key">Sincronizza con il cloud</string>
<string name="label_fingerprint">Impronta</string>
<string name="expiry_date_dialog_title">Impostare la data di scadenza</string>
<string name="label_first_keyserver_is_used">(Primo server delle chiavi elencato è il preferito)</string>
@@ -183,7 +183,6 @@
<string name="passphrase_must_not_be_empty">Si prega di inserire una frase di accesso.</string>
<string name="passphrase_for_symmetric_encryption">Codifica Simmetrica.</string>
<string name="passphrase_for">Inserisci la frase di accesso per \'%s\'</string>
- <string name="yubikey_pin">Inserisci il PIN per accedere a Yubikey con \'%s\'</string>
<string name="file_delete_confirmation">Sei sicuro di voler eliminare\n%s?</string>
<string name="file_delete_successful">Eliminato correttamente.</string>
<string name="no_file_selected">Seleziona un file prima.</string>
@@ -350,7 +349,6 @@ Non potrai annullare!</string>
<string name="import_qr_code_wrong">Codica QR deformato! Prova di nuovo!</string>
<string name="import_qr_code_too_short_fingerprint">Impronta troppo corta (&lt; 16 caratteri)</string>
<!--Generic result toast-->
- <string name="view_log">Mostra registro</string>
<string name="with_warnings">, con avvisi</string>
<string name="with_cancelled">, fino all\'annullamento</string>
<!--Import result toast-->
@@ -406,7 +404,6 @@ Non potrai annullare!</string>
<string name="api_settings_delete_account">Cancella account</string>
<string name="api_settings_package_name">Nome Pacchetto</string>
<string name="api_settings_package_signature">SHA-256 della Firma del Pacchetto</string>
- <string name="api_settings_accounts">Account</string>
<string name="api_settings_settings">Impostazioni</string>
<string name="api_settings_key">Chiave account:</string>
<string name="api_settings_accounts_empty">Nessun account collegato a questa applicazione</string>
@@ -430,6 +427,7 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<item quantity="one">1 chiave selezionata.</item>
<item quantity="other">%d chiavi selezionate.</item>
</plurals>
+ <string name="key_list_empty_text1">Nessuna chiave trovata!</string>
<string name="key_list_filter_show_all">Mostra tutte le chiavi</string>
<string name="key_list_filter_show_certified">Mostra solo le chiavi certificate</string>
<!--Key view-->
@@ -450,6 +448,7 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="user_id_info_certified_title">Certificato</string>
<string name="user_id_info_certified_text">Questa identità è stata certificata da te.</string>
<string name="user_id_info_uncertified_title">Non certificato</string>
+ <string name="user_id_info_uncertified_text">Questa identità non è stata ancora certificata. Non puoi esser sicuro che l\'identità corrisponda veramente ad una specifica persona.</string>
<string name="user_id_info_invalid_title">Non valido</string>
<string name="user_id_info_invalid_text">C\'è qualcosa che non va con questa identità!</string>
<!--Edit key-->
@@ -491,9 +490,6 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="view_key_expired">Questa chiave è scaduta</string>
<!--Navigation Drawer-->
<string name="nav_keys">Chiavi</string>
- <string name="nav_encrypt_text">Codifica Testo</string>
- <string name="nav_encrypt_files">Codifica documenti</string>
- <string name="nav_decrypt">Decodifica</string>
<string name="nav_apps">Apps</string>
<string name="drawer_open">Apri drawer di navigazione</string>
<string name="drawer_close">Chiudi drawer di navigazione</string>
@@ -599,11 +595,6 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="msg_kc_secret">Canonicalizzazione portachiavi segreto %s</string>
<string name="msg_kc_error_v3">Questa è una chiave OpenPGP versione 3, è deprecata e non più supportata!</string>
<string name="msg_kc_master">Elaborazione chiave principale</string>
- <string name="msg_kc_revoke_bad_err">Rimozione di certificato di revoca del portachiavi corrotto</string>
- <string name="msg_kc_revoke_bad_local">Rimozione certificato di revoca del portachiavi con caratteristica \"locale\"</string>
- <string name="msg_kc_revoke_bad_time">Rimozione certificato di revoca del portachiavi con marca temporale futura</string>
- <string name="msg_kc_revoke_bad_type">Rimozione certificato della chiave principale di tipo sconosciuto (%s)</string>
- <string name="msg_kc_revoke_bad">Rimozione certificato di revoca del portachiavi corrotto</string>
<string name="msg_kc_revoke_dup">Rimozione certificato di revoca del portachiavi ridondante</string>
<string name="msg_kc_sub">Elaborazione sottochiave %s</string>
<string name="msg_kc_sub_bad">Rimozione certificato vincolante di sottochiave non valido</string>
@@ -637,6 +628,7 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="msg_mg_secret">Fusione nel portachiavi privato %s</string>
<string name="msg_mg_new_subkey">Aggiunta nuova sottochiave %s</string>
<string name="msg_mg_found_new">Trovati %s nuovi certificati nel portachiavi</string>
+ <string name="msg_mg_unchanged">Nulla da unire</string>
<!--createSecretKeyRing-->
<string name="msg_cr">Generazione nuova chiave principale</string>
<string name="msg_cr_error_no_master">Nessuna opzione della chiave principale specificata!</string>
@@ -644,7 +636,6 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="msg_cr_error_null_expiry">La data di scadenza non può essere \'come prima\' sulla creazione di chiavi. Questo è un errore di programmazione, si prega di inviare una segnalazione di bug!</string>
<string name="msg_cr_error_keysize_512">La grandezza della chiave deve essere di 512bit o maggiore</string>
<string name="msg_cr_error_no_keysize">Nessuna curva ellittica specificata! Questo è un errore di programmazione, per favore invia una segnalazione!</string>
- <string name="msg_cr_error_internal_pgp">Errore PGP interno!</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Modifica del portachiavi %s</string>
<string name="msg_mf_error_encode">Eccezione di codifica!</string>
@@ -654,10 +645,8 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="msg_mf_error_master_none">Nessun certificato principale trovato su cui operare! (Tutti revocati?)</string>
<string name="msg_mf_error_null_expiry">La data di scadenza non può essere \"come prima\" sulla creazione di sottochiavi. Questo è un errore di programmazione, si prega di inviare una segnalazione di bug!</string>
<string name="msg_mf_error_passphrase_master">Errore irreversibile nella decodifica della chiave principale! Questo è probabilmente un errore di programmazione, si prega di inviare una segnalazione di bug!</string>
- <string name="msg_mf_error_pgp">Errore PGP interno!</string>
<string name="msg_mf_error_sig">Eccezione di firma!</string>
<string name="msg_mf_master">Modifica delle certificazioni principali</string>
- <string name="msg_mf_passphrase">Cambio frase di accesso del portachiavi...</string>
<string name="msg_mf_passphrase_key">Ri-codifica sottochiave %s con nuova frase di accesso</string>
<string name="msg_mf_passphrase_empty_retry">Impostazione nuova frase di accesso fallita, provo di nuovo con frase precedente di accesso vuota</string>
<string name="msg_mf_passphrase_fail">La frase di accesso per la sottochiave non può essere modificata! (Ne ha una diversa dalle altre chiavi?)</string>
@@ -700,6 +689,8 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="msg_con_reimport_secret_skip">Nessuna chiave privata da reimportare, proseguo...</string>
<string name="msg_con_warn_delete_public">Eccezione durante la eliminazione del file di cache pubblico</string>
<string name="msg_con_warn_delete_secret">Eccezione durante la eliminazione del file di cache privato</string>
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_divert">La Modifica delle chiavi NFC non è (ancora) supportata!</string>
<string name="msg_ek_error_not_found">Chiave non trovata!</string>
@@ -719,13 +710,7 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="msg_dc_sym_skip">Dati simmetrici non permessi, proseguo...</string>
<string name="msg_dc_unlocking">Sblocco chiave segreta</string>
<!--Messages for SignEncrypt operation-->
- <string name="msg_se_asymmetric">Preparazione chiavi pubbliche per la codifica</string>
- <string name="msg_se_compressing">Preparazione compressione</string>
- <string name="msg_se_encrypting">Codifica dati</string>
- <string name="msg_se_error_bad_passphrase">Frase di Accesso errata</string>
- <string name="msg_se_error_nfc">Errore Dati NFC!</string>
- <string name="msg_se_error_no_passphrase">Nessuna frase di accesso disponibile!</string>
- <string name="msg_se_error_pgp">Errore PGP interno!</string>
+ <!--Messages for PgpSignEncrypt operation-->
<string name="msg_crt_success">Identità certificata correttamente</string>
<string name="msg_crt_warn_not_found">Chiave non trovata!</string>
<string name="msg_crt_upload_success">Chiave caricata con successo sul server</string>
@@ -742,6 +727,10 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="passp_cache_notif_keys">Frasi di accesso memorizzate:</string>
<string name="passp_cache_notif_clear">Pulisci Cache</string>
<string name="passp_cache_notif_pwd">Frase di Accesso</string>
+ <!--First Time-->
+ <string name="first_time_text1">Riappropriati della tua privacy con OpenKeychain!</string>
+ <string name="first_time_create_key">Crea mia chiave</string>
+ <string name="first_time_skip">Salta Installazione</string>
<!--unsorted-->
<string name="section_certifier_id">Certificatore</string>
<string name="section_cert">Dettagli Certificato</string>
@@ -766,8 +755,8 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
<string name="error_no_file_selected">Seleziona almeno un file da codificare!</string>
<string name="error_multi_not_supported">Il salvataggio di più file non è supportato. Questa è una limitazione corrente di Android.</string>
<string name="key_colon">Chiave:</string>
- <!--First Time-->
- <string name="first_time_text1">Riappropriati della tua privacy con OpenKeychain!</string>
- <string name="first_time_create_key">Crea mia chiave</string>
- <string name="first_time_skip">Salta Installazione</string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml
index 607dfa833..936440893 100644
--- a/OpenKeychain/src/main/res/values-ja/strings.xml
+++ b/OpenKeychain/src/main/res/values-ja/strings.xml
@@ -9,13 +9,13 @@
<string name="title_encrypt_text">テキスト暗å·åŒ–</string>
<string name="title_encrypt_files">ファイル暗å·åŒ–</string>
<string name="title_decrypt">復å·åŒ–</string>
- <string name="title_authentication">パスフレーズ</string>
+ <string name="title_unlock">éµã®ãƒ­ãƒƒã‚¯è§£é™¤</string>
<string name="title_add_subkey">副éµã®è¿½åŠ </string>
<string name="title_edit_key">éµã®ç·¨é›†</string>
<string name="title_preferences">設定</string>
<string name="title_cloud_search_preferences">クラウド検索設定</string>
<string name="title_api_registered_apps">アプリ</string>
- <string name="title_key_server_preference">éµã‚µãƒ¼ãƒè¨­å®š</string>
+ <string name="title_key_server_preference">éµã‚µãƒ¼ãƒ</string>
<string name="title_change_passphrase">パスフレーズã®å¤‰æ›´</string>
<string name="title_share_fingerprint_with">...ã§æŒ‡ç´‹ã®å…±æœ‰</string>
<string name="title_share_key">...ã§éµã®å…±æœ‰</string>
@@ -36,6 +36,7 @@
<string name="title_create_key">éµã®ç”Ÿæˆ</string>
<string name="title_exchange_keys">éµã®äº¤æ›</string>
<string name="title_advanced_key_info">éµã®è©³ç´°æƒ…å ±</string>
+ <string name="title_keys">éµ</string>
<!--section-->
<string name="section_user_ids">ユーザID</string>
<string name="section_keys">副éµ</string>
@@ -55,6 +56,8 @@
<string name="section_decrypt_files">ファイル</string>
<string name="section_decrypt_text">テキスト</string>
<string name="section_certs">証明</string>
+ <string name="section_encrypt">æš—å·åŒ–</string>
+ <string name="section_decrypt">復å·åŒ–</string>
<!--button-->
<string name="btn_decrypt_verify_file">復å·åŒ–ã¨æ¤œè¨¼ã€ãã—ã¦ãƒ•ã‚¡ã‚¤ãƒ«ã®ä¿å­˜</string>
<string name="btn_decrypt_verify_message">メッセージã®å¾©å·åŒ–ã¨æ¤œè¨¼</string>
@@ -74,9 +77,11 @@
<string name="btn_create_key">éµã®ç”Ÿæˆ</string>
<string name="btn_add_files">ファイルã®è¿½åŠ </string>
<string name="btn_add_share_decrypted_text">復å·åŒ–ã—ãŸãƒ†ã‚­ã‚¹ãƒˆã®å…±æœ‰</string>
- <string name="btn_decrypt_clipboard">クリップボードã‹ã‚‰å¾©å·åŒ–</string>
+ <string name="btn_decrypt_clipboard">クリップボードã‹ã‚‰ãƒ†ã‚­ã‚¹ãƒˆã‚’復å·åŒ–</string>
<string name="btn_decrypt_and_verify">ã¨ç½²åã®æ¤œè¨¼</string>
<string name="btn_decrypt_files">ファイルã®å¾©å·åŒ–</string>
+ <string name="btn_encrypt_files">ファイルã®æš—å·åŒ–</string>
+ <string name="btn_encrypt_text">テキストã®æš—å·åŒ–</string>
<!--menu-->
<string name="menu_preferences">設定</string>
<string name="menu_help">ヘルプ</string>
@@ -90,6 +95,7 @@
<string name="menu_encrypt_to">æš—å·åŒ–...</string>
<string name="menu_select_all">ã™ã¹ã¦é¸æŠž</string>
<string name="menu_add_keys">éµã®è¿½åŠ </string>
+ <string name="menu_search_cloud">クラウドを検索</string>
<string name="menu_export_all_keys">ã™ã¹ã¦ã®éµã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ</string>
<string name="menu_advanced">詳細情報を表示</string>
<!--label-->
@@ -104,9 +110,9 @@
<string name="label_algorithm">アルゴリズム</string>
<string name="label_ascii_armor">アスキー形å¼ãƒ•ã‚¡ã‚¤ãƒ«</string>
<string name="label_file_ascii_armor">アスキー形å¼ãƒ•ã‚¡ã‚¤ãƒ«ã‚’有効</string>
- <string name="label_write_version_header">ä»–ã®äººã«ã‚ãªãŸãŒOpenKeychain使用ã—ã¦ã„ã‚‹ã“ã¨ã‚’知ã£ã¦ã‚‚らã„ã¾ã—ょã†</string>
+ <string name="label_write_version_header">OpenKeychainã®åˆ©ç”¨ã‚’通知ã™ã‚‹</string>
<string name="label_write_version_header_summary">OpenPGPã® ç½²åã€æš—å·æ–‡ã€ãã—ã¦ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—ãŸéµã« \'OpenKeychain v2.7\' ã¨æ›¸ãよã†ã«ãªã‚Šã¾ã—ãŸ</string>
- <string name="label_use_default_yubikey_pin">Yubikey PINをデフォルトã§ä½¿ç”¨ã™ã‚‹</string>
+ <string name="label_use_default_yubikey_pin">デフォルトã®Yubikey PINを使用ã™ã‚‹</string>
<string name="label_use_num_keypad_for_yubikey_pin">Yubikey PINã§æ•°å­—キーパッドを使ã†</string>
<string name="label_label_use_default_yubikey_pin_summary"> NFC越ã—ã«Yubikeyã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚デフォルトã®PIN (123456) を使用ã™ã‚‹</string>
<string name="label_asymmetric_from">ç½²å:</string>
@@ -187,7 +193,9 @@
<string name="passphrase_must_not_be_empty">パスフレーズを入れã¦ãã ã•ã„。</string>
<string name="passphrase_for_symmetric_encryption">対称暗å·ã€‚</string>
<string name="passphrase_for">\'%s\' ã«ãƒ‘スフレーズを入れã¦ãã ã•ã„。</string>
- <string name="yubikey_pin">\'%s\' ã® Yubikey ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã®PINを入力ã—ã¦ãã ã•ã„</string>
+ <string name="pin_for">\'%s\' ã«PINを入力ã—ã¦ãã ã•ã„</string>
+ <string name="yubikey_pin_for">\'%s\' ã® Yubikey ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã®PINを入力ã—ã¦ãã ã•ã„</string>
+ <string name="nfc_text">ã‚ãªãŸã®ãƒ‡ãƒã‚¤ã‚¹ã®èƒŒé¢ã«YubiKeyを固定ã—ã¦ãã ã•ã„。</string>
<string name="file_delete_confirmation">%s
を削除ã—ã¦ã‚‚ã‹ã¾ã„ã¾ã›ã‚“ã‹?</string>
<string name="file_delete_successful">削除ã«æˆåŠŸã—ã¾ã—ãŸã€‚</string>
@@ -255,7 +263,7 @@
<string name="error_generic_report_bug">一般エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€ã“ã®æ–°ã—ã„ãƒã‚°ã®æƒ…報をOpenKeychainプロジェクトã«é€ã£ã¦ãã ã•ã„</string>
<!--results shown after decryption/verification-->
<string name="decrypt_result_no_signature">未署å</string>
- <string name="decrypt_result_invalid_signature">ä¸æ­£ãªç½²åã§ã™!</string>
+ <string name="decrypt_result_invalid_signature">無効ãªç½²åã§ã™!</string>
<string name="decrypt_result_signature_uncertified">ç½²å(未検証!)</string>
<string name="decrypt_result_signature_certified">ç½²å</string>
<string name="decrypt_result_signature_expired_key">éµãŒæœŸé™åˆ‡ã‚Œ!</string>
@@ -265,6 +273,8 @@
<string name="decrypt_result_not_encrypted">未暗å·åŒ–</string>
<string name="decrypt_result_action_show">表示</string>
<string name="decrypt_result_action_Lookup">検出</string>
+ <string name="decrypt_invalid_text">ç½²åãŒç„¡åŠ¹ã‚‚ã—ãã¯éµãŒç ´æ£„ã•ã‚ŒãŸ/期é™ãŒåˆ‡ã‚Œã¦ã„ã¾ã™ã€‚ãªã®ã§ã ã‚Œã‹ãŒã‚ãªãŸã¸æ–‡æ›¸ã‚’書ããªã©ã¨ã¦ã‚‚出ãã¾ã›ã‚“。ã¾ã è¡¨ç¤ºã—ã¾ã™ã‹?</string>
+ <string name="decrypt_invalid_button">表示ã•ã‚Œã¦ã„ã‚‹ã€ãƒªã‚¹ã‚¯ã«ã¤ã„ã¦ç†è§£ã—ã¾ã—ãŸ!</string>
<!--Add keys-->
<string name="add_keys_my_key">自分ã®éµ:</string>
<!--progress dialogs, usually ending in '…'-->
@@ -285,6 +295,7 @@
<string name="progress_modify">éµè¼ªã‚’変更中...</string>
<string name="progress_modify_unlock">éµè¼ªã®ãƒ­ãƒƒã‚¯è§£é™¤ä¸­...</string>
<string name="progress_modify_adduid">ユーザIDを追加中...</string>
+ <string name="progress_modify_adduat">ユーザ属性を追加...</string>
<string name="progress_modify_revokeuid">ユーザIDを破棄中...</string>
<string name="progress_modify_primaryuid">主ユーザIDを変更中...</string>
<string name="progress_modify_subkeychange">副éµã®å¤‰æ›´ä¸­...</string>
@@ -358,8 +369,9 @@
<string name="import_qr_code_wrong">ä¸é©QRコード! ã‚‚ã†ä¸€åº¦!</string>
<string name="import_qr_code_too_short_fingerprint">指紋ãŒçŸ­ã‹ã™ãŽã¾ã™ (&lt; 16 文字)</string>
<string name="import_qr_code_button">QCコードã®ã‚¹ã‚­ãƒ£ãƒ³</string>
+ <string name="import_qr_code_text">カメラをQRコードã«ã‹ã–ã—ã¦ãã ã•ã„!</string>
<!--Generic result toast-->
- <string name="view_log">ログを見る</string>
+ <string name="view_log">概è¦</string>
<string name="with_warnings">ã€ã¨ãƒ¯ãƒ¼ãƒ‹ãƒ³ã‚°</string>
<string name="with_cancelled">ã€ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•ã‚Œã‚‹ã¾ã§</string>
<!--Import result toast-->
@@ -384,7 +396,30 @@
<string name="import_error_nothing">インãƒãƒ¼ãƒˆã™ã‚‹ã‚‚ã®ãŒã‚ã‚Šã¾ã›ã‚“。</string>
<string name="import_error_nothing_cancelled">インãƒãƒ¼ãƒˆã‚’キャンセルã—ã¾ã—ãŸã€‚</string>
<!--Delete result toast-->
+ <plurals name="delete_ok_but_fail_1">
+ <item quantity="other">%1$d 個ã®éµã®å‰Šé™¤ã«æˆåŠŸ</item>
+ </plurals>
+ <plurals name="delete_ok_but_fail_2">
+ <item quantity="other">ã€ã—ã‹ã— %1$d 個ã®éµ %2$s ã®å‰Šé™¤ãŒå¤±æ•—。</item>
+ </plurals>
+ <plurals name="delete_ok">
+ <item quantity="other">%1$d ã®éµ%2$sを削除ã™ã‚‹ã®ã«æˆåŠŸã—ã¾ã—ãŸã€‚</item>
+ </plurals>
+ <plurals name="delete_fail">
+ <item quantity="other">%1$d ã®éµã‚’削除中ã«ã‚¨ãƒ©ãƒ¼ã—ã¾ã—ãŸã€‚</item>
+ </plurals>
+ <string name="delete_nothing">削除ã™ã‚‹ã‚‚ã®ãŒã‚ã‚Šã¾ã›ã‚“。</string>
+ <string name="delete_cancelled">削除æ“作をキャンセルã—ã¾ã—ãŸã€‚</string>
<!--Certify result toast-->
+ <plurals name="certify_keys_ok">
+ <item quantity="other">%1$d 個ã®éµ %2$s ã®æ¤œè¨¼ã«æˆåŠŸã€‚</item>
+ </plurals>
+ <plurals name="certify_keys_with_errors">
+ <item quantity="other">%d 個ã®éµã§æ¤œè¨¼å¤±æ•—!</item>
+ </plurals>
+ <plurals name="certify_error">
+ <item quantity="other">%d 個ã®éµã®æ¤œè¨¼ãŒå¤±æ•—!</item>
+ </plurals>
<!--Intent labels-->
<string name="intent_decrypt_file">OpenKeychainã§ãƒ•ã‚¡ã‚¤ãƒ«ã‚’復å·åŒ–</string>
<string name="intent_import_key">OpenKeychainã«éµã‚’インãƒãƒ¼ãƒˆ</string>
@@ -409,7 +444,9 @@
<string name="api_settings_delete_account">アカウントを削除</string>
<string name="api_settings_package_name">パッケージå</string>
<string name="api_settings_package_signature">パッケージã®ç½²å SHA-256</string>
- <string name="api_settings_accounts">アカウント</string>
+ <string name="api_settings_accounts">アカウント(deprecated API)</string>
+ <string name="api_settings_advanced">詳細情報</string>
+ <string name="api_settings_allowed_keys">å—ã‘入れるéµ</string>
<string name="api_settings_settings">設定</string>
<string name="api_settings_key">アカウントéµ:</string>
<string name="api_settings_accounts_empty">ã“ã®ã‚¢ãƒ—リã«æŽ¥ç¶šã•ã‚Œã¦ã‚‹ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“。</string>
@@ -436,6 +473,7 @@
<plurals name="key_list_selected_keys">
<item quantity="other">%d ã®éµã‚’é¸æŠžã€‚</item>
</plurals>
+ <string name="key_list_empty_text1">éµãŒè¦‹å½“ã‚Šã¾ã›ã‚“!</string>
<string name="key_list_filter_show_all">ã™ã¹ã¦ã®éµã‚’表示</string>
<string name="key_list_filter_show_certified">検証済ã¿ã®éµã®ã¿è¡¨ç¤º</string>
<!--Key view-->
@@ -454,8 +492,10 @@
<string name="user_id_info_revoked_title">破棄</string>
<string name="user_id_info_revoked_text">ã“ã®IDã¯éµã®æ‰€æœ‰è€…ã«ã‚ˆã‚Šç ´æ£„ã•ã‚Œã¦ã„ã¾ã™ã€‚ã‚‚ã†é©æ­£ã§ã¯ã‚ã‚Šã¾ã›ã‚“。</string>
<string name="user_id_info_certified_title">検証済ã¿</string>
+ <string name="user_id_info_certified_text">ã“ã®IDã¯è²´æ–¹ã«ã‚ˆã£ã¦è¨¼æ˜Žã•ã‚Œã¦ã„ã¾ã™ã€‚</string>
<string name="user_id_info_uncertified_title">未検証</string>
- <string name="user_id_info_invalid_title">ä¸é©æ­£</string>
+ <string name="user_id_info_uncertified_text">ã“ã®IDã¯ã¾ã æ¤œè¨¼ã•ã‚Œã¦ã„ã¾ã›ã‚“。IDãŒæœ¬å½“ã«ç‰¹å®šã®äººã«å¯¾å¿œã—ã¦ã„ã‚‹å ´åˆã‚’ã€ã‚ãªãŸã¯ç¢ºèªã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。</string>
+ <string name="user_id_info_invalid_title">無効</string>
<string name="user_id_info_invalid_text">ã“ã®IDã§ã¯ãªã«ã‹ã—らå•é¡ŒãŒã‚ã‚Šã¾ã™!</string>
<!--Edit key-->
<string name="edit_key_action_change_passphrase">パスフレーズã®å¤‰æ›´</string>
@@ -496,9 +536,7 @@
<string name="view_key_expired">ã“ã®éµã¯æœŸé™åˆ‡ã‚Œã§ã™!</string>
<!--Navigation Drawer-->
<string name="nav_keys">éµ</string>
- <string name="nav_encrypt_text">テキスト暗å·åŒ–</string>
- <string name="nav_encrypt_files">ファイル暗å·åŒ–</string>
- <string name="nav_decrypt">復å·åŒ–</string>
+ <string name="nav_encrypt_decrypt">æš—å·åŒ–/復å·åŒ–</string>
<string name="nav_apps">アプリ</string>
<string name="drawer_open">ナビゲーションドロワーを開ã</string>
<string name="drawer_close">ナビゲーションドロワーを閉ã‚ã‚‹</string>
@@ -586,9 +624,27 @@
<plurals name="msg_ip_uid_certs_unknown">
<item quantity="other">ä¸æ˜Žãªå…¬é–‹éµã‹ã‚‰ %s ã®æ¤œè¨¼ã‚’無視</item>
</plurals>
+ <string name="msg_ip_uid_classifying_zero">ユーザIDを検証 (ä¿¡é ¼ã•ã‚ŒãŸéµãŒã‚ã‚Šã¾ã›ã‚“)</string>
+ <plurals name="msg_ip_uid_classifying">
+ <item quantity="other">ユーザIDを検証 ( %s ã®ä¿¡é ¼ã•ã‚ŒãŸéµã‚’使ã„ã¾ã—ãŸ)</item>
+ </plurals>
<string name="msg_ip_uid_reorder">ユーザIDã®ä¸¦ã¹ç›´ã—</string>
<string name="msg_ip_uid_processing">ユーザID %s ã®å‡¦ç†ä¸­</string>
<string name="msg_ip_uid_revoked">ユーザIDã¯ç ´æ£„ã•ã‚Œã¾ã—ãŸ</string>
+ <string name="msg_ip_uat_processing_image">ç”»åƒåž‹ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å±žæ€§ã®å‡¦ç†ä¸­</string>
+ <string name="msg_ip_uat_processing_unknown">ä¸æ˜Žãªåž‹ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å±žæ€§ã®å‡¦ç†ä¸­</string>
+ <string name="msg_ip_uat_cert_bad">å•é¡Œã®ã‚る検証を検出ã—ã¾ã—ãŸ!</string>
+ <string name="msg_ip_uat_cert_error">検証ã®å‡¦ç†ã§ã‚¨ãƒ©ãƒ¼ã—ã¾ã—ãŸ!</string>
+ <string name="msg_ip_uat_cert_nonrevoke">ã™ã§ã«æŒã£ã¦ã„る破棄ä¸èƒ½ãªè¨¼æ˜Žã§ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™ã€‚</string>
+ <string name="msg_ip_uat_cert_old">証明ãŒå‰å‡ºã®ã‚‚ã®ã‚ˆã‚Šå¤ã„ã§ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™ã€‚</string>
+ <string name="msg_ip_uat_cert_new">証明ãŒã‚ˆã‚Šæ–°ã—ã„ã§ã™ã€ä»¥å‰ã®ã‚‚ã®ã‚’ç½®ãæ›ãˆã¾ã™ã€‚</string>
+ <string name="msg_ip_uat_cert_good">%1$s ã«ã¦è‰¯å¥½ãªè¨¼æ˜Žã‚’見付ã‘ã¾ã—ãŸ</string>
+ <string name="msg_ip_uat_cert_good_revoke">%1$s ã«ã¦è‰¯å¥½ãªç ´æ£„証明を見付ã‘ã¾ã—ãŸ</string>
+ <plurals name="msg_ip_uat_certs_unknown">
+ <item quantity="other">ä¸æ˜Žãªå…¬é–‹éµãªã®ã§ %s ã®æ¤œè¨¼ã‚’無視</item>
+ </plurals>
+ <string name="msg_ip_uat_classifying">ユーザ属性ã®æ¤œæŸ»</string>
+ <string name="msg_ip_uat_revoked">ユーザ属性ã¯ç ´æ£„ã•ã‚Œã¾ã—ãŸ</string>
<string name="msg_is_bad_type_public">公開éµã®éµè¼ªã‚’秘密éµã¨ã—ã¦ã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚’試行ã—ã¾ã—ãŸã€‚ã“ã‚Œã¯ãƒã‚°ã§ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’レãƒãƒ¼ãƒˆã—ã¦ãã ã•ã„\"</string>
<string name="msg_is_bad_type_uncanon">æ­£è¦åŒ–ã›ãšã«éµè¼ªã¸ã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚’試行ã—ãŸã€‚ã“ã‚Œã¯ãƒã‚°ã§ã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚’レãƒãƒ¼ãƒˆã—ã¦ãã ã•ã„!</string>
<!--Import Secret log entries-->
@@ -603,6 +659,7 @@
<string name="msg_is_subkey_nonexistent">秘密éµã®å‰¯éµ %s ãŒåˆ©ç”¨ä¸å¯èƒ½</string>
<string name="msg_is_subkey_ok">秘密éµã®å‰¯éµ %s を利用å¯èƒ½ã¨ã—ã¦ãƒžãƒ¼ã‚¯</string>
<string name="msg_is_subkey_empty">秘密éµã®å‰¯éµ %s を利用å¯èƒ½ã¨ã—ã¦ãƒžãƒ¼ã‚¯ã€ç©ºã®ãƒ‘スフレーズã§</string>
+ <string name="msg_is_subkey_pin">秘密éµã®å‰¯éµ %s ã‚’PINã¨ã—ã¦åˆ©ç”¨å¯èƒ½ã¨ãƒžãƒ¼ã‚¯</string>
<string name="msg_is_subkey_stripped">秘密éµã®å‰¯éµ %s をストリップã¨ã—ã¦ãƒžãƒ¼ã‚¯</string>
<string name="msg_is_subkey_divert">秘密éµã®å‰¯éµ %s ã‚’\'スマートカード/NFCã¸è¿‚回\'ã¨ã—ã¦ãƒžãƒ¼ã‚¯</string>
<string name="msg_is_success_identical">éµè¼ªã«ãƒ‡ãƒ¼ã‚¿ãŒãªã„ãŸã‚ã€ãªã«ã‚‚ã—ã¾ã›ã‚“</string>
@@ -615,22 +672,25 @@
<string name="msg_kc_error_master_algo">主éµã§ä¸æ˜Žãªã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ (%s)を利用ã—ã¦ã„ã¾ã™!</string>
<string name="msg_kc_error_dup_key">éµè¼ªã®ä¸­ã«å‰¯éµ %s ãŒ2度出ç¾ã—ã¾ã—ãŸã€‚éµè¼ªãŒä¸æ•´å½¢ã¨ãªã£ã¦ãŠã‚Šã€ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãã‚ã›ã‚“!</string>
<string name="msg_kc_master">主éµå‡¦ç†ä¸­</string>
- <string name="msg_kc_revoke_bad_err">å•é¡Œã®ã‚ã‚‹éµè¼ªã®ç ´æ£„証明を破棄中</string>
- <string name="msg_kc_revoke_bad_local">éµè¼ªã®ãƒ­ãƒ¼ã‚«ãƒ«ãƒ•ãƒ©ã‚°ä»˜ã破棄証明を破棄中</string>
- <string name="msg_kc_revoke_bad_time">éµè¼ªã®æœªæ¥ã«ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ãŒã‚る破棄証明を破棄中</string>
- <string name="msg_kc_revoke_bad_type">å•é¡Œã®ã‚る主éµã®ä¸æ˜Žãªåž‹ (%s) ã®è¨¼æ˜Žã‚’破棄中</string>
- <string name="msg_kc_revoke_bad_type_uid">ä¸æ­£ãªä½ç½®ã®ãƒ¦ãƒ¼ã‚¶ID検証を破棄中</string>
- <string name="msg_kc_revoke_bad">å•é¡Œã®ã‚ã‚‹éµè¼ªã®ç ´æ£„証明を破棄中</string>
+ <string name="msg_kc_master_bad_type">主éµã®ä¸æ˜Žãªåž‹ (%s) ã®è¨¼æ˜Žã‚’破棄中</string>
+ <string name="msg_kc_master_bad_local">ローカルフラグ付ãã®ä¸»éµæ¤œè¨¼ã‚’破棄中</string>
+ <string name="msg_kc_master_bad_err">証明ãŒä»˜éšã™ã‚‹å•é¡Œã®ã‚る主éµã‚’破棄中</string>
+ <string name="msg_kc_master_bad_time">éµè¼ªã®æœªæ¥ã«ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ãŒã‚る破棄証明を破棄中</string>
+ <string name="msg_kc_master_bad_type_uid">ä¸æ­£ãªä½ç½®ã®ãƒ¦ãƒ¼ã‚¶ID検証を破棄中</string>
+ <string name="msg_kc_master_bad">証明ãŒä»˜éšã™ã‚‹å•é¡Œã®ã‚る主éµã‚’破棄中</string>
+ <string name="msg_kc_master_local">ローカルフラグ付ãã®ä¸»éµæ¤œè¨¼ã‚’破棄中</string>
<string name="msg_kc_revoke_dup">é‡è¤‡ã—ã¦ã„ã‚‹éµè¼ªã®ç ´æ£„証明を破棄中</string>
+ <string name="msg_kc_notation_dup">é‡è¤‡ã—ã¦ã„るノーテーション証明を破棄中</string>
+ <string name="msg_kc_notation_empty">空ã®ãƒŽãƒ¼ãƒ†ãƒ¼ã‚·ãƒ§ãƒ³è¨¼æ˜Žã‚’破棄中</string>
<string name="msg_kc_sub">å‰¯éµ %s ã®å‡¦ç†ä¸­</string>
- <string name="msg_kc_sub_bad">証明ãŒä»˜éšã™ã‚‹ä¸æ­£ãªå‰¯éµã‚’破棄中</string>
+ <string name="msg_kc_sub_bad">証明ãŒä»˜éšã™ã‚‹ç„¡åŠ¹ãªå‰¯éµã‚’破棄中</string>
<string name="msg_kc_sub_bad_err">証明ãŒä»˜éšã™ã‚‹å•é¡Œã®ã‚る副éµã‚’破棄中</string>
<string name="msg_kc_sub_bad_local">ローカルフラグ付ãã®è¨¼æ˜ŽãŒä»˜éšã™ã‚‹å‰¯éµã‚’破棄中</string>
<string name="msg_kc_sub_bad_keyid">副éµã®ç™ºè¡Œè€…ã®IDã¨ä»˜éšã™ã‚‹IDãŒãƒŸã‚¹ãƒžãƒƒãƒ</string>
<string name="msg_kc_sub_bad_time">未æ¥ã«ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ãŒã‚る証明ãŒä»˜éšã™ã‚‹å‰¯éµã‚’破棄中</string>
<string name="msg_kc_sub_bad_type">ä¸æ˜Žãªæ¤œè¨¼ã®ã‚¿ã‚¤ãƒ—: %sã®å‰¯éµ</string>
<string name="msg_kc_sub_dup">証明ãŒä»˜éšã™ã‚‹é‡è¤‡ã™ã‚‹å‰¯éµã‚’破棄中</string>
- <string name="msg_kc_sub_primary_bad">付éšã™ã‚‹ä¸»ãŸã‚‹è¨¼æ˜ŽãŒæ­£ã—ããªã„証明ãŒä»˜éšã™ã‚‹å‰¯éµã‚’破棄中</string>
+ <string name="msg_kc_sub_primary_bad">付éšã™ã‚‹ä¸»ãŸã‚‹è¨¼æ˜ŽãŒç„¡åŠ¹ã§ã‚ã‚‹ã‚‚ã®ãŒä»˜éšã™ã‚‹å‰¯éµã‚’破棄中</string>
<string name="msg_kc_sub_primary_bad_err">付éšã™ã‚‹ä¸»ãŸã‚‹è¨¼æ˜Žã«å•é¡ŒãŒã‚る証明ãŒä»˜éšã™ã‚‹å‰¯éµã‚’破棄中</string>
<string name="msg_kc_sub_primary_none">付éšã™ã‚‹ä¸»ãŸã‚‹è¨¼æ˜ŽãŒå¤±ãªã‚ã‚Œã¦ã„る証明ãŒä»˜éšã™ã‚‹å‰¯éµã‚’破棄中</string>
<string name="msg_kc_sub_no_cert">%s ã‹ã‚‰æ­£å¸¸ãªæ¤œè¨¼ãŒè¦‹ä»˜ã‹ã‚Šã¾ã›ã‚“ã€éµè¼ªã‹ã‚‰é™¤å¤–ã—ã¾ã™</string>
@@ -648,7 +708,34 @@
<plurals name="msg_kc_success_redundant">
<item quantity="other">éµè¼ªã®èªå¯ã«æˆåŠŸã€ %d 個ã®é‡è¤‡ã‚’除去</item>
</plurals>
+ <string name="msg_kc_uid_bad_err">ユーザID \'%s\' ã«ã‚ˆã‚‹å•é¡Œã®ã‚る自己検証を破棄中</string>
+ <string name="msg_kc_uid_bad_local">\'ローカル\'フラグ付ãã®ãƒ¦ãƒ¼ã‚¶ID検証を破棄中</string>
+ <string name="msg_kc_uid_bad_time">未æ¥ã®ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ã«ãªã£ã¦ã„るユーザIDを破棄中</string>
+ <string name="msg_kc_uid_bad_type">ä¸æ˜Žãªåž‹ (%s) ã§ã®ãƒ¦ãƒ¼ã‚¶ID検証を破棄中</string>
+ <string name="msg_kc_uid_bad">ユーザID \'%s\' ã«ã‚ˆã‚‹å•é¡Œã®ã‚る自己検証を破棄中</string>
+ <string name="msg_kc_uid_cert_dup">期é™ã®åˆ‡ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ID \'%s\' ã«ã‚ˆã‚‹è‡ªå·±æ¤œè¨¼ã‚’破棄中</string>
+ <string name="msg_kc_uid_foreign">\'%s\' ã«ã‚ˆã£ã¦æ¤œè¨¼ã•ã‚Œã¦ã„る外部ユーザIDを破棄中</string>
+ <string name="msg_kc_uid_revoke_dup">ユーザID \'%s\' ã«ã‚ˆã‚‹é‡è¤‡ã—ãŸç ´æ£„証明を破棄中</string>
+ <string name="msg_kc_uid_revoke_old">ユーザID \'%s\' ã«ã‚ˆã‚‹æœŸé™åˆ‡ã‚Œç ´æ£„証明を破棄中</string>
+ <string name="msg_kc_uid_no_cert">ユーザID \'%s\' ã®æ­£å¸¸ãªè‡ªå·±ç½²åãŒè¦‹ä»˜ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€éµè¼ªã‹ã‚‰é™¤åŽ»ã—ã¾ã—ãŸ</string>
+ <string name="msg_kc_uid_remove">無効ãªãƒ¦ãƒ¼ã‚¶ID \'%s\' を破棄中</string>
+ <string name="msg_kc_uid_dup">é‡è¤‡ã—ãŸãƒ¦ãƒ¼ã‚¶ID \'%s\' を削除中。IDを二ã¤ã‚‚ã£ã¦ã„ã¾ã™ã€‚ã“ã®çµæžœã¯ç½²åを失ã£ã¦ã„ã‚‹ãŸã‚ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“!</string>
<string name="msg_kc_uid_warn_encoding">ユーザIDãŒUTF-8ã§æ¤œè¨¼ã§ãã¾ã›ã‚“ã§ã—ãŸ!</string>
+ <string name="msg_kc_uat_jpeg">JPEGåž‹ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å±žæ€§ã®å‡¦ç†ä¸­</string>
+ <string name="msg_kc_uat_unknown">ä¸æ˜Žãªåž‹ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å±žæ€§ã®å‡¦ç†ä¸­</string>
+ <string name="msg_kc_uat_bad_err">ユーザ属性ã§å•é¡Œã®ã‚る自己検証を破棄中</string>
+ <string name="msg_kc_uat_bad_local">\'ローカル\'フラグ付ãã®ãƒ¦ãƒ¼ã‚¶å±žæ€§æ¤œè¨¼ã‚’破棄中</string>
+ <string name="msg_kc_uat_bad_time">タイムスタンプãŒæœªæ¥ã®ãƒ¦ãƒ¼ã‚¶å±žæ€§ã‚’破棄中</string>
+ <string name="msg_kc_uat_bad_type">ä¸æ˜Žãªåž‹ (%s) ã§ã®ãƒ¦ãƒ¼ã‚¶å±žæ€§æ¤œè¨¼ã‚’破棄中</string>
+ <string name="msg_kc_uat_bad">ユーザ属性ã§å•é¡Œã®ã‚る自己検証を破棄中</string>
+ <string name="msg_kc_uat_cert_dup">期é™ã®åˆ‡ã‚ŒãŸãƒ¦ãƒ¼ã‚¶å±žæ€§ã®è‡ªå·±æ¤œè¨¼ã‚’破棄中</string>
+ <string name="msg_kc_uat_dup">é‡è¤‡ã—ãŸãƒ¦ãƒ¼ã‚¶å±žæ€§ã‚’削除中。属性を二ã¤ã‚‚ã£ã¦ã„ã¾ã™ã€‚ã“ã®çµæžœã¯ç½²åを失ã£ã¦ã„ã‚‹ãŸã‚ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“!</string>
+ <string name="msg_kc_uat_foreign">ã“ã‚Œã«ã‚ˆã£ã¦æ¤œè¨¼ã•ã‚Œã¦ã„る外部ユーザ属性を破棄中</string>
+ <string name="msg_kc_uat_revoke_dup">ユーザ属性ã®é‡è¤‡ã—ãŸç ´æ£„証明を破棄中</string>
+ <string name="msg_kc_uat_revoke_old">ユーザ属性ã®æœŸé™ã®åˆ‡ã‚ŒãŸç ´æ£„証明を破棄中</string>
+ <string name="msg_kc_uat_no_cert">ユーザー属性ã¨ã—ã¦æ­£å¸¸ãªè‡ªå·±ç½²åãŒè¦‹ä»˜ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€éµè¼ªã‹ã‚‰é™¤åŽ»ã—ã¾ã—ãŸ</string>
+ <string name="msg_kc_uat_remove">無効ãªãƒ¦ãƒ¼ã‚¶å±žæ€§ã‚’破棄中</string>
+ <string name="msg_kc_uat_warn_encoding">ユーザIDãŒUTF-8ã¨ã—ã¦æ¤œè¨¼ã§ãã¾ã›ã‚“ã§ã—ãŸ!</string>
<!--Keyring merging log entries-->
<string name="msg_mg_error_secret_dummy">æ–°ã—ã„公開éµã®å‰¯éµã‚’見付ã‘ã¾ã—ãŸã€ã—ã‹ã—ダミー生æˆã®ç§˜å¯†éµã®å‰¯éµã§ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¾ã›ã‚“。!</string>
<string name="msg_mg_error_heterogeneous">指紋ãŒç•°ãªã‚‹éµè¼ªã‚’マージã—よã†ã¨ã—ã¦ã„ã¾ã™!</string>
@@ -663,32 +750,36 @@
<string name="msg_cr_error_no_master">主éµã‚ªãƒ—ション特有ã§ã¯ã‚ã‚Šã¾ã›ã‚“!</string>
<string name="msg_cr_error_no_user_id">éµè¼ªã¯æœ€ä½Žã§ã‚‚1ã¤ã®ãƒ¦ãƒ¼ã‚¶IDã®ç”ŸæˆãŒå¿…è¦ã§ã™!</string>
<string name="msg_cr_error_no_certify">主éµã¯æ¤œè¨¼ãƒ•ãƒ©ã‚°ãŒå¿…é ˆã§ã™!</string>
- <string name="msg_cr_error_null_expiry">éµã®ç”Ÿæˆæ™‚ã«æœŸé™ã‚’\'éŽåŽ»\'ã¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。ã“ã‚Œã¯ãƒ—ログラムエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã¨ã—ã¦ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é€ã£ã¦ãã ã•ã„!</string>
+ <string name="msg_cr_error_null_expiry">éµã®ç”Ÿæˆæ™‚ã«æœŸé™ã‚’\'éŽåŽ»\'ã¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。ã“ã‚Œã¯ãƒ—ログラムエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é€ã£ã¦ãã ã•ã„!</string>
<string name="msg_cr_error_keysize_512">éµã‚µã‚¤ã‚ºã¯512ã‹ãれ以上ãŒå¿…é ˆã§ã™!</string>
- <string name="msg_cr_error_no_curve">éµã‚µã‚¤ã‚ºãŒä¸æ˜Žã§ã™! ã“ã‚Œã¯ãƒ—ログラミングã®ã‚¨ãƒ©ãƒ¼ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
- <string name="msg_cr_error_no_keysize">楕円暗å·ãŒä¸æ˜Žã§ã™! ã“ã‚Œã¯ãƒ—ログラミングã®ã‚¨ãƒ©ãƒ¼ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_cr_error_no_curve">éµã‚µã‚¤ã‚ºãŒä¸æ˜Žã§ã™! ã“ã‚Œã¯ãƒ—ログラムエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_cr_error_no_keysize">楕円暗å·ãŒä¸æ˜Žã§ã™! ã“ã‚Œã¯ãƒ—ログラムエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
<string name="msg_cr_error_internal_pgp">PGP内部エラー!</string>
- <string name="msg_cr_error_unknown_algo">ä¸æ˜Žãªã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã™! ã“ã‚Œã¯ãƒ—ログラミングã®ã‚¨ãƒ©ãƒ¼ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_cr_error_unknown_algo">ä¸æ˜Žãªã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã™! ã“ã‚Œã¯ãƒ—ログラムエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
<string name="msg_cr_error_flags_dsa">å•é¡Œã®ã‚ã‚‹éµãƒ•ãƒ©ã‚°ãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã™ã€DSAã¯æš—å·åŒ–ã«ä½¿ãˆã¾ã›ã‚“!</string>
<string name="msg_cr_error_flags_elgamal">å•é¡Œã®ã‚ã‚‹éµãƒ•ãƒ©ã‚°ãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã™ã€ElGamalã¯ç½²åã«ä½¿ãˆã¾ã›ã‚“!</string>
<string name="msg_cr_error_flags_ecdsa">å•é¡Œã®ã‚ã‚‹éµãƒ•ãƒ©ã‚°ãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã™ã€æ¥•å††æ›²ç·šDSAã¯æš—å·åŒ–ã«ä½¿ãˆã¾ã›ã‚“!</string>
<string name="msg_cr_error_flags_ecdh">å•é¡Œã®ã‚ã‚‹éµãƒ•ãƒ©ã‚°ãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã™ã€æ¥•å††æ›²ç·šDHã¯ç½²åã«ä½¿ãˆã¾ã›ã‚“!</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">éµè¼ª %s を変更中</string>
+ <string name="msg_mf_error_divert_serial">カードã«å¯¾æ¯”ã—ãŸéµã®ã‚·ãƒªã‚¢ãƒ«ç•ªå·ã«ã¯16ãƒã‚¤ãƒˆã¯å¿…è¦ã§ã™!ã“ã‚Œã¯ãƒ—ロラグラムエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
<string name="msg_mf_error_encode">エンコード例外!</string>
<string name="msg_mf_error_fingerprint">ç¾å®Ÿã®éµæŒ‡ç´‹ãŒæƒ³å®šã®1ã¤ã¨åˆè‡´ã—ã¾ã›ã‚“ã§ã—ãŸ!</string>
- <string name="msg_mf_error_keyid">éµIDãŒãªã„。 ã“ã‚Œã¯å†…部エラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_mf_error_keyid">éµIDãŒã‚ã‚Šã¾ã›ã‚“。 ã“ã‚Œã¯å†…部エラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
<string name="msg_mf_error_integrity">内部エラーã€å®Œå…¨æ€§ãƒã‚§ãƒƒã‚¯ãŒå¤±æ•—!</string>
<string name="msg_mf_error_master_none">マスターèªè¨¼ãŒæ“作ã§è¦‹ä»˜ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ(ã™ã¹ã¦ç ´æ£„ã—ã¾ã—ãŸã‹?)</string>
<string name="msg_mf_error_noexist_primary">å•é¡Œã®ã‚る主ユーザIDãŒæŒ‡å®šã•ã‚ŒãŸ!</string>
<string name="msg_mf_error_noexist_revoke">破棄ã«ãŠã„ã¦å•é¡Œã®ã‚るユーザIDãŒæŒ‡å®šã•ã‚ŒãŸ!</string>
+ <string name="msg_mf_error_restricted">パスフレーズã®ãªã„厳密ãªæœæŸ»ã‚’実行ã—ã¦ã¿ã¦ãã ã•ã„!ãã‚Œã¯ãƒ—ロラミングエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
<string name="msg_mf_error_revoked_primary">主ユーザIDã®ç ´æ£„ã¯ã§ãã¾ã›ã‚“!</string>
- <string name="msg_mf_error_null_expiry">副éµã®ç”Ÿæˆæ™‚ã«æœŸé™ã‚’\"éŽåŽ»\"ã¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。ã“ã‚Œã¯ãƒ—ログラムエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã¨ã—ã¦ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é€ã£ã¦ãã ã•ã„!</string>
- <string name="msg_mf_error_passphrase_master">主éµã®å¾©å·ã§è‡´å‘½çš„ãªå¤±æ•—! ã“ã‚Œã¯ãƒ—ログラミングã®ã‚¨ãƒ©ãƒ¼ã®å ´åˆãŒã‚ã‚Šã¾ã™ã®ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_mf_error_null_expiry">副éµã®ç”Ÿæˆæ™‚ã«æœŸé™ã‚’\"éŽåŽ»\"ã¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。ã“ã‚Œã¯ãƒ—ログラムエラーã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_mf_error_passphrase_master">主éµã®å¾©å·ã§è‡´å‘½çš„ãªå¤±æ•—! ã“ã‚Œã¯ãƒ—ログラムエラーã®å ´åˆãŒã‚ã‚Šã¾ã™ã®ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
<string name="msg_mf_error_pgp">PGP内部エラー!</string>
<string name="msg_mf_error_sig">ç½²å例外!</string>
<string name="msg_mf_master">マスターèªè¨¼ã‚’変更</string>
- <string name="msg_mf_passphrase">éµè¼ªã®ãƒ‘スフレーズã®å¤‰æ›´ä¸­...</string>
+ <string name="msg_mf_notation_empty">空ã®ãƒŽãƒ¼ãƒ†ãƒ¼ã‚·ãƒ§ãƒ³ãƒ‘ケットを追加</string>
+ <string name="msg_mf_notation_pin">PINノーテーションパケットを追加</string>
+ <string name="msg_mf_passphrase">éµè¼ªã®ãƒ‘スフレーズã®å¤‰æ›´ä¸­</string>
<string name="msg_mf_passphrase_key">å‰¯éµ %s ã‚’æ–°ã—ã„パスフレーズã§å†æš—å·åŒ–</string>
<string name="msg_mf_passphrase_empty_retry">æ–°ã—ã„パスフレーズã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸã€ç©ºã®å¤ã„パスフレーズã§å†åº¦è©¦ã—ã¦ãã ã•ã„</string>
<string name="msg_mf_passphrase_fail">副éµã®ãƒ‘スフレーズã¯å¤‰æ›´ã•ã‚Œã¦ã„ã¾ã›ã‚“! (ä»–ã®éµã¨ã¯ç•°ãªã‚‹ã«ãªã£ã¦ã„ã¾ã›ã‚“ã‹?)</string>
@@ -703,12 +794,17 @@
<string name="msg_mf_subkey_strip">å‰¯éµ %s ã®ã‚¹ãƒˆãƒªãƒƒãƒ—中</string>
<string name="msg_mf_success">éµè¼ªã®å¤‰æ›´ã«æˆåŠŸ</string>
<string name="msg_mf_uid_add">ユーザID %s を追加中</string>
+ <string name="msg_mf_uid_primary">主UIDã‚’ %s ã«å¤‰æ›´ä¸­</string>
+ <string name="msg_mf_uid_revoke">ユーザID %s を破棄中</string>
<string name="msg_mf_uid_error_empty">ユーザIDã¯ç©ºã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“!</string>
+ <string name="msg_mf_uat_error_empty">ユーザ属性ã¯ç©ºã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“!</string>
+ <string name="msg_mf_uat_add_image">ç”»åƒåž‹ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å±žæ€§ã®è¿½åŠ ä¸­</string>
+ <string name="msg_mf_uat_add_unknown">ä¸æ˜Žãªåž‹ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å±žæ€§ã®è¿½åŠ ä¸­</string>
<string name="msg_mf_unlock_error">éµè¼ªã®ãƒ­ãƒƒã‚¯è§£é™¤ã‚¨ãƒ©ãƒ¼!</string>
<string name="msg_mf_unlock">éµè¼ªã®ãƒ­ãƒƒã‚¯è§£é™¤ä¸­</string>
<!--Consolidate-->
<string name="msg_con">データベースã®çµ±åˆä¸­</string>
- <string name="msg_con_error_bad_state">データベースã§ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã›ãšã«çµ±åˆãŒé–‹å§‹ã•ã‚Œã¦ã„ã¾ã™! ã“ã‚Œã¯ãŠãらãプログラミングã®ã‚¨ãƒ©ãƒ¼ãªã®ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_con_error_bad_state">データベースã§ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã›ãšã«çµ±åˆãŒé–‹å§‹ã•ã‚Œã¦ã„ã¾ã™! ã“ã‚Œã¯ãŠãらãプログラムエラーãªã®ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã§ãƒ•ã‚¡ã‚¤ãƒ«ã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
<string name="msg_con_error_concurrent">çµ±åˆã‚’中断ã—ã¾ã—ãŸã€ã™ã§ã«ä»–ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã§å‹•ã„ã¦ã„ã‚‹ãŸã‚ã§ã™!</string>
<string name="msg_con_save_secret">秘密éµã®éµè¼ªã‚’ä¿å­˜ä¸­</string>
<string name="msg_con_save_public">公開éµã®éµè¼ªã‚’ä¿å­˜ä¸­</string>
@@ -723,6 +819,9 @@
<string name="msg_con_error_io_secret">キャッシュã«ç§˜å¯†éµã‚’書ãéš›ã«I/Oエラー!</string>
<string name="msg_con_error_public">公開éµã®å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã®ã‚¨ãƒ©ãƒ¼!</string>
<string name="msg_con_error_secret">秘密éµã®å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã®ã‚¨ãƒ©ãƒ¼!</string>
+ <string name="msg_con_recover">çµ±åˆæ•´ç†å‡¦ç†ã®ãƒ¬ã‚¸ãƒ¥ãƒ¼ãƒ </string>
+ <string name="msg_con_recursive">å†å¸°çµ±åˆå‡¦ç†ã‚’スキップ</string>
+ <string name="msg_con_recover_unknown">ä¸æ˜ŽãªçŠ¶æ…‹ã‹ã‚‰ã®çµ±åˆæ•´ç†å‡¦ç†ã®ãƒ¬ã‚¸ãƒ¥ãƒ¼ãƒ </string>
<plurals name="msg_con_reimport_public">
<item quantity="other">%d ã®å…¬é–‹éµã‚’å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆä¸­</item>
</plurals>
@@ -733,6 +832,19 @@
<string name="msg_con_reimport_secret_skip">å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ç§˜å¯†éµãŒã‚ã‚Šã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™...</string>
<string name="msg_con_warn_delete_public">公開éµã‚­ãƒ£ãƒƒã‚·ãƒ¥ãƒ•ã‚¡ã‚¤ãƒ«ã®å‰Šé™¤ä¾‹å¤–</string>
<string name="msg_con_warn_delete_secret">秘密éµã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãƒ•ã‚¡ã‚¤ãƒ«ã‚’削除中ã«ä¾‹å¤–発生</string>
+ <!--Edit Key (higher level than modify)-->
+ <string name="msg_ed">キーæ“作ã®å®Ÿè¡Œ</string>
+ <string name="msg_ed_caching_new">æ–°ã—ã„パスフレーズをキャッシュ</string>
+ <string name="msg_ed_error_no_parcel">SaveKeyringParcel欠è½!(ã“ã‚Œã¯ãƒã‚°ã§ã™ã€ãƒ¬ãƒãƒ¼ãƒˆã—ã¦ãã ã•ã„)</string>
+ <string name="msg_ed_error_key_not_found">éµãŒè¦‹å½“ã‚Šã¾ã›ã‚“!</string>
+ <string name="msg_ed_fetching">フェッãƒã—ãŸéµã‚’変更 (%s)</string>
+ <string name="msg_ed_success">éµã®æ“作ã«æˆåŠŸ</string>
+ <!--Promote key-->
+ <string name="msg_pr">公開éµãŒç§˜å¯†éµã«æ˜‡æ ¼ã—ã¾ã—ãŸ</string>
+ <string name="msg_pr_error_already_secret">éµã¯ã™ã§ã«ç§˜å¯†éµã¨ãªã£ã¦ã„ã¾ã™!</string>
+ <string name="msg_pr_error_key_not_found">éµãŒè¦‹å½“ã‚Šã¾ã›ã‚“!</string>
+ <string name="msg_pr_fetching">フェッãƒã—ãŸéµã‚’変更 (%s)</string>
+ <string name="msg_pr_success">éµã¯æ­£å¸¸ã«æ˜‡æ ¼ã—ã¾ã—ãŸ</string>
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_divert">NFCã®éµã®ç·¨é›†ã¯(ã¾ã )サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“!</string>
<string name="msg_ek_error_dummy">ストリップã—ãŸä¸»éµã§ã¯éµè¼ªã‚’編集ã§ãã¾ã›ã‚“!</string>
@@ -741,11 +853,13 @@
<string name="msg_dc_askip_no_key">既知ã®éµã§æš—å·åŒ–ã•ã‚Œã¦ã„ãªã„データã§ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™...</string>
<string name="msg_dc_askip_not_allowed">å—ã‘入れãŸéµã§æš—å·åŒ–ã•ã‚Œã¦ã„ãªã„データã§ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™...</string>
<string name="msg_dc_asym">éµ %s ã§éžå¯¾ç§°ã®æš—å·åŒ–ã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ã®ãƒ–ロックを検出</string>
+ <string name="msg_dc_charset">文字セットヘッダを発見: \'%s\'</string>
<string name="msg_dc_clear_data">固定データを処ç†ä¸­</string>
<string name="msg_dc_clear_decompress">圧縮データã®å±•é–‹ä¸­</string>
<string name="msg_dc_clear_meta_file">ファイルå: %s</string>
<string name="msg_dc_clear_meta_mime">MIME種別: %s</string>
<string name="msg_dc_clear_meta_size">ファイルサイズ: %s</string>
+ <string name="msg_dc_clear_meta_size_unknown">ファイルサイズãŒä¸æ˜Ž</string>
<string name="msg_dc_clear_meta_time">更新日時: %s</string>
<string name="msg_dc_clear_signature_bad">ç½²åã®ç¢ºèªãŒOKã§ã¯ã‚ã‚Šã¾ã›ã‚“!</string>
<string name="msg_dc_clear_signature_check">ç½²åデータã®æ¤œè¨¼ä¸­</string>
@@ -755,6 +869,7 @@
<string name="msg_dc_error_bad_passphrase">éµã®ãƒ­ãƒƒã‚¯è§£é™¤ã‚¨ãƒ©ãƒ¼ã€ãƒ‘スフレーズã«å•é¡ŒãŒã‚ã‚Šã¾ã™!</string>
<string name="msg_dc_error_extract_key">éµã®ãƒ­ãƒƒã‚¯è§£é™¤ã§ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼!</string>
<string name="msg_dc_error_integrity_check">完全性ãƒã‚§ãƒƒã‚¯ã‚¨ãƒ©ãƒ¼!</string>
+ <string name="msg_dc_error_integrity_missing">完全è–ãƒã‚§ãƒƒã‚¯ã®æ¬ è½!ã“ã‚Œã¯æš—å·åŒ–アプリケーションãŒæœŸé™åˆ‡ã‚Œã«ãªã£ãŸå ´åˆã€ã‚‚ã—ãã¯æš—å·å¼·åº¦ä½Žä¸‹æ”»æ’ƒãŒã‚ã‚‹å ´åˆã«ç™ºç”Ÿã—ã¾ã™ã€‚</string>
<string name="msg_dc_error_invalid_siglist">正常ãªç½²åデータãŒè¦‹ä»˜ã‹ã‚‰ãªã‹ã£ãŸ!</string>
<string name="msg_dc_error_io">æ“作中ã«IO例外ã«å½“ãŸã‚Šã¾ã—ãŸ!</string>
<string name="msg_dc_error_no_data">ストリーム中ã«æš—å·åŒ–ã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ãŒè¦‹ä»˜ã‹ã‚‰ãªã‹ã£ãŸ!</string>
@@ -775,30 +890,48 @@
<string name="msg_dc_trail_unknown">追跡ã§æœªçŸ¥ã®ã‚¿ã‚¤ãƒ—ã®ãƒ‡ãƒ¼ã‚¿ã«é­é‡</string>
<string name="msg_dc_unlocking">秘密éµã®ãƒ­ãƒƒã‚¯è§£é™¤</string>
<!--Messages for SignEncrypt operation-->
- <string name="msg_se_asymmetric">æš—å·åŒ–ã®ãŸã‚ã®å…¬é–‹éµã®æ¤œè¨¼</string>
- <string name="msg_se_clearsign_only">クリアテキスト署åã®å…¥åŠ›ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“!</string>
- <string name="msg_se_compressing">圧縮ã®æ¤œè¨¼</string>
- <string name="msg_se_encrypting">æš—å·åŒ–データ</string>
- <string name="msg_se_error_bad_passphrase">駄目ãªãƒ‘スフレーズ!</string>
- <string name="msg_se_error_io">æ“作中ã«IO例外ã«å½“ãŸã‚Šã¾ã—ãŸ!</string>
- <string name="msg_se_error_key_sign">é¸æŠžã—ãŸç½²åéµã§ç½²åデータãŒã§ãã¾ã›ã‚“!</string>
- <string name="msg_se_error_sign_key">ç½²åéµã®å–得エラー!</string>
- <string name="msg_se_error_nfc">NFC データエラー!</string>
- <string name="msg_se_error_no_passphrase">パスフレーズãªã—ã§æä¾›!</string>
- <string name="msg_se_error_pgp">PGP内部エラー!</string>
- <string name="msg_se_error_sig">PGPç½²å例外ã«å½“ãŸã‚Šã¾ã—ãŸ!</string>
- <string name="msg_se_error_unlock">éµã®ãƒ­ãƒƒã‚¯è§£é™¤ã§ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼!</string>
- <string name="msg_se_key_ok">æš—å·åŒ–ã®éµ: %s</string>
- <string name="msg_se_key_unknown">æš—å·åŒ–ã§éµã‚’紛失: %s</string>
- <string name="msg_se_key_warn">æš—å·åŒ–ã«å•é¡Œã®ã‚ã‚‹éµ: %s</string>
- <string name="msg_se_ok">ç½²å/æš—å·åŒ–æ“作ã«æˆåŠŸ!</string>
- <string name="msg_se_pending_nfc">NFCトークンãŒå¿…è¦ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼å…¥åŠ›ã‚’è¦æ±‚中...</string>
- <string name="msg_se_pending_passphrase">パスフレーズãŒå¿…è¦ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼å…¥åŠ›ã‚’è¦æ±‚中...</string>
- <string name="msg_se_signing">ç½²åデータ(æš—å·åŒ–ã—ã¦ã„ãªã„)</string>
- <string name="msg_se_sigcrypting">データを署å付ãã§æš—å·åŒ–中</string>
<string name="msg_se">ç½²å/æš—å·åŒ–æ“作を開始ã—ã¾ã™</string>
- <string name="msg_se_symmetric">対称暗å·ã®æ¤œè¨¼</string>
+ <string name="msg_se_input_bytes">ãƒã‚¤ãƒˆé…列ã‹ã‚‰ã®å…¥åŠ›å‡¦ç†ä¸­</string>
+ <string name="msg_se_input_uri">URIã‹ã‚‰ã®å…¥åŠ›å‡¦ç†ä¸­</string>
+ <string name="msg_se_error_no_input">入力ãŒã‚ã‚Šã¾ã›ã‚“!</string>
+ <string name="msg_se_error_input_uri_not_found">読ã¿å‡ºã™ãŸã‚ã«URIã‚’é–‹ã時ã«ã‚¨ãƒ©ãƒ¼!</string>
+ <string name="msg_se_error_output_uri_not_found">書ã込むãŸã‚ã«URIã‚’é–‹ã時ã«ã‚¨ãƒ©ãƒ¼!</string>
+ <string name="msg_se_error_too_many_inputs">ä¸æ˜Žãªå‡ºåŠ›ä»¥ä¸Šã®å…¥åŠ›éŽå¤šã§ã™! ã“ã‚Œã¯ãƒ—ログラミングã®ã‚¨ãƒ©ãƒ¼ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_se_warn_output_left">得られãŸå‡ºåŠ›ãŒå…¥åŠ›ã‹ã‚‰ä¹–離ã—ã¦ã„る。ã“ã‚Œã¯ãƒ—ログラミングã®ã‚¨ãƒ©ãƒ¼ã§ã€ãƒã‚°ãƒ¬ãƒãƒ¼ãƒˆã®æ出をãŠé¡˜ã„ã—ã¾ã™!</string>
+ <string name="msg_se_success">ç½²å/æš—å·åŒ–æ“作ã«æˆåŠŸ!</string>
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_pse_asymmetric">æš—å·åŒ–ã®ãŸã‚ã®å…¬é–‹éµã®æº–å‚™</string>
+ <string name="msg_pse_clearsign_only">クリアテキスト署åã®å…¥åŠ›ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“!</string>
+ <string name="msg_pse_compressing">圧縮ã®æº–å‚™</string>
+ <string name="msg_pse_encrypting">データ暗å·åŒ–</string>
+ <string name="msg_pse_error_bad_passphrase">駄目ãªãƒ‘スフレーズ!</string>
+ <string name="msg_pse_error_hash_algo">ã“ã®éµã§ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„ãƒãƒƒã‚·ãƒ¥ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’è¦æ±‚ã•ã‚Œã¦ã„ã¾ã™!</string>
+ <string name="msg_pse_error_io">æ“作中ã«IO例外ã«å½“ãŸã‚Šã¾ã—ãŸ!</string>
+ <string name="msg_pse_error_key_sign">é¸æŠžã—ãŸç½²åéµã§ç½²åデータを作れã¾ã›ã‚“!</string>
+ <string name="msg_pse_error_sign_key">ç½²åéµã®å–得エラー!</string>
+ <string name="msg_pse_error_nfc">NFC データエラー!</string>
+ <string name="msg_pse_error_no_passphrase">パスフレーズãŒæä¾›ã•ã‚Œã¦ãªã„!</string>
+ <string name="msg_pse_error_pgp">OpenPGP内部エラー!</string>
+ <string name="msg_pse_error_sig">OpenPGPç½²å例外ã«å½“ãŸã‚Šã¾ã—ãŸ!</string>
+ <string name="msg_pse_error_unlock">éµã®ãƒ­ãƒƒã‚¯è§£é™¤ã§ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼!</string>
+ <string name="msg_pse_key_ok">æš—å·åŒ–ã®éµ: %s</string>
+ <string name="msg_pse_key_unknown">æš—å·åŒ–ã®éµã‚’紛失: %s</string>
+ <string name="msg_pse_key_warn">æš—å·åŒ–ã«å•é¡Œã®ã‚ã‚‹éµ: %s</string>
+ <string name="msg_pse_ok">ç½²å/æš—å·åŒ–æ“作ã«æˆåŠŸ!</string>
+ <string name="msg_pse_pending_nfc">NFCトークンãŒå¿…è¦ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼å…¥åŠ›ã‚’è¦æ±‚中...</string>
+ <string name="msg_pse_pending_passphrase">パスフレーズãŒå¿…è¦ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼å…¥åŠ›ã‚’è¦æ±‚中...</string>
+ <string name="msg_pse_signing">ç½²åデータ(æš—å·åŒ–ãªã—)</string>
+ <string name="msg_pse_signing_cleartext">クリアテキスト署å作æˆä¸­</string>
+ <string name="msg_pse_signing_detached">分離署å作æˆä¸­</string>
+ <string name="msg_pse_sigcrypting">データを署å付ãã§æš—å·åŒ–中</string>
+ <string name="msg_pse">ç½²å/æš—å·åŒ–æ“作を開始ã—ã¾ã™</string>
+ <string name="msg_pse_symmetric">対称暗å·ã®æº–å‚™</string>
<string name="msg_crt_certifying">検証ã®ç”Ÿæˆä¸­</string>
+ <string name="msg_crt_certify_all">éµ %s ã§ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶IDã®æ¤œè¨¼ä¸­</string>
+ <plurals name="msg_crt_certify_some">
+ <item quantity="other">éµ %2$s 㧠%1$d 個ã®ãƒ¦ãƒ¼ã‚¶IDã®æ¤œè¨¼ä¸­</item>
+ </plurals>
+ <string name="msg_crt_error_self">自己証明書的ãªç™ºè¡Œã¯è¡Œãˆã¾ã›ã‚“!</string>
<string name="msg_crt_error_master_not_found">主éµãŒè¦‹å½“ã‚Šã¾ã›ã‚“!</string>
<string name="msg_crt_error_nothing">検証ã§ããŸéµãŒãªã„!</string>
<string name="msg_crt_error_unlock">主éµã®ãƒ­ãƒƒã‚¯è§£é™¤ã‚¨ãƒ©ãƒ¼!</string>
@@ -813,16 +946,29 @@
<string name="msg_crt_warn_cert_failed">証明ã®ç”ŸæˆãŒå¤±æ•—!</string>
<string name="msg_crt_warn_save_failed">ä¿å­˜æ“作ãŒå¤±æ•—!</string>
<string name="msg_crt_upload_success">éµã‚’サーãƒã«ã‚¢ãƒƒãƒ—ロードã—ã¾ã—ãŸ</string>
+ <plurals name="msg_import">
+ <item quantity="other">%d 個ã®éµã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ</item>
+ </plurals>
+ <string name="msg_import_fetch_error_decode">éµè¼ªã®ãƒ‡ã‚³ãƒ¼ãƒ‰ã‚¨ãƒ©ãƒ¼</string>
<string name="msg_import_fetch_error">éµã®å±•é–‹ãŒã§ãã¾ã›ã‚“! (ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®å•é¡Œ?)</string>
- <string name="msg_import_fetch_keybase">keybase.ioã‹ã‚‰å±•é–‹: %s</string>
+ <string name="msg_import_fetch_keybase">keybase.ioã‹ã‚‰å›žåŽ: %s</string>
<string name="msg_import_fetch_keyserver_error">keybaseã‹ã‚‰ã®éµã®å±•é–‹ãŒã§ãã¾ã›ã‚“!</string>
+ <string name="msg_import_fetch_keyserver">éµã‚µãƒ¼ãƒã‹ã‚‰ã®å›žåŽ: %s</string>
<string name="msg_import_fetch_keyserver_ok">éµã®å±•é–‹ã«æˆåŠŸ</string>
+ <string name="msg_import_keyserver">éµã‚µãƒ¼ãƒ %s を使ã†</string>
+ <string name="msg_import_fingerprint_error">フェッãƒã—ãŸéµã®éµæŒ‡ç´‹ãŒå®Œå…¨ã«ã¯ä¸€è‡´ã—ã¾ã›ã‚“ã§ã—ãŸ!</string>
<string name="msg_import_fingerprint_ok">指紋ãƒã‚§ãƒƒã‚¯OK!</string>
<string name="msg_import_merge">展開ã—ãŸãƒ‡ãƒ¼ã‚¿ã‚’マージ</string>
<string name="msg_import_error">インãƒãƒ¼ãƒˆæ“作ã«å¤±æ•—!</string>
+ <string name="msg_import_error_io">I/Oエラーã«ã‚ˆã‚Šã‚¤ãƒ³ãƒãƒ¼ãƒˆæ“作ãŒå¤±æ•—ã—ã¾ã—ãŸ!</string>
<string name="msg_import_partial">インãƒãƒ¼ãƒˆæ“作ã«æˆåŠŸã€ãŸã ã—エラーã‚ã‚Š!</string>
<string name="msg_import_success">インãƒãƒ¼ãƒˆæ“作ã«æˆåŠŸ!</string>
+ <plurals name="msg_export">
+ <item quantity="other">%d 個ã®éµã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ</item>
+ </plurals>
<string name="msg_export_all">ã™ã¹ã¦ã®éµã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ</string>
+ <string name="msg_export_public">å…¬é–‹éµ %s ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ</string>
+ <string name="msg_export_secret">ç§˜å¯†éµ %s ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ</string>
<string name="msg_export_error_no_file">指定ã®ãƒ•ã‚¡ã‚¤ãƒ«åã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã‚ã‚Šã¾ã›ã‚“!</string>
<string name="msg_export_error_fopen">ファイルオープン中ã®ã‚¨ãƒ©ãƒ¼!</string>
<string name="msg_export_error_no_uri">指定ã®URIã¯ã‚ã‚Šã¾ã›ã‚“!</string>
@@ -830,13 +976,32 @@
<string name="msg_export_error_storage">ストレージãŒæ›¸ãè¾¼ã¿æº–å‚™ã§ãã¦ã„ã¾ã›ã‚“!</string>
<string name="msg_export_error_db">データベースエラー!</string>
<string name="msg_export_error_io">入出力エラー!</string>
+ <string name="msg_export_error_key">éµãƒ‡ãƒ¼ã‚¿ã®äº‹å‰å‡¦ç†ã®ã‚¨ãƒ©ãƒ¼!</string>
<string name="msg_export_success">エクスãƒãƒ¼ãƒˆæ“作ã«æˆåŠŸ!</string>
<string name="msg_del_error_empty">削除ã™ã‚‹ã‚‚ã®ãŒã‚ã‚Šã¾ã›ã‚“!</string>
+ <string name="msg_del_error_multi_secret">秘密éµã¯å€‹åˆ¥ã«ã—ã‹å‰Šé™¤ã§ãã¾ã›ã‚“!</string>
+ <plurals name="msg_del">
+ <item quantity="other">%d 個ã®éµã®å‰Šé™¤</item>
+ </plurals>
+ <string name="msg_del_key">éµ %s ã®å‰Šé™¤ä¸­</string>
+ <string name="msg_del_key_fail">éµ %s ã®å‰Šé™¤ã«å¤±æ•—</string>
+ <string name="msg_del_consolidate">秘密éµå‰Šé™¤å¾Œã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®çµ±åˆ</string>
+ <plurals name="msg_del_ok">
+ <item quantity="other">%d 個ã®éµã®å‰Šé™¤ã«æˆåŠŸ</item>
+ </plurals>
+ <plurals name="msg_del_fail">
+ <item quantity="other">%d 個ã®éµã®å‰Šé™¤ã«å¤±æ•—</item>
+ </plurals>
<string name="msg_acc_saved">アカウントä¿å­˜</string>
<string name="msg_download_success">ダウンロードã«æˆåŠŸã—ã¾ã—ãŸ!</string>
+ <string name="msg_download_no_valid_keys">ファイル/クリップボードã«ã¦æ­£ã—ã„éµãŒè¦‹ä»˜ã‹ã‚Šã¾ã›ã‚“!</string>
+ <string name="msg_download_no_pgp_parts">TODO: 複数部分!</string>
<plurals name="error_import_non_pgp_part">
<item quantity="other">読ã¿è¾¼ã‚“ã ãƒ•ã‚¡ã‚¤ãƒ«ã®OpenPGPオブジェクト部分ã¯æ­£ã—ã„ã§ã™ãŒã€OpenPGPã®éµã§ã¯ã‚ã‚Šã¾ã›ã‚“</item>
</plurals>
+ <string name="msg_download_query_too_short">éµæ¤œç´¢ã®ã‚¯ã‚¨ãƒªãŒçŸ­ã‹ã™ãŽã¾ã™ã€‚クエリを精密化ã—ã¦ãã ã•ã„!</string>
+ <string name="msg_download_too_many_responses">éµæ¤œç´¢ã®ã‚¯ã‚¨ãƒªãŒæ²¢å±±ã®å€™è£œã‚’è¿”ã—ã¾ã—ãŸã€‚クエリを精密化ã—ã¦ãã ã•ã„!</string>
+ <string name="msg_download_query_too_short_or_too_many_responses">éµãŒã¾ã£ãŸãç„¡ã„ã‹ã€å¤šã™ãŽã‚‹éµãŒè¦‹ä»˜ã‹ã‚Šã¾ã—ãŸã€‚クエリを改善ã—ã¦ãã ã•ã„!</string>
<string name="msg_download_query_failed">éµã®æ¤œç´¢æ™‚ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚</string>
<!--PassphraseCache-->
<string name="passp_cache_notif_click_to_clear">クリックã—ã¦ãƒ‘スフレーズã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’クリア</string>
@@ -844,6 +1009,11 @@
<string name="passp_cache_notif_keys">パスフレーズã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥:</string>
<string name="passp_cache_notif_clear">キャッシュクリア</string>
<string name="passp_cache_notif_pwd">パスフレーズ</string>
+ <!--First Time-->
+ <string name="first_time_text1">OpenKeychainã§ã‚ãªãŸã®ãƒ—ライãƒã‚·ãƒ¼ã‚’å–り戻ã—ã¾ã—ょã†!</string>
+ <string name="first_time_create_key">自分ã®éµã®ç”Ÿæˆ</string>
+ <string name="first_time_import_key">ファイルã‹ã‚‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆ</string>
+ <string name="first_time_skip">セットアップをスキップ</string>
<!--unsorted-->
<string name="section_certifier_id">検証者</string>
<string name="section_cert">証明ã®è©³ç´°</string>
@@ -852,6 +1022,7 @@
<string name="empty_certs">ã“ã®éµã«è¨¼æ˜ŽãŒãªã„</string>
<string name="certs_text">ã‚ãªãŸã®æ¤œè¨¼ã•ã‚ŒãŸè‡ªå·±è¨¼æ˜Žã¨ã‚ãªãŸã®éµã§ç”Ÿæˆã•ã‚ŒãŸè¨¼æ˜ŽãŒã“ã“ã«è¡¨ç¤ºã•ã‚Œã¾ã™</string>
<string name="section_uids_to_certify">ユーザID</string>
+ <string name="certify_text">インãƒãƒ¼ãƒˆã—ãŸéµã«ã¯\"アイデンティティ\": åå‰ã¨ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ ã‚’å«ã¿ã¾ã™ã€‚正確ã«æœŸå¾…ã—ãŸã‚‚ã®ã¨ä¸€è‡´ã—ã¦ã„ã‚‹ã‹èªå®šã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã‚’é¸æŠžã—ã¾ã™ã€‚</string>
<string name="label_revocation">破棄ã®ç†ç”±</string>
<string name="label_verify_status">検証ステータス</string>
<string name="label_cert_type">種別</string>
@@ -873,9 +1044,32 @@
<string name="error_no_file_selected">æš—å·åŒ–ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å°‘ãªãã¨ã‚‚1ã¤é¸æŠžã—ã¦ä¸‹ã•ã„。</string>
<string name="error_multi_not_supported">複数ファイルã®ä¿å­˜ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。ã“ã‚Œã¯ç¾åœ¨ã®Androidã§ã®åˆ¶é™ã§ã™ã€‚</string>
<string name="key_colon">éµ:</string>
- <!--First Time-->
- <string name="first_time_text1">OpenKeychainã§ã‚ãªãŸã®ãƒ—ライãƒã‚·ãƒ¼ã‚’å–り戻ã—ã¾ã—ょã†!</string>
- <string name="first_time_create_key">自分ã®éµã®ç”Ÿæˆ</string>
- <string name="first_time_import_key">ファイルã‹ã‚‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆ</string>
- <string name="first_time_skip">セットアップをスキップ</string>
+ <string name="exchange_description">éµäº¤æ›ã®é–‹å§‹ã¯ã€å³å´ã®å‚加者ã®ç•ªå·ã‚’é¸æŠžã—ã€ãã®å¾Œã€\"交æ›é–‹å§‹\"ボタンを推ã—ã¾ã™ã€‚\n\n2ã¤ä»¥ä¸Šã®è³ªå•ã§äº¤æ›ã«ã„ã‚‹å³ã®å‚加者ã¨ãã®æŒ‡ç´‹ãŒæ­£ã—ã„ã‹ã‚’確èªã—ã¦ãã ã•ã„。</string>
+ <string name="user_id_none"><![CDATA[<none>]]></string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <string name="title_unlock_method">アンロックã™ã‚‹æ‰‹æ®µã‚’é¸æŠžã—ã¦ãã ã•ã„</string>
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <string name="enter_passphrase">パスフレーズã®å…¥åŠ›</string>
+ <string name="passphrase">パスフレーズ</string>
+ <string name="noPassphrase">パスフレーズãªã—</string>
+ <string name="no_passphrase_set">パスフレーズãŒè¨­å®šã•ã‚Œã¦ãªã„</string>
+ <string name="passphrases_match">パスフレーズãŒä¸€è‡´ã—ãªã„</string>
+ <string name="passphrase_saved">パスフレーズをä¿å­˜</string>
+ <string name="passphrase_invalid">無効ãªãƒ‘スフレーズ</string>
+ <string name="missing_passphrase">パスフレーズãŒã‚ã‚Šã¾ã›ã‚“</string>
+ <string name="passphrase_again">ã‚‚ã†ä¸€åº¦</string>
+ <string name="lockpattern">ロックパターン</string>
+ <string name="lockpatternNFC">NFCã¨ãƒ­ãƒƒã‚¯ãƒ‘ターン</string>
+ <string name="unlock_method">アンロック手段</string>
+ <string name="set_passphrase">パスフレーズã®è¨­å®š</string>
+ <string name="draw_lockpattern">ロックパターンをæã„ã¦ãã ã•ã„</string>
+ <string name="nfc_title">NFC</string>
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+ <string name="nfc_wrong_tag">ダメãªã‚¿ã‚°ã€‚å†åº¦å®Ÿæ–½ã—ã¦ãã ã•ã„。</string>
+ <string name="enable_nfc">設定ã‹ã‚‰NFCを有効ã«ã—ã¦ãã ã•ã„</string>
+ <string name="no_nfc_support">ã“ã®è£…ç½®ã§ã¯NFCをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“</string>
+ <string name="nfc_write_succesful">NFCã‚¿ã‚°ã«æ›¸ã‘ã¾ã—ãŸ!</string>
+ <string name="unlocked">アンロック</string>
+ <string name="nfc_settings">設定</string>
</resources>
diff --git a/OpenKeychain/src/main/res/values-large/dimens.xml b/OpenKeychain/src/main/res/values-large/dimens.xml
index 192a4bb99..045e125f3 100644
--- a/OpenKeychain/src/main/res/values-large/dimens.xml
+++ b/OpenKeychain/src/main/res/values-large/dimens.xml
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <dimen name="drawer_content_padding">240dp</dimen>
</resources>
diff --git a/OpenKeychain/src/main/res/values-nl/strings.xml b/OpenKeychain/src/main/res/values-nl/strings.xml
index f777977bb..6a7f53e35 100644
--- a/OpenKeychain/src/main/res/values-nl/strings.xml
+++ b/OpenKeychain/src/main/res/values-nl/strings.xml
@@ -2,80 +2,146 @@
<resources>
<!--GENERAL: Please put all strings inside quotes as described in example 1 on
http://developer.android.com/guide/topics/resources/string-resource.html (scroll down to "Escaping apostrophes and quotes").-->
+ <string name="app_name">OpenKeychain</string>
<!--title-->
+ <string name="title_select_recipients">Selecteer sleutels</string>
+ <string name="title_select_secret_key">Selecteer je sleutel</string>
+ <string name="title_encrypt_text">Versleutel tekst</string>
+ <string name="title_encrypt_files">Versleutel bestanden</string>
<string name="title_decrypt">Ontsleutelen</string>
- <string name="title_authentication">Wachtwoord</string>
+ <string name="title_unlock">Ontgrendel sleutel</string>
+ <string name="title_add_subkey">Voeg subsleutel toe</string>
<string name="title_edit_key">Sleutel bewerken</string>
<string name="title_preferences">Instellingen</string>
- <string name="title_key_server_preference">Sleutelserver Voorkeur</string>
+ <string name="title_cloud_search_preferences">Cloud-zoekvoorkeuren</string>
+ <string name="title_api_registered_apps">Apps</string>
+ <string name="title_key_server_preference">Sleutelservers</string>
<string name="title_change_passphrase">Wachtwoord wijzigen</string>
- <string name="title_share_fingerprint_with">Vingerafdruk delen met...</string>
- <string name="title_share_key">Sleutel delen met...</string>
- <string name="title_share_file">Bestand delen met...</string>
+ <string name="title_share_fingerprint_with">Vingerafdruk delen met…</string>
+ <string name="title_share_key">Sleutel delen met…</string>
+ <string name="title_share_file">Bestand delen met…</string>
+ <string name="title_share_message">Bericht delen met…</string>
<string name="title_encrypt_to_file">Versleutelen naar bestand</string>
<string name="title_decrypt_to_file">Ontsleutelen naar bestand</string>
<string name="title_import_keys">Sleutels importeren</string>
+ <string name="title_add_keys">Voeg sleutels toe</string>
<string name="title_export_key">Sleutels exporteren</string>
<string name="title_export_keys">Sleutels exporteren</string>
<string name="title_key_not_found">Sleutel niet gevonden</string>
- <string name="title_send_key">Upload naar Sleutelserver</string>
- <string name="title_certify_key">Certifiëer Identiteiten</string>
+ <string name="title_send_key">Upload naar sleutelserver</string>
+ <string name="title_certify_key">Certifieer Identiteiten</string>
<string name="title_key_details">Sleutel Details</string>
<string name="title_help">Help</string>
+ <string name="title_log_display">Log</string>
+ <string name="title_create_key">Sleutel aanmaken</string>
+ <string name="title_exchange_keys">Sleutels uitwisselen</string>
+ <string name="title_advanced_key_info">Geavanceerde sleutelinfo</string>
+ <string name="title_keys">Sleutels</string>
<!--section-->
<string name="section_user_ids">Identiteiten</string>
<string name="section_keys">Subsleutels</string>
+ <string name="section_cloud_search">Cloud zoeken</string>
<string name="section_general">Algemeen</string>
<string name="section_defaults">Standaard</string>
<string name="section_advanced">Geavanceerd</string>
+ <string name="section_passphrase_cache">Wachtwoordcache</string>
+ <string name="section_certify">Certificeren</string>
<string name="section_actions">Acties</string>
+ <string name="section_share_key">Sleutel</string>
<string name="section_certification_key">Uw Sleutel die u gebruikt voor certificatie</string>
+ <string name="section_upload_key">Synchroniseer sleutel</string>
<string name="section_key_server">Sleutelserver</string>
<string name="section_fingerprint">Vingerafdruk</string>
<string name="section_key_to_certify">Sleutel om te certificeren</string>
+ <string name="section_decrypt_files">Bestanden</string>
+ <string name="section_decrypt_text">Tekst</string>
+ <string name="section_certs">Certificaten</string>
+ <string name="section_encrypt">Versleutelen</string>
+ <string name="section_decrypt">Ontsleutelen</string>
<!--button-->
<string name="btn_decrypt_verify_file">Decodeer, verifiëer en sla bestand op</string>
<string name="btn_decrypt_verify_message">Decodeer en verifiëer bericht</string>
<string name="btn_encrypt_file">Codeer en sla bestanden op</string>
+ <string name="btn_encrypt_share_file">Bestand versleutelen en delen</string>
<string name="btn_save">Opslaan</string>
<string name="btn_do_not_save">Annuleren</string>
<string name="btn_delete">Verwijderen</string>
+ <string name="btn_no_date">Geen einddatum</string>
<string name="btn_okay">OK</string>
<string name="btn_export_to_server">Upload Naar Sleutelserver</string>
<string name="btn_next">Volgende</string>
<string name="btn_back">Terug</string>
<string name="btn_lookup_key">Opzoeksleutel</string>
+ <string name="btn_share_encrypted_signed">Bericht versleutelen en delen</string>
<string name="btn_view_cert_key">Toon certificatiesleutel</string>
+ <string name="btn_create_key">Sleutel aanmaken</string>
+ <string name="btn_add_files">Bestand(en) toevoegen</string>
+ <string name="btn_add_share_decrypted_text">Ontcijferde tekst delen</string>
+ <string name="btn_decrypt_clipboard">Tekst van klembord ontsleutelen</string>
+ <string name="btn_decrypt_and_verify">en ondertekeningen verifiëren</string>
+ <string name="btn_decrypt_files">Bestanden ontcijferen</string>
+ <string name="btn_encrypt_files">Bestanden versleutelen</string>
+ <string name="btn_encrypt_text">Tekst versleutelen</string>
<!--menu-->
<string name="menu_preferences">Instellingen</string>
<string name="menu_help">Help</string>
<string name="menu_export_key">Exporteren naar bestand</string>
<string name="menu_delete_key">Sleutel verwijderen</string>
+ <string name="menu_create_key">Mijn sleutel aanmaken</string>
+ <string name="menu_import_existing_key">Importeren van bestand</string>
<string name="menu_search">Zoeken</string>
<string name="menu_beam_preferences">Beam-instellingen</string>
<string name="menu_key_edit_cancel">Annuleren</string>
- <string name="menu_encrypt_to">Versleutelen naar...</string>
+ <string name="menu_encrypt_to">Versleutelen naar…</string>
<string name="menu_select_all">Alles selecteren</string>
<string name="menu_add_keys">Sleutels toevoegen</string>
+ <string name="menu_search_cloud">Zoeken</string>
<string name="menu_export_all_keys">Alle sleutels exporteren</string>
+ <string name="menu_advanced">Geavanceerde info tonen</string>
<!--label-->
<string name="label_message">Bericht</string>
<string name="label_file">Bestand</string>
+ <string name="label_files">Bestand(en)</string>
+ <string name="label_file_colon">Bestand:</string>
<string name="label_no_passphrase">Geen wachtwoord</string>
<string name="label_passphrase">Wachtwoord</string>
+ <string name="label_unlock">Bezig met ontgrendelen…</string>
+ <string name="label_passphrase_again">Herhaal wachtwoord</string>
<string name="label_algorithm">Algoritme</string>
+ <string name="label_ascii_armor">Bestand ASCII Armor</string>
+ <string name="label_file_ascii_armor">ASCII Armor aanzetten</string>
+ <string name="label_write_version_header">Laat anderen weten dat je OpenKeychain gebruikt</string>
+ <string name="label_write_version_header_summary">Voegt \'OpenKeychain v2.7\' toe aan OpenPGP ondertekeningen, cijfertekst en geëxporteerde sleutels</string>
+ <string name="label_use_default_yubikey_pin">Gebruik standaard YubiKey PIN</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Gebruik numeriek toetsenbord voor YubiKey PIN</string>
+ <string name="label_label_use_default_yubikey_pin_summary">Gebruikt standaard PIN (123456) om YubiKeys over NFC te bereiken</string>
+ <string name="label_asymmetric_from">Ondertekend door:</string>
+ <string name="label_to">Versleutelen naar:</string>
+ <string name="label_delete_after_encryption">Verwijder bestand na versleuteling</string>
+ <string name="label_delete_after_decryption">Verwijder na ontcijfering</string>
+ <string name="label_encryption_algorithm">Versleutelingsalgoritme</string>
+ <string name="label_hash_algorithm">Hashalgoritme</string>
+ <string name="label_symmetric">Versleutelen met wachtwoord</string>
+ <string name="label_passphrase_cache_ttl">Cachetijd</string>
+ <string name="label_passphrase_cache_subs">Cache wachtwoorden per subsleutel</string>
+ <string name="label_message_compression">Berichtscompressie</string>
+ <string name="label_file_compression">Bestandscompressie</string>
<string name="label_keyservers">Sleutelservers</string>
<string name="label_key_id">Sleutel-id</string>
<string name="label_creation">Aanmaak</string>
<string name="label_expiry">Verlopen</string>
<string name="label_usage">Gebruik</string>
<string name="label_key_size">Sleutelgrootte</string>
+ <string name="label_ecc_curve">Elliptische curve</string>
<string name="label_main_user_id">Primaire identiteit</string>
<string name="label_name">Naam</string>
<string name="label_comment">Opmerking</string>
<string name="label_email">E-mailadres</string>
+ <string name="label_send_key">Synchroniseren met de cloud</string>
<string name="label_fingerprint">Vingerafdruk</string>
<string name="expiry_date_dialog_title">Bepaal verloopdatum</string>
+ <string name="label_first_keyserver_is_used">(Voorkeur gaat uit naar de eerste keyserver in de lijst)</string>
+ <string name="label_preferred">voorkeur</string>
<string name="user_id_no_name">&lt;no naam&gt;</string>
<string name="none">&lt;geen&gt;</string>
<string name="no_key">&lt;geen sleutel&gt;</string>
@@ -111,7 +177,9 @@
<string name="dsa">DSA</string>
<string name="elgamal">ElGamal</string>
<string name="rsa">RSA</string>
- <string name="filemanager_title_open">Openen...</string>
+ <string name="ecdh">ECDH</string>
+ <string name="ecdsa">ECDSA</string>
+ <string name="filemanager_title_open">Openen…</string>
<string name="warning">Waarschuwing</string>
<string name="error">Fout</string>
<string name="error_message">Fout: %s</string>
@@ -127,6 +195,10 @@
<string name="passphrase_must_not_be_empty">Vul een wachtwoord in.</string>
<string name="passphrase_for_symmetric_encryption">Symmetrische versleuteling.</string>
<string name="passphrase_for">Voer het wachtwoord in voor \'%s\'</string>
+ <string name="pin_for">Voer PIN in voor \'%s\'</string>
+ <string name="yubikey_pin_for">Voer PIN in om toegang te verkrijgen tot YubiKey voor \'%s\'</string>
+ <string name="nfc_text">Hou YubiKey tegen de achterkant van je toestel</string>
+ <string name="file_delete_confirmation">Ben je zeker dat je %s wil verwijderen?</string>
<string name="file_delete_successful">Succesvol verwijderd.</string>
<string name="no_file_selected">Selecteer eerst een bestand.</string>
<string name="encrypt_sign_successful">Succesvol gesigneerd en/of gecodeerd.</string>
@@ -134,17 +206,30 @@
<string name="enter_passphrase_twice">Voer het wachtwoord tweemaal in.</string>
<string name="select_encryption_key">Selecteer ten minste één versleutelingssleutel.</string>
<string name="select_encryption_or_signature_key">Selecter ten minste één versleutelings-/ondertekeningssleutel.</string>
+ <string name="specify_file_to_encrypt_to">Gelieve aan te geven naar welk bestand versleuteld moet worden.\nWAARSCHUWING: Als het bestand al bestaat, zal het overschreven worden.</string>
+ <string name="specify_file_to_decrypt_to">Gelieve aan te geven naar welk bestand ontcijferd moet worden.\nWAARSCHUWING: Als het bestand al bestaat, zal het overschreven worden.</string>
+ <string name="specify_file_to_export_to">Gelieve aan te geven naar welk bestand geëxporteerd moet worden.\nWAARSCHUWING: Als het bestand al bestaat, zal het overschreven worden.</string>
+ <string name="key_deletion_confirmation_multi">Ben je zeker dat je alle geselecteerde publieke sleutels wil verwijderen?\nJe kan dit niet ongedaan maken!</string>
+ <string name="secret_key_deletion_confirmation">Ben je zeker dat je de GEHEIME sleutel \'%s\' wil verwijderen?\nJe kan dit niet ongedaan maken!</string>
+ <string name="public_key_deletetion_confirmation">Ben je zeker dat je de publieke sleutel \'%s\' wil verwijderen?\nJe kan dit niet ongedaan maken!</string>
+ <string name="also_export_secret_keys">Exporteer ook geheime sleutels</string>
+ <string name="reinstall_openkeychain">Je bent een gekende Android-bug tegengekomen. Gelieve OpenKeychain opnieuw te installeren als je je contacten met sleutels wil verbinden.</string>
<string name="key_exported">1 sleutel succesvol geëxporteerd.</string>
<string name="keys_exported">Succesvol %d sleutels geëxporteerd.</string>
<string name="no_keys_exported">Geen sleutels geëxporteerd.</string>
<string name="key_creation_el_gamal_info">Opmerking: alleen subsleutels ondersteunen ElGamal.</string>
<string name="key_not_found">Kan de sleutel %08X niet vinden.</string>
+ <plurals name="bad_keys_encountered">
+ <item quantity="one">%d slechte geheime sleutel genegeerd. Misschien heb je geëxporteerd met de optie\n--export-secret-subkeys\nZorg ervoor dat je in plaats daarvan met --export-secret-keys exporteert.</item>
+ <item quantity="other">%d slechte geheime sleutels genegeerd. Misschien heb je geëxporteerd met de optie\n--export-secret-subkeys\nZorg ervoor dat je in plaats daarvan met --export-secret-keys exporteert.</item>
+ </plurals>
<string name="list_empty">Lijst is leeg</string>
<string name="nfc_successful">Succesvol sleutel verstuurd met NFC Beam!</string>
<string name="key_copied_to_clipboard">Sleutel is gekopieerd naar het klembord!</string>
<string name="fingerprint_copied_to_clipboard">Sleutel is gekopieerd naar het klembord!</string>
<string name="select_key_to_certify">Selecteer een sleutel die gebruikt moet worden voor certificatie!</string>
<string name="key_too_big_for_sharing">Sleutel is te groot om op deze manier gedeeld te worden!</string>
+ <string name="text_copied_to_clipboard">Tekst is gekopieerd naar klembord!</string>
<!--errors
no punctuation, all lowercase,
they will be put after "error_message", e.g. "Error: file not found"-->
@@ -158,44 +243,84 @@
<string name="error_key_needs_a_user_id">minstens een identiteit vereist</string>
<string name="error_no_signature_passphrase">geen wachtwoord opgegeven</string>
<string name="error_no_signature_key">geen ondertekeningssleutel opgegeven</string>
+ <string name="error_invalid_data">Geen geldige versleutelde of ondertekende OpenPGP-inhoud!</string>
<string name="error_integrity_check_failed">integriteitcheck niet geslaagd! Data is bewerkt!</string>
- <string name="error_wrong_passphrase">wachtwoord verekerd</string>
+ <string name="error_wrong_passphrase">wachtwoord verkeerd</string>
<string name="error_could_not_extract_private_key">kan privésleutel niet uitpakken</string>
<!--errors without preceeding Error:-->
<string name="error_jelly_bean_needed">U heeft minstens Android 4.1 nodig om Androids NFC Beam eigenschap te gebruiken!</string>
<string name="error_nfc_needed">Uw apparaat biedt geen ondersteuning voor NFC</string>
- <string name="error_generic_report_bug">Een algemene fout is opgetreden, maak alstublieft een nieuwe bug report voor OpenKeychain.</string>
+ <string name="error_nothing_import">Geen sleutels gevonden!</string>
+ <string name="error_contacts_key_id_missing">Sleutel-ID van contacten ophalen mislukt!</string>
+ <string name="error_generic_report_bug">Een algemene fout is opgetreden, gelieve een nieuw bug-verslag te maken voor OpenKeychain.</string>
<!--results shown after decryption/verification-->
+ <string name="decrypt_result_no_signature">Niet ondertekend</string>
<string name="decrypt_result_invalid_signature">Ongeldige handtekening!</string>
+ <string name="decrypt_result_signature_uncertified">Ondertekend door (niet gecertificeerd!)</string>
+ <string name="decrypt_result_signature_certified">Ondertekend door</string>
+ <string name="decrypt_result_signature_expired_key">Sleutel is verlopen!</string>
+ <string name="decrypt_result_signature_revoked_key">Sleutel is ingetrokken!</string>
+ <string name="decrypt_result_signature_missing_key">Onbekende publieke sleutel</string>
+ <string name="decrypt_result_encrypted">Versleuteld</string>
+ <string name="decrypt_result_not_encrypted">Niet versleuteld</string>
+ <string name="decrypt_result_action_show">Toon</string>
+ <string name="decrypt_result_action_Lookup">Zoek</string>
+ <string name="decrypt_invalid_text">De ondertekening is ongeldig of de sleutel is ingetrokken/verlopen. Je kan niet zeker zijn wie de tekst geschreven heeft. Ben je zeker dat je ze wil weergeven?</string>
+ <string name="decrypt_invalid_button">Ik begrijp de risico\'s, geef de tekst weer!</string>
<!--Add keys-->
+ <string name="add_keys_my_key">Mijn sleutel:</string>
<!--progress dialogs, usually ending in '…'-->
<string name="progress_done">Gereed.</string>
<string name="progress_cancel">Annuleren</string>
- <string name="progress_saving">opslaan...</string>
- <string name="progress_importing">importeren...</string>
- <string name="progress_exporting">exporteren...</string>
- <string name="progress_building_key">sleutel maken...</string>
- <string name="progress_building_master_key">hoofdsleutelbos maken...</string>
+ <string name="progress_cancelling">bezig met annuleren…</string>
+ <string name="progress_saving">opslaan…</string>
+ <string name="progress_importing">importeren…</string>
+ <string name="progress_exporting">exporteren…</string>
+ <string name="progress_uploading">bezig met uploaden…</string>
+ <string name="progress_building_key">sleutel maken…</string>
+ <string name="progress_building_master_key">hoofdsleutelbos maken…</string>
+ <string name="progress_generating_rsa">bezig met genereren van nieuwe RSA-sleutel…</string>
+ <string name="progress_generating_dsa">bezig met genereren van nieuwe DSA-sleutel…</string>
+ <string name="progress_generating_elgamal">bezig met genereren van nieuwe ElGamal-sleutel…</string>
+ <string name="progress_generating_ecdsa">bezig met genereren van nieuwe ECDSA-sleutel…</string>
+ <string name="progress_generating_ecdh">bezig met genereren van nieuwe ECDH-sleutel…</string>
+ <string name="progress_modify">bezig met wijzigen van sleutelbos…</string>
+ <string name="progress_modify_unlock">bezig met ontgrendelen van sleutelbos…</string>
+ <string name="progress_modify_adduid">bezig met toevoegen van gebruikers-ID\'s…</string>
+ <string name="progress_modify_adduat">bezig met toevoegen van gebruikersattributen…</string>
+ <string name="progress_modify_revokeuid">bezig met intrekken van gebruikers-ID\'s…</string>
+ <string name="progress_modify_primaryuid">bezig met primaire gebruikers-ID te veranderen…</string>
+ <string name="progress_modify_subkeychange">bezig met wijzigen van subsleutels…</string>
+ <string name="progress_modify_subkeyrevoke">bezig met terugtrekken van subsleutels…</string>
+ <string name="progress_modify_subkeystrip">bezig met strippen van subsleutels…</string>
+ <string name="progress_modify_subkeyadd">bezig met toevoegen van subsleutels…</string>
+ <string name="progress_modify_passphrase">bezig met veranderen van wachtwoord…</string>
<plurals name="progress_exporting_key">
- <item quantity="one">sleutel exporteren...</item>
- <item quantity="other">sleutels exporteren...</item>
- </plurals>
- <string name="progress_extracting_signature_key">ondertekeningssleutel uitpakken...</string>
- <string name="progress_extracting_key">sleutel uitpakken...</string>
- <string name="progress_preparing_streams">streams voorbereiden...</string>
- <string name="progress_encrypting">gegevens versleutelen...</string>
- <string name="progress_decrypting">gegevens ontsleutelen...</string>
- <string name="progress_preparing_signature">handtekening voorbereiden...</string>
- <string name="progress_generating_signature">handtekening genereren...</string>
- <string name="progress_processing_signature">handtekening verwerken...</string>
- <string name="progress_verifying_signature">handtekening verifiëren...</string>
- <string name="progress_signing">ondertekenen...</string>
- <string name="progress_reading_data">gegevens lezen...</string>
- <string name="progress_finding_key">sleutel opzoeken...</string>
- <string name="progress_decompressing_data">gegevens decomprimeren...</string>
- <string name="progress_verifying_integrity">integriteit verifiëren...</string>
- <string name="progress_deleting_securely">\'%s\' veilig verwijderen...</string>
+ <item quantity="one">sleutel exporteren…</item>
+ <item quantity="other">sleutels exporteren…</item>
+ </plurals>
+ <string name="progress_extracting_signature_key">ondertekeningssleutel uitpakken…</string>
+ <string name="progress_extracting_key">sleutel uitpakken…</string>
+ <string name="progress_preparing_streams">streams voorbereiden…</string>
+ <string name="progress_encrypting">gegevens versleutelen…</string>
+ <string name="progress_decrypting">gegevens ontsleutelen…</string>
+ <string name="progress_preparing_signature">handtekening voorbereiden…</string>
+ <string name="progress_generating_signature">handtekening genereren…</string>
+ <string name="progress_processing_signature">handtekening verwerken…</string>
+ <string name="progress_verifying_signature">handtekening verifiëren…</string>
+ <string name="progress_signing">ondertekenen…</string>
+ <string name="progress_certifying">bezig met certificeren…</string>
+ <string name="progress_reading_data">gegevens lezen…</string>
+ <string name="progress_finding_key">sleutel opzoeken…</string>
+ <string name="progress_decompressing_data">gegevens decomprimeren…</string>
+ <string name="progress_verifying_integrity">integriteit verifiëren…</string>
+ <string name="progress_deleting_securely">\'%s\' veilig verwijderen…</string>
+ <string name="progress_deleting">bezig met verwijderen van sleutels…</string>
+ <string name="progress_con_saving">consolidatie: bezig met opslaan naar cache…</string>
+ <string name="progress_con_reimport">consolidatie: bezig met opnieuw importeren…</string>
<!--action strings-->
+ <string name="hint_keyserver_search_hint">Naam/E-mail/Sleutel ID…</string>
+ <string name="hint_cloud_search_hint">Name/E-mail/Bewijs/Sleutel…</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@@ -207,8 +332,12 @@
<string name="key_size_8192">8192</string>
<string name="key_size_custom">Aangepaste sleutelgrootte</string>
<string name="key_size_custom_info">Typ aangepaste sleutellengte (in bits):</string>
+ <string name="key_size_custom_info_rsa">RSA sleutellengte moet groter zijn dan 1024 en ten hoogste 16384. Ze moet ook deelbaar zijn door 8.</string>
<string name="key_size_custom_info_dsa">DSA sleutellengte moet minstens 512 zijn en maximaal 1024. Het moet ook deelbaar zijn door 64.</string>
<!--elliptic curve names-->
+ <string name="key_curve_nist_p256">NIST P-256</string>
+ <string name="key_curve_nist_p384">NIST P-384</string>
+ <string name="key_curve_nist_p521">NIST P-521</string>
<!--not in for now, see SaveKeyringParcel
<string name="key_curve_bp_p256">"Brainpool P-256"</string>
<string name="key_curve_bp_p384">"Brainpool P-384"</string>
@@ -225,19 +354,85 @@
<string name="help_tab_about">Over</string>
<string name="help_about_version">Versie:</string>
<!--Import-->
+ <string name="import_tab_keyserver">Sleutelserver</string>
+ <string name="import_tab_cloud">Zoeken</string>
+ <string name="import_tab_direct">Bestand/klembord</string>
+ <string name="import_tab_qr_code">QR code/NFC</string>
<string name="import_import">Geselecteerde sleutels importeren</string>
<string name="import_qr_code_wrong">QR-code ongeldig. Probeer het opnieuw</string>
<string name="import_qr_code_too_short_fingerprint">Vingerafdruk is te kort (&lt; 16 tekens)</string>
+ <string name="import_qr_code_button">QR code scannen</string>
+ <string name="import_qr_code_text">Plaats je camera voor de QR-code!</string>
<!--Generic result toast-->
+ <string name="view_log">Details</string>
+ <string name="with_warnings">, met waarschuwingen</string>
+ <string name="with_cancelled">, tot annulatie</string>
<!--Import result toast-->
+ <plurals name="import_keys_added_and_updated_1">
+ <item quantity="one">Sleutel succesvol geïmporteerd</item>
+ <item quantity="other">%1$d sleutels succesvol geïmporteerd</item>
+ </plurals>
+ <plurals name="import_keys_added_and_updated_2">
+ <item quantity="one">en sleutel%2$s geüpdatet.</item>
+ <item quantity="other">en %1$d sleutels%2$s.</item>
+ </plurals>
+ <plurals name="import_keys_added">
+ <item quantity="one">Sleutel%2$s succesvol geïmporteerd.</item>
+ <item quantity="other">%1$d sleutels%2$s succesvol geïmporteerd.</item>
+ </plurals>
+ <plurals name="import_keys_updated">
+ <item quantity="one">Sleutel%2$s succesvol geüpdatet.</item>
+ <item quantity="other">%1$d sleutels%2$s succesvol geüpdatet.</item>
+ </plurals>
+ <plurals name="import_keys_with_errors">
+ <item quantity="one">Importeren mislukt voor een sleutel!</item>
+ <item quantity="other">Importeren mislukt voor %d sleutels!</item>
+ </plurals>
+ <plurals name="import_error">
+ <item quantity="one">Importeren mislukt!</item>
+ <item quantity="other">Importeren van %d sleutels mislukt!</item>
+ </plurals>
+ <string name="import_error_nothing">Niets te importeren.</string>
+ <string name="import_error_nothing_cancelled">Importeren geannuleerd.</string>
<!--Delete result toast-->
+ <plurals name="delete_ok_but_fail_1">
+ <item quantity="one">Een sleutel succesvol verwijderd</item>
+ <item quantity="other">%1$d sleutels succesvol verwijderd</item>
+ </plurals>
+ <plurals name="delete_ok_but_fail_2">
+ <item quantity="one">, maar verwijderen van een sleutel%2$s mislukt.</item>
+ <item quantity="other">, maar verwijderen van %1$d sleutels%2$s mislukt.</item>
+ </plurals>
+ <plurals name="delete_ok">
+ <item quantity="one">Sleutel%2$s succesvol verwijderd.</item>
+ <item quantity="other">%1$d sleutels%2$s succesvol verwijderd.</item>
+ </plurals>
+ <plurals name="delete_fail">
+ <item quantity="one">Fout bij verwijderen van een sleutel%2$s.</item>
+ <item quantity="other">Fout bij verwijderen van %1$d sleutels.</item>
+ </plurals>
+ <string name="delete_nothing">Niets te verwijderen.</string>
+ <string name="delete_cancelled">Verwijderen geannuleerd.</string>
<!--Certify result toast-->
+ <plurals name="certify_keys_ok">
+ <item quantity="one">Sleutel%2$s succesvol gecertificeerd.</item>
+ <item quantity="other">%1$d sleutels%2$s succesvol gecertificeerd.</item>
+ </plurals>
+ <plurals name="certify_keys_with_errors">
+ <item quantity="one">Certificatie mislukt!</item>
+ <item quantity="other">Certificatie mislukt voor %d sleutels!</item>
+ </plurals>
+ <plurals name="certify_error">
+ <item quantity="one">Certificatie mislukt!</item>
+ <item quantity="other">Certificatie van %d sleutels mislukt!</item>
+ </plurals>
<!--Intent labels-->
<string name="intent_decrypt_file">Decodeer bestand met OpenKeychain</string>
<string name="intent_import_key">Importeer Sleutel met OpenKeychain</string>
<string name="intent_send_encrypt">Codeer met OpenKeychain</string>
<string name="intent_send_decrypt">Decodeer met OpenKeychain</string>
<!--Remote API-->
+ <string name="api_no_apps">Geen geregistreerde apps!\n\nEen lijst van ondersteunde derde-partij applicaties kan gevonden worden in \'Help\'!</string>
<string name="api_settings_show_info">Toon geavanceerde informatie</string>
<string name="api_settings_hide_info">Verberg geavanceerde informatie</string>
<string name="api_settings_show_advanced">Toon geavanceerde instellingen</string>
@@ -246,17 +441,29 @@
<string name="api_settings_select_key">Sleutel selecteren</string>
<string name="api_settings_create_key">Maak nieuwe sleutel voor dit account</string>
<string name="api_settings_save">Opslaan</string>
+ <string name="api_settings_save_msg">Account is opgeslaan</string>
<string name="api_settings_cancel">Annuleren</string>
<string name="api_settings_revoke">Toegang herroepen</string>
<string name="api_settings_start">Start applicatie</string>
<string name="api_settings_delete_account">Verwijder account</string>
<string name="api_settings_package_name">Pakketnaam</string>
<string name="api_settings_package_signature">SHA-256 van Pakkethandtekening</string>
- <string name="api_settings_accounts">Accounts</string>
+ <string name="api_settings_accounts">Accounts (verouderde API)</string>
+ <string name="api_settings_advanced">Geavanceerde informatie</string>
+ <string name="api_settings_allowed_keys">Toegestane sleutels</string>
+ <string name="api_settings_settings">Instellingen</string>
+ <string name="api_settings_key">Accountsleutel:</string>
+ <string name="api_settings_accounts_empty">Geen accounts verbonden aan deze app.</string>
+ <string name="api_create_account_text">Geen sleutel ingesteld voor deze account. Gelieve een van je bestaande sleutels te selecteren, of een nieuwe sleutel aan te maken.\nApps kunnen enkel ontcijferen/ondertekenen met de sleutels die je hier selecteert!</string>
+ <string name="api_update_account_text">De sleutel opgeslaan voor deze account is verwijderd. Gelieve een andere te selecteren!\nApps kunnen enkel ontcijferen/ondertekenen met de sleutels die je hier selecteert!</string>
+ <string name="api_register_text">De weergegeven app will berichten versleutelen/ontcijferen en ze in jouw naam ondertekenen.\nToegang toestaan?\n\nWAARSCHUWING: als je niet weet waarom dit scherm verscheen, sta dan geen toegang toe! Je kan later toegang weghalen via het \'Apps\' scherm.</string>
<string name="api_register_allow">Toegang toestaan</string>
<string name="api_register_disallow">Toegang weigeren</string>
<string name="api_register_error_select_key">Selecteert u a.u.b. een sleutel</string>
+ <string name="api_select_pub_keys_missing_text">Geen sleutels gevonden voor deze identiteiten:</string>
+ <string name="api_select_pub_keys_dublicates_text">Meer dan een sleutel bestaat voor deze identiteiten:</string>
<string name="api_select_pub_keys_text">Bekijkt u a.u.b. de ontvangers</string>
+ <string name="api_select_pub_keys_text_no_user_ids">Gelieve de ontvangers te selecteren!</string>
<string name="api_error_wrong_signature">Handtekening check mislukt! Hebt u deze app van een andere bron geïnstalleerd? Als u zeker weet dat dit geen aanval is, haal dan de registratie van deze app in OpenKeychain weg en registreer de app opnieuw.</string>
<!--Share-->
<string name="share_qr_code_dialog_title">Delen met QR-code</string>
@@ -266,63 +473,616 @@
<item quantity="one">1 sleutel geselecteerd.</item>
<item quantity="other">%d sleutels geselecteerd.</item>
</plurals>
+ <string name="key_list_empty_text1">Geen sleutels gevonden!</string>
+ <string name="key_list_filter_show_all">Alle sleutels weergeven</string>
+ <string name="key_list_filter_show_certified">Enkel gecertificeerde sleutels weergeven</string>
<!--Key view-->
<string name="key_view_action_edit">Sleutel bewerken</string>
+ <string name="key_view_action_encrypt">Versleutel tekst</string>
+ <string name="key_view_action_encrypt_files">bestanden</string>
<string name="key_view_action_certify">Certifiëer identiteiten</string>
- <string name="key_view_action_share_with">Delen met...</string>
+ <string name="key_view_action_update">Update van sleutelserver</string>
+ <string name="key_view_action_share_with">Delen met…</string>
+ <string name="key_view_action_share_nfc">Delen over NFC</string>
+ <string name="key_view_action_upload">Uploaden naar sleutelserver</string>
<string name="key_view_tab_main">Hoofd Info</string>
<string name="key_view_tab_share">Delen</string>
<string name="key_view_tab_keys">Subsleutels</string>
<string name="key_view_tab_certs">Certificaten</string>
+ <string name="user_id_info_revoked_title">Ingetrokken</string>
+ <string name="user_id_info_revoked_text">Deze identiteit is door de sleuteleigenaar ingetrokken. Ze is niet langer geldig.</string>
+ <string name="user_id_info_certified_title">Gecertificeerd</string>
+ <string name="user_id_info_certified_text">Deze identiteit is door jou gecertificeerd.</string>
+ <string name="user_id_info_uncertified_title">Niet gecertificeerd</string>
+ <string name="user_id_info_uncertified_text">Deze identiteit is nog niet gecertificeerd. Je kan niet zeker zijn dat deze identiteit echt overeenkomt met een bepaald persoon.</string>
+ <string name="user_id_info_invalid_title">Ongeldig</string>
+ <string name="user_id_info_invalid_text">Er is iets mis met deze identiteit!</string>
<!--Edit key-->
+ <string name="edit_key_action_change_passphrase">Wachtwoord wijzigen</string>
+ <string name="edit_key_action_add_identity">Identiteit toevoegen</string>
+ <string name="edit_key_action_add_subkey">Subsleutel toevoegen</string>
+ <string name="edit_key_edit_user_id_title">Selecteer een actie!</string>
+ <string-array name="edit_key_edit_user_id">
+ <item>Verander naar primaire identiteit</item>
+ <item>Trek identiteit in</item>
+ </string-array>
+ <string-array name="edit_key_edit_user_id_revert_revocation">
+ <item>Intrekking ongedaan maken</item>
+ </string-array>
+ <string name="edit_key_edit_user_id_revoked">Deze identiteit is ingetrokken. Dit kan niet ongedaan gemaakt worden.</string>
+ <string name="edit_key_edit_subkey_title">Selecteer een actie!</string>
+ <string-array name="edit_key_edit_subkey">
+ <item>Vervaldatum veranderen</item>
+ <item>Subsleutel intrekken</item>
+ <item>Subsleutel strippen</item>
+ </string-array>
+ <string name="edit_key_new_subkey">nieuwe subsleutel</string>
+ <string name="edit_key_select_flag">Gelieve minstens een vlag te selecteren!</string>
+ <string name="edit_key_error_add_identity">Voeg minstens een identiteit toe!</string>
+ <string name="edit_key_error_add_subkey">Voeg minstens een subsleutel toe!</string>
<!--Create key-->
+ <string name="create_key_upload">Upload sleutel naar sleutelserver</string>
+ <string name="create_key_empty">Dit veld moet ingevuld worden</string>
+ <string name="create_key_passphrases_not_equal">Wachtwoorden komen niet overeen</string>
+ <string name="create_key_final_text">Je hebt volgende identiteit ingevoerd:</string>
+ <string name="create_key_final_robot_text">Een sleutel aanmaken kan even duren, maak intussen een tasje thee klaar…</string>
+ <string name="create_key_rsa">(3 subsleutels, RSA, 4096 bit)</string>
+ <string name="create_key_custom">(aangepaste sleutelconfiguratie)</string>
+ <string name="create_key_text">Voer je volledige naam en e-mailadres in, en kies een wachtwoord.</string>
+ <string name="create_key_hint_full_name">Volledige naam, bv. Max Mustermann</string>
+ <string name="create_key_edit">Sleutelconfiguratie wijzigen</string>
<!--View key-->
+ <string name="view_key_revoked">Deze sleutel is ingetrokken!</string>
+ <string name="view_key_expired">Deze sleutel is verlopen!</string>
<!--Navigation Drawer-->
<string name="nav_keys">Sleutels</string>
+ <string name="nav_encrypt_decrypt">Versleutelen/Ontsleutelen</string>
+ <string name="nav_apps">Apps</string>
<string name="drawer_open">Open navigatiemenu</string>
<string name="drawer_close">Sluit navigatiemenu</string>
<string name="my_keys">Mijn Sleutels</string>
<!--hints-->
+ <string name="encrypt_content_edit_text_hint">Type tekst</string>
<!--certs-->
<string name="cert_default">standaard</string>
<string name="cert_none">geen</string>
<string name="cert_casual">eenvoudig</string>
<string name="cert_positive">positief</string>
<string name="cert_revoke">ingetrokken</string>
+ <string name="cert_verify_ok">Oké</string>
<string name="cert_verify_failed">mislukt!</string>
<string name="cert_verify_error">fout!</string>
<string name="cert_verify_unavailable">sleutel onbeschikbaar</string>
<!--LogType log messages. Errors should have _ERROR_ in their name and end with a !-->
+ <string name="msg_internal_error">Interne fout!</string>
+ <string name="msg_cancelled">Bewerking geannuleerd.</string>
<!--Import Public log entries-->
+ <string name="msg_ip_apply_batch">Bezig met toepassen van invoeg-batchbewerking.</string>
+ <string name="msg_ip_bad_type_secret">Geprobeerd een geheime sleutel als publieke sleutel te importeren. Dit is een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_ip_delete_old_fail">Geen oude sleutel verwijderd (een nieuwe aan het aanmaken?)</string>
+ <string name="msg_ip_delete_old_ok">Oude sleutel van database verwijderd</string>
+ <string name="msg_ip_encode_fail">Bewerking mislukt door coderingsfout</string>
+ <string name="msg_ip_error_io_exc">Bewerking mislukt door i/o-fout</string>
+ <string name="msg_ip_error_op_exc">Bewerking mislukt door databasefout</string>
+ <string name="msg_ip_error_remote_ex">Bewerking mislukt door interne fout</string>
+ <string name="msg_ip">Bezig met importeren van publieke sleutelbos %s</string>
+ <string name="msg_ip_insert_keyring">Bezig met coderen van sleutelbosgegevens</string>
+ <string name="msg_ip_insert_keys">Bezig met analyseren van sleutels</string>
+ <string name="msg_ip_prepare">Bezig met voorbereiden van databasebewerkingen</string>
+ <string name="msg_ip_master">Bezig met verwerken van hoofdsleutel %s</string>
+ <string name="msg_ip_master_expired">Sleutelbos is verlopen op %s</string>
+ <string name="msg_ip_master_expires">Sleutelbos verloopt op %s</string>
+ <string name="msg_ip_master_flags_unspecified">Hoofdvlaggen: niet gespecificeerd (alle worden verondersteld)</string>
+ <string name="msg_ip_master_flags_cesa">Hoofdvlaggen: certificeren, versleutelen, ondertekenen, authenticeren</string>
+ <string name="msg_ip_master_flags_cesx">Hoofdvlaggen: certificeren, versleutelen, ondertekenen</string>
+ <string name="msg_ip_master_flags_cexa">Hoofdvlaggen: certificeren, versleutelen, authenticeren</string>
+ <string name="msg_ip_master_flags_cexx">Hoofdvlaggen: certificeren, versleutelen</string>
+ <string name="msg_ip_master_flags_cxsa">Hoofdvlaggen: certificeren, versleutelen, authenticeren</string>
+ <string name="msg_ip_master_flags_cxsx">Hoofdvlaggen: certificeren, ondertekenen</string>
+ <string name="msg_ip_master_flags_cxxa">Hoofdvlaggen: certificeren, authenticeren</string>
+ <string name="msg_ip_master_flags_cxxx">Hoofdvlaggen: certificeren</string>
+ <string name="msg_ip_master_flags_xesa">Hoofdvlaggen: versleutelen, ondertekenen, authenticeren</string>
+ <string name="msg_ip_master_flags_xesx">Hoofdvlaggen: versleutelen, ondertekenen</string>
+ <string name="msg_ip_master_flags_xexa">Hoofdvlaggen: versleutelen, authenticeren</string>
+ <string name="msg_ip_master_flags_xexx">Hoofdvlaggen: versleutelen</string>
+ <string name="msg_ip_master_flags_xxsa">Hoofdvlaggen: ondertekenen, authenticeren</string>
+ <string name="msg_ip_master_flags_xxsx">Hoofdvlaggen: ondertekenen</string>
+ <string name="msg_ip_master_flags_xxxa">Hoofdvlaggen: authenticeren</string>
+ <string name="msg_ip_master_flags_xxxx">Hoofdvlaggen: geen</string>
+ <string name="msg_ip_merge_public">Bezig met samenvoegen van geïmporteerde gegevens in bestaande publieke sleutelbos</string>
+ <string name="msg_ip_merge_secret">Bezig met samenvoegen van geïmporteerde gegevens in bestaande publieke sleutelbos</string>
+ <string name="msg_ip_subkey">Bezig met verwerken van subsleutel %s</string>
+ <string name="msg_ip_subkey_expired">Subsleutel is vervallen op %s</string>
+ <string name="msg_ip_subkey_expires">Subsleutel vervalt op %s</string>
+ <string name="msg_ip_subkey_flags_unspecified">Subsleutelvlaggen: niet gespecificeerd (alle worden verondersteld)</string>
+ <string name="msg_ip_subkey_flags_cesa">Subsleutelvlaggen: certificeren, versleutelen, ondertekenen, authenticeren</string>
+ <string name="msg_ip_subkey_flags_cesx">Subsleutelvlaggen: certificeren, versleutelen, ondertekenen</string>
+ <string name="msg_ip_subkey_flags_cexa">Subsleutelvlaggen: certificeren, versleutelen, authenticeren</string>
+ <string name="msg_ip_subkey_flags_cexx">Subsleutelvlaggen: certificeren, versleutelen</string>
+ <string name="msg_ip_subkey_flags_cxsa">Subsleutelvlaggen: certificeren, ondertekenen, authenticeren</string>
+ <string name="msg_ip_subkey_flags_cxsx">Subsleutelvlaggen: certificeren, ondertekenen</string>
+ <string name="msg_ip_subkey_flags_cxxa">Subsleutelvlaggen: certificeren, authenticeren</string>
+ <string name="msg_ip_subkey_flags_cxxx">Subsleutelvlaggen: certificeren</string>
+ <string name="msg_ip_subkey_flags_xesa">Subsleutelvlaggen: versleutelen, ondertekenen, authenticeren</string>
+ <string name="msg_ip_subkey_flags_xesx">Subsleutelvlaggen: versleutelen, ondertekenen</string>
+ <string name="msg_ip_subkey_flags_xexa">Subsleutelvlaggen: versleutelen, authenticeren</string>
+ <string name="msg_ip_subkey_flags_xexx">Subsleutelvlaggen: versleutelen</string>
+ <string name="msg_ip_subkey_flags_xxsa">Subsleutelvlaggen: ondertekenen, authenticeren</string>
+ <string name="msg_ip_subkey_flags_xxsx">Subsleutelvlaggen: ondertekenen</string>
+ <string name="msg_ip_subkey_flags_xxxa">Subsleutelvlaggen: authenticeren</string>
+ <string name="msg_ip_subkey_flags_xxxx">Subsleutelvlaggen: geen</string>
+ <string name="msg_ip_success">Publieke sleutelbos succesvol geïmporteerd</string>
+ <string name="msg_ip_success_identical">Sleutelbos bevat geen nieuwe gegevens, niets te doen</string>
+ <string name="msg_ip_reinsert_secret">Bezig met opnieuw invoegen van geheime sleutel</string>
+ <string name="msg_ip_uid_cert_bad">Slecht certificaat tegengekomen!</string>
+ <string name="msg_ip_uid_cert_error">Fout bij verwerken van certificaat!</string>
+ <string name="msg_ip_uid_cert_nonrevoke">Er is al een niet-intrekbaar certificaat, dit certificaat wordt overgeslaan.</string>
+ <string name="msg_ip_uid_cert_old">Dit certificaat is ouder dan het vorige en wordt overgeslaan.</string>
+ <string name="msg_ip_uid_cert_new">Dit certificaat is recenter en vervangt het vorige.</string>
+ <string name="msg_ip_uid_cert_good">Goed certificaat door %1$s gevonden</string>
+ <string name="msg_ip_uid_cert_good_revoke">Goede intrekking van certificaat door %1$s gevonden</string>
+ <plurals name="msg_ip_uid_certs_unknown">
+ <item quantity="one">Een certificaat uitgegeven door een onbekende publieke sleutel wordt genegeerd</item>
+ <item quantity="other">%s certificaten uitgegeven door onbekende publieke sleutels worden genegeerd</item>
+ </plurals>
+ <string name="msg_ip_uid_classifying_zero">Bezig met classificeren van gebruikers-ID\'s (geen vertrouwde sleutels beschikbaar)</string>
+ <plurals name="msg_ip_uid_classifying">
+ <item quantity="one">Bezig met classificeren van gebruikers-ID\'s (een vertrouwde sleutel wordt gebruikt)</item>
+ <item quantity="other">Bezig met classificeren van gebruikers-ID\'s (%s vertrouwde sleutels worden gebruikt)</item>
+ </plurals>
+ <string name="msg_ip_uid_reorder">Bezig met opnieuw ordenen van gebruikers-ID\'s</string>
+ <string name="msg_ip_uid_processing">Bezig met verwerken van gebruikers-ID %s</string>
+ <string name="msg_ip_uid_revoked">Gebruikers-ID is ingetrokken</string>
+ <string name="msg_ip_uat_processing_image">Bezig met verwerken van gebruikersattribuut van type afbeelding</string>
+ <string name="msg_ip_uat_processing_unknown">Bezig met verwerken van gebruikersattribuut van onbekend type</string>
+ <string name="msg_ip_uat_cert_bad">Slecht certificaat tegengekomen!</string>
+ <string name="msg_ip_uat_cert_error">Fout bij verwerken van certificaat!</string>
+ <string name="msg_ip_uat_cert_nonrevoke">Er is al een niet-intrekbaar certificaat, dit certificaat wordt overgeslaan.</string>
+ <string name="msg_ip_uat_cert_old">Dit certificaat is ouder dan het vorige en wordt overgeslaan.</string>
+ <string name="msg_ip_uat_cert_new">Dit certificaat is recenter en vervangt het vorige.</string>
+ <string name="msg_ip_uat_cert_good">Goed certificaat door %1$s gevonden</string>
+ <string name="msg_ip_uat_cert_good_revoke">Goede intrekking van certificaat door %1$s gevonden</string>
+ <plurals name="msg_ip_uat_certs_unknown">
+ <item quantity="one">Een certificaat uitgegeven door een onbekende publieke sleutel wordt genegeerd</item>
+ <item quantity="other">%s certificaten uitgegeven door onbekende publieke sleutels worden genegeerd</item>
+ </plurals>
+ <string name="msg_ip_uat_classifying">Bezig met classificeren van gebruikersattributen</string>
+ <string name="msg_ip_uat_revoked">Gebruikersattribuut is ingetrokken</string>
+ <string name="msg_is_bad_type_public">Geprobeerd een geheime sleutelbos als publieke sleutelbos te importeren. Dit is een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_is_bad_type_uncanon">Geprobeerd een sleutelbos zonder standaardisatie te importeren. Dit is een bug, gelieve een verslag in te dienen!</string>
<!--Import Secret log entries-->
+ <string name="msg_is">Bezig met importeren van geheime sleutel %s</string>
+ <string name="msg_is_db_exception">Databasefout!</string>
+ <string name="msg_is_importing_subkeys">Bezig met verwerken van geheime subsleutels</string>
+ <string name="msg_is_error_io_exc">Fout bij coderen van sleutelbos</string>
+ <string name="msg_is_merge_public">Bezig met samenvoegen van geïmporteerde gegevens in bestaande publieke sleutelbos</string>
+ <string name="msg_is_merge_secret">Bezig met samenvoegen van geïmporteerde gegevens in bestaande publieke sleutelbos</string>
+ <string name="msg_is_merge_special">Bezig met samenvoegen van gegevens van self-certificaten uit publieke sleutelbos</string>
+ <string name="msg_is_pubring_generate">Bezig met aanmaken van publieke sleutelbos uit geheime sleutelbos</string>
+ <string name="msg_is_subkey_nonexistent">Subsleutel %s niet beschikbaar in geheime sleutel</string>
+ <string name="msg_is_subkey_ok">Geheime subsleutel %s gemarkeerd als beschikbaar</string>
+ <string name="msg_is_subkey_empty">Geheime subsleutel %s gemarkeerd als beschikbaar, met leeg wachtwoord</string>
+ <string name="msg_is_subkey_pin">Geheime subsleutel %s gemarkeerd als beschikbaar, met PIN</string>
+ <string name="msg_is_subkey_stripped">Geheime subsleutel %s gemarkeerd als gestript</string>
+ <string name="msg_is_subkey_divert">Geheime subsleutel %s gemarkeerd als \'doorschakelen naar smartcard/NFC\'</string>
+ <string name="msg_is_success_identical">Sleutelbos bevat geen nieuwe gegevens, niets te doen</string>
+ <string name="msg_is_success">Geheime sleutelbos succesvol geïmporteerd</string>
<!--Keyring Canonicalization log entries-->
+ <string name="msg_kc_public">Bezig met standaardiseren van publieke sleutelbos %s</string>
+ <string name="msg_kc_secret">Bezig met standaardiseren van geheime sleutelbos %s</string>
+ <string name="msg_kc_error_v3">Dit is een OpenPGP versie 3 sleutel, deze is verouderd en wordt niet meer ondersteund!</string>
+ <string name="msg_kc_error_no_uid">Sleutelbos bevat geen geldige gebruikers-ID\'s!</string>
+ <string name="msg_kc_error_master_algo">De hoofdsleutel gebruikt een onbekend (%s) algoritme!</string>
+ <string name="msg_kc_error_dup_key">Subsleutel %s komt tweemaal voor in sleutelbos. Sleutelbos is misvormd en wordt niet geïmporteerd!</string>
+ <string name="msg_kc_master">Bezig met verwerken van hoofdsleutel</string>
+ <string name="msg_kc_master_bad_type">Bezig met verwijderen van hoofdsleutelcertificaat van onbekend type (%s)</string>
+ <string name="msg_kc_master_bad_local">Bezig met verwijderen van hoofdsleutelcertificaat met vlag \'lokaal\'</string>
+ <string name="msg_kc_master_bad_err">Bezig met verwijderen van slecht hoofdsleutelcertificaat</string>
+ <string name="msg_kc_master_bad_time">Bezig met verwijderen van sleutelbosintrekkingscertificaat met toekomstige tijdstempel</string>
+ <string name="msg_kc_master_bad_type_uid">Bezig met verwijderen van gebruikers-ID-certificaat in slechte positie</string>
+ <string name="msg_kc_master_bad">Bezig met verwijderen van slecht hoofdsleutelcertificaat</string>
+ <string name="msg_kc_master_local">Bezig met verwijderen van hoofdsleutelcertificaat met vlag \'lokaal\'</string>
+ <string name="msg_kc_revoke_dup">Bezig met verwijderen van overbodig sleutelbosintrekkingscertificaat</string>
+ <string name="msg_kc_notation_dup">Bezig met verwijderen van overbodig notatiecertificaat</string>
+ <string name="msg_kc_notation_empty">Bezig met verwijderen van leeg notatiecertificaat</string>
+ <string name="msg_kc_sub">Bezig met verwerken van subsleutel %s</string>
+ <string name="msg_kc_sub_bad">Bezig met verwijderen van ongeldig subsleutelbindend certificaat</string>
+ <string name="msg_kc_sub_bad_err">Bezig met verwijderen van slecht subsleutelbindend certificaat</string>
+ <string name="msg_kc_sub_bad_local">Bezig met verwijderen van subsleutelbindend certificaat met vlag \'lokaal\'</string>
+ <string name="msg_kc_sub_bad_keyid">Subsleutelbindende uitgevers-ID komt niet overeen</string>
+ <string name="msg_kc_sub_bad_time">Bezig met verwijderen van subsleutelbindend certificaat met toekomstige tijdstempel</string>
+ <string name="msg_kc_sub_bad_type">Onbekend subsleutelcertificaattype: %s</string>
+ <string name="msg_kc_sub_dup">Bezig met verwijderen van overbodig subsleutelbindend certificaat</string>
+ <string name="msg_kc_sub_primary_bad">Bezig met verwijderen van subsleutelbindend certificaat wegens ongeldig primair bindend certificaat</string>
+ <string name="msg_kc_sub_primary_bad_err">Bezig met verwijderen van subsleutelbindend certificaat wegens slecht primair bindend certificaat</string>
+ <string name="msg_kc_sub_primary_none">Bezig met verwijderen van subsleutelbindend certificaat wegens ontbrekend primair bindend certificaat</string>
+ <string name="msg_kc_sub_no_cert">Geen geldig certificaat gevonden voor %s, wordt verwijderd van sleutelbos</string>
+ <string name="msg_kc_sub_revoke_bad_err">Bezig met verwijderen van slecht subsleutelintrekkingscertificaat</string>
+ <string name="msg_kc_sub_revoke_bad">Bezig met verwijderen van slecht subsleutelintrekkingscertificaat</string>
+ <string name="msg_kc_sub_revoke_dup">Bezig met verwijderen van overbodig subsleutelintrekkingscertificaat</string>
+ <string name="msg_kc_sub_unknown_algo">Subsleutel gebruikt een onbekend algoritme en wordt niet geïmporteerd…</string>
+ <string name="msg_kc_sub_algo_bad_encrpyt">Subsleutel heeft versleuteling-gebruiksvlag, maar algoritme is niet geschikt voor versleuteling.</string>
+ <string name="msg_kc_sub_algo_bad_sign">Subsleutel heeft ondertekenen-gebruiksvlag, maar algoritme is niet geschikt voor ondertekenen.</string>
+ <string name="msg_kc_success">Standaardisatie van sleutelbos geslaagd, geen wijzigingen</string>
+ <plurals name="msg_kc_success_bad">
+ <item quantity="one">Standaardisatie van sleutelbos geslaagd, een foutief certificaat verwijderd</item>
+ <item quantity="other">Standaardisatie van sleutelbos geslaagd, %d foutieve certificaten verwijderd</item>
+ </plurals>
+ <string name="msg_kc_success_bad_and_red">Standaardisatie van sleutelbos geslaagd, %1$s foutieve en %2$s overbodige certificaten verwijderd</string>
+ <plurals name="msg_kc_success_redundant">
+ <item quantity="one">Standaardisatie van sleutelbos geslaagd, een overbodig certificaat verwijderd</item>
+ <item quantity="other">Standaardisatie van sleutelbos geslaagd, %d overbodige certificaten verwijderd</item>
+ </plurals>
+ <string name="msg_kc_uid_bad_err">Bezig met verwijderen van slecht self-certificaat voor gebruikers-ID \'%s\'</string>
+ <string name="msg_kc_uid_bad_local">Bezig met verwijderen van gebruikers-ID-certificaat met vlag \'lokaal\'</string>
+ <string name="msg_kc_uid_bad_time">Bezig met verwijderen van gebruikers-ID-certificaat met toekomstige tijdstempel</string>
+ <string name="msg_kc_uid_bad_type">Bezig met verwijderen van gebruikers-ID-certificaat van onbekend type (%s)</string>
+ <string name="msg_kc_uid_bad">Bezig met verwijderen van slecht self-certificaat voor gebruikers-ID \'%s\'</string>
+ <string name="msg_kc_uid_cert_dup">Bezig met verwijderen van verlopen self-certificaat voor gebruikers-ID \'%s\'</string>
+ <string name="msg_kc_uid_foreign">Bezig met verwijderen van vreemd gebruikers-ID-certificaat door \'%s\'</string>
+ <string name="msg_kc_uid_revoke_dup">Bezig met verwijderen van overbodig intrekkingscertificaat voor gebruikers-ID \'%s\'</string>
+ <string name="msg_kc_uid_revoke_old">Bezig met verwijderen van verlopen intrekkingscertificaat voor gebruikers-ID \'%s\'</string>
+ <string name="msg_kc_uid_no_cert">Geen geldig self-certificaat gevonden voor gebruikers-ID \'%s\', wordt verwijderd van sleutelbos</string>
+ <string name="msg_kc_uid_remove">Bezig met verwijderen van ongeldige gebruikers-ID \'%s\'</string>
+ <string name="msg_kc_uid_dup">Bezig met verwijderen van dubbele gebruikers-ID \'%s\'. De sleutelbos bevat er twee. Dit kan resulteren in ontbrekende certificaten!</string>
+ <string name="msg_kc_uid_warn_encoding">Gebruikers-ID verifieert niet als UTF-8!</string>
+ <string name="msg_kc_uat_jpeg">Bezig met verwerken van gebruikersattribuut van type JPEG</string>
+ <string name="msg_kc_uat_unknown">Bezig met verwerken van gebruikersattribuut van onbekend type</string>
+ <string name="msg_kc_uat_bad_err">Bezig met verwijderen van slecht self-certificaat voor gebruikersattribuut</string>
+ <string name="msg_kc_uat_bad_local">Bezig met verwijderen van gebruikersattribuut-certificaat met vlag \'lokaal\'</string>
+ <string name="msg_kc_uat_bad_time">Bezig met verwijderen van gebruikersattribuut-certificaat met toekomstige tijdstempel</string>
+ <string name="msg_kc_uat_bad_type">Bezig met verwijderen van gebruikersattribuut-certificaat van onbekend type (%s)</string>
+ <string name="msg_kc_uat_bad">Bezig met verwijderen van slecht self-certificaat voor gebruikersattribuut</string>
+ <string name="msg_kc_uat_cert_dup">Bezig met verwijderen van verlopen self-certificaat voor gebruikersattribuut</string>
+ <string name="msg_kc_uat_dup">Bezig met verwijderen van dubbel gebruikersattribuut. De sleutelbos bevat er twee. Dit kan resulteren in ontbrekende certificaten!</string>
+ <string name="msg_kc_uat_foreign">Bezig met verwijderen van vreemd gebruikersattribuut-certificaat door</string>
+ <string name="msg_kc_uat_revoke_dup">Bezig met verwijderen van overbodig intrekkingscertificaat voor gebruikersattribuut</string>
+ <string name="msg_kc_uat_revoke_old">Bezig met verwijderen van verlopen intrekkingscertificaat voor gebruikersattribuut</string>
+ <string name="msg_kc_uat_no_cert">Geen geldig self-certificaat gevonden voor gebruikersattribuut, wordt verwijderd van sleutelbos</string>
+ <string name="msg_kc_uat_remove">Bezig met verwijderen van ongeldig gebruikersattribuut</string>
+ <string name="msg_kc_uat_warn_encoding">Gebruikers-ID verifieert niet als UTF-8!</string>
<!--Keyring merging log entries-->
+ <string name="msg_mg_error_secret_dummy">Nieuwe publieke subsleutel gevonden, maar geheime subsleutel dummy-generatie wordt niet ondersteund!</string>
+ <string name="msg_mg_error_heterogeneous">Geprobeerd om sleutelbossen met verschillende vingerafdrukken samen te voegen!</string>
+ <string name="msg_mg_error_encode">Fatale fout bij coderen van ondertekening!</string>
+ <string name="msg_mg_public">Bezig met samenvoegen in publieke sleutelbos %s</string>
+ <string name="msg_mg_secret">Bezig met samenvoegen in geheime sleutelbos %s</string>
+ <string name="msg_mg_new_subkey">Bezig met toevoegen van nieuwe subsleutel %s</string>
+ <string name="msg_mg_found_new">%s nieuwe certificaten in sleutelbos gevonden</string>
+ <string name="msg_mg_unchanged">Niets om samen te voegen</string>
<!--createSecretKeyRing-->
+ <string name="msg_cr">Bezig met aanmaken van nieuwe hoofdsleutel</string>
+ <string name="msg_cr_error_no_master">Geen hoofdsleutel-opties opgegeven!</string>
+ <string name="msg_cr_error_no_user_id">Sleutelbossen moeten met minstens een gebruikers-ID aangemaakt worden!</string>
+ <string name="msg_cr_error_no_certify">Hoofdsleutel moet certificeer-vlag hebben!</string>
+ <string name="msg_cr_error_null_expiry">Verloopdatum kan niet hetzelfde als voordien zijn bij aanmaken van een sleutel. Dit is een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_cr_error_keysize_512">Sleutelgrootte moet groter dan of gelijk zijn aan 512!</string>
+ <string name="msg_cr_error_no_curve">Geen sleutelgrootte opgegeven! Dit is een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_cr_error_no_keysize">Geen elliptische curve opgegeven! Dit is een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_cr_error_internal_pgp">Interne OpenPGP-fout!</string>
+ <string name="msg_cr_error_unknown_algo">Onbekend algoritme geselecteerd! Dit is een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_cr_error_flags_dsa">Slechte sleutelvlaggen geselecteerd, DSA kan niet gebruikt worden voor versleuteling!</string>
+ <string name="msg_cr_error_flags_elgamal">Slechte sleutelvlaggen geselecteerd, ElGamal kan niet gebruikt worden voor versleuteling!</string>
+ <string name="msg_cr_error_flags_ecdsa">Slechte sleutelvlaggen geselecteerd, ECDSA kan niet gebruikt worden voor versleuteling!</string>
+ <string name="msg_cr_error_flags_ecdh">Slechte sleutelvlaggen geselecteerd, ECDH kan niet gebruikt worden voor versleuteling!</string>
<!--modifySecretKeyRing-->
+ <string name="msg_mr">Bezig met wijzigen van sleutelbos %s</string>
+ <string name="msg_mf_error_divert_serial">Het serienummer van een doorschakelen-naar-kaart sleutel moet 16 bytes zijn! Dit is een programmeerfout, gelieve een verslag in te dienen!</string>
+ <string name="msg_mf_error_encode">Codeeruitzondering!</string>
+ <string name="msg_mf_error_fingerprint">Eigenlijke vingerafdruk van sleutel komt niet overeen met verwachte vingerafdruk!</string>
+ <string name="msg_mf_error_keyid">Geen sleutel-ID. Dit is een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_mf_error_integrity">Interne fout, integriteitscheck mislukt!</string>
+ <string name="msg_mf_error_master_none">Geen hoofdcertificaat gevonden om mee te werken! (Allemaal ingetrokken?)</string>
+ <string name="msg_mf_error_noexist_primary">Slechte primaire gebruikers-ID opgegeven!</string>
+ <string name="msg_mf_error_noexist_revoke">Slechte gebruikers-ID voor intrekking opgegeven!</string>
+ <string name="msg_mf_error_restricted">Geprobeerd een beperkte bewerking uit te voeren zonder wachtwoord! Dit is een programmeerfout, gelieve een verslag in te dienen!</string>
+ <string name="msg_mf_error_revoked_primary">Ingetrokken gebruikers-ID\'s kunnen niet primair zijn!</string>
+ <string name="msg_mf_error_null_expiry">Verloopdatum kan niet hetzelfde als voordien zijn bij aanmaken van een subsleutel. Dit is een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_mf_error_passphrase_master">Fatale fout bij ontcijferen van hoofdsleutel. Dit is waarschijnlijk een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_mf_error_pgp">Interne OpenPGP-fout!</string>
+ <string name="msg_mf_error_sig">Ondertekeningsuitzondering!</string>
+ <string name="msg_mf_master">Bezig met wijzigen van hoofdcertificaten</string>
+ <string name="msg_mf_notation_empty">Bezig met toevoegen van leeg notatiepakket</string>
+ <string name="msg_mf_notation_pin">Bezig met toevoegen van PIN-notatiepakket</string>
+ <string name="msg_mf_passphrase">Bezig met wijzigen van wachtwoord voor sleutelbos</string>
+ <string name="msg_mf_passphrase_key">Bezig met opnieuw versleutelen van subsleutel %s met nieuw wachtwoord</string>
+ <string name="msg_mf_passphrase_empty_retry">Instellen van nieuw wachtwoord mislukt, opnieuw proberen met leeg oud wachtwoord</string>
+ <string name="msg_mf_passphrase_fail">Wachtwoord voor subsleutel kon niet gewijzigd worden! (Heeft het een ander wachtwoord dan de andere sleutels?)</string>
+ <string name="msg_mf_primary_replace_old">Bezig met vervangen van certificaat van vorige primaire gebruikers-ID</string>
+ <string name="msg_mf_primary_new">Bezig met aanmaken van nieuw certificaat voor nieuwe primaire gebruikers-ID</string>
+ <string name="msg_mf_subkey_change">Bezig met wijzigen van subsleutel %s</string>
+ <string name="msg_mf_error_subkey_missing">Geprobeerd om bewerking uit te voeren op ontbrekende subsleutel %s!</string>
+ <string name="msg_mf_subkey_new">Bezig met toevoegen van nieuwe subsleutel of type %s</string>
+ <string name="msg_mf_subkey_new_id">Nieuwe subsleutel-ID: %s</string>
+ <string name="msg_mf_error_past_expiry">Verloopdatum kan niet in het verleden zijn!</string>
+ <string name="msg_mf_subkey_revoke">Bezig met intrekken van subsleutel %s</string>
+ <string name="msg_mf_subkey_strip">Bezig met strippen van subsleutel %s</string>
+ <string name="msg_mf_success">Sleutelbos succesvol gewijzigd</string>
+ <string name="msg_mf_uid_add">Bezig met toevoegen van gebruikers-ID %s</string>
+ <string name="msg_mf_uid_primary">Bezig met wijzigen van primaire gebruikers-ID naar %s</string>
+ <string name="msg_mf_uid_revoke">Bezig met intrekken van gebruikers-ID %s</string>
+ <string name="msg_mf_uid_error_empty">Gebruikers-ID kan niet leeg zijn!</string>
+ <string name="msg_mf_uat_error_empty">Gebruikersattribuut kan niet leeg zijn!</string>
+ <string name="msg_mf_uat_add_image">Bezig met toevoegen van gebruikersattribuut van type afbeelding</string>
+ <string name="msg_mf_uat_add_unknown">Bezig met toevoegen van gebruikersattribuut van onbekend type</string>
+ <string name="msg_mf_unlock_error">Fout bij ontgrendelen van sleutelbos!</string>
+ <string name="msg_mf_unlock">Bezig met ontgrendelen van sleutelbos</string>
<!--Consolidate-->
+ <string name="msg_con">Bezig met consolideren van database</string>
+ <string name="msg_con_error_bad_state">Consolidatie gestart terwijl er geen database was gecached! Dit is waarschijnlijk een bug, gelieve een verslag in te dienen!</string>
+ <string name="msg_con_error_concurrent">Consolidatie afgebroken, loopt al op een andere draad!</string>
+ <string name="msg_con_save_secret">Bezig met opslaan van geheime sleutelbossen</string>
+ <string name="msg_con_save_public">Bezig met opslaan van publieke sleutelbossen</string>
+ <string name="msg_con_db_clear">Bezig met wissen van database</string>
+ <string name="msg_con_success">Database succesvol geconsolideerd</string>
+ <string name="msg_con_critical_in">Begin van kritieke fase</string>
+ <string name="msg_con_critical_out">Einde van kritieke fase</string>
+ <string name="msg_con_delete_public">Bezig met verwijderen van cachebestand van publieke sleutelbos</string>
+ <string name="msg_con_delete_secret">Bezig met verwijderen van cachebestand van geheime sleutelbos</string>
+ <string name="msg_con_error_db">Fout bij openen van database!</string>
+ <string name="msg_con_error_io_public">I/O-fout bij schrijven van publieke sleutels naar cache!</string>
+ <string name="msg_con_error_io_secret">I/O-fout bij schrijven van geheime sleutels naar cache!</string>
+ <string name="msg_con_error_public">Fout bij opnieuw importeren van publieke sleutels!</string>
+ <string name="msg_con_error_secret">Fout bij opnieuw importeren van geheime sleutels!</string>
+ <string name="msg_con_recover">Bezig met hervatten van consolidatieproces</string>
+ <string name="msg_con_recursive">Recursief samenvoegen wordt overgeslaan</string>
+ <string name="msg_con_recover_unknown">Bezig met hervatten van consolidatieproces uit onbekende staat</string>
+ <plurals name="msg_con_reimport_public">
+ <item quantity="one">Bezig met opnieuw importeren van een publieke sleutel</item>
+ <item quantity="other">Bezig met opnieuw importeren van %d publieke sleutels</item>
+ </plurals>
+ <string name="msg_con_reimport_public_skip">Geen publieke sleutels om opnieuw te importeren, bewerking wordt overgeslaan…</string>
+ <plurals name="msg_con_reimport_secret">
+ <item quantity="one">Bezig met opnieuw importeren van een geheime sleutel</item>
+ <item quantity="other">Bezig met opnieuw importeren van %d geheime sleutels</item>
+ </plurals>
+ <string name="msg_con_reimport_secret_skip">Geen geheime sleutel om opnieuw te importeren, bewerking wordt overgeslaan…</string>
+ <string name="msg_con_warn_delete_public">Uitzondering bij verwijderen van publiek cachebestand</string>
+ <string name="msg_con_warn_delete_secret">Uitzondering bij verwijderen van geheim cachebestand</string>
+ <!--Edit Key (higher level than modify)-->
+ <string name="msg_ed">Bezig met uitvoeren van sleutelbewerking</string>
+ <string name="msg_ed_caching_new">Bezig met cachen van nieuw wachtwoord</string>
+ <string name="msg_ed_error_no_parcel">SaveKeyringParcel ontbreekt! (dit is een bug, gelieve een verslag in te dienen)</string>
+ <string name="msg_ed_error_key_not_found">Sleutel niet gevonden!</string>
+ <string name="msg_ed_fetching">Bezig met ophalen van de te wijzigen sleutel (%s)</string>
+ <string name="msg_ed_success">Sleutelbewerking geslaagd</string>
+ <!--Promote key-->
+ <string name="msg_pr">Bezig met promoveren van publieke sleutel naar geheime sleutel</string>
+ <string name="msg_pr_error_already_secret">Sleutel is al een geheime sleutel!</string>
+ <string name="msg_pr_error_key_not_found">Sleutel niet gevonden!</string>
+ <string name="msg_pr_fetching">Bezig met ophalen van de te wijzigen sleutel (%s)</string>
+ <string name="msg_pr_success">Sleutel succesvol gepromoveerd!</string>
<!--Other messages used in OperationLogs-->
+ <string name="msg_ek_error_divert">Bewerken van NFC-sleutels wordt (nog) niet ondersteund!</string>
+ <string name="msg_ek_error_dummy">Kan sleutelbos niet bewerken met gestripte hoofdsleutel!</string>
+ <string name="msg_ek_error_not_found">Sleutel niet gevonden!</string>
<!--Messages for DecryptVerify operation-->
+ <string name="msg_dc_askip_no_key">Gegevens niet versleuteld met bekende sleutel, bewerking wordt overgeslaan…</string>
+ <string name="msg_dc_askip_not_allowed">Gegevens niet versleuteld met toegestane sleutel, bewerking wordt overgeslaan…</string>
+ <string name="msg_dc_asym">Blok van asymmetrisch versleutelde gegevens gevonden voor sleutel %s</string>
+ <string name="msg_dc_charset">Karakterset-header gevonder: \'%s\'</string>
+ <string name="msg_dc_clear_data">Bezig met verwerken van letterlijke gegevens</string>
+ <string name="msg_dc_clear_decompress">Bezig met uitpakken van gecomprimeerde gegevens</string>
+ <string name="msg_dc_clear_meta_file">Bestandsnaam: %s</string>
+ <string name="msg_dc_clear_meta_mime">MIME-type: %s</string>
+ <string name="msg_dc_clear_meta_size">Bestandsgrootte: %s</string>
+ <string name="msg_dc_clear_meta_size_unknown">Bestandsgrootte onbekend</string>
+ <string name="msg_dc_clear_meta_time">Wijzigingstijd: %s</string>
+ <string name="msg_dc_clear_signature_bad">Ondertekeningscontrole NIET OKÉ!</string>
+ <string name="msg_dc_clear_signature_check">Bezig met verifiëren van ondertekeningsgegevens</string>
+ <string name="msg_dc_clear_signature_ok">Ondertekeningscontrole OKÉ</string>
+ <string name="msg_dc_clear_signature">Bezig met opslaan van ondertekeningsgegevens voor later</string>
+ <string name="msg_dc_clear">Bezig met verwerken van platte tekst-gegevens</string>
+ <string name="msg_dc_error_bad_passphrase">Fout bij ontcijferen van sleutel, slecht wachtwoord!</string>
+ <string name="msg_dc_error_extract_key">Onbekende fout bij ontgrendelen van sleutel!</string>
+ <string name="msg_dc_error_integrity_check">Fout bij integriteitscontrole!</string>
+ <string name="msg_dc_error_integrity_missing">Integriteitscheck ontbreekt! Dit kan gebeuren omdat de versleutelingsapplicatie verouderd is, of door een downgrade-aanval.</string>
+ <string name="msg_dc_error_invalid_siglist">Geen geldige ondertekeningsgegevens gevonden!</string>
+ <string name="msg_dc_error_io">I/O-uitzondering tegengekomen tijdens bewerking!</string>
+ <string name="msg_dc_error_no_data">Geen versleutelde gegevens gevonden!</string>
+ <string name="msg_dc_error_no_key">Geen versleutelde gegevens met bekende geheime sleutel gevonden!</string>
+ <string name="msg_dc_error_pgp_exception">OpenPGP-uitzondering tegengekomen tijdens bewerking!</string>
+ <string name="msg_dc_integrity_check_ok">Integriteitscontrole OKÉ!</string>
+ <string name="msg_dc_ok_meta_only">Enkel metadata opgevraagd, ontcijferen wordt overgeslaan</string>
+ <string name="msg_dc_ok">Oké</string>
+ <string name="msg_dc_pass_cached">Wachtwoord wordt uit cache gebruikt</string>
+ <string name="msg_dc_pending_nfc">NFC token vereist, gebruikersinput wordt gevraagd…</string>
+ <string name="msg_dc_pending_passphrase">Wachtwoord vereist, gebruikersinput wordt gevraagd…</string>
+ <string name="msg_dc_prep_streams">Bezig met voorbereiden van streams voor ontcijfering</string>
+ <string name="msg_dc">Ontcijfering wordt gestart…</string>
+ <string name="msg_dc_sym_skip">Symmetrische gegevens niet toegestaan, bewerking wordt overgeslaan…</string>
+ <string name="msg_dc_sym">Blok met symmetrisch versleutelde gegevens gevonden</string>
+ <string name="msg_dc_trail_asym">Achterlopende, asymmetrisch versleutelde gegevens tegengekomen voor sleutel %s</string>
+ <string name="msg_dc_trail_sym">Achterlopende, symmetrisch versleutelde gegevens tegengekomen</string>
+ <string name="msg_dc_trail_unknown">Achterlopende gegevens van onbekend type tegengekomen</string>
+ <string name="msg_dc_unlocking">Bezig met ontgrendelen van geheime sleutel</string>
<!--Messages for SignEncrypt operation-->
+ <string name="msg_se">Ondertekening/versleuteling wordt gestart</string>
+ <string name="msg_se_input_bytes">Bezig met verwerken van input van byte array</string>
+ <string name="msg_se_input_uri">Bezig met verwerken van input van URI</string>
+ <string name="msg_se_error_no_input">Geen input gegeven!</string>
+ <string name="msg_se_error_input_uri_not_found">Fout bij openen van URI voor lezen!</string>
+ <string name="msg_se_error_output_uri_not_found">Fout bij openen van URI voor schrijven!</string>
+ <string name="msg_se_error_too_many_inputs">Meer inputs dan outputs opgegeven! Dit is waarschijnlijk een programmeerfout, gelieve dit te melden!</string>
+ <string name="msg_se_warn_output_left">Er blijven outputs over maar geen inputs. Dit is waarschijnlijk een programmeerfout, gelieve dit te melden!</string>
+ <string name="msg_se_success">Ondertekening/versleuteling geslaagd</string>
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_pse_asymmetric">Bezig met publieke sleutels voorbereiden voor versleuteling</string>
+ <string name="msg_pse_clearsign_only">Ondertekenen van platte tekst-input wordt niet ondersteund!</string>
+ <string name="msg_pse_compressing">Bezig met voorbereiden van comprimeren</string>
+ <string name="msg_pse_encrypting">Bezig met versleutelen van gegevens</string>
+ <string name="msg_pse_error_bad_passphrase">Slecht wachtwoord!</string>
+ <string name="msg_pse_error_hash_algo">Het gevraagde hashing-algoritme wordt niet ondersteund door deze sleutel!</string>
+ <string name="msg_pse_error_io">I/O-uitzondering tegengekomen tijdens bewerking!</string>
+ <string name="msg_pse_error_key_sign">Geselecteerde sleutel kan geen gegevens ondertekenen!</string>
+ <string name="msg_pse_error_sign_key">Fout bij ophalen van ondertekeningssleutel!</string>
+ <string name="msg_pse_error_nfc">NFC-gegevensfout!</string>
+ <string name="msg_pse_error_no_passphrase">Geen wachtwoord gegeven!</string>
+ <string name="msg_pse_error_pgp">Interne OpenPGP-fout!</string>
+ <string name="msg_pse_error_sig">OpenPGP-ondertekeningsuitzondering tegengekomen!</string>
+ <string name="msg_pse_error_unlock">Onbekende fout bij ontgrendelen van sleutel!</string>
+ <string name="msg_pse_key_ok">Bezig met versleutelen voor sleutel: %s</string>
+ <string name="msg_pse_key_unknown">Ontbrekende sleutel voor versleuteling: %s</string>
+ <string name="msg_pse_key_warn">Slechte sleutel voor versleuteling: %s</string>
+ <string name="msg_pse_ok">Ondertekening/versleuteling geslaagd!</string>
+ <string name="msg_pse_pending_nfc">NFC token vereist, gebruikersinput gevraagd…</string>
+ <string name="msg_pse_pending_passphrase">Wachtwoord vereist, gebruikersinput gevraagd…</string>
+ <string name="msg_pse_signing">Bezig met ondertekenen van gegevens (zonder versleuteling)</string>
+ <string name="msg_pse_signing_cleartext">Bezig met aanmaken van platte tekst-ondertekening</string>
+ <string name="msg_pse_signing_detached">Bezig met aanmaken van vrijstaande ondertekening</string>
+ <string name="msg_pse_sigcrypting">Bezig met versleutelen van gegevens met ondertekening</string>
+ <string name="msg_pse">Ondertekening en/of versleuteling wordt gestart</string>
+ <string name="msg_pse_symmetric">Bezig met voorbereiden van symmetrische versleuteling</string>
+ <string name="msg_crt_certifying">Bezig met aanmaken van certificaten</string>
+ <string name="msg_crt_certify_all">Bezig met certificeren van alle gebruikers-ID\'s voor sleutel %s</string>
+ <plurals name="msg_crt_certify_some">
+ <item quantity="one">Bezig met certificeren van een gebruikers-ID voor sleutel %2$s</item>
+ <item quantity="other">Bezig met certificeren van %1$d gebruikers-ID\'s voor sleutel %2$s</item>
+ </plurals>
+ <string name="msg_crt_error_self">Kan self-certificaat zo niet uitgeven!</string>
+ <string name="msg_crt_error_master_not_found">Hoofdsleutel niet gevonden!</string>
+ <string name="msg_crt_error_nothing">Geen sleutels gecertificeerd!</string>
+ <string name="msg_crt_error_unlock">Fout bij ontgrendelen van hoofdsleutel!</string>
+ <string name="msg_crt_error_divert">Certificatie met NFC wordt (nog) niet ondersteund!</string>
+ <string name="msg_crt">Bezig met certificeren van sleutelbossen</string>
+ <string name="msg_crt_master_fetch">Bezig met ophalen van gecertificeerde hoofdsleutel</string>
+ <string name="msg_crt_save">Bezig met opslaan van gecertificeerde sleutel %s</string>
+ <string name="msg_crt_saving">Bezig met opslaan van sleutelbossen</string>
+ <string name="msg_crt_unlock">Bezig met ontgrendelen van hoofdsleutel</string>
+ <string name="msg_crt_success">Identiteiten succesvol gecertificeerd</string>
+ <string name="msg_crt_warn_not_found">Sleutel niet gevonden!</string>
+ <string name="msg_crt_warn_cert_failed">Aanmaken van certificaat mislukt!</string>
+ <string name="msg_crt_warn_save_failed">Opslaan mislukt!</string>
+ <string name="msg_crt_upload_success">Sleutel succesvol geüpload naar server</string>
+ <plurals name="msg_import">
+ <item quantity="one">Bezig met importeren van sleutel</item>
+ <item quantity="other">Bezig met importeren van %d sleutels</item>
+ </plurals>
+ <string name="msg_import_fetch_error_decode">Fout bij decoderen van opgehaalde sleutelbos!</string>
+ <string name="msg_import_fetch_error">Sleutel kon niet opgehaald worden! (Netwerkproblemen?)</string>
+ <string name="msg_import_fetch_keybase">Bezig met ophalen van keybase.io: %s</string>
+ <string name="msg_import_fetch_keyserver_error">Kon sleutel niet ophalen!</string>
+ <string name="msg_import_fetch_keyserver">Bezig met ophalen van sleutelserver: %s</string>
+ <string name="msg_import_fetch_keyserver_ok">Ophalen van sleutel geslaagd!</string>
+ <string name="msg_import_keyserver">Sleutelserver %s wordt gebruikt</string>
+ <string name="msg_import_fingerprint_error">Vingerafdruk van opgehaalde sleutel komt niet overeen met verwachte vingerafdruk!</string>
+ <string name="msg_import_fingerprint_ok">Vingerafdrukcontrole OKÉ</string>
+ <string name="msg_import_merge">Bezig met samenvoegen van opgehaalde gegevens</string>
+ <string name="msg_import_error">Importeren mislukt!</string>
+ <string name="msg_import_error_io">Importeren mislukt door i/o-fout!</string>
+ <string name="msg_import_partial">Importeren geslaagd, met fouten!</string>
+ <string name="msg_import_success">Importeren geslaagd!</string>
+ <plurals name="msg_export">
+ <item quantity="one">Bezig met exporteren van een sleutel</item>
+ <item quantity="other">Bezig met exporteren van %d sleutels</item>
+ </plurals>
+ <string name="msg_export_all">Bezig met exporteren van alle sleutels</string>
+ <string name="msg_export_public">Bezig met exporteren van publieke sleutel %s</string>
+ <string name="msg_export_secret">Bezig met exporteren van geheime sleutel %s</string>
+ <string name="msg_export_error_no_file">Geen bestandsnaam opgegeven!</string>
+ <string name="msg_export_error_fopen">Fout bij openen van bestand!</string>
+ <string name="msg_export_error_no_uri">Geen URI opgegeven!</string>
+ <string name="msg_export_error_uri_open">Fout bij openen van URI stream!</string>
+ <string name="msg_export_error_storage">Opslag is niet klaar voor schrijven!</string>
+ <string name="msg_export_error_db">Databasefout!</string>
+ <string name="msg_export_error_io">Input/output-fout!</string>
+ <string name="msg_export_error_key">Fout bij voorwerken van sleutelgegevens!</string>
+ <string name="msg_export_success">Exporteren geslaagd</string>
+ <string name="msg_del_error_empty">Niets om te verwijderen!</string>
+ <string name="msg_del_error_multi_secret">Geheime sleutels kunnen enkel individueel verwijderd worden!</string>
+ <plurals name="msg_del">
+ <item quantity="one">Bezig met verwijderen van een sleutel</item>
+ <item quantity="other">Bezig met verwijderen van %d sleutels</item>
+ </plurals>
+ <string name="msg_del_key">Bezig met verwijderen van sleutel %s</string>
+ <string name="msg_del_key_fail">Verwijderen van sleutel %s mislukt</string>
+ <string name="msg_del_consolidate">Bezig met consolideren van database na verwijderen van geheime sleutel</string>
+ <plurals name="msg_del_ok">
+ <item quantity="one">Sleutel succesvol verwijderd</item>
+ <item quantity="other">%d sleutels succesvol verwijderd</item>
+ </plurals>
+ <plurals name="msg_del_fail">
+ <item quantity="one">Verwijderen van een sleutel mislukt</item>
+ <item quantity="other">Verwijderen van %d sleutels mislukt</item>
+ </plurals>
+ <string name="msg_acc_saved">Account opgeslaan</string>
+ <string name="msg_download_success">Succesvol gedownload!</string>
+ <string name="msg_download_no_valid_keys">Geen geldige sleutels gevonden in bestand/klembord!</string>
+ <string name="msg_download_no_pgp_parts">TODO: meervouden!</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">Deel van het geladen bestand is geldig OpenPGP object maar niet een OpenPGP sleutel</item>
<item quantity="other">Delen van het geladen bestand zijn geldige OpenPGP objecten maar niet OpenPGP sleutels</item>
</plurals>
+ <string name="msg_download_query_too_short">Zoekopdracht te kort. Gelieve je zoekopdracht te verfijnen!</string>
+ <string name="msg_download_too_many_responses">Zoekopdracht gaf te veel kandidaten. Gelieve je zoekopdracht te verfijnen!</string>
+ <string name="msg_download_query_too_short_or_too_many_responses">Geen of te veel sleutels werden gevonden. Gelieve je zoekopdracht te verfijnen!</string>
+ <string name="msg_download_query_failed">Er trad een fout op bij het zoeken naar sleutels.</string>
<!--PassphraseCache-->
+ <string name="passp_cache_notif_click_to_clear">Klik om de gecachete wachtwoorden te wissen</string>
+ <string name="passp_cache_notif_n_keys">OpenKeychain heeft %d wachtwoorden gecachet</string>
+ <string name="passp_cache_notif_keys">Gecachete wachtwoorden:</string>
+ <string name="passp_cache_notif_clear">Wis cache</string>
+ <string name="passp_cache_notif_pwd">Wachtwoord</string>
+ <!--First Time-->
+ <string name="first_time_text1">Neem je privacy terug met OpenKeychain!</string>
+ <string name="first_time_create_key">Maak mijn sleutel aan</string>
+ <string name="first_time_import_key">Importeren van bestand</string>
+ <string name="first_time_skip">Setup overslaan</string>
<!--unsorted-->
<string name="section_certifier_id">Certificeer</string>
<string name="section_cert">Certificaat Details</string>
<string name="label_user_id">Identiteit</string>
<string name="unknown_uid">&lt;onbekend&gt;</string>
<string name="empty_certs">Geen certificaten voor deze sleutel</string>
+ <string name="certs_text">Enkel gevalideerde self-certificaten en gevalideerde certificaten gemaakt met jouw sleutels worden hier weergegeven.</string>
+ <string name="section_uids_to_certify">Identiteiten voor</string>
+ <string name="certify_text">De sleutels die je importeert bevatten \'identiteiten\': namen en e-mailadressen. Selecteer precies die voor certificatie die overeenkomen met wat je had verwacht.</string>
<string name="label_revocation">Intrek Reden</string>
<string name="label_verify_status">Verificatie Status</string>
<string name="label_cert_type">Type</string>
<string name="error_key_not_found">Sleutel niet gevonden!</string>
<string name="error_key_processing">Fout bij verwerken sleutel!</string>
<string name="key_stripped">gestript</string>
+ <string name="key_divert">doorschakelen naar smartcard/NFC</string>
+ <string name="key_no_passphrase">geen wachtwoord</string>
+ <string name="key_unavailable">niet beschikbaar</string>
+ <string name="secret_cannot_multiple">Je eigen sleutels kunnen enkel individueel verwijderd worden!</string>
<string name="title_view_cert">Toon Certificaat Details</string>
<string name="unknown_algorithm">onbekend</string>
<string name="can_sign_not">kan niet ondertekenen</string>
<string name="error_no_encrypt_subkey">Geen codeer-subsleutel beschikbaar!</string>
- <!--First Time-->
+ <string name="info_no_manual_account_creation">Maak OpenKeychain-accounts niet handmatig aan.\nVoor meer informatie, zie Help.</string>
+ <string name="contact_show_key">Toon sleutel (%s)</string>
+ <string name="swipe_to_update">Veeg naar beneden om van sleutelserver te updaten</string>
+ <string name="error_no_file_selected">Selecteer minstens een bestand om te versleutelen!</string>
+ <string name="error_multi_not_supported">Opslaan van meerdere bestanden wordt niet ondersteund. Dit is een beperking van Android.</string>
+ <string name="key_colon">Sleutel:</string>
+ <string name="exchange_description">Selecteer om een sleuteluitwisseling te starten het aantal deelnemers aan de rechterkant, en klik vervolgens op de knop \'Start uitwisseling\'.\n\nJe zal twee vragne gesteld worden om zeker te zijn dat enkel de juiste deelnemers zich in de uitwisseling bevinden en dat hun vingerafdrukken correct zijn.</string>
+ <string name="user_id_none"><![CDATA[<none>]]></string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <string name="title_unlock_method">Kies een ontgrendelingsmethode</string>
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <string name="enter_passphrase">Voer wachtwoord in</string>
+ <string name="passphrase">Wachtwoord</string>
+ <string name="noPassphrase">Geen wachtwoord</string>
+ <string name="no_passphrase_set">Geen wachtwoord ingesteld</string>
+ <string name="passphrases_match">Wachtwoorden komen niet overeen</string>
+ <string name="passphrase_saved">Wachtwoord opgeslagen</string>
+ <string name="passphrase_invalid">Wachtwoord ongeldig</string>
+ <string name="missing_passphrase">Ontbrekend wachtwoord</string>
+ <string name="passphrase_again">Opnieuw</string>
+ <string name="lockpattern">Vergrendelingspatroon</string>
+ <string name="lockpatternNFC">NFC + vergrendelingspatroon</string>
+ <string name="unlock_method">Ontgrendelingsmethode</string>
+ <string name="set_passphrase">Wachtwoord instellen</string>
+ <string name="draw_lockpattern">Vergrendelingspatroon tekenen</string>
+ <string name="nfc_title">NFC</string>
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+ <string name="nfc_wrong_tag">Verkeerde tag. Gelieve opnieuw te proberen.</string>
+ <string name="enable_nfc">Gelieve NFC in je instellingen te activeren</string>
+ <string name="no_nfc_support">Dit toestel biedt geen ondersteuning voor NFC</string>
+ <string name="nfc_write_succesful">Succesvol geschreven op NFC-tag</string>
+ <string name="unlocked">Ontgrendeld</string>
+ <string name="nfc_settings">Instellingen</string>
</resources>
diff --git a/OpenKeychain/src/main/res/values-pl/strings.xml b/OpenKeychain/src/main/res/values-pl/strings.xml
index 8b114d5c9..bf15bfff9 100644
--- a/OpenKeychain/src/main/res/values-pl/strings.xml
+++ b/OpenKeychain/src/main/res/values-pl/strings.xml
@@ -9,13 +9,11 @@
<string name="title_encrypt_text">Szyfruj tekst</string>
<string name="title_encrypt_files">Szyfruj pliki</string>
<string name="title_decrypt">Odszyfruj</string>
- <string name="title_authentication">Hasło</string>
+ <string name="title_unlock">Klucz odblokowania</string>
<string name="title_add_subkey">Dodaj pod-klucz</string>
<string name="title_edit_key">Edytuj klucz</string>
- <string name="title_preferences">Właściwości</string>
<string name="title_cloud_search_preferences">Właściwości Szukania w Chmurze</string>
<string name="title_api_registered_apps">Aplikacje</string>
- <string name="title_key_server_preference">Właściwości serwera kluczy</string>
<string name="title_change_passphrase">Zmień hasło</string>
<string name="title_share_fingerprint_with">Podziel siÄ™ fingerprintem z...</string>
<string name="title_share_key">Podziel siÄ™ kluczem z...</string>
@@ -34,6 +32,8 @@
<string name="title_help">Pomoc</string>
<string name="title_log_display">Logi</string>
<string name="title_create_key">Utwórz klucz</string>
+ <string name="title_exchange_keys">Wymień się kluczami</string>
+ <string name="title_advanced_key_info">Zaawansowane Info Klucza</string>
<!--section-->
<string name="section_user_ids">Tożsamości</string>
<string name="section_keys">Pod-klucze</string>
@@ -52,6 +52,7 @@
<string name="section_key_to_certify">Klucz do certyfikacji</string>
<string name="section_decrypt_files">Pliki</string>
<string name="section_decrypt_text">Tekst</string>
+ <string name="section_certs">Certyfikaty</string>
<!--button-->
<string name="btn_decrypt_verify_file">Odszyfruj, weryfikuj i zapisz plik</string>
<string name="btn_decrypt_verify_message">Odszyfruj i weryfikuj wiadomość</string>
@@ -71,7 +72,6 @@
<string name="btn_create_key">Utwórz klucz</string>
<string name="btn_add_files">Dodaj plik(i)</string>
<string name="btn_add_share_decrypted_text">Podziel siÄ™ odszyfrowanym tekstem</string>
- <string name="btn_decrypt_clipboard">Odszyfruj ze schowka</string>
<string name="btn_decrypt_and_verify">oraz weryfikuj podpisy</string>
<string name="btn_decrypt_files">Odszyfruj pliki</string>
<!--menu-->
@@ -80,6 +80,7 @@
<string name="menu_export_key">Eksportuj do pliku</string>
<string name="menu_delete_key">Usuń klucz</string>
<string name="menu_create_key">Utwórz mój klucz</string>
+ <string name="menu_import_existing_key">Importuj z pliku</string>
<string name="menu_search">Szukaj</string>
<string name="menu_beam_preferences">Ustawienia Beam</string>
<string name="menu_key_edit_cancel">Anuluj</string>
@@ -102,9 +103,9 @@
<string name="label_file_ascii_armor">WÅ‚Ä…cz ASCII Armor</string>
<string name="label_write_version_header">Niech inni wiedzą, że używasz OpenKeychain</string>
<string name="label_write_version_header_summary">Napisze \'\'OpenKeychain v2.7\' do podpisów OpenPGP, ciphertekstu i wyeksportowanych kluczy</string>
- <string name="label_use_default_yubikey_pin">Użyj domyślnego Yubikey PINa</string>
- <string name="label_use_num_keypad_for_yubikey_pin">Użyj klawiatury numerycznej dla PINu Yubikey</string>
- <string name="label_label_use_default_yubikey_pin_summary">Używa domyślnego PINu (123456) do dostępu do Yubikeys przez NFC</string>
+ <string name="label_use_default_yubikey_pin">Użyj domyślnego PINu YubiKey </string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Użyj klawiatury numerycznej dla PIN\'u YubiKey</string>
+ <string name="label_label_use_default_yubikey_pin_summary">Używa domyślnego PINu (123456) do dostępu do YubiKeys przez NFC</string>
<string name="label_asymmetric_from">Podpisane przez:</string>
<string name="label_to">Szyfruj do:</string>
<string name="label_delete_after_encryption">Usuń plik po zaszyfrowaniu</string>
@@ -127,6 +128,7 @@
<string name="label_name">ImiÄ™</string>
<string name="label_comment">Komentarz</string>
<string name="label_email">Adres email</string>
+ <string name="label_send_key">Synchronizuj z chmurÄ…</string>
<string name="label_fingerprint">Odcisk</string>
<string name="expiry_date_dialog_title">Ustaw datę wygaśnięcia</string>
<string name="label_first_keyserver_is_used">(Pierwszy serwer kluczy jest preferowany)</string>
@@ -186,7 +188,8 @@
<string name="passphrase_must_not_be_empty">Podaj hasło.</string>
<string name="passphrase_for_symmetric_encryption">Szyfrowanie symetryczne.</string>
<string name="passphrase_for">Podaj hasło dla \'%s\'</string>
- <string name="yubikey_pin">Wpisz PIN, aby otworzyć Yubikey dla \'%s\'</string>
+ <string name="pin_for">Wpisz PIN dla \'%s\'</string>
+ <string name="nfc_text">Trzymaj YubiKey z tyłu Twojego urządzenia.</string>
<string name="file_delete_confirmation">Czy jesteś pewny, że chcesz usunąć\n%s?</string>
<string name="file_delete_successful">Usunięto pomyślnie.</string>
<string name="no_file_selected">Najpierw wskaż plik.</string>
@@ -255,6 +258,7 @@
<string name="decrypt_result_not_encrypted">Nie szyfrowane</string>
<string name="decrypt_result_action_show">Pokaż</string>
<string name="decrypt_result_action_Lookup">Sprawdź</string>
+ <string name="decrypt_invalid_button">Rozumiem ryzko, pokaż!</string>
<!--Add keys-->
<string name="add_keys_my_key">Mój klucz:</string>
<!--progress dialogs, usually ending in '…'-->
@@ -347,8 +351,8 @@
<string name="import_import">Zaimportuj wybrane klucze</string>
<string name="import_qr_code_wrong">Kod QR zniekształcony! Spróbuj jeszcze raz!</string>
<string name="import_qr_code_too_short_fingerprint">Odcisk klucza jest za krótki (&lt; 16 znaków)</string>
+ <string name="import_qr_code_button">Skanuj kod QR</string>
<!--Generic result toast-->
- <string name="view_log">Pokaż logi</string>
<string name="with_warnings">, z ostrzeżeniami</string>
<string name="with_cancelled">, aż anulowano</string>
<!--Import result toast-->
@@ -445,7 +449,6 @@
<string name="api_settings_delete_account">Usuń konto</string>
<string name="api_settings_package_name">Nazwa paczki</string>
<string name="api_settings_package_signature">Skrót SHA-256 podpisu paczki</string>
- <string name="api_settings_accounts">Konta</string>
<string name="api_settings_settings">Ustawienia</string>
<string name="api_settings_key">Klucz konta:</string>
<string name="api_settings_accounts_empty">Brak kont połączonych z tą aplikacją.</string>
@@ -471,6 +474,7 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw
<item quantity="few">%d kluczy wybranych.</item>
<item quantity="other">%d kluczy wybranych.</item>
</plurals>
+ <string name="key_list_empty_text1">Nie znaleziono kluczy!</string>
<string name="key_list_filter_show_all">Pokaż wszystkie klucze</string>
<string name="key_list_filter_show_certified">Pokaż tylko certyfikowane klucze</string>
<!--Key view-->
@@ -533,9 +537,6 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw
<string name="view_key_expired">Ten klucz stracił swoją ważność!</string>
<!--Navigation Drawer-->
<string name="nav_keys">Klucze</string>
- <string name="nav_encrypt_text">Szyfruj tekst</string>
- <string name="nav_encrypt_files">Szyfruj pliki</string>
- <string name="nav_decrypt">Odszyfruj</string>
<string name="nav_apps">Aplikacje</string>
<string name="drawer_open">Otwórz panel nawigacji</string>
<string name="drawer_close">Zamknij panel nawigacji</string>
@@ -571,10 +572,7 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw
<!--Keyring merging log entries-->
<!--createSecretKeyRing-->
<string name="msg_cr">Generowanie nowego master klucza</string>
- <string name="msg_cr_error_internal_pgp">Wewnętrzny błąd PGP!</string>
<!--modifySecretKeyRing-->
- <string name="msg_mf_error_pgp">Wewnętrzny błąd PGP!</string>
- <string name="msg_mf_passphrase">Zmienianie hasła dla pęku kluczy...</string>
<string name="msg_mf_error_past_expiry">Data ważności nie może być przeszła!</string>
<string name="msg_mf_subkey_revoke">Unieważnianie pod-klucza %s</string>
<string name="msg_mf_uid_error_empty">ID użytkownika nie może być pusty!</string>
@@ -583,6 +581,8 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw
<string name="msg_con_save_secret">Zapisywanie prywatnych pęków kluczy</string>
<string name="msg_con_save_public">Zapisywanie publicznych pęków kluczy</string>
<string name="msg_con_db_clear">Czyszczenie bazy danych</string>
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_not_found">Nie znaleziono klucza!</string>
<!--Messages for DecryptVerify operation-->
@@ -600,17 +600,7 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw
<string name="msg_dc_pending_passphrase">Hasło wymagane, wymagana reakcja użytkownika...</string>
<string name="msg_dc">Rozpoczynanie operacji odszyfrowania...</string>
<!--Messages for SignEncrypt operation-->
- <string name="msg_se_encrypting">Szyfrowanie danych</string>
- <string name="msg_se_error_bad_passphrase">Nieprawidłowe hasło!</string>
- <string name="msg_se_error_no_passphrase">Nie wprowadzono hasła!</string>
- <string name="msg_se_key_ok">Szyfrowanie dla klucza: %s</string>
- <string name="msg_se_key_unknown">BrakujÄ…cy klucz do szyfrowania: %s</string>
- <string name="msg_se_key_warn">ZÅ‚y klucz do szyfrowania: %s</string>
- <string name="msg_se_ok">Operacja Podpisania/Szyfrowania zakończona pomyślnie!</string>
- <string name="msg_se_pending_nfc">Token NFC jest wymagany, wymagana reakcja użytkownika...</string>
- <string name="msg_se_pending_passphrase">Hasło wymagane, wymagana reakcja użytkownika...</string>
- <string name="msg_se_signing">Podpisywanie danych (bez podpisu)</string>
- <string name="msg_se_sigcrypting">Szyfrowanie danych z podpisem</string>
+ <!--Messages for PgpSignEncrypt operation-->
<string name="msg_crt_saving">Zapisywanie pęków kluczy</string>
<string name="msg_crt_unlock">Odblokowanie master klucza</string>
<string name="msg_crt_success">Pomyślnie certyfikowane tożsamości</string>
@@ -659,12 +649,17 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw
<string name="passp_cache_notif_keys">Zapamiętane hasła:</string>
<string name="passp_cache_notif_clear">Wyczyść pamięć cache</string>
<string name="passp_cache_notif_pwd">Hasło</string>
+ <!--First Time-->
+ <string name="first_time_text1">Weź prywatność w swoje ręce używając OpenKeychain!</string>
+ <string name="first_time_create_key">Utwórz mój klucz</string>
+ <string name="first_time_skip">Pomiń ustawienia</string>
<!--unsorted-->
<string name="section_certifier_id">CertyfikujÄ…cy</string>
<string name="section_cert">Szczegóły certyfikatu</string>
<string name="label_user_id">Tożsamość</string>
<string name="unknown_uid">&lt;nieznany&gt;</string>
<string name="empty_certs">Nie ma certyfikatów dla tego klucza</string>
+ <string name="section_uids_to_certify">Tożsamości dla</string>
<string name="label_revocation">Powód odwołania</string>
<string name="label_verify_status">Stan weryfikacji</string>
<string name="label_cert_type">Typ</string>
@@ -682,8 +677,8 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw
<string name="swipe_to_update">Pociągnij w dół, aby aktualizować z serwera kluczy</string>
<string name="error_no_file_selected">Wybierz przynajmniej jeden plik, aby szyfrować!</string>
<string name="key_colon">Klucz:</string>
- <!--First Time-->
- <string name="first_time_text1">Weź prywatność w swoje ręce używając OpenKeychain!</string>
- <string name="first_time_create_key">Utwórz mój klucz</string>
- <string name="first_time_skip">Pomiń ustawienia</string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-pt/strings.xml b/OpenKeychain/src/main/res/values-pt/strings.xml
index 460c5462e..ef0a0ce94 100644
--- a/OpenKeychain/src/main/res/values-pt/strings.xml
+++ b/OpenKeychain/src/main/res/values-pt/strings.xml
@@ -50,10 +50,17 @@
<!--createSecretKeyRing-->
<!--modifySecretKeyRing-->
<!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<!--Messages for DecryptVerify operation-->
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<!--PassphraseCache-->
- <!--unsorted-->
<!--First Time-->
+ <!--unsorted-->
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-ro/strings.xml b/OpenKeychain/src/main/res/values-ro/strings.xml
new file mode 100644
index 000000000..ef0a0ce94
--- /dev/null
+++ b/OpenKeychain/src/main/res/values-ro/strings.xml
@@ -0,0 +1,66 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+ <!--GENERAL: Please put all strings inside quotes as described in example 1 on
+ http://developer.android.com/guide/topics/resources/string-resource.html (scroll down to "Escaping apostrophes and quotes").-->
+ <!--title-->
+ <!--section-->
+ <!--button-->
+ <!--menu-->
+ <!--label-->
+ <!--choice-->
+ <!--key flags-->
+ <!--sentences-->
+ <!--errors
+ no punctuation, all lowercase,
+ they will be put after "error_message", e.g. "Error: file not found"-->
+ <!--errors without preceeding Error:-->
+ <!--results shown after decryption/verification-->
+ <!--Add keys-->
+ <!--progress dialogs, usually ending in '…'-->
+ <!--action strings-->
+ <!--key bit length selections-->
+ <!--elliptic curve names-->
+ <!--not in for now, see SaveKeyringParcel
+ <string name="key_curve_bp_p256">"Brainpool P-256"</string>
+ <string name="key_curve_bp_p384">"Brainpool P-384"</string>
+ <string name="key_curve_bp_p512">"Brainpool P-512"</string>-->
+ <!--compression-->
+ <!--Help-->
+ <!--Import-->
+ <!--Generic result toast-->
+ <!--Import result toast-->
+ <!--Delete result toast-->
+ <!--Certify result toast-->
+ <!--Intent labels-->
+ <!--Remote API-->
+ <!--Share-->
+ <!--Key list-->
+ <!--Key view-->
+ <!--Edit key-->
+ <!--Create key-->
+ <!--View key-->
+ <!--Navigation Drawer-->
+ <!--hints-->
+ <!--certs-->
+ <!--LogType log messages. Errors should have _ERROR_ in their name and end with a !-->
+ <!--Import Public log entries-->
+ <!--Import Secret log entries-->
+ <!--Keyring Canonicalization log entries-->
+ <!--Keyring merging log entries-->
+ <!--createSecretKeyRing-->
+ <!--modifySecretKeyRing-->
+ <!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
+ <!--Other messages used in OperationLogs-->
+ <!--Messages for DecryptVerify operation-->
+ <!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
+ <!--PassphraseCache-->
+ <!--First Time-->
+ <!--unsorted-->
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+</resources>
diff --git a/OpenKeychain/src/main/res/values-ru/strings.xml b/OpenKeychain/src/main/res/values-ru/strings.xml
index a41953a12..ec862020a 100644
--- a/OpenKeychain/src/main/res/values-ru/strings.xml
+++ b/OpenKeychain/src/main/res/values-ru/strings.xml
@@ -5,13 +5,16 @@
<!--title-->
<string name="title_select_recipients">Выберите ключи</string>
<string name="title_select_secret_key">Выберите Ваш ключ</string>
+ <string name="title_encrypt_text">Зашифровать текÑÑ‚</string>
+ <string name="title_encrypt_files">Зашифровать файлы</string>
<string name="title_decrypt">РаÑшифровать</string>
- <string name="title_authentication">Пароль</string>
+ <string name="title_unlock">Разблокировать ключ</string>
<string name="title_add_subkey">Добавить доп. ключ</string>
<string name="title_edit_key">Изменить ключ</string>
<string name="title_preferences">ÐаÑтройки</string>
+ <string name="title_cloud_search_preferences">ÐаÑтройки облачного поиÑка</string>
<string name="title_api_registered_apps">ПриложениÑ</string>
- <string name="title_key_server_preference">ÐаÑтройки Ñервера ключей</string>
+ <string name="title_key_server_preference">Серверы ключей</string>
<string name="title_change_passphrase">Изменить пароль</string>
<string name="title_share_fingerprint_with">Отправить отпечаток...</string>
<string name="title_share_key">Отправить ключ...</string>
@@ -20,6 +23,7 @@
<string name="title_encrypt_to_file">Зашифровать в файл</string>
<string name="title_decrypt_to_file">РаÑшифровать в файл</string>
<string name="title_import_keys">Импорт ключей</string>
+ <string name="title_add_keys">Добавить ключи</string>
<string name="title_export_key">ЭкÑпортировать ключ</string>
<string name="title_export_keys">ЭкÑпорт ключей</string>
<string name="title_key_not_found">Ключ не найден</string>
@@ -29,17 +33,30 @@
<string name="title_help">Помощь</string>
<string name="title_log_display">Журнал</string>
<string name="title_create_key">Создать ключ</string>
+ <string name="title_exchange_keys">Обмен ключами</string>
+ <string name="title_advanced_key_info">Ð”ÐµÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ ключе</string>
+ <string name="title_keys">Ключи</string>
<!--section-->
<string name="section_user_ids">Идентификаторы</string>
<string name="section_keys">Доп. ключи</string>
+ <string name="section_cloud_search">Облачный поиÑк</string>
<string name="section_general">Приложение</string>
<string name="section_defaults">Ðлгоритмы</string>
<string name="section_advanced">Дополнительно</string>
+ <string name="section_passphrase_cache">КÑш паролÑ</string>
+ <string name="section_certify">УдоÑтоверить</string>
<string name="section_actions">ДейÑтвиÑ</string>
+ <string name="section_share_key">Ключ</string>
<string name="section_certification_key">Ваш ключ Ð´Ð»Ñ Ñертификации</string>
+ <string name="section_upload_key">Синхронизировать ключ</string>
<string name="section_key_server">Сервер ключей</string>
<string name="section_fingerprint">Отпечаток ключа</string>
<string name="section_key_to_certify">Сертифицируемый ключ</string>
+ <string name="section_decrypt_files">Файлы</string>
+ <string name="section_decrypt_text">ТекÑÑ‚</string>
+ <string name="section_certs">Сертификаты</string>
+ <string name="section_encrypt">Зашифровать</string>
+ <string name="section_decrypt">РаÑшифровать</string>
<!--button-->
<string name="btn_decrypt_verify_file">РаÑшифровать, проверить и Ñохранить файл</string>
<string name="btn_decrypt_verify_message">РаÑшифровать и проверить Ñообщение</string>
@@ -58,18 +75,26 @@
<string name="btn_view_cert_key">ПроÑмотр ключа</string>
<string name="btn_create_key">Создать ключ</string>
<string name="btn_add_files">Добавить файл(ы)</string>
+ <string name="btn_add_share_decrypted_text">ПоделитьÑÑ Ñ€Ð°Ñшифрованным текÑтом</string>
+ <string name="btn_decrypt_clipboard">РаÑшифровать текÑÑ‚ из буфера обмена</string>
+ <string name="btn_decrypt_and_verify">и проверить подпиÑи</string>
+ <string name="btn_decrypt_files">РаÑшифровать файлы</string>
+ <string name="btn_encrypt_files">Зашифровать файлы</string>
+ <string name="btn_encrypt_text">Зашифровать текÑÑ‚</string>
<!--menu-->
<string name="menu_preferences">ÐаÑтройки</string>
<string name="menu_help">Помощь</string>
<string name="menu_export_key">ЭкÑпорт в файл</string>
<string name="menu_delete_key">Удалить ключ</string>
<string name="menu_create_key">Создать Ñвой ключ</string>
+ <string name="menu_import_existing_key">Импорт из файла</string>
<string name="menu_search">ПоиÑк</string>
<string name="menu_beam_preferences">ÐаÑтройки Beam</string>
<string name="menu_key_edit_cancel">Отмена</string>
<string name="menu_encrypt_to">Зашифровать....</string>
<string name="menu_select_all">Выбрать вÑе</string>
<string name="menu_add_keys">Добавить ключи</string>
+ <string name="menu_search_cloud">ПоиÑк в облаке</string>
<string name="menu_export_all_keys">ЭкÑпорт вÑех ключей</string>
<string name="menu_advanced">Подробные данные</string>
<!--label-->
@@ -79,11 +104,27 @@
<string name="label_file_colon">Файл:</string>
<string name="label_no_passphrase">Без паролÑ</string>
<string name="label_passphrase">Пароль</string>
+ <string name="label_unlock">Идет разблокировка...</string>
<string name="label_passphrase_again">Повторите пароль</string>
<string name="label_algorithm">Ðлгоритм</string>
<string name="label_ascii_armor">ASCII формат</string>
+ <string name="label_file_ascii_armor">ИÑпользовать ASCII формат</string>
<string name="label_write_version_header">Добавить комментарий об иÑпользовании OpenKeychain</string>
<string name="label_write_version_header_summary">ДопиÑывать \'OpenKeychain v2.x\' в OpenPGP подпиÑи, шифры, и ÑкÑпортируемые ключи</string>
+ <string name="label_use_default_yubikey_pin">ИÑпользовать YubiKey PIN по умолчанию</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">ИÑпользовать цифровую клавиатуру Ð´Ð»Ñ YubiKey PIN</string>
+ <string name="label_label_use_default_yubikey_pin_summary">ИÑпользовать PIN по умолчанию (123456) Ð´Ð»Ñ Ð´Ð¾Ñтупа к YubiKeys через NFC</string>
+ <string name="label_asymmetric_from">ПодпиÑано:</string>
+ <string name="label_to">Зашифровать длÑ:</string>
+ <string name="label_delete_after_encryption">Удалить файл поÑле шифрованиÑ</string>
+ <string name="label_delete_after_decryption">Удалить поÑле шифрованиÑ</string>
+ <string name="label_encryption_algorithm">Ðлгоритм шифрованиÑ</string>
+ <string name="label_hash_algorithm">ХЭШ-алгоритм</string>
+ <string name="label_symmetric">Зашифровать паролем</string>
+ <string name="label_passphrase_cache_ttl">Ð’Ñ€ÐµÐ¼Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð² кÑше</string>
+ <string name="label_passphrase_cache_subs">КÑшировать пароли по доп. ключу</string>
+ <string name="label_message_compression">Сжимать Ñообщение</string>
+ <string name="label_file_compression">Сжатие файла</string>
<string name="label_keyservers">Серверы ключей</string>
<string name="label_key_id">ID ключа</string>
<string name="label_creation">Создан</string>
@@ -95,8 +136,11 @@
<string name="label_name">ИмÑ</string>
<string name="label_comment">Комментарий</string>
<string name="label_email">Email</string>
+ <string name="label_send_key">Синхронизировать Ñ Ð¾Ð±Ð»Ð°ÐºÐ¾Ð¼</string>
<string name="label_fingerprint">Отпечаток</string>
<string name="expiry_date_dialog_title">Срок годноÑти</string>
+ <string name="label_first_keyserver_is_used">(ПредпочеÑÑ‚ÑŒ первый Ñервер ключей)</string>
+ <string name="label_preferred">предпочитаемый</string>
<string name="user_id_no_name">&lt;нет имени&gt;</string>
<string name="none">&lt;нет&gt;</string>
<string name="no_key">&lt;нет ключа&gt;</string>
@@ -153,6 +197,12 @@
<string name="passphrase_for_symmetric_encryption">Симметричное шифрование.</string>
<string name="passphrase_for">Введите пароль длÑ
\'%s\'</string>
+ <string name="pin_for">Введите PIN длÑ
+\'%s\'</string>
+ <string name="yubikey_pin_for">Введите PIN Ð´Ð»Ñ Ð´Ð¾Ñтупа к YubiKey длÑ
+\'%s\'</string>
+ <string name="nfc_text">Держите YubiKey возле задней чаÑти вашего уÑтройÑтва.</string>
+ <string name="file_delete_confirmation">Вы уверены, что хотите удалить\n%s?</string>
<string name="file_delete_successful">Удалено.</string>
<string name="no_file_selected">Сначала выберите файл.</string>
<string name="encrypt_sign_successful">УÑпешно подпиÑано и/или зашифровано.</string>
@@ -160,7 +210,14 @@
<string name="enter_passphrase_twice">Дважды введите пароль.</string>
<string name="select_encryption_key">Укажите Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один ключ.</string>
<string name="select_encryption_or_signature_key">Выберите Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один ключ Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ подпиÑи.</string>
+ <string name="specify_file_to_encrypt_to">ПожалуйÑта, выберите файл Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ.\nÐ’ÐИМÐÐИЕ! Файл будет перезапиÑан еÑли он уже ÑущеÑтвует.</string>
+ <string name="specify_file_to_decrypt_to">ПожалуйÑта, выберите файл Ð´Ð»Ñ Ñ€Ð°Ñшифровки.\nÐ’ÐИМÐÐИЕ! Файл будет перезапиÑан еÑли он уже ÑущеÑтвует.</string>
+ <string name="specify_file_to_export_to">ПожалуйÑта, выберите файл Ð´Ð»Ñ ÑкÑпорта.\nÐ’ÐИМÐÐИЕ! Файл будет перезапиÑан еÑли он уже ÑущеÑтвует.</string>
+ <string name="key_deletion_confirmation_multi">Ð’Ñ‹ уверены, что хотите удалить ВСЕ выбранные Публичные ключи?\nЭто дейÑтвие Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!</string>
+ <string name="secret_key_deletion_confirmation">Ð’Ñ‹ уверены, что хотите удалить СЕКРЕТÐЫЙ ключ \'%s\'?\nЭто дейÑтвие Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!</string>
+ <string name="public_key_deletetion_confirmation">Ð’Ñ‹ правда хотите удалить публичный ключ \'%s\'?\nЭто дейÑтвие Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!</string>
<string name="also_export_secret_keys">ЭкÑпортировать Ñекретные ключи</string>
+ <string name="reinstall_openkeychain">Ð’Ñ‹ ÑтолкнулиÑÑŒ Ñ Ð±Ð°Ð³Ð¾Ð¼ Ðндроид. ПожалуйÑта, переуÑтановите OpenKeychain чтобы ÑвÑзать ваши контакты и ключи. </string>
<string name="key_exported">УÑпешный ÑкÑпорт 1 ключа.</string>
<string name="keys_exported">ЭкÑпортировано %d ключей.</string>
<string name="no_keys_exported">Ключи не были ÑкÑпортированы.</string>
@@ -172,6 +229,7 @@
<string name="fingerprint_copied_to_clipboard">Отпечаток ключа Ñкопирован в буфер обмена!</string>
<string name="select_key_to_certify">Выберите ключ, иÑпользуемый Ð´Ð»Ñ Ñертификации!</string>
<string name="key_too_big_for_sharing">Ключ Ñлишком большой Ð´Ð»Ñ Ñтого ÑпоÑоба передачи!</string>
+ <string name="text_copied_to_clipboard">ТеÑÑ‚ Ñкопирован в буфер обмена!</string>
<!--errors
no punctuation, all lowercase,
they will be put after "error_message", e.g. "Error: file not found"-->
@@ -185,6 +243,7 @@
<string name="error_key_needs_a_user_id">необходим Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один идентификатор</string>
<string name="error_no_signature_passphrase">пароль не задан</string>
<string name="error_no_signature_key">ключ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи не задан</string>
+ <string name="error_invalid_data">Зашифрованные или подпиÑанные данные OpenPGP не найдены!</string>
<string name="error_integrity_check_failed">Проверка целоÑтноÑти не удалаÑÑŒ! Данные изменилиÑÑŒ!</string>
<string name="error_wrong_passphrase">неправильный пароль</string>
<string name="error_could_not_extract_private_key">не удалоÑÑŒ извлечь личный ключ</string>
@@ -192,13 +251,28 @@
<string name="error_jelly_bean_needed">Ð”Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ NFC Beam требуетÑÑ Android 4.1+ !</string>
<string name="error_nfc_needed">Ваше уÑтройÑтво не поддерживает NFC!</string>
<string name="error_nothing_import">Ключи не найдены!</string>
+ <string name="error_contacts_key_id_missing">Ошибка Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð° ключа из контактов!</string>
<string name="error_generic_report_bug">Ð’Ñ‹Ñвлена ошибка. ПожалуйÑта, Ñообщите о ней разработчику.</string>
<!--results shown after decryption/verification-->
+ <string name="decrypt_result_no_signature">Ðе подпиÑано</string>
<string name="decrypt_result_invalid_signature">ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ!</string>
+ <string name="decrypt_result_signature_uncertified">ПодпиÑано (не удоÑтоверено!)</string>
+ <string name="decrypt_result_signature_certified">ПодпиÑано:</string>
+ <string name="decrypt_result_signature_expired_key">Срок годноÑти ключа иÑтёк!</string>
+ <string name="decrypt_result_signature_revoked_key">Ключ аннулирован!</string>
+ <string name="decrypt_result_signature_missing_key">ÐеизвеÑтный открытый ключ</string>
+ <string name="decrypt_result_encrypted">Зашифровано</string>
+ <string name="decrypt_result_not_encrypted">Ðе зашифровано</string>
+ <string name="decrypt_result_action_show">Показать</string>
+ <string name="decrypt_result_action_Lookup">ИÑкать</string>
+ <string name="decrypt_invalid_text">ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ или ключ был отозван или проÑрочен. ÐвторÑтво текÑта невозможно проверить. Показать текÑÑ‚?</string>
+ <string name="decrypt_invalid_button">Мне понÑтны вÑе риÑки, показать!</string>
<!--Add keys-->
+ <string name="add_keys_my_key">Мой ключ:</string>
<!--progress dialogs, usually ending in '…'-->
<string name="progress_done">Готово.</string>
<string name="progress_cancel">Отмена</string>
+ <string name="progress_cancelling">отмена...</string>
<string name="progress_saving">Ñохранение...</string>
<string name="progress_importing">импорт...</string>
<string name="progress_exporting">ÑкÑпорт...</string>
@@ -213,10 +287,12 @@
<string name="progress_modify">изменение ÑвÑзки ключей...</string>
<string name="progress_modify_unlock">разблокирование ÑвÑзки...</string>
<string name="progress_modify_adduid">добавление идентификатора...</string>
+ <string name="progress_modify_adduat">добавление аттрибутов пользователÑ...</string>
<string name="progress_modify_revokeuid">аннулирование идентификатора...</string>
<string name="progress_modify_primaryuid">изменение оÑновного идентификатора...</string>
<string name="progress_modify_subkeychange">изменение доп. ключей...</string>
<string name="progress_modify_subkeyrevoke">аннулирование доп. ключей...</string>
+ <string name="progress_modify_subkeystrip">отделение доп.ключей...</string>
<string name="progress_modify_subkeyadd">добавление доп. ключей...</string>
<string name="progress_modify_passphrase">изменение паролÑ...</string>
<plurals name="progress_exporting_key">
@@ -241,8 +317,11 @@
<string name="progress_verifying_integrity">проверка целоÑтноÑти...</string>
<string name="progress_deleting_securely">безопаÑное удаление \'%s\'...</string>
<string name="progress_deleting">удаление ключей...</string>
+ <string name="progress_con_saving">объединение: Ñохранение в кÑш...</string>
+ <string name="progress_con_reimport">объединение: реимпорт...</string>
<!--action strings-->
<string name="hint_keyserver_search_hint">ИмÑ/Email/ID ключа…</string>
+ <string name="hint_cloud_search_hint">ИмÑ/Email/Проверка/Ключ...</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@@ -277,13 +356,18 @@
<string name="help_about_version">ВерÑиÑ:</string>
<!--Import-->
<string name="import_tab_keyserver">Сервер ключей</string>
+ <string name="import_tab_cloud">ПоиÑк в облаке</string>
<string name="import_tab_direct">Файл/Буфер</string>
<string name="import_tab_qr_code">QR код/NFC</string>
<string name="import_import">Импорт выбранных ключей</string>
<string name="import_qr_code_wrong">Ðекорректный QR код. Попробуйте Ñнова!</string>
<string name="import_qr_code_too_short_fingerprint">Отпечаток Ñлишком коротнкий (&lt; 16 Ñимволов)</string>
+ <string name="import_qr_code_button">Сканировать QR код...</string>
+ <string name="import_qr_code_text">РаÑположите вашу камеру над QR кодом!</string>
<!--Generic result toast-->
- <string name="view_log">Смотреть журнал</string>
+ <string name="view_log">СведениÑ</string>
+ <string name="with_warnings">, Ñ Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñми</string>
+ <string name="with_cancelled">, до отмены</string>
<!--Import result toast-->
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Ключ уÑпешно импортирован</item>
@@ -291,7 +375,10 @@
<item quantity="other">УÑпешно добавлено %1$d ключей</item>
</plurals>
<string name="import_error_nothing">Ðет данных Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð°.</string>
+ <string name="import_error_nothing_cancelled">Импорт отменен.</string>
<!--Delete result toast-->
+ <string name="delete_nothing">Ðет данных Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ!</string>
+ <string name="delete_cancelled">Удаление отменено.</string>
<!--Certify result toast-->
<!--Intent labels-->
<string name="intent_decrypt_file">OpenKeychain: РаÑшифровать файл</string>
@@ -299,6 +386,7 @@
<string name="intent_send_encrypt">OpenKeychain: Зашифровать</string>
<string name="intent_send_decrypt">OpenKeychain: РаÑшифровать</string>
<!--Remote API-->
+ <string name="api_no_apps">Ðет ÑвÑзанных приложений!\n\nСпиÑок приложений, поддерживающих интеграцию, доÑтупен в разделе \'Помощь\'!</string>
<string name="api_settings_show_info">Показать подробную информацию</string>
<string name="api_settings_hide_info">Скрыть подробную информацию</string>
<string name="api_settings_show_advanced">Показать раÑширенные наÑтройки</string>
@@ -307,18 +395,29 @@
<string name="api_settings_select_key">Выбрать ключ</string>
<string name="api_settings_create_key">Создать новый ключ Ð´Ð»Ñ Ñтого аккаунта</string>
<string name="api_settings_save">Сохранить</string>
+ <string name="api_settings_save_msg">Ðккаунт Ñохранен</string>
<string name="api_settings_cancel">Отмена</string>
<string name="api_settings_revoke">Отозвать доÑтуп</string>
<string name="api_settings_start">ЗапуÑтить приложение</string>
<string name="api_settings_delete_account">Удалить аккаунт</string>
<string name="api_settings_package_name">Ðаименование пакета</string>
<string name="api_settings_package_signature">SHA-256 подпиÑи пакета</string>
- <string name="api_settings_accounts">Ðккаунты</string>
+ <string name="api_settings_accounts">Ðккаунты (уÑтаревший API)</string>
+ <string name="api_settings_advanced">ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ</string>
+ <string name="api_settings_allowed_keys">Разрешённые ключи</string>
+ <string name="api_settings_settings">ÐаÑтройки</string>
+ <string name="api_settings_key">Ключ аккаунта:</string>
<string name="api_settings_accounts_empty">Ðет аккаунтов, ÑвÑзанных Ñ Ñтим приложением.</string>
+ <string name="api_create_account_text">ОтÑутÑтвует ключ наÑтроенный Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ аккаунта. Выберите имеющийÑÑ ÐºÐ»ÑŽÑ‡ или Ñоздайте новый.\nÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ раÑшифровывать/подпиÑывать только при помощи выбранных здеÑÑŒ ключей!</string>
+ <string name="api_update_account_text">Ключ, Ñохранённый Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ аккаунта, был удалён. ПожалуйÑта, выберите другой!\nÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ раÑшифровывать/подпиÑывать только при помощи выбранных здеÑÑŒ ключей!</string>
+ <string name="api_register_text">Отображаемое приложение ÑобираетÑÑ Ð·Ð°ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ/раÑшифровать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ подпиÑать их Вашим именем.\nРазрешить доÑтуп?\n\nÐ’ÐИМÐÐИЕ: ЕÑли вы не знаете почему возник Ñтот запроÑ, откажите в доÑтупе! Позже вы можете отозвать право доÑтупа в разделе \"Программы\"</string>
<string name="api_register_allow">Разрешить доÑтуп</string>
<string name="api_register_disallow">Запретить доÑтуп</string>
<string name="api_register_error_select_key">ПожалуйÑта, выберите ключ!</string>
+ <string name="api_select_pub_keys_missing_text">Ð”Ð»Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… лиц ключи не найдены:</string>
+ <string name="api_select_pub_keys_dublicates_text">Ð”Ð»Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… лиц имеетÑÑ Ð±Ð¾Ð»ÐµÐµ одного ключа: </string>
<string name="api_select_pub_keys_text">ПожалуйÑта, проверьте получателей!</string>
+ <string name="api_select_pub_keys_text_no_user_ids">ПожалуйÑта, выберите получателей!</string>
<string name="api_error_wrong_signature">Проверка подпиÑи пакета не удалаÑÑŒ! ЕÑли вы уÑтановили программу из другого иÑточника, отзовите Ð´Ð»Ñ Ð½ÐµÑ‘ доÑтуп к Ñтой программе или обновите право доÑтупа.</string>
<!--Share-->
<string name="share_qr_code_dialog_title">Отправить как QR код</string>
@@ -329,15 +428,28 @@
<item quantity="few">%d ключей выбрано.</item>
<item quantity="other">%d ключей выбрано.</item>
</plurals>
+ <string name="key_list_empty_text1">Ключи не найдены!</string>
+ <string name="key_list_filter_show_all">Показать вÑе ключи</string>
+ <string name="key_list_filter_show_certified">Показать только Ñертифицированные ключи</string>
<!--Key view-->
<string name="key_view_action_edit">Изменить ключ</string>
+ <string name="key_view_action_encrypt">Зашифровать текÑÑ‚</string>
+ <string name="key_view_action_encrypt_files">файлы</string>
<string name="key_view_action_certify">Сертифицировать</string>
+ <string name="key_view_action_update">Обновить Ñ Ñервера ключей</string>
<string name="key_view_action_share_with">Отправить...</string>
+ <string name="key_view_action_share_nfc">Отправить через NFC</string>
+ <string name="key_view_action_upload">Загрузить на Ñервер ключей</string>
<string name="key_view_tab_main">ОÑновные данные</string>
<string name="key_view_tab_share">Отправить...</string>
<string name="key_view_tab_keys">Доп. ключи</string>
<string name="key_view_tab_certs">СертификациÑ</string>
<string name="user_id_info_revoked_title">Ðннулировано</string>
+ <string name="user_id_info_revoked_text">Этот идентификатор отозван владельцем ключа. Он больше недейÑтвителен.</string>
+ <string name="user_id_info_certified_title">Сертифицировано</string>
+ <string name="user_id_info_certified_text">Этот идентификатор был Ñертифицирован Вами</string>
+ <string name="user_id_info_uncertified_title">Ðе Ñертифицирован</string>
+ <string name="user_id_info_uncertified_text">Этот идентификатор не был заверен. Ðет гарантии, что он принадлежит Ñтому человеку.</string>
<string name="user_id_info_invalid_title">ÐедейÑтвительно</string>
<string name="user_id_info_invalid_text">Что-то не так Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼!</string>
<!--Edit key-->
@@ -345,73 +457,238 @@
<string name="edit_key_action_add_identity">Добавить идентификатор</string>
<string name="edit_key_action_add_subkey">Добавить доп. ключ</string>
<string name="edit_key_edit_user_id_title">Выберите дейÑтвие!</string>
+ <string-array name="edit_key_edit_user_id">
+ <item>Изменить на оÑновной идентификатор</item>
+ <item>Отозвать идентификатор</item>
+ </string-array>
+ <string-array name="edit_key_edit_user_id_revert_revocation">
+ <item>Отменить отзыв</item>
+ </string-array>
+ <string name="edit_key_edit_user_id_revoked">Этот идентификатор был отозван. Это не может быть отменено.</string>
+ <string name="edit_key_edit_subkey_title">Выберите дейÑтвие!</string>
+ <string-array name="edit_key_edit_subkey">
+ <item>Изменить Ñрок годноÑти</item>
+ <item>Отозвать доп. ключ</item>
+ <item>Отделить доп. ключ</item>
+ </string-array>
+ <string name="edit_key_new_subkey">новый доп. ключ</string>
+ <string name="edit_key_select_flag">ПожалуйÑта, выберите Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один флаг!</string>
+ <string name="edit_key_error_add_identity">Добавьте Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один идентификатор!</string>
+ <string name="edit_key_error_add_subkey">Добавьте Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один доп. ключ!</string>
<!--Create key-->
<string name="create_key_upload">Загрузить ключ на Ñервер</string>
<string name="create_key_empty">Это обÑзательне поле</string>
<string name="create_key_passphrases_not_equal">Пароли не Ñовпадают.</string>
<string name="create_key_final_text">Ð’Ñ‹ указали Ñледующие данные:</string>
+ <string name="create_key_final_robot_text">Создание ключа займет некоторое времÑ, можете пока выпить чашечку кофе...</string>
+ <string name="create_key_rsa">(3 доп. ключа, RSA, 4096 bit)</string>
+ <string name="create_key_custom">(Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð°)</string>
<string name="create_key_text">Укажите полное имÑ, Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ñ‡Ñ‚Ñ‹ и придумайте надежный пароль.</string>
<string name="create_key_hint_full_name">Полное имÑ, напр. Иван ХлеÑтаков</string>
+ <string name="create_key_edit">Изменить конфигурацию ключа</string>
<!--View key-->
<string name="view_key_revoked">Этот ключ был аннулирован!</string>
<string name="view_key_expired">Срок годноÑти ключа иÑтёк!</string>
<!--Navigation Drawer-->
<string name="nav_keys">Ключи</string>
+ <string name="nav_encrypt_decrypt">Зашифровать/РаÑшифровать</string>
<string name="nav_apps">ПриложениÑ</string>
<string name="drawer_open">Открыть панель навигации</string>
<string name="drawer_close">Закрыть панель навигации</string>
<string name="my_keys">Мои ключи</string>
<!--hints-->
+ <string name="encrypt_content_edit_text_hint">Ðапишите текÑÑ‚</string>
<!--certs-->
<string name="cert_default">по умолчанию</string>
<string name="cert_none">нет</string>
+ <string name="cert_casual">Ñлучайный</string>
+ <string name="cert_positive">положительный</string>
<string name="cert_revoke">отозван</string>
<string name="cert_verify_ok">OK</string>
<string name="cert_verify_failed">Ñбой!</string>
<string name="cert_verify_error">ошибка!</string>
- <string name="cert_verify_unavailable">ключ не доÑтупен</string>
+ <string name="cert_verify_unavailable">ключ недоÑтупен</string>
<!--LogType log messages. Errors should have _ERROR_ in their name and end with a !-->
+ <string name="msg_internal_error">ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°!</string>
+ <string name="msg_cancelled">ДейÑтвие отменено.</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">Выполнение пакетной вÑтавки.</string>
<string name="msg_ip_bad_type_secret">Попытка импорта Ñекретной ÑвÑзки как публичной. Это ошибка, пожалуйÑта, Ñообщите об Ñтом.</string>
<string name="msg_ip_delete_old_fail">Старый ключ не удален (Ñоздать новый?)</string>
<string name="msg_ip_delete_old_ok">Старый ключ удален из базы</string>
- <string name="msg_ip_encode_fail">ДейÑтвие прервано из-за ошибки кодировки</string>
+ <string name="msg_ip_encode_fail">ДейÑтвие прервано из-за ошибки кодированиÑ</string>
+ <string name="msg_ip_error_io_exc">ДейÑтвие прервано из-за ошибки ввода/вывода</string>
+ <string name="msg_ip_error_op_exc">ДейÑтвие прервано из-за ошибки базы</string>
+ <string name="msg_ip_error_remote_ex">ДейÑтвие прервано из-за внутренней ошибки</string>
<string name="msg_ip">Импорт ÑвÑзки публичных ключей %s</string>
+ <string name="msg_ip_insert_keyring">Кодирование ÑвÑзки ключей</string>
<string name="msg_ip_insert_keys">Разбор ключей</string>
<string name="msg_ip_prepare">Подготовка операций</string>
<string name="msg_ip_master">Подготовка оÑновного ключа %s</string>
+ <string name="msg_ip_master_expired">Срок годноÑти ÑвÑзки ключей иÑтек %s</string>
+ <string name="msg_ip_master_expires">Срок годноÑти ÑвÑзки ключей иÑтекает %s</string>
+ <string name="msg_ip_master_flags_unspecified">ОÑновные флаги: не определены (подразумеваютÑÑ Ð²Ñе)</string>
+ <string name="msg_ip_master_flags_cesa">ОÑновные флаги: Ñертифицировать, зашифровать, подпиÑать, удоÑтоверить</string>
+ <string name="msg_ip_master_flags_cesx">ОÑновные флаги: Ñертифицировать, зашифровать, подпиÑать</string>
+ <string name="msg_ip_master_flags_cexa">ОÑновные флаги: Ñертифицировать, зашифровать, удоÑтоверить</string>
+ <string name="msg_ip_master_flags_cexx">ОÑновные флаги: Ñертифицировать, зашифровать</string>
+ <string name="msg_ip_master_flags_cxsa">ОÑновные флаги: Ñертифицировать, подпиÑать, удоÑтоверить</string>
+ <string name="msg_ip_master_flags_cxsx">ОÑновные флаги: Ñертифицировать, подпиÑать</string>
+ <string name="msg_ip_master_flags_cxxa">ОÑновные флаги: Ñертифицировать, удоÑтоверить</string>
+ <string name="msg_ip_master_flags_cxxx">ОÑновные флаги: Ñертифицировать</string>
+ <string name="msg_ip_master_flags_xesa">ОÑновные флаги: зашифровать, подпиÑать, удоÑтоверить</string>
+ <string name="msg_ip_master_flags_xesx">ОÑновные флаги: зашифровать, подпиÑать</string>
+ <string name="msg_ip_master_flags_xexa">ОÑновные флаги: зашифровать, удоÑтоверить</string>
+ <string name="msg_ip_master_flags_xexx">ОÑновные флаги: зашифровать</string>
+ <string name="msg_ip_master_flags_xxsa">ОÑновные флаги: подпиÑать, удоÑтоверить</string>
+ <string name="msg_ip_master_flags_xxsx">ОÑновные флаги: подпиÑать</string>
+ <string name="msg_ip_master_flags_xxxa">ОÑновные флаги: удоÑтоверить</string>
+ <string name="msg_ip_master_flags_xxxx">ОÑновные флаги: нет</string>
+ <string name="msg_ip_merge_public">Объединение импортированных данных Ñ ÑущеÑтвующей ÑвÑзкой публичных ключей</string>
+ <string name="msg_ip_merge_secret">Объединение импортированных данных Ñ ÑущеÑтвующей ÑвÑзкой публичных ключей</string>
+ <string name="msg_ip_subkey">Обработка доп. ключа %s</string>
+ <string name="msg_ip_subkey_expired">Срок годноÑти доп. ключа иÑтек %s</string>
+ <string name="msg_ip_subkey_expires">Срок годноÑти доп. ключа иÑтекает %s</string>
+ <string name="msg_ip_subkey_flags_unspecified">Флаги доп. ключа: не определены (подразумеваютÑÑ Ð²Ñе)</string>
+ <string name="msg_ip_subkey_flags_cesa">Флаги доп. ключа: Ñертифицировать, зашифровать, подпиÑать, удоÑтоверить</string>
+ <string name="msg_ip_subkey_flags_cesx">Флаги доп. ключа: Ñертифицировать, зашифровать, подпиÑать</string>
+ <string name="msg_ip_subkey_flags_cexa">Флаги доп. ключа: Ñертифицировать, зашифровать, удоÑтоверить</string>
+ <string name="msg_ip_subkey_flags_cexx">Флаги доп. ключа: Ñертифицировать, зашифровать</string>
+ <string name="msg_ip_subkey_flags_cxsa">Флаги доп. ключа: Ñертифицировать, подпиÑать, удоÑтоверить</string>
+ <string name="msg_ip_subkey_flags_cxsx">Флаги доп. ключа: Ñертифицировать, подпиÑать</string>
+ <string name="msg_ip_subkey_flags_cxxa">Флаги доп. ключа: Ñертифицировать, удоÑтоверить</string>
+ <string name="msg_ip_subkey_flags_cxxx">Флаги доп. ключа: Ñертифицировать</string>
+ <string name="msg_ip_subkey_flags_xesa">Флаги доп. ключа: зашифровать, подпиÑать, удоÑтоверить</string>
+ <string name="msg_ip_subkey_flags_xesx">Флаги доп. ключа: зашифровать, подпиÑать</string>
+ <string name="msg_ip_subkey_flags_xexa">Флаги доп. ключа: зашифровать, удоÑтоверить</string>
+ <string name="msg_ip_subkey_flags_xexx">Флаги доп. ключа: зашифровать</string>
+ <string name="msg_ip_subkey_flags_xxsa">Флаги доп. ключа: подпиÑать, удоÑтоверить</string>
+ <string name="msg_ip_subkey_flags_xxsx">Флаги доп. ключа: подпиÑать</string>
+ <string name="msg_ip_subkey_flags_xxxa">Флаги доп. ключа: удоÑтоверить</string>
+ <string name="msg_ip_subkey_flags_xxxx">Флаги доп. ключа: нет</string>
<string name="msg_ip_success">УÑпешно внеÑена ÑвÑзка публичных ключей</string>
+ <string name="msg_ip_success_identical">СвÑзка ключей не Ñодержит новых данных, нечего делать</string>
<string name="msg_ip_reinsert_secret">Повторное внеÑение Ñекретного ключа</string>
<string name="msg_ip_uid_cert_bad">Плохой Ñертификат!</string>
<string name="msg_ip_uid_cert_error">Ошибка обработки Ñертификата!</string>
+ <string name="msg_ip_uid_cert_nonrevoke">Уже еÑÑ‚ÑŒ неотзываемый Ñертификат, пропуÑкаем.</string>
+ <string name="msg_ip_uid_cert_old">Сертификат Ñтарее, чем предыдущий, пропуÑкаем.</string>
+ <string name="msg_ip_uid_cert_new">Сертификат более новый, заменÑем предыдущий.</string>
+ <string name="msg_ip_uid_cert_good">Ðайден хороший Ñертификат %1$s</string>
+ <string name="msg_ip_uid_cert_good_revoke">Ðайдено аннулирование хорошего Ñертификата %1$s</string>
+ <string name="msg_ip_uid_classifying_zero">Сортировка пользовательÑких ID (доверенные ключи недоÑтупны)</string>
+ <string name="msg_ip_uid_reorder">ПереупорÑдочение пользовательÑких ID</string>
+ <string name="msg_ip_uid_processing">Обработка id %s</string>
+ <string name="msg_ip_uid_revoked">id аннулирован</string>
+ <string name="msg_ip_uat_processing_image">Обработка пользовательÑкого атрибута типа изображениÑ</string>
+ <string name="msg_ip_uat_processing_unknown">Обработка пользовательÑкого атрибута неизвеÑтного типа</string>
+ <string name="msg_ip_uat_cert_bad">Плохой Ñертификат!</string>
+ <string name="msg_ip_uat_cert_error">Ошибка обработки Ñертификата!</string>
+ <string name="msg_ip_uat_cert_nonrevoke">Уже еÑÑ‚ÑŒ неотзываемый Ñертификат, пропуÑкаем.</string>
+ <string name="msg_ip_uat_cert_old">Сертификат Ñтарее, чем предыдущий, пропуÑкаем.</string>
+ <string name="msg_ip_uat_cert_new">Сертификат более новый, заменÑем предыдущий.</string>
+ <string name="msg_ip_uat_cert_good">Ðайден хороший Ñертификат %1$s</string>
+ <string name="msg_ip_uat_cert_good_revoke">Ðайдено аннулирование хорошего Ñертификата %1$s</string>
+ <string name="msg_ip_uat_classifying">Сортировка атрибутов пользователÑ</string>
+ <string name="msg_ip_uat_revoked">Ðтрибут Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð°Ð½Ð½ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½</string>
<string name="msg_is_bad_type_public">Попытка импорта публичной ÑвÑзки как Ñекретной. Это ошибка, пожалуйÑта, Ñообщите об Ñтом.</string>
+ <string name="msg_is_bad_type_uncanon">Попытка импорта ÑвÑзки без нормализации. Это ошибка, пожалуйÑта, Ñообщите об Ñтом.</string>
<!--Import Secret log entries-->
<string name="msg_is">Импорт Ñекретного ключа %s</string>
<string name="msg_is_db_exception">Ошибка базы данных!</string>
- <string name="msg_is_importing_subkeys">Обработка Ñекретных ключей</string>
+ <string name="msg_is_importing_subkeys">Обработка Ñекретных доп. ключей</string>
+ <string name="msg_is_error_io_exc">Ошибка ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð°</string>
+ <string name="msg_is_merge_public">Объединение импортированных данных Ñ ÑущеÑтвующей ÑвÑзкой публичных ключей</string>
+ <string name="msg_is_merge_secret">Объединение импортированных данных Ñ ÑущеÑтвующей ÑвÑзкой публичных ключей</string>
+ <string name="msg_is_merge_special">Объединение Ñамо-Ñертифицированных данных из публичных ключей</string>
+ <string name="msg_is_pubring_generate">Формирование публичной ÑвÑзки из Ñекретной ÑвÑзки</string>
+ <string name="msg_is_subkey_nonexistent">Доп. ключ %s недоÑтупен в Ñекретном ключе</string>
+ <string name="msg_is_subkey_ok">Секретный доп. ключ %s отмечен как доÑтупный</string>
+ <string name="msg_is_subkey_empty">Секретный доп. ключ %s отмечен как доÑтупный, Ñ Ð¿ÑƒÑтым паролем</string>
+ <string name="msg_is_subkey_pin">Секретный доп. ключ %s отмечен как доÑтупный, Ñ PIN</string>
+ <string name="msg_is_subkey_stripped">Секретный доп. ключ %s отмечен как отделённый</string>
+ <string name="msg_is_subkey_divert">Секретный доп. ключ %s отмечен как \'переключенный на Ñмарт-карту/NFC\'</string>
+ <string name="msg_is_success_identical">СвÑзка ключей не Ñодержит новых данных, нечего делать</string>
<string name="msg_is_success">УÑпешно добавлена ÑвÑзка Ñекретных ключей</string>
<!--Keyring Canonicalization log entries-->
+ <string name="msg_kc_public">ÐÐ¾Ñ€Ð¼Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¾Ð¹ ÑвÑзки %s</string>
+ <string name="msg_kc_secret">ÐÐ¾Ñ€Ð¼Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñекретной ÑвÑзки %s</string>
+ <string name="msg_kc_error_v3">Это ключ OpenPGP верÑии 3, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÑƒÑтарела и больше не поддерживаетÑÑ!</string>
+ <string name="msg_kc_error_no_uid">СвÑзка не имеет допуÑтимых ID!</string>
+ <string name="msg_kc_error_master_algo">ОÑновной ключ иÑпользует неизвеÑтный алгоритм (%s)!</string>
+ <string name="msg_kc_error_dup_key">Доп. ключ %s найден дважды в ÑвÑзке. СвÑзка некорректна, не импортируетÑÑ!</string>
<string name="msg_kc_master">Подготовка оÑновного ключа</string>
+ <string name="msg_kc_master_bad_type">Удаление Ñертификата оÑновного ключа неизвеÑтного типа (%s)</string>
+ <string name="msg_kc_master_bad_local">Удаление Ñертификата оÑновного ключа Ñ \"локальным\" флагом</string>
+ <string name="msg_kc_master_bad_err">Удаление плохого Ñертификата оÑновного ключа</string>
+ <string name="msg_kc_master_bad_time">Удаление Ñертификата Ð°Ð½Ð½ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð° Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¾Ð¹ времени, находÑщейÑÑ Ð² будущем</string>
+ <string name="msg_kc_master_bad_type_uid">Удаление Ñертификата ID в некорректном положении</string>
+ <string name="msg_kc_master_bad">Удаление плохого Ñертификата оÑновного ключа</string>
+ <string name="msg_kc_master_local">Удаление Ñертификата оÑновного ключа Ñ \"локальным\" флагом</string>
+ <string name="msg_kc_revoke_dup">Удаление лишнего Ñертификата Ð°Ð½Ð½ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð°</string>
+ <string name="msg_kc_notation_dup">Удаление лишнего Ñертификата обозначениÑ</string>
+ <string name="msg_kc_notation_empty">Удаление пуÑтого Ñертификата обозначениÑ</string>
+ <string name="msg_kc_sub">Обработка доп. ключа %s</string>
+ <string name="msg_kc_sub_bad">Удаление недопуÑтимого Ñертификата ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа</string>
+ <string name="msg_kc_sub_bad_err">Удаление плохого Ñертификата ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа</string>
+ <string name="msg_kc_sub_bad_local">Удаление Ñертификата ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа Ñ \"локальным\" флагом</string>
+ <string name="msg_kc_sub_bad_keyid">ÐеÑоответÑтвие id Ð¸Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа</string>
+ <string name="msg_kc_sub_bad_time">Удаление Ñертификата ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¾Ð¹ времени, находÑщейÑÑ Ð² будущем</string>
+ <string name="msg_kc_sub_bad_type">ÐеизвеÑтный тип Ñертификата доп. ключа: %s</string>
+ <string name="msg_kc_sub_dup">Удаление лишнего Ñертификата ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа</string>
+ <string name="msg_kc_sub_primary_bad">Удаление Ñертификата ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа вÑледÑтвие недопуÑтимого оÑновного Ñертификата ÑвÑзываниÑ</string>
+ <string name="msg_kc_sub_primary_bad_err">Удаление Ñертификата ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа вÑледÑтвие плохого оÑновного Ñертификата ÑвÑзываниÑ</string>
+ <string name="msg_kc_sub_primary_none">Удаление Ñертификата ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа вÑледÑтвие отÑутÑтвующего оÑновного Ñертификата ÑвÑзываниÑ</string>
+ <string name="msg_kc_sub_no_cert">Ðет допуÑтимого Ñертификата Ð´Ð»Ñ %s, удаление из ÑвÑзки</string>
+ <string name="msg_kc_sub_revoke_bad_err">Удаление плохого Ñертификата Ð°Ð½Ð½ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа</string>
+ <string name="msg_kc_sub_revoke_bad">Удаление плохого Ñертификата Ð°Ð½Ð½ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа</string>
+ <string name="msg_kc_sub_revoke_dup">Удаление лишнего Ñертификата Ð°Ð½Ð½ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿. ключа</string>
+ <string name="msg_kc_sub_unknown_algo">Доп. ключ иÑпользует неизвеÑтный алгоритм, не импортируетÑÑ...</string>
+ <string name="msg_kc_sub_algo_bad_encrpyt">Доп. ключ имеет флаг иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ, но алгоритм не подходит Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ.</string>
+ <string name="msg_kc_sub_algo_bad_sign">Доп. ключ имеет флаг иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи, но алгоритм не подходит Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи.</string>
+ <string name="msg_kc_success">СвÑзка нормализована уÑпешно, нет изменений</string>
+ <string name="msg_kc_success_bad_and_red">СвÑзка нормализована уÑпешно, удалено %1$s ошибочных и %2$s лишних Ñертификатов</string>
<!--Keyring merging log entries-->
<!--createSecretKeyRing-->
+ <string name="msg_cr">Создание нового оÑновного ключа</string>
+ <string name="msg_cr_error_keysize_512">Размер ключа должен быть больше или равен 512!</string>
+ <string name="msg_cr_error_internal_pgp">ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° OpenPGP!</string>
<!--modifySecretKeyRing-->
<string name="msg_mf_error_encode">Ошибка кодированиÑ!</string>
<string name="msg_mf_error_integrity">ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°, Ñбой проверки целоÑтноÑти!</string>
+ <string name="msg_mf_error_pgp">ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° OpenPGP!</string>
<string name="msg_mf_error_sig">Ошибка подпиÑи!</string>
<string name="msg_mf_success">СвÑзка уÑпешно изменена</string>
<string name="msg_mf_unlock_error">Ошибка Ñ€Ð°Ð·Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑвÑзки!</string>
<string name="msg_mf_unlock">Разблокирование ÑвÑзки</string>
<!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
+ <string name="msg_pr_error_key_not_found">Ключ не найден!</string>
<!--Other messages used in OperationLogs-->
+ <string name="msg_ek_error_divert">Редактирование NFC ключей (еще) не поддерживаетÑÑ!</string>
+ <string name="msg_ek_error_not_found">Ключ не найден!</string>
<!--Messages for DecryptVerify operation-->
+ <string name="msg_dc_unlocking">Разблокировка Ñекретного ключа</string>
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_pse_error_pgp">ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° OpenPGP!</string>
+ <string name="msg_crt_saving">Сохранение ÑвÑзки</string>
+ <string name="msg_crt_unlock">Разблокировка оÑновного ключа</string>
+ <string name="msg_crt_warn_not_found">Ключ не найден!</string>
+ <string name="msg_crt_upload_success">Ключ уÑпешно загружен на Ñервер</string>
+ <string name="msg_export_error_fopen">Ошибка Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð°!</string>
+ <string name="msg_export_error_db">Ошибка базы данных!</string>
+ <string name="msg_export_error_io">Ошибка ввода/вывода!</string>
+ <string name="msg_del_error_empty">Ðет данных Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ!</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">чаÑÑ‚ÑŒ загруженного файла Ñодержит данные OpenPGP, но Ñто не ключ</item>
<item quantity="few">чаÑти загруженного файла Ñодержат данные OpenPGP, но Ñто не ключ</item>
<item quantity="other">чаÑти загруженного файла Ñодержат данные OpenPGP, но Ñто не ключ</item>
</plurals>
<!--PassphraseCache-->
+ <!--First Time-->
+ <string name="first_time_text1">Верните вашу приватноÑÑ‚ÑŒ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ OpenKeychain!</string>
<!--unsorted-->
<string name="section_certifier_id">Кем подпиÑан</string>
<string name="section_cert">Детали Ñертификации</string>
@@ -423,10 +700,14 @@
<string name="label_cert_type">Тип</string>
<string name="error_key_not_found">Ключ не найден!</string>
<string name="error_key_processing">Ошибка обработки ключа!</string>
+ <string name="key_unavailable">недоÑтупно</string>
<string name="title_view_cert">ПроÑмотреть детали Ñертификации</string>
<string name="unknown_algorithm">неизв.</string>
<string name="can_sign_not">не Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑаниÑ</string>
<string name="error_no_encrypt_subkey">Ðет доп. ключа Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ!</string>
<string name="contact_show_key">Показать ключ (%s)</string>
- <!--First Time-->
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-sl/strings.xml b/OpenKeychain/src/main/res/values-sl/strings.xml
index c99b24d79..499ff8468 100644
--- a/OpenKeychain/src/main/res/values-sl/strings.xml
+++ b/OpenKeychain/src/main/res/values-sl/strings.xml
@@ -9,13 +9,11 @@
<string name="title_encrypt_text">Å ifriraj besedilo</string>
<string name="title_encrypt_files">Å ifriraj datoteko</string>
<string name="title_decrypt">Dešifriraj</string>
- <string name="title_authentication">Geslo</string>
+ <string name="title_unlock">Odkleni kljuÄ</string>
<string name="title_add_subkey">Dodaj podkljuÄ</string>
<string name="title_edit_key">Uredi kljuÄ</string>
- <string name="title_preferences">Nastavitve</string>
<string name="title_cloud_search_preferences">Nastavitve iskanja v oblaku</string>
<string name="title_api_registered_apps">Aplikacije</string>
- <string name="title_key_server_preference">Nastavitve strežnikov</string>
<string name="title_change_passphrase">Spremeni geslo</string>
<string name="title_share_fingerprint_with">Deli prstni odtis z...</string>
<string name="title_share_key">Deli kljuÄ z...</string>
@@ -253,6 +251,7 @@
<string name="progress_generating_elgamal">ustvarjanje novega ElGamal kljuÄa...</string>
<string name="progress_generating_ecdsa">ustvarjanje novega ECDSA kljuÄa...</string>
<string name="progress_generating_ecdh">ustvarjanje novega ECDH kljuÄa...</string>
+ <string name="progress_modify_primaryuid">menjavam glavno identiteto uporabnika...</string>
<string name="progress_modify_subkeychange">spreminjanje podkljuÄev...</string>
<string name="progress_modify_subkeyrevoke">preklicevanje podkljuÄev...</string>
<string name="progress_modify_subkeyadd">dodajanje podkljuÄev...</string>
@@ -323,7 +322,6 @@
<string name="import_qr_code_wrong">Koda QR je deformirana! Poskusite znova!</string>
<string name="import_qr_code_too_short_fingerprint">Prstni odtis je prekratek (&lt; 16 znakov)</string>
<!--Generic result toast-->
- <string name="view_log">Poglej dnevnik</string>
<!--Import result toast-->
<string name="import_error_nothing">NiÄ za uvoziti.</string>
<string name="import_error_nothing_cancelled">Uvoz preklican.</string>
@@ -349,7 +347,6 @@
<string name="api_settings_delete_account">IzbriÅ¡i raÄun</string>
<string name="api_settings_package_name">Ime paketa</string>
<string name="api_settings_package_signature">SHA-256 podpisa paketa</string>
- <string name="api_settings_accounts">RaÄuni</string>
<string name="api_settings_settings">Nastavitve</string>
<string name="api_settings_accounts_empty">S to aplikacijo ni povezan noben raÄun</string>
<string name="api_register_allow">Dovoli dostop</string>
@@ -402,9 +399,6 @@
<string name="view_key_expired">Ta kljuÄ je pretekel!</string>
<!--Navigation Drawer-->
<string name="nav_keys">KljuÄi</string>
- <string name="nav_encrypt_text">Å ifriraj besedilo</string>
- <string name="nav_encrypt_files">Å ifriraj datoteke</string>
- <string name="nav_decrypt">Dešifriraj</string>
<string name="nav_apps">Aplikacije</string>
<string name="drawer_open">Odprite navigacijski poteznik</string>
<string name="drawer_close">Zaprite navigacijski poteznik</string>
@@ -447,11 +441,6 @@
<string name="msg_is_success">Zasebna zbirka kljuÄev uspeÅ¡no uvožena</string>
<!--Keyring Canonicalization log entries-->
<string name="msg_kc_master">Obdelujem glavni kljuÄ...</string>
- <string name="msg_kc_revoke_bad_err">Umikam slab certifikat za preklic zbirk kljuÄev</string>
- <string name="msg_kc_revoke_bad_local">Umikam certifikat za preklic zbirk kljuÄev z oznako \"lokalno\"</string>
- <string name="msg_kc_revoke_bad_time">Umikam certifikat za preklic zbirk kljuÄev s Äasovno znamko v prihodnosti</string>
- <string name="msg_kc_revoke_bad_type">Umikam certifikat glavnega kljuÄa neznanega tipa (%s)</string>
- <string name="msg_kc_revoke_bad">Umikam slab certifikat za preklic zbirk kljuÄev</string>
<string name="msg_kc_revoke_dup">Umikam odveÄen certifikat za preklic zbirk kljuÄev</string>
<string name="msg_kc_sub">Obdelujem podkljuÄ %s</string>
<string name="msg_kc_sub_bad">Umikam neveljaven certifikat za povezovanje podkljuÄev</string>
@@ -465,10 +454,13 @@
<string name="msg_mf_subkey_revoke">Preklic podkljuÄa %s</string>
<!--Consolidate-->
<string name="msg_con_db_clear">ÄŒiÅ¡Äenje podatkovne baze</string>
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_not_found">KljuÄ ni bil najden!</string>
<!--Messages for DecryptVerify operation-->
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<string name="msg_crt_warn_not_found">KljuÄ ni bil najden!</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">Del naložene datoteke je veljavnen objekt OpenPGP a ni kljuÄ.</item>
@@ -481,6 +473,11 @@
<string name="passp_cache_notif_n_keys">OpenKeychain pomni gesla: %d</string>
<string name="passp_cache_notif_keys">Zapomnjena gesla:</string>
<string name="passp_cache_notif_pwd">Geslo</string>
+ <!--First Time-->
+ <string name="first_time_text1">Vzemite si svojo zasebnost nazaj v svoje roke z OpenKeychain!</string>
+ <string name="first_time_create_key">Ustvari zasebni kljuÄ</string>
+ <string name="first_time_import_key">Uvozi iz datoteke</string>
+ <string name="first_time_skip">PreskoÄi nastavitev</string>
<!--unsorted-->
<string name="section_certifier_id">Overovitelj</string>
<string name="section_cert">Podrobnosti potrdil</string>
@@ -502,9 +499,8 @@
<string name="error_no_encrypt_subkey">Ni nobenega podkljuÄa za Å¡ifriranje!</string>
<string name="contact_show_key">Prikaži kljuÄ (%s)</string>
<string name="key_colon">KljuÄ:</string>
- <!--First Time-->
- <string name="first_time_text1">Vzemite si svojo zasebnost nazaj v svoje roke z OpenKeychain!</string>
- <string name="first_time_create_key">Ustvari zasebni kljuÄ</string>
- <string name="first_time_import_key">Uvozi iz datoteke</string>
- <string name="first_time_skip">PreskoÄi nastavitev</string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-sr/strings.xml b/OpenKeychain/src/main/res/values-sr/strings.xml
index ff50a637b..b3a15cb7f 100644
--- a/OpenKeychain/src/main/res/values-sr/strings.xml
+++ b/OpenKeychain/src/main/res/values-sr/strings.xml
@@ -9,13 +9,13 @@
<string name="title_encrypt_text">Шифруј текÑÑ‚</string>
<string name="title_encrypt_files">Шифруј фајлове</string>
<string name="title_decrypt">Дешифруј</string>
- <string name="title_authentication">Лозинка</string>
+ <string name="title_unlock">Откључај кључ</string>
<string name="title_add_subkey">Додај поткључ</string>
<string name="title_edit_key">Уреди кључ</string>
<string name="title_preferences">ПоÑтавке</string>
<string name="title_cloud_search_preferences">ПоÑтавке клауд претраге</string>
<string name="title_api_registered_apps">Ðпликације</string>
- <string name="title_key_server_preference">ПоÑтавка Ñервера кључева</string>
+ <string name="title_key_server_preference">Сервери кључева</string>
<string name="title_change_passphrase">Измени лозинку</string>
<string name="title_share_fingerprint_with">Подели отиÑак Ñа…</string>
<string name="title_share_key">Подели кључ Ñа…</string>
@@ -36,6 +36,7 @@
<string name="title_create_key">Ðаправи кључ</string>
<string name="title_exchange_keys">Размена кључева</string>
<string name="title_advanced_key_info">Ðапредни подаци о кључу</string>
+ <string name="title_keys">Кључеви</string>
<!--section-->
<string name="section_user_ids">Идентитети</string>
<string name="section_keys">Поткључеви</string>
@@ -55,6 +56,8 @@
<string name="section_decrypt_files">Фајлови</string>
<string name="section_decrypt_text">ТекÑÑ‚</string>
<string name="section_certs">Сертификати</string>
+ <string name="section_encrypt">Шифровање</string>
+ <string name="section_decrypt">Дешифровање</string>
<!--button-->
<string name="btn_decrypt_verify_file">Дешифруј, овери и Ñачувај фајл</string>
<string name="btn_decrypt_verify_message">Дешифруј и овери поруку</string>
@@ -74,9 +77,11 @@
<string name="btn_create_key">Ðаправи кључ</string>
<string name="btn_add_files">Додај фајл(ове)</string>
<string name="btn_add_share_decrypted_text">Подели дешифрован текÑÑ‚</string>
- <string name="btn_decrypt_clipboard">Дешифруј Ñа клипборда</string>
+ <string name="btn_decrypt_clipboard">Дешифруј текÑÑ‚ Ñа клипборда</string>
<string name="btn_decrypt_and_verify">и овери потпиÑе</string>
<string name="btn_decrypt_files">Дешифруј фајлове</string>
+ <string name="btn_encrypt_files">Шифруј фајлове</string>
+ <string name="btn_encrypt_text">Шифруј текÑÑ‚</string>
<!--menu-->
<string name="menu_preferences">ПоÑтавке</string>
<string name="menu_help">Помоћ</string>
@@ -90,6 +95,7 @@
<string name="menu_encrypt_to">Шифруј у…</string>
<string name="menu_select_all">Изабери Ñве</string>
<string name="menu_add_keys">Додај кључеве</string>
+ <string name="menu_search_cloud">Клауд претрага</string>
<string name="menu_export_all_keys">Извези Ñве кључеве</string>
<string name="menu_advanced">Прикажи напредне податке</string>
<!--label-->
@@ -108,7 +114,7 @@
<string name="label_write_version_header_summary">УпиÑује „OpenKeychain v3.0“ у ОпенПГП потпиÑе, шифровани текÑÑ‚ и извезене кључеве</string>
<string name="label_use_default_yubikey_pin">КориÑти подразумевани Јубикључ ПИÐ</string>
<string name="label_use_num_keypad_for_yubikey_pin">КориÑти бројчану таÑтатуру за Јубикључ ПИÐ</string>
- <string name="label_label_use_default_yubikey_pin_summary">КориÑти подразумевани ПИР(123456) за приÑтуп Јуби-кључевима преко ÐФЦ-а</string>
+ <string name="label_label_use_default_yubikey_pin_summary">КориÑти подразумевани ПИР(123456) за приÑтуп Јубикључевима преко ÐФЦ-а</string>
<string name="label_asymmetric_from">ПотпиÑник:</string>
<string name="label_to">Шифруј за:</string>
<string name="label_delete_after_encryption">Обриши фајл након шифровања</string>
@@ -191,7 +197,9 @@
<string name="passphrase_must_not_be_empty">УнеÑите лозинку.</string>
<string name="passphrase_for_symmetric_encryption">Симетрично шифровање.</string>
<string name="passphrase_for">УнеÑите лозинку за „%s“</string>
- <string name="yubikey_pin">УнеÑите ПИРза приÑтуп Јубикључу за „%s“</string>
+ <string name="pin_for">УнеÑите ПИРза „%s“</string>
+ <string name="yubikey_pin_for">УнеÑите ПИРза приÑтуп Јубикључу за „%s“</string>
+ <string name="nfc_text">Држите Јубикључ на полеђини вашег уређаја.</string>
<string name="file_delete_confirmation">Желите ли заиÑта да обришете\n%s?</string>
<string name="file_delete_successful">БриÑање је уÑпело.</string>
<string name="no_file_selected">Ðајпре изаберите фајл.</string>
@@ -282,6 +290,7 @@
<string name="progress_modify">модификујем привезак…</string>
<string name="progress_modify_unlock">откључавам привезак…</string>
<string name="progress_modify_adduid">додајем кориÑничке ИД-ове…</string>
+ <string name="progress_modify_adduat">додајем кориÑничке атрибуте…</string>
<string name="progress_modify_revokeuid">опозивам кориÑничке ИД-ове…</string>
<string name="progress_modify_primaryuid">мењам примарни кориÑнички ИД…</string>
<string name="progress_modify_subkeychange">модификујем поткључеве…</string>
@@ -357,8 +366,9 @@
<string name="import_qr_code_wrong">Бар-код деформиÑан! Покушајте поново!</string>
<string name="import_qr_code_too_short_fingerprint">ОтиÑак је прекратак (&lt; 16 знакова)</string>
<string name="import_qr_code_button">Очитај бар-код</string>
+ <string name="import_qr_code_text">УÑмерите камеру на бар-код!</string>
<!--Generic result toast-->
- <string name="view_log">Прикажи дневник</string>
+ <string name="view_log">Детаљи</string>
<string name="with_warnings">, Ñа упозорењима</string>
<string name="with_cancelled">, док није отказано</string>
<!--Import result toast-->
@@ -455,7 +465,9 @@
<string name="api_settings_delete_account">Обриши налог</string>
<string name="api_settings_package_name">Име пакета</string>
<string name="api_settings_package_signature">СХÐ-256 потпиÑа пакета</string>
- <string name="api_settings_accounts">Ðалози</string>
+ <string name="api_settings_accounts">Ðалози (заÑтарели ÐПИ)</string>
+ <string name="api_settings_advanced">Ðапредни подаци</string>
+ <string name="api_settings_allowed_keys">Дозвољени кључеви</string>
<string name="api_settings_settings">ПоÑтавке</string>
<string name="api_settings_key">Кључ налога:</string>
<string name="api_settings_accounts_empty">Ðема налога придружених овој апликацији.</string>
@@ -542,9 +554,7 @@
<string name="view_key_expired">Овај кључ је иÑтекао!</string>
<!--Navigation Drawer-->
<string name="nav_keys">Кључеви</string>
- <string name="nav_encrypt_text">Шифруј текÑÑ‚</string>
- <string name="nav_encrypt_files">Шифруј фајлове</string>
- <string name="nav_decrypt">Дешифруј</string>
+ <string name="nav_encrypt_decrypt">Шифруј/дешифруј</string>
<string name="nav_apps">Ðпликације</string>
<string name="drawer_open">Отвори навигациону фиоку</string>
<string name="drawer_close">Затвори навигациону фиоку</string>
@@ -570,7 +580,7 @@
<string name="msg_ip_delete_old_fail">Ðиједан Ñтари кључ није обриÑан (прављење новог?)</string>
<string name="msg_ip_delete_old_ok">ОбриÑан Ñтари кључ из базе података</string>
<string name="msg_ip_encode_fail">Радња није уÑпела због грешке кодирања</string>
- <string name="msg_ip_error_io_exc">Радња није уÑпела због улазно/излазне грешке</string>
+ <string name="msg_ip_error_io_exc">Радња није уÑпела због У/И грешке</string>
<string name="msg_ip_error_op_exc">Радња није уÑпела због грешке базе података</string>
<string name="msg_ip_error_remote_ex">Радња није уÑпела због унутрашње грешке</string>
<string name="msg_ip">Увозим јавни привезак %s</string>
@@ -643,6 +653,22 @@
<string name="msg_ip_uid_reorder">Поново разврÑтавам кориÑничке ИД-ове</string>
<string name="msg_ip_uid_processing">Обрађујем кориÑнички ИД %s</string>
<string name="msg_ip_uid_revoked">КориÑнички ИД је опозван</string>
+ <string name="msg_ip_uat_processing_image">Обрађујем кориÑнички атрибут типа Ñлике</string>
+ <string name="msg_ip_uat_processing_unknown">Обрађујем кориÑнички атрибут непознатог типа</string>
+ <string name="msg_ip_uat_cert_bad">Ðаиђох на лош Ñертификат!</string>
+ <string name="msg_ip_uat_cert_error">Грешка обраде Ñертификата!</string>
+ <string name="msg_ip_uat_cert_nonrevoke">Већ поÑтоји неопозив Ñертификат, преÑкачем.</string>
+ <string name="msg_ip_uat_cert_old">Сертификат је Ñтарији него претходни, преÑкачем.</string>
+ <string name="msg_ip_uat_cert_new">Сертификат је новији, замењујем претходни.</string>
+ <string name="msg_ip_uat_cert_good">Ðађен добар Ñертификат од %1$s</string>
+ <string name="msg_ip_uat_cert_good_revoke">Ðађен добар опозив Ñертификата од %1$s</string>
+ <plurals name="msg_ip_uat_certs_unknown">
+ <item quantity="one">Игноришем Ñертификат издат од непознатог јавног кључа</item>
+ <item quantity="few">Игноришем %s Ñертификата издата од непознатих јавних кључева</item>
+ <item quantity="other">Игноришем %s Ñертификата издатих од непознатих јавних кључева</item>
+ </plurals>
+ <string name="msg_ip_uat_classifying">РазврÑтавам кориÑничке атрибуте</string>
+ <string name="msg_ip_uat_revoked">КориÑнички атрибут је опозван</string>
<string name="msg_is_bad_type_public">Покушај увоза јавног привеÑка као тајног. Ово је грешка, поднеÑите извештај!</string>
<string name="msg_is_bad_type_uncanon">Покушај увоза привеÑка без каноникализације. Ово је грешка, поднеÑите извештај!</string>
<!--Import Secret log entries-->
@@ -657,6 +683,7 @@
<string name="msg_is_subkey_nonexistent">Поткључ %s није доÑтупан у тајном кључу</string>
<string name="msg_is_subkey_ok">Тајни поткључ %d означен као доÑтупан</string>
<string name="msg_is_subkey_empty">Тајни поткључ %d означен као доÑтупан, без лозинке</string>
+ <string name="msg_is_subkey_pin">Тајни поткључ %s означен као доÑтупан, Ñа ПИÐом</string>
<string name="msg_is_subkey_stripped">Тајни поткључ %d означен као огољен</string>
<string name="msg_is_subkey_divert">Тајни поткључ %d означен као „преуÑмерен на картицу/ÐФЦ“</string>
<string name="msg_is_success_identical">Привезак не Ñадржи нове податке, нема шта да Ñе ради</string>
@@ -669,13 +696,16 @@
<string name="msg_kc_error_master_algo">Главни кључ кориÑти непознат алгоритам (%s)!</string>
<string name="msg_kc_error_dup_key">Поткључ %s Ñе појављује два пута у привеÑку. Привезак је деформиÑан, не увозим!</string>
<string name="msg_kc_master">Обрађујем главни кључ</string>
- <string name="msg_kc_revoke_bad_err">Уклањам лош Ñертификат опозива привеÑка</string>
- <string name="msg_kc_revoke_bad_local">Уклањам Ñертификат опозива привеÑка Ñа заÑтавицом „локални“</string>
- <string name="msg_kc_revoke_bad_time">Уклањам Ñертификат опозива привеÑка Ñа временÑком ознаком у будућноÑти</string>
- <string name="msg_kc_revoke_bad_type">Уклањам Ñертификат главног кључа непознатог типа (%s)</string>
- <string name="msg_kc_revoke_bad_type_uid">Уклањам Ñертификат кориÑничког ИД-а Ñа погрешног меÑта</string>
- <string name="msg_kc_revoke_bad">Уклањам лош Ñертификат опозива привеÑка</string>
+ <string name="msg_kc_master_bad_type">Уклањам Ñертификат главног кључа непознатог типа (%s)</string>
+ <string name="msg_kc_master_bad_local">Уклањам Ñертификат главног кључа Ñа заÑтавицом „локални“</string>
+ <string name="msg_kc_master_bad_err">Уклањам лош Ñертификат главног кључа</string>
+ <string name="msg_kc_master_bad_time">Уклањам Ñертификат опозива привеÑка Ñа временÑком ознаком у будућноÑти</string>
+ <string name="msg_kc_master_bad_type_uid">Уклањам Ñертификат кориÑничког ИД-а Ñа погрешног меÑта</string>
+ <string name="msg_kc_master_bad">Уклањам лош Ñертификат главног кључа</string>
+ <string name="msg_kc_master_local">Уклањам Ñертификат главног кључа Ñа заÑтавицом „локални“</string>
<string name="msg_kc_revoke_dup">Уклањам Ñувишни Ñертификат опозива привеÑка</string>
+ <string name="msg_kc_notation_dup">Уклањам Ñувишни Ñертификат нотације</string>
+ <string name="msg_kc_notation_empty">Уклањам празни Ñертификат нотације</string>
<string name="msg_kc_sub">Обрађујем поткључ %s</string>
<string name="msg_kc_sub_bad">Уклањам неиÑправан повезујући Ñертификат поткључа</string>
<string name="msg_kc_sub_bad_err">Уклањам лош повезујући Ñертификат поткључа</string>
@@ -717,8 +747,23 @@
<string name="msg_kc_uid_revoke_old">Уклањам заÑтарели Ñертификат опозива за кориÑнички ИД „%s“</string>
<string name="msg_kc_uid_no_cert">Ðије нађен иÑправан ÑопÑтвени Ñертификат за кориÑнички ИД „%s“, уклањам из прÑтена</string>
<string name="msg_kc_uid_remove">Уклањам неиÑправан кориÑнички ИД „%s“</string>
- <string name="msg_kc_uid_dup">Уклањам дупли кориÑнички ИД „%s“. Тајни кључ је Ñадржао два. Ово може да доведе до недоÑтајућих Ñертификата!</string>
+ <string name="msg_kc_uid_dup">Уклањам дупли кориÑнички ИД „%s“. Привезак је Ñадржао два. Ово може да доведе до недоÑтајућих Ñертификата!</string>
<string name="msg_kc_uid_warn_encoding">ИД кориÑника није потврђен као УТФ-8!</string>
+ <string name="msg_kc_uat_jpeg">Обрађујем кориÑнички атрибут ЈПЕГ типа</string>
+ <string name="msg_kc_uat_unknown">Обрађујем кориÑнички атрибут непознатог типа</string>
+ <string name="msg_kc_uat_bad_err">Уклањам лош ÑопÑтвени Ñертификат за кориÑнички атрибут</string>
+ <string name="msg_kc_uat_bad_local">Уклањам Ñертификат кориÑничког атрибута Ñа заÑтавицом „локални“</string>
+ <string name="msg_kc_uat_bad_time">Уклањам кориÑнички атрибут Ñа временÑком ознаком у будућноÑти</string>
+ <string name="msg_kc_uat_bad_type">Уклањам Ñертификат кориÑничког атрибута непознатог типа (%s)</string>
+ <string name="msg_kc_uat_bad">Уклањам лош ÑопÑтвени Ñертификат за кориÑнички атрибут</string>
+ <string name="msg_kc_uat_cert_dup">Уклањам заÑтарели ÑопÑтвени Ñертификат за кориÑнички атрибут</string>
+ <string name="msg_kc_uat_dup">Уклањам дупли кориÑнички атрибут. Привезак је Ñадржао два. Ово може да доведе до недоÑтајућих Ñертификата!</string>
+ <string name="msg_kc_uat_foreign">Уклањам Ñтрани Ñертификат кориÑничког атрибута од</string>
+ <string name="msg_kc_uat_revoke_dup">Уклањам Ñувишни Ñертификат опозива за кориÑнички атрибут</string>
+ <string name="msg_kc_uat_revoke_old">Уклањам заÑтарели Ñертификат опозива за кориÑнички атрибут</string>
+ <string name="msg_kc_uat_no_cert">Ðије нађен иÑправан ÑопÑтвени Ñертификат за кориÑнички атрибут, уклањам из прÑтена</string>
+ <string name="msg_kc_uat_remove">Уклањам неиÑправан кориÑнички атрибут</string>
+ <string name="msg_kc_uat_warn_encoding">ИД кориÑника није потврђен као УТФ-8!</string>
<!--Keyring merging log entries-->
<string name="msg_mg_error_secret_dummy">Ðађен је нови јавни поткључ, али генериÑање лажног тајног поткључа није подржано!</string>
<string name="msg_mg_error_heterogeneous">Покушај Ñпајања привезака Ñа различитим отиÑцима!</string>
@@ -737,7 +782,7 @@
<string name="msg_cr_error_keysize_512">Величина кључа мора бити већа или једнака 512!</string>
<string name="msg_cr_error_no_curve">Ðије наведена величина кључа! Ово је грешка у програмирању, поднеÑите извештај о грешци!</string>
<string name="msg_cr_error_no_keysize">Ðије наведена елиптичка крива! Ово је грешка у програмирању, поднеÑите извештај о грешци!</string>
- <string name="msg_cr_error_internal_pgp">Унутрашња ПГП грешка!</string>
+ <string name="msg_cr_error_internal_pgp">Унутрашња ОпенПГП грешка!</string>
<string name="msg_cr_error_unknown_algo">Одређен је непознат алгоритам! Ово је грешка у програмирању, поднеÑите извештај о грешци!</string>
<string name="msg_cr_error_flags_dsa">Изабране Ñу погрешне заÑтавице кључа, ДСРне може да Ñе кориÑти за шифровање!</string>
<string name="msg_cr_error_flags_elgamal">Изабране Ñу погрешне заÑтавице кључа, Елгамал не може да Ñе кориÑти за потпиÑивање!</string>
@@ -745,6 +790,7 @@
<string name="msg_cr_error_flags_ecdh">Изабране Ñу погрешне заÑтавице кључа, ЕЦДХ не може да Ñе кориÑти за потпиÑивање!</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Модификујем привезак %s</string>
+ <string name="msg_mf_error_divert_serial">СеријÑки број преуÑмеравање-у-картицу кључа мора бити 16 бита. Ово је грешка у програмирању, поднеÑите извештај о грешци!</string>
<string name="msg_mf_error_encode">Изузетак кодирања!</string>
<string name="msg_mf_error_fingerprint">Стварни отиÑак кључа не одговара очекиваном!</string>
<string name="msg_mf_error_keyid">Ðема ИД-а кључа. Ово је унутрашња грешка, поднеÑите извештај о грешци!</string>
@@ -752,13 +798,16 @@
<string name="msg_mf_error_master_none">Ðема главног Ñертификата на којем треба да Ñе изврши радња! (Сви Ñу опозвани?)</string>
<string name="msg_mf_error_noexist_primary">Ðаведен је лош примарни кориÑнички ИД!</string>
<string name="msg_mf_error_noexist_revoke">Ðаведен је лош кориÑнички ИД за опозив!</string>
+ <string name="msg_mf_error_restricted">Покушај извршења ограничене радње без лозинке! Ово је грешка у програмирању, поднеÑите извештај о грешци!</string>
<string name="msg_mf_error_revoked_primary">Опозвани кориÑнички ИД-ови не могу бити примарни!</string>
<string name="msg_mf_error_null_expiry">Датум иÑтицања не може бити „иÑти као пре“ на Ñтварању поткључа. Ово је грешка у програмирању, поднеÑите извештај о грешци!</string>
<string name="msg_mf_error_passphrase_master">Кобна грешка дешифровања главног кључа! Ово је вероватно грешка у програмирању, поднеÑите извештај о грешци!</string>
- <string name="msg_mf_error_pgp">Унутрашња ПГП грешка!</string>
+ <string name="msg_mf_error_pgp">Унутрашња ОпенПГП грешка!</string>
<string name="msg_mf_error_sig">Изузетак потпиÑа!</string>
<string name="msg_mf_master">Модификујем главне Ñертификате</string>
- <string name="msg_mf_passphrase">Мењам лозинку за поткључ…</string>
+ <string name="msg_mf_notation_empty">Додајем празни пакет нотације</string>
+ <string name="msg_mf_notation_pin">Додајем ПИРпакет нотације</string>
+ <string name="msg_mf_passphrase">Мењам лозинку за привезак</string>
<string name="msg_mf_passphrase_key">Поново шифрујем поткључ %s новом лозинком</string>
<string name="msg_mf_passphrase_empty_retry">ПоÑтављање нове лозинке није уÑпело, покушавам поново Ñа празном Ñтаром лозинком</string>
<string name="msg_mf_passphrase_fail">Ðе могу да променим лозинку за поткључ! (Да ли Ñе разликује од оне у оÑталим кључевима?)</string>
@@ -775,7 +824,10 @@
<string name="msg_mf_uid_add">Додајем кориÑнички ИД %s</string>
<string name="msg_mf_uid_primary">ПоÑтављам примарни кориÑнички ИД на %s</string>
<string name="msg_mf_uid_revoke">Опозивам кориÑнички ИД %s</string>
- <string name="msg_mf_uid_error_empty">КориÑнички ИД не Ñмије бити празан!</string>
+ <string name="msg_mf_uid_error_empty">КориÑнички ИД не Ñме бити празан!</string>
+ <string name="msg_mf_uat_error_empty">КориÑнички атрибут не Ñме бити празан!</string>
+ <string name="msg_mf_uat_add_image">Додајем кориÑнички атрибут типа Ñлике</string>
+ <string name="msg_mf_uat_add_unknown">Додајем кориÑнички атрибут непознатог типа</string>
<string name="msg_mf_unlock_error">Грешка откључавања привеÑка!</string>
<string name="msg_mf_unlock">Откључавам привезак</string>
<!--Consolidate-->
@@ -796,6 +848,7 @@
<string name="msg_con_error_public">Грешка поновног увоза јавних кључева!</string>
<string name="msg_con_error_secret">Грешка поновног увоза тајних кључева!</string>
<string name="msg_con_recover">ÐаÑтављам Ð¿Ñ€Ð¾Ñ†ÐµÑ ÑƒÑ‡Ð²Ñ€ÑˆÑ›Ð¸Ð²Ð°ÑšÐ°</string>
+ <string name="msg_con_recursive">ПреÑкачем рекурзивно учвршћивање</string>
<string name="msg_con_recover_unknown">ÐаÑтављам Ð¿Ñ€Ð¾Ñ†ÐµÑ ÑƒÑ‡Ð²Ñ€ÑˆÑ›Ð¸Ð²Ð°ÑšÐ° из непознатог Ñтања</string>
<plurals name="msg_con_reimport_public">
<item quantity="one">Поново увозим %d јавни кључ</item>
@@ -811,6 +864,19 @@
<string name="msg_con_reimport_secret_skip">Ðема тајних кључева за поновно увожење, преÑкачем…</string>
<string name="msg_con_warn_delete_public">Изузетак при бриÑању фајла јавног кеша</string>
<string name="msg_con_warn_delete_secret">Изузетак при бриÑању фајла тајног кеша</string>
+ <!--Edit Key (higher level than modify)-->
+ <string name="msg_ed">Извршавам радњу на кључу</string>
+ <string name="msg_ed_caching_new">Кеширам нову лозинку</string>
+ <string name="msg_ed_error_no_parcel">ÐедоÑтаје SaveKeyringParcel! (ово је грешка, пријавите је)</string>
+ <string name="msg_ed_error_key_not_found">Кључ није нађен!</string>
+ <string name="msg_ed_fetching">Добављам кључ за модификовање (%s)</string>
+ <string name="msg_ed_success">Радња на кључу је уÑпела</string>
+ <!--Promote key-->
+ <string name="msg_pr">Унапређујем јавни кључ у тајни кључ</string>
+ <string name="msg_pr_error_already_secret">Кључ је већ тајни кључ!</string>
+ <string name="msg_pr_error_key_not_found">Кључ није нађен!</string>
+ <string name="msg_pr_fetching">Добављам кључ за модификовање (%s)</string>
+ <string name="msg_pr_success">Кључ уÑпешно унапређен</string>
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_divert">Уређивање ÐФЦ кључева (још) није подржано!</string>
<string name="msg_ek_error_dummy">Ðе могу да уредим кључ Ñа огољеним главним кључем!</string>
@@ -819,11 +885,13 @@
<string name="msg_dc_askip_no_key">Подаци ниÑу шифровани познатим кључем, преÑкачем…</string>
<string name="msg_dc_askip_not_allowed">Подаци ниÑу шифровани дозвољеним кључем, преÑкачем…</string>
<string name="msg_dc_asym">Ðађен блок аÑиметрично шифрованих података за кључ %s</string>
+ <string name="msg_dc_charset">Ðађено заглавље кодирања: „%s“</string>
<string name="msg_dc_clear_data">Обрађујем доÑловне податке</string>
<string name="msg_dc_clear_decompress">РаÑпакујем компреÑоване податке</string>
<string name="msg_dc_clear_meta_file">Име фајла: %s</string>
<string name="msg_dc_clear_meta_mime">МИМЕ тип: %s</string>
<string name="msg_dc_clear_meta_size">Величина: %s</string>
+ <string name="msg_dc_clear_meta_size_unknown">Величина није позната</string>
<string name="msg_dc_clear_meta_time">Време измене: %s</string>
<string name="msg_dc_clear_signature_bad">Провера потпиÑа ÐИЈЕ У РЕДУ!</string>
<string name="msg_dc_clear_signature_check">Оверавам податке потпиÑа</string>
@@ -833,11 +901,12 @@
<string name="msg_dc_error_bad_passphrase">Грешка откључавања кључа, погрешна лозинка!</string>
<string name="msg_dc_error_extract_key">Ðепозната грешка откључавања кључа!</string>
<string name="msg_dc_error_integrity_check">Грешка провере интегритета!</string>
+ <string name="msg_dc_error_integrity_missing">ÐедоÑтаје провера интегритета! Ово може да Ñе деÑи ако је апликација за шифровање заÑтарела, или уÑлед напада Ñтаријег издања.</string>
<string name="msg_dc_error_invalid_siglist">ÐиÑу нађени иÑправни подаци потпиÑа!</string>
<string name="msg_dc_error_io">Ðаиђох на У/И изузетак током радње!</string>
<string name="msg_dc_error_no_data">Шифровани подаци ниÑу нађени у току!</string>
<string name="msg_dc_error_no_key">Подаци шифровани познатим тајним кључем ниÑу нађени у току!</string>
- <string name="msg_dc_error_pgp_exception">Ðаиђох на ПГП изузетак током радње!</string>
+ <string name="msg_dc_error_pgp_exception">Ðаиђох на ОпенПГП изузетак током радње!</string>
<string name="msg_dc_integrity_check_ok">Провера интегритета је у реду!</string>
<string name="msg_dc_ok_meta_only">Само Ñу метаподаци затражени, преÑкачем дешифровање</string>
<string name="msg_dc_ok">У реду</string>
@@ -853,29 +922,42 @@
<string name="msg_dc_trail_unknown">Ðаиђох на пратеће податке непознатог типа</string>
<string name="msg_dc_unlocking">Откључавам тајни кључ</string>
<!--Messages for SignEncrypt operation-->
- <string name="msg_se_asymmetric">Припремам јавне кључеве за шифровање</string>
- <string name="msg_se_clearsign_only">ПотпиÑивање обичног текÑта није подржано!</string>
- <string name="msg_se_compressing">Припремам компреÑију</string>
- <string name="msg_se_encrypting">Шифрујем податке</string>
- <string name="msg_se_error_bad_passphrase">Ðетачна лозинка!</string>
- <string name="msg_se_error_io">Ðаиђох на У/И изузетак током радње!</string>
- <string name="msg_se_error_key_sign">Изабрани кључ за потпиÑивање не може да потпише податке!</string>
- <string name="msg_se_error_sign_key">Грешка добављања кључа за потпиÑивање!</string>
- <string name="msg_se_error_nfc">Грешка ÐФЦ података!</string>
- <string name="msg_se_error_no_passphrase">Лозинка није дата!</string>
- <string name="msg_se_error_pgp">Унутрашња ПГП грешка!</string>
- <string name="msg_se_error_sig">Ðаиђох на изузетак ПГП потпиÑивања!</string>
- <string name="msg_se_error_unlock">Ðепозната грешка откључавања кључа!</string>
- <string name="msg_se_key_ok">Шифрујем за кључ: %s</string>
- <string name="msg_se_key_unknown">ÐедоÑтаје кључ за шифровање: %s</string>
- <string name="msg_se_key_warn">Лош кључ за шифровање: %s</string>
- <string name="msg_se_ok">Радња потпиÑивања/шифровања је уÑпела!</string>
- <string name="msg_se_pending_nfc">Потребан је ÐФЦ токен. захтевам ÑƒÐ½Ð¾Ñ ÐºÐ¾Ñ€Ð¸Ñника…</string>
- <string name="msg_se_pending_passphrase">Потребна је лозинка, захтевам ÑƒÐ½Ð¾Ñ ÐºÐ¾Ñ€Ð¸Ñника…</string>
- <string name="msg_se_signing">ПотпиÑујем податке (без шифровања)</string>
- <string name="msg_se_sigcrypting">Шифрујем податке Ñа потпиÑом</string>
- <string name="msg_se">Почињем радњу потпиÑивања и/или шифровања</string>
- <string name="msg_se_symmetric">Припремам Ñиметрично шифровање</string>
+ <string name="msg_se">Почињем радњу потпиÑивања/шифровања</string>
+ <string name="msg_se_input_bytes">Обрађујем улаз низа бајтова</string>
+ <string name="msg_se_input_uri">Обрађујем УРИ уноÑ</string>
+ <string name="msg_se_error_no_input">Ð£Ð½Ð¾Ñ Ð½Ð¸Ñ˜Ðµ дат!</string>
+ <string name="msg_se_error_input_uri_not_found">Грешка отварања УРИ-ја за читање!</string>
+ <string name="msg_se_error_output_uri_not_found">Грешка отварања УРИ-ја за упиÑ!</string>
+ <string name="msg_se_error_too_many_inputs">Ðаведено више улаза него излаза! Ово је грешка у програмирању, поднеÑите извештај о грешци!</string>
+ <string name="msg_se_warn_output_left">ПреоÑтали Ñу излази али нема улаза. Ово је вероватно грешка у програмирању, поднеÑите извештај о грешци.</string>
+ <string name="msg_se_success">Радња потпиÑивања/шифровања је уÑпела!</string>
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_pse_asymmetric">Припремам јавне кључеве за шифровање</string>
+ <string name="msg_pse_clearsign_only">ПотпиÑивање обичног текÑта није подржано!</string>
+ <string name="msg_pse_compressing">Припремам компреÑију</string>
+ <string name="msg_pse_encrypting">Шифрујем податке</string>
+ <string name="msg_pse_error_bad_passphrase">Ðетачна лозинка!</string>
+ <string name="msg_pse_error_hash_algo">Овај кључ не подржава захтевани хеш алгоритам!</string>
+ <string name="msg_pse_error_io">Ðаиђох на У/И изузетак током радње!</string>
+ <string name="msg_pse_error_key_sign">Изабрани кључ за потпиÑивање не може да потпише податке!</string>
+ <string name="msg_pse_error_sign_key">Грешка добављања кључа за потпиÑивање!</string>
+ <string name="msg_pse_error_nfc">Грешка ÐФЦ података!</string>
+ <string name="msg_pse_error_no_passphrase">Лозинка није дата!</string>
+ <string name="msg_pse_error_pgp">Унутрашња ОпенПГП грешка!</string>
+ <string name="msg_pse_error_sig">Ðаиђох на изузетак ОпенПГП потпиÑивања!</string>
+ <string name="msg_pse_error_unlock">Ðепозната грешка откључавања кључа!</string>
+ <string name="msg_pse_key_ok">Шифрујем за кључ: %s</string>
+ <string name="msg_pse_key_unknown">ÐедоÑтаје кључ за шифровање: %s</string>
+ <string name="msg_pse_key_warn">Лош кључ за шифровање: %s</string>
+ <string name="msg_pse_ok">Радња потпиÑивања/шифровања је уÑпела!</string>
+ <string name="msg_pse_pending_nfc">Потребан је ÐФЦ токен, захтевам ÑƒÐ½Ð¾Ñ ÐºÐ¾Ñ€Ð¸Ñника…</string>
+ <string name="msg_pse_pending_passphrase">Потребна је лозинка, захтевам ÑƒÐ½Ð¾Ñ ÐºÐ¾Ñ€Ð¸Ñника…</string>
+ <string name="msg_pse_signing">ПотпиÑујем податке (без шифровања)</string>
+ <string name="msg_pse_signing_cleartext">Правим обични текÑтуални потпиÑ</string>
+ <string name="msg_pse_signing_detached">Правим одвојени потпиÑ</string>
+ <string name="msg_pse_sigcrypting">Шифрујем податке Ñа потпиÑом</string>
+ <string name="msg_pse">Почињем радњу потпиÑивања и/или шифровања</string>
+ <string name="msg_pse_symmetric">Припремам Ñиметрично шифровање</string>
<string name="msg_crt_certifying">Генеришем Ñертификате</string>
<string name="msg_crt_certify_all">Оверавам Ñве кориÑничке ИД-ове за кључ %s</string>
<plurals name="msg_crt_certify_some">
@@ -883,6 +965,7 @@
<item quantity="few">Оверавам %1$d кориÑничка ИД-а за кључ %2$s</item>
<item quantity="other">Оверавам %1$d кориÑничких ИД-ова за кључ %2$s</item>
</plurals>
+ <string name="msg_crt_error_self">Ðе могу да издам овакав ÑамопотпиÑани Ñертификат!</string>
<string name="msg_crt_error_master_not_found">Главни кључ није нађен!</string>
<string name="msg_crt_error_nothing">Ðема оверених кључева!</string>
<string name="msg_crt_error_unlock">Грешка откључавања главног кључа!</string>
@@ -913,6 +996,7 @@
<string name="msg_import_fingerprint_ok">Провера отиÑка је у реду</string>
<string name="msg_import_merge">Спајам добављене податке</string>
<string name="msg_import_error">Радња увоза није уÑпела!</string>
+ <string name="msg_import_error_io">Радња увоза није уÑпела због У/И грешке!</string>
<string name="msg_import_partial">Радња увоза је уÑпела, Ñа грешкама!</string>
<string name="msg_import_success">Радња увоза је уÑпела!</string>
<plurals name="msg_export">
@@ -929,7 +1013,8 @@
<string name="msg_export_error_uri_open">Грешка отварања УРИ тока!</string>
<string name="msg_export_error_storage">Складиште није Ñпремно за упиÑивање!</string>
<string name="msg_export_error_db">Грешка базе података!</string>
- <string name="msg_export_error_io">Улазно/излазна грешка!</string>
+ <string name="msg_export_error_io">Грешка улаза/излаза!</string>
+ <string name="msg_export_error_key">Грешка предобраде података кључа!</string>
<string name="msg_export_success">Радња извоза је уÑпела</string>
<string name="msg_del_error_empty">Ðема ништа за бриÑање!</string>
<string name="msg_del_error_multi_secret">Тајне кључеве можете бриÑати Ñамо појединачно!</string>
@@ -970,6 +1055,11 @@
<string name="passp_cache_notif_keys">Кеширане лозинке:</string>
<string name="passp_cache_notif_clear">ОчиÑти кеш</string>
<string name="passp_cache_notif_pwd">Лозинка</string>
+ <!--First Time-->
+ <string name="first_time_text1">Преузмите вашу приватноÑÑ‚ помоћу Отвореног кључарника!</string>
+ <string name="first_time_create_key">Ðаправи ми кључ</string>
+ <string name="first_time_import_key">Увези из фајла</string>
+ <string name="first_time_skip">ПреÑкочи поÑтаву</string>
<!--unsorted-->
<string name="section_certifier_id">Сертификатор</string>
<string name="section_cert">Детаљи Ñертификата</string>
@@ -1000,9 +1090,32 @@
<string name="error_multi_not_supported">Ð£Ð¿Ð¸Ñ Ð²Ð¸ÑˆÐµ фајлова није подржан. Ово је ограничење у текућем издању Ðндроида.</string>
<string name="key_colon">Кључ:</string>
<string name="exchange_description">Да биÑте почели размену кључева, Ñа деÑне Ñтране изаберите број учеÑника и додирните дугме „Почни размену“.\n\nБиће вам поÑтављено још два питања да би Ñе оÑигурало да Ñу Ñамо иÑправни учеÑници у размени и да Ñу њихови отиÑци тачни.</string>
- <!--First Time-->
- <string name="first_time_text1">Преузмите вашу приватноÑÑ‚ помоћу Отвореног кључарника!</string>
- <string name="first_time_create_key">Ðаправи ми кључ</string>
- <string name="first_time_import_key">Увези из фајла</string>
- <string name="first_time_skip">ПреÑкочи поÑтаву</string>
+ <string name="btn_start_exchange">Почни размену</string>
+ <string name="user_id_none"><![CDATA[<ништа>]]></string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <string name="title_unlock_method">Одредите методу откључавања</string>
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <string name="enter_passphrase">УнеÑите лозинку</string>
+ <string name="passphrase">Лозинка</string>
+ <string name="noPassphrase">Без лозинке</string>
+ <string name="no_passphrase_set">Лозинка није поÑтављена</string>
+ <string name="passphrases_match">Лозинке Ñе поклапају</string>
+ <string name="passphrase_saved">Лозинка Ñачувана</string>
+ <string name="passphrase_invalid">Лозинка није иÑправна</string>
+ <string name="missing_passphrase">ÐедоÑтаје лозинка</string>
+ <string name="passphrase_again">Поновите</string>
+ <string name="lockpattern">Шаблон закључавања</string>
+ <string name="lockpatternNFC">ÐФЦ + шаблон</string>
+ <string name="unlock_method">Метода откључавања</string>
+ <string name="set_passphrase">ПоÑтави лозинку</string>
+ <string name="draw_lockpattern">Ðацртајте шаблон</string>
+ <string name="nfc_title">ÐФЦ</string>
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+ <string name="nfc_wrong_tag">Погрешна ознака. Покушајте поново.</string>
+ <string name="enable_nfc">Ðктивирајте ÐФЦ у поÑтавкама</string>
+ <string name="no_nfc_support">Овај уређај не подржава ÐФЦ</string>
+ <string name="nfc_write_succesful">УÑпешно упиÑах на ÐФЦ ознаку</string>
+ <string name="unlocked">Откључан</string>
+ <string name="nfc_settings">ПоÑтавке</string>
</resources>
diff --git a/OpenKeychain/src/main/res/values-sv/strings.xml b/OpenKeychain/src/main/res/values-sv/strings.xml
index a56eb7f75..7c855176b 100644
--- a/OpenKeychain/src/main/res/values-sv/strings.xml
+++ b/OpenKeychain/src/main/res/values-sv/strings.xml
@@ -9,13 +9,13 @@
<string name="title_encrypt_text">Kryptera text</string>
<string name="title_encrypt_files">Kryptera filer</string>
<string name="title_decrypt">Dekryptera</string>
- <string name="title_authentication">Lösenordsfras</string>
+ <string name="title_unlock">LÃ¥s upp nyckel</string>
<string name="title_add_subkey">Lägg till undernyckel</string>
<string name="title_edit_key">Redigera nyckel</string>
<string name="title_preferences">Inställningar</string>
<string name="title_cloud_search_preferences">Inställningar för molnsökning</string>
<string name="title_api_registered_apps">Appar</string>
- <string name="title_key_server_preference">Inställningar för nyckelserver</string>
+ <string name="title_key_server_preference">Nyckelservrar</string>
<string name="title_change_passphrase">Ändra lösenordsfras</string>
<string name="title_share_fingerprint_with">Dela fingeravtryck med…</string>
<string name="title_share_key">Dela nyckel med…</string>
@@ -34,6 +34,9 @@
<string name="title_help">Hjälp</string>
<string name="title_log_display">Logg</string>
<string name="title_create_key">Skapa nyckel</string>
+ <string name="title_exchange_keys">Utbyt nycklar</string>
+ <string name="title_advanced_key_info">Avancerad nyckelinfo</string>
+ <string name="title_keys">Nycklar</string>
<!--section-->
<string name="section_user_ids">Identiteter</string>
<string name="section_keys">Undernycklar</string>
@@ -52,6 +55,9 @@
<string name="section_key_to_certify">Nyckel att certifiera</string>
<string name="section_decrypt_files">Filer</string>
<string name="section_decrypt_text">Text</string>
+ <string name="section_certs">Certifikat</string>
+ <string name="section_encrypt">Kryptera</string>
+ <string name="section_decrypt">Dekryptera</string>
<!--button-->
<string name="btn_decrypt_verify_file">Dekryptera, verifiera och spara fil</string>
<string name="btn_decrypt_verify_message">Dekryptera och verifiera meddelande</string>
@@ -71,21 +77,25 @@
<string name="btn_create_key">Skapa nyckel</string>
<string name="btn_add_files">Lägg till fil(er)</string>
<string name="btn_add_share_decrypted_text">Dela dekrypterad text</string>
- <string name="btn_decrypt_clipboard">Dekryptera från urklipp</string>
+ <string name="btn_decrypt_clipboard">Dekryptera text från urklipp</string>
<string name="btn_decrypt_and_verify">och verifiera signaturer</string>
<string name="btn_decrypt_files">Dekryptera filer</string>
+ <string name="btn_encrypt_files">Kryptera filer</string>
+ <string name="btn_encrypt_text">Kryptera text</string>
<!--menu-->
<string name="menu_preferences">Inställningar</string>
<string name="menu_help">Hjälp</string>
<string name="menu_export_key">Exportera till fil</string>
<string name="menu_delete_key">Radera nyckel</string>
<string name="menu_create_key">Skapa min nyckel</string>
+ <string name="menu_import_existing_key">Importera från fil</string>
<string name="menu_search">Sök</string>
<string name="menu_beam_preferences">Beam-inställningar</string>
<string name="menu_key_edit_cancel">Avbryt</string>
<string name="menu_encrypt_to">Kryptera till…</string>
<string name="menu_select_all">Markera alla</string>
<string name="menu_add_keys">Lägg till nycklar</string>
+ <string name="menu_search_cloud">Sök i molnet</string>
<string name="menu_export_all_keys">Exportera alla nycklar</string>
<string name="menu_advanced">Visa avancerad information</string>
<!--label-->
@@ -102,8 +112,9 @@
<string name="label_file_ascii_armor">Aktivera ASCII-format</string>
<string name="label_write_version_header">Låt andra se att du använder OpenKeychain</string>
<string name="label_write_version_header_summary">Skriver \'OpenKeychain v2.7\' till OpenPGP-signaturer, chiffertext och exporterade nycklar.</string>
- <string name="label_use_default_yubikey_pin">Använd förvald Yubikey PIN</string>
- <string name="label_label_use_default_yubikey_pin_summary">Använder förvald PIN (123456) för att få åtkomst till Yubikeys via NFC</string>
+ <string name="label_use_default_yubikey_pin">Använd förvald YubiKey PIN</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Använd numeriska tangentbordet för YubiKey PIN</string>
+ <string name="label_label_use_default_yubikey_pin_summary">Använder förvald PIN (123456) för att få åtkomst till YubiKeys via NFC</string>
<string name="label_asymmetric_from">Signerat av:</string>
<string name="label_to">Kryptera till:</string>
<string name="label_delete_after_encryption">Radera fil efter kryptering</string>
@@ -116,7 +127,7 @@
<string name="label_message_compression">Meddelandekompression</string>
<string name="label_file_compression">Filkompression</string>
<string name="label_keyservers">Nyckelservrar</string>
- <string name="label_key_id">nyckel-ID</string>
+ <string name="label_key_id">Nyckel-ID</string>
<string name="label_expiry">GÃ¥r ut</string>
<string name="label_usage">Användning</string>
<string name="label_key_size">Nyckelstorlek</string>
@@ -125,10 +136,13 @@
<string name="label_name">Namn</string>
<string name="label_comment">Kommentar</string>
<string name="label_email">E-post</string>
+ <string name="label_send_key">Synkronisera med molnet</string>
<string name="label_fingerprint">Fingeravtryck</string>
<string name="expiry_date_dialog_title">Ställ in utgångsdatum</string>
<string name="label_first_keyserver_is_used">(Nyckelservern först i listan är den som föredras)</string>
+ <string name="label_preferred">föredraget</string>
<string name="user_id_no_name">&lt;inget namn&gt;</string>
+ <string name="none">&lt;ingen&gt;</string>
<string name="no_key">&lt;ingen nyckel&gt;</string>
<string name="can_encrypt">kan kryptera</string>
<string name="can_sign">kan signera</string>
@@ -144,7 +158,7 @@
<item quantity="one">%d nyckelserver</item>
<item quantity="other">%d nyckelservrar</item>
</plurals>
- <string name="secret_key">Privat nyckel</string>
+ <string name="secret_key">Privat nyckel:</string>
<!--choice-->
<string name="choice_none">Ingen</string>
<string name="choice_15secs">15 s</string>
@@ -180,10 +194,12 @@
<string name="passphrase_must_not_be_empty">Ange en lösenordsfras.</string>
<string name="passphrase_for_symmetric_encryption">Symmetrisk kryptering.</string>
<string name="passphrase_for">Ange lösenordsfras för \'%s\'</string>
- <string name="yubikey_pin">Ange PIN för att få åtkomst till Yubikey för \'%s\'</string>
+ <string name="pin_for">Ange PIN för \'%s\'</string>
+ <string name="yubikey_pin_for">Ange PIN för att få åtkomst till YubiKey för \'%s\'</string>
+ <string name="nfc_text">HÃ¥ll YubiKey mot baksidan av din enhet.</string>
<string name="file_delete_confirmation">Vill du verkligen radera\n%s?</string>
<string name="file_delete_successful">Raderades.</string>
- <string name="no_file_selected">Välj en nyckel först.</string>
+ <string name="no_file_selected">Välj en fil först.</string>
<string name="encrypt_sign_successful">Signerades och/eller krypterades.</string>
<string name="encrypt_sign_clipboard_successful">Signerades och/eller krypterades till urklipp.</string>
<string name="enter_passphrase_twice">Ange lösenordsfrasen två gånger.</string>
@@ -227,6 +243,7 @@
<string name="error_no_signature_passphrase">ingen lösenordsfras angiven</string>
<string name="error_no_signature_key">ingen signaturnyckel angiven</string>
<string name="error_invalid_data">Inget giltigt krypterat eller signerat OpenPGP-innehåll!</string>
+ <string name="error_integrity_check_failed">integritetskontroll misslyckades! Data har modifierats!</string>
<string name="error_wrong_passphrase">fel lösenordsfras</string>
<string name="error_could_not_extract_private_key">kunde inte extrahera privat nyckel</string>
<!--errors without preceeding Error:-->
@@ -247,6 +264,7 @@
<string name="decrypt_result_not_encrypted">Inte krypterat</string>
<string name="decrypt_result_action_show">Visa</string>
<string name="decrypt_result_action_Lookup">Sök efter</string>
+ <string name="decrypt_invalid_text">Antingen är signaturen ogiltig eller så har nyckeln återkallats/gått ut. Du kan inte vara säker på vem som skrev texten. Vill du fortfarande visa den?</string>
<string name="decrypt_invalid_button">Jag förstår riskerna, visa den!</string>
<!--Add keys-->
<string name="add_keys_my_key">Min nyckel:</string>
@@ -268,6 +286,7 @@
<string name="progress_modify">modifierar nyckelring…</string>
<string name="progress_modify_unlock">låser upp nyckelring…</string>
<string name="progress_modify_adduid">lägger till användar-ID:n…</string>
+ <string name="progress_modify_adduat">lägger till användarattribut...</string>
<string name="progress_modify_revokeuid">återkallar användar-ID:n…</string>
<string name="progress_modify_primaryuid">ändrar primärt användar-ID…</string>
<string name="progress_modify_subkeychange">modifierar undernycklar…</string>
@@ -299,8 +318,8 @@
<string name="progress_con_saving">konsolidera: sparar till cache…</string>
<string name="progress_con_reimport">konsolidera: återimporterar…</string>
<!--action strings-->
- <string name="hint_keyserver_search_hint">Namn/E-post/Nyckel-ID</string>
- <string name="hint_cloud_search_hint">Namn/E-post/Bevis/Nyckel…</string>
+ <string name="hint_keyserver_search_hint">Namn/e-post/nyckel-ID…</string>
+ <string name="hint_cloud_search_hint">Namn/e-post/bevis/nyckel…</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@@ -340,8 +359,12 @@
<string name="import_import">Importera markerade nycklar</string>
<string name="import_qr_code_wrong">Något är fel med QR-koden! Försök igen!</string>
<string name="import_qr_code_too_short_fingerprint">Fingeravtryck är för kort (&lt; 16 tecken)</string>
+ <string name="import_qr_code_button">Skanna QR-kod</string>
+ <string name="import_qr_code_text">Håll din kamera över QR-koden!</string>
<!--Generic result toast-->
- <string name="view_log">Visa logg</string>
+ <string name="view_log">Detaljer</string>
+ <string name="with_warnings">, med varningar</string>
+ <string name="with_cancelled">, tills det avbryts</string>
<!--Import result toast-->
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">Importerade nyckel</item>
@@ -374,6 +397,10 @@
<item quantity="one">Raderade en nyckel</item>
<item quantity="other">Raderade %1$d nycklar</item>
</plurals>
+ <plurals name="delete_ok_but_fail_2">
+ <item quantity="one">, men misslyckades med att radera en nyckel%2$s.</item>
+ <item quantity="other">, men misslyckades med att radera %1$d nycklar%2$s.</item>
+ </plurals>
<plurals name="delete_ok">
<item quantity="one">Raderade nyckel%2$s.</item>
<item quantity="other">Raderade %1$d nycklar%2$s.</item>
@@ -383,11 +410,20 @@
<item quantity="other">Fel vid radering av %1$d nycklar.</item>
</plurals>
<string name="delete_nothing">Inget att radera.</string>
+ <string name="delete_cancelled">Raderingsoperation avbruten.</string>
<!--Certify result toast-->
<plurals name="certify_keys_ok">
<item quantity="one">Certifierade nyckel%2$s.</item>
<item quantity="other">Certifierade %1$d nycklar%2$s.</item>
</plurals>
+ <plurals name="certify_keys_with_errors">
+ <item quantity="one">Certifiering misslyckades!</item>
+ <item quantity="other">Certifiering misslyckades för %d nycklar!</item>
+ </plurals>
+ <plurals name="certify_error">
+ <item quantity="one">Certifiering misslyckades!</item>
+ <item quantity="other">Certifiering av %d nycklar misslyckades!</item>
+ </plurals>
<!--Intent labels-->
<string name="intent_decrypt_file">Dekryptera fil med OpenKeychain</string>
<string name="intent_import_key">Importera nyckel med OpenKeychain</string>
@@ -405,15 +441,20 @@
<string name="api_settings_save">Spara</string>
<string name="api_settings_save_msg">Konto har sparats</string>
<string name="api_settings_cancel">Avbryt</string>
+ <string name="api_settings_revoke">Återkalla åtkomst</string>
<string name="api_settings_start">Starta app</string>
<string name="api_settings_delete_account">Radera konto</string>
<string name="api_settings_package_name">Paketnamn</string>
<string name="api_settings_package_signature">SHA-256 för paketsignatur</string>
- <string name="api_settings_accounts">Konton</string>
+ <string name="api_settings_accounts">Konton (övergivet API)</string>
+ <string name="api_settings_advanced">Avancerad information</string>
+ <string name="api_settings_allowed_keys">Tillåtna nycklar</string>
<string name="api_settings_settings">Inställningar</string>
<string name="api_settings_key">Kontonyckel:</string>
<string name="api_settings_accounts_empty">Inga konton kopplade till denna app.</string>
+ <string name="api_create_account_text">Ingen nyckel är konfigurerad för detta konto. Välj en av dina existerande nycklar eller skapa en ny.\nAppar kan endast dekryptera/signera med nycklarna som valts här!</string>
<string name="api_update_account_text">Nyckeln som sparats för detta konto har raderats. Välj en annan!\nAppar kan endast dekryptera/signera med nycklarna som valts här!</string>
+ <string name="api_register_text">Appen som visas vill kryptera/dekryptera meddelanden och signera dem i ditt namn.\nTillåt åtkomst?\n\nVARNING: Om du inte vet varför denna sida visas, neka åtkomst! Du kan återkalla åtkomst senare från \'Appar\' sidan.</string>
<string name="api_register_allow">Tillåt åtkomst</string>
<string name="api_register_disallow">Tillåt inte åtkomst</string>
<string name="api_register_error_select_key">Välj en nyckel!</string>
@@ -421,6 +462,7 @@
<string name="api_select_pub_keys_dublicates_text">Mer än en nyckel finns för dessa identiteter:</string>
<string name="api_select_pub_keys_text">Se över listan med mottagare!</string>
<string name="api_select_pub_keys_text_no_user_ids">Välj mottagare!</string>
+ <string name="api_error_wrong_signature">Signaturkontroll misslyckades! Har du installerat appen från en annan källa? Om du är säker på att det här inte är en attack, återkalla den här appens registrering i OpenKeychain och registrera sen om appen igen.</string>
<!--Share-->
<string name="share_qr_code_dialog_title">Dela med QR-kod</string>
<string name="share_nfc_dialog">Dela med NFC</string>
@@ -429,6 +471,7 @@
<item quantity="one">1 nyckel vald.</item>
<item quantity="other">%d nycklar valda.</item>
</plurals>
+ <string name="key_list_empty_text1">Inga nycklar hittades!</string>
<string name="key_list_filter_show_all">Visa alla nycklar</string>
<string name="key_list_filter_show_certified">Visa endast certifierade nycklar</string>
<!--Key view-->
@@ -449,6 +492,7 @@
<string name="user_id_info_certified_title">Certifierad</string>
<string name="user_id_info_certified_text">Den här identiteten har certifierats av dig.</string>
<string name="user_id_info_uncertified_title">Inte certifierad.</string>
+ <string name="user_id_info_uncertified_text">Den här identiteten har ännu inte certifierats. Du kan inte vara säker på att identiteten verkligen hänger ihop med en viss person.</string>
<string name="user_id_info_invalid_title">Ogiltig</string>
<string name="user_id_info_invalid_text">Något är fel med den här identiteten!</string>
<!--Edit key-->
@@ -471,6 +515,7 @@
<string name="edit_key_error_add_subkey">Lägg till åtminstone en undernyckel!</string>
<!--Create key-->
<string name="create_key_upload">Ladda upp nyckel till nyckelserver</string>
+ <string name="create_key_empty">Detta fält krävs</string>
<string name="create_key_passphrases_not_equal">Lösenordsfraser stämmer inte överens</string>
<string name="create_key_final_text">Du angav följande identitet:</string>
<string name="create_key_final_robot_text">Att skapa en nyckel kan ta ett tag, drick en kopp kaffe under tiden…</string>
@@ -478,14 +523,13 @@
<string name="create_key_custom">(anpassad nyckelkonfiguration)</string>
<string name="create_key_text">Ange ditt fullständiga namn, e-postadress och välj en lösenordsfras.</string>
<string name="create_key_hint_full_name">Fullständigt namn, t.ex. Kalle Svensson</string>
+ <string name="create_key_edit">Ändra nyckelkonfiguration</string>
<!--View key-->
<string name="view_key_revoked">Den här nyckeln har återkallats!</string>
<string name="view_key_expired">Den här nyckeln har gått ut!</string>
<!--Navigation Drawer-->
<string name="nav_keys">Nycklar</string>
- <string name="nav_encrypt_text">Kryptera text</string>
- <string name="nav_encrypt_files">Kryptera filer</string>
- <string name="nav_decrypt">Dekryptera</string>
+ <string name="nav_encrypt_decrypt">Kryptera/Dekryptera</string>
<string name="nav_apps">Appar</string>
<string name="my_keys">Mina nycklar</string>
<!--hints-->
@@ -502,11 +546,16 @@
<string name="cert_verify_unavailable">nyckel inte tillgänglig</string>
<!--LogType log messages. Errors should have _ERROR_ in their name and end with a !-->
<string name="msg_internal_error">Intern fel!</string>
+ <string name="msg_cancelled">Operation avbruten.</string>
<!--Import Public log entries-->
<string name="msg_ip_bad_type_secret">Försökte att importera privat nyckelring som publik. Detta är en bugg, skicka en felrapport!</string>
<string name="msg_ip_delete_old_fail">Ingen gammal nyckel raderad (skapa en ny?)</string>
<string name="msg_ip_delete_old_ok">Raderade gammal nyckel från databas</string>
+ <string name="msg_ip_error_op_exc">Operationen misslyckades på grund av ett databasfel</string>
+ <string name="msg_ip_error_remote_ex">Operationen misslyckades på grund av ett internt fel</string>
<string name="msg_ip">Importerar publik nyckelring %s</string>
+ <string name="msg_ip_insert_keyring">Kodar nyckelringens data</string>
+ <string name="msg_ip_insert_keys">Läser nycklar</string>
<string name="msg_ip_prepare">Förebereder databasoperationer</string>
<string name="msg_ip_master">Bearbetar huvudnyckel %s</string>
<string name="msg_ip_master_expired">Nyckelring gick ut %s</string>
@@ -528,6 +577,8 @@
<string name="msg_ip_master_flags_xxsx">Huvudflaggor: signera</string>
<string name="msg_ip_master_flags_xxxa">Huvudflaggor: autentisera</string>
<string name="msg_ip_master_flags_xxxx">Huvudflaggor: ingen</string>
+ <string name="msg_ip_merge_public">Slår ihop importerade data med befintlig publik nyckelring</string>
+ <string name="msg_ip_merge_secret">Slår ihop importerade data med befintlig publik nyckelring</string>
<string name="msg_ip_subkey">Bearbetar undernyckel %s</string>
<string name="msg_ip_subkey_expired">Undernyckel gick ut %s</string>
<string name="msg_ip_subkey_expires">Undernyckel går ut %s</string>
@@ -553,28 +604,61 @@
<string name="msg_ip_reinsert_secret">Sätter in privat nyckel på nytt</string>
<string name="msg_ip_uid_cert_bad">Stötte på ett dåligt certifikat!</string>
<string name="msg_ip_uid_cert_error">Fel vid bearbetning av certifikat!</string>
+ <string name="msg_ip_uid_cert_nonrevoke">Har redan ett icke-återkalleligt certifikat, hoppar över.</string>
<string name="msg_ip_uid_cert_old">Certifikat är äldre än det förra, hoppar över.</string>
<string name="msg_ip_uid_cert_new">Certifikat är mer aktuellt, ersätter det förra.</string>
+ <string name="msg_ip_uid_cert_good">Hittade ett bra certifikat från %1$s</string>
+ <string name="msg_ip_uid_cert_good_revoke">Hittade bra certifikatåterkallning från %1$s</string>
<plurals name="msg_ip_uid_certs_unknown">
<item quantity="one">Hoppar över ett certifikat utfärdat av okända publika nycklar</item>
<item quantity="other">Hoppar över %s certifikat utfärdade av okända publika nycklar</item>
</plurals>
+ <string name="msg_ip_uid_classifying_zero">Klassificerar användar-ID:n (inga tillförlitliga nycklar tillgängliga)</string>
+ <plurals name="msg_ip_uid_classifying">
+ <item quantity="one">Klassificerar användar-ID:n (använder en tillförlitlig nyckel)</item>
+ <item quantity="other">Klassificerar användar-ID:n (använder %s tillförlitliga nycklar)</item>
+ </plurals>
+ <string name="msg_ip_uid_reorder">Ordnar om användar-ID:n</string>
+ <string name="msg_ip_uid_processing">Bearbetar användar-ID %s</string>
+ <string name="msg_ip_uid_revoked">Användar-ID är återkallat</string>
+ <string name="msg_ip_uat_processing_image">Bearbetar användarattribut av typen bild</string>
+ <string name="msg_ip_uat_processing_unknown">Bearbetar användarattribut av okänd typ</string>
+ <string name="msg_ip_uat_cert_bad">Stötte på ett dåligt certifikat!</string>
+ <string name="msg_ip_uat_cert_error">Fel vid bearbetning av certifikat!</string>
+ <string name="msg_ip_uat_cert_nonrevoke">Har redan ett icke-återkalleligt certifikat, hoppar över.</string>
+ <string name="msg_ip_uat_cert_old">Certifikat är äldre än det förra, hoppar över.</string>
+ <string name="msg_ip_uat_cert_new">Certifikat är mer aktuellt, ersätter det förra.</string>
+ <string name="msg_ip_uat_cert_good">Hittade ett bra certifikat från %1$s</string>
+ <string name="msg_ip_uat_cert_good_revoke">Hittade bra certifikatåterkallning från %1$s</string>
+ <plurals name="msg_ip_uat_certs_unknown">
+ <item quantity="one">Hoppar över ett certifikat utfärdat av en okänd publik nyckel</item>
+ <item quantity="other">Hoppar över %s certifikat utfärdade av okända publika nycklar</item>
+ </plurals>
+ <string name="msg_ip_uat_classifying">Klassificerar användarattribut</string>
+ <string name="msg_ip_uat_revoked">Användarattribut är återkallat</string>
+ <string name="msg_is_bad_type_public">Försökte att importera publik nyckelring som privat. Detta är en bugg, skicka en felrapport!</string>
<!--Import Secret log entries-->
<string name="msg_is">Importerar privat nyckel %s</string>
<string name="msg_is_db_exception">Databasfel!</string>
<string name="msg_is_importing_subkeys">Bearbetar privata undernycklar</string>
+ <string name="msg_is_error_io_exc">Fel vid kodning av nyckelring</string>
+ <string name="msg_is_merge_public">Slår ihop importerade data med befintlig publik nyckelring</string>
+ <string name="msg_is_merge_secret">Slår ihop importerade data med befintlig publik nyckelring</string>
<string name="msg_is_pubring_generate">Genererar publik nyckelring från privat nyckelring</string>
<string name="msg_is_subkey_nonexistent">Undernyckel %s inte tillgänglig i privat nyckelring</string>
<string name="msg_is_success_identical">Nyckelringen innehåller ingen ny information, inget att göra</string>
<string name="msg_is_success">Importerade privat nyckelring</string>
<!--Keyring Canonicalization log entries-->
<string name="msg_kc_error_v3">Den här nyckeln är skapad med OpenPGP version 3, vilken är en föråldrad version som inte längre stöds!</string>
+ <string name="msg_kc_error_no_uid">Nyckelringen har inga giltiga användar-ID:n!</string>
<string name="msg_kc_error_master_algo">Den här huvudnyckeln använder en okänd (%s) algoritm!</string>
<string name="msg_kc_master">Bearbetar huvudnyckel</string>
- <string name="msg_kc_revoke_bad_err">Tar bort dåligt återkallelsecertifikat för nyckelring</string>
- <string name="msg_kc_revoke_bad_time">Tar bort återkallelsecertifikat för nyckelring med framtida tidstämpel</string>
- <string name="msg_kc_revoke_bad_type">Tar bort huvudnyckelcertifikat av okänd typ (%s)</string>
- <string name="msg_kc_revoke_bad">Tar bort dåligt återkallelsecertifikat för nyckelring</string>
+ <string name="msg_kc_master_bad_type">Tar bort huvudnyckelcertifikat av okänd typ (%s)</string>
+ <string name="msg_kc_master_bad_local">Tar bort huvudnyckelcertifikat med flaggan \"local\"</string>
+ <string name="msg_kc_master_bad_err">Tar bort dåligt huvudnyckelcertifikat</string>
+ <string name="msg_kc_master_bad_time">Tar bort återkallelsecertifikat för nyckelring med framtida tidstämpel</string>
+ <string name="msg_kc_master_bad">Tar bort dåligt huvudnyckelcertifikat</string>
+ <string name="msg_kc_master_local">Tar bort huvudnyckelcertifikat med flaggan \"local\"</string>
<string name="msg_kc_revoke_dup">Tar bort överflödigt återkallelsecertifikat för nyckelring</string>
<string name="msg_kc_sub">Bearbetar undernyckel %s</string>
<string name="msg_kc_sub_no_cert">Inget giltigt certifikat hittades för %s, tar bort från nyckelring</string>
@@ -582,17 +666,30 @@
<string name="msg_kc_sub_revoke_bad">Tar bort dåligt återkallelsecertifikat för undernyckel</string>
<string name="msg_kc_sub_revoke_dup">Tar bort överflödigt återkallelsecertifikat för undernyckel</string>
<string name="msg_kc_sub_unknown_algo">Undernyckel använder en okänd algoritm, importerar inte…</string>
+ <string name="msg_kc_uid_bad_err">Tar bort dåligt eget-certifikat för användar-ID \'%s\'</string>
+ <string name="msg_kc_uid_bad_time">Tar bort användar-ID med framtida tidstämpel</string>
+ <string name="msg_kc_uid_bad">Tar bort dåligt eget-certifikat för användar-ID \'%s\'</string>
+ <string name="msg_kc_uid_cert_dup">Tar bort föråldrat eget-certifikat för användar-ID \'%s\'</string>
+ <string name="msg_kc_uid_revoke_dup">Tar bort överflödigt återkallelsecertifikat för användar-ID \'%s\'</string>
+ <string name="msg_kc_uid_revoke_old">Tar bort föråldrat återkallelsecertifikat för användar-ID \'%s\'</string>
+ <string name="msg_kc_uid_no_cert">Inget giltigt eget-certifikat hittades för användar-ID \'%s\', tar bort från nyckelring</string>
+ <string name="msg_kc_uid_remove">Tar bort ogiltigt användar-ID \'%s\'</string>
<string name="msg_kc_uid_warn_encoding">Användar-ID verifierar inte som UTF-8!</string>
+ <string name="msg_kc_uat_remove">Tar bort ogiltigt användarattribut</string>
<!--Keyring merging log entries-->
<string name="msg_mg_error_heterogeneous">Försökte att slå ihop nyckelringar med olika fingeravtryck!</string>
+ <string name="msg_mg_error_encode">Allvarligt fel vid kodning av signatur!</string>
<string name="msg_mg_public">Slår ihop till publik nyckelring %s</string>
<string name="msg_mg_secret">Slår ihop till privat nyckelring %s</string>
<string name="msg_mg_new_subkey">Lägger till ny undernyckel %s</string>
+ <string name="msg_mg_found_new">Hittade %s nya certifikat i nyckelring</string>
+ <string name="msg_mg_unchanged">Inget att slå ihop</string>
<!--createSecretKeyRing-->
<string name="msg_cr">Genererar ny huvudnyckel</string>
+ <string name="msg_cr_error_no_user_id">Nyckelringar måste skapas med minst ett användar-ID!</string>
<string name="msg_cr_error_no_certify">Huvudnyckel måste ha en certifieringsflagga!</string>
<string name="msg_cr_error_keysize_512">Nyckelstorlek måste vara större eller lika med 512!</string>
- <string name="msg_cr_error_internal_pgp">Internt PGP-fel!</string>
+ <string name="msg_cr_error_internal_pgp">Internt OpenPGP-fel!</string>
<string name="msg_cr_error_unknown_algo">Okänd algoritm vald. Detta är ett programmeringsfel, skicka en buggrapport!</string>
<string name="msg_cr_error_flags_dsa">Dåliga nyckelflaggor valda, DSA kan inte användas för kryptering!</string>
<string name="msg_cr_error_flags_elgamal">Dåliga nyckelflaggor valda, ElGamal kan inte användas för signering!</string>
@@ -600,22 +697,33 @@
<string name="msg_cr_error_flags_ecdh">Dåliga nyckelflaggor valda, ECDH kan inte användas för signering!</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">Modifierar nyckelring %s</string>
+ <string name="msg_mf_error_fingerprint">Det verkliga nyckelfingeravtrycket stämmer inte överens med det som förväntades!</string>
<string name="msg_mf_error_keyid">Inget nyckel-ID. Det här är ett internt fel, skicka en buggrapport!</string>
- <string name="msg_mf_error_pgp">Internt PGP-fel!</string>
- <string name="msg_mf_passphrase">Ändrar lösenordsfras för nyckelring…</string>
+ <string name="msg_mf_error_noexist_primary">Dåligt primärt användar-ID angivet!</string>
+ <string name="msg_mf_error_revoked_primary">Återkallade användar-ID:n kan inte vara primära!</string>
+ <string name="msg_mf_error_pgp">Internt OpenPGP-fel!</string>
+ <string name="msg_mf_passphrase">Ändrar lösenordsfras för nyckelring</string>
<string name="msg_mf_passphrase_key">Krypterar undernyckel %s på nytt med ny lösenordsfras</string>
<string name="msg_mf_passphrase_empty_retry">Det gick inte att ställa in ny lösenordsfras, försök igen med en tom gammal lösenordsfras</string>
+ <string name="msg_mf_primary_replace_old">Ersätter certifikat för tidigare primärt användar-ID</string>
+ <string name="msg_mf_primary_new">Genererar nytt certifikat för nytt primärt användar-ID</string>
<string name="msg_mf_subkey_change">Modifierar undernyckel %s</string>
<string name="msg_mf_subkey_new">Lägger till ny undernyckel av typen %s</string>
<string name="msg_mf_subkey_new_id">Nytt undernyckel-ID: %s</string>
<string name="msg_mf_error_past_expiry">Utgångsdatum kan inte vara i det förflutna!</string>
<string name="msg_mf_subkey_revoke">Ã…terkallar undernyckel %s</string>
<string name="msg_mf_subkey_strip">Rensar undernyckel %s</string>
+ <string name="msg_mf_uid_add">Lägger till användar-ID %s</string>
+ <string name="msg_mf_uid_primary">Ändrar primärt användar-ID till %s</string>
+ <string name="msg_mf_uid_revoke">Återkallar användar-ID %s</string>
<string name="msg_mf_uid_error_empty">Användar-ID får inte vara tomt!</string>
+ <string name="msg_mf_unlock">LÃ¥ser upp nyckelring</string>
<!--Consolidate-->
<string name="msg_con">Konsoliderar databas</string>
<string name="msg_con_error_bad_state">Konsolidering startade medan ingen databas var cachad! Detta är förmodligen ett programmeringsfel, skicka en buggrapport.</string>
<string name="msg_con_save_secret">Sparar privata nyckelringar</string>
+ <string name="msg_con_save_public">Sparar publika nyckelringar</string>
+ <string name="msg_con_db_clear">Rensar databas</string>
<string name="msg_con_success">Konsoliderade databas</string>
<string name="msg_con_delete_public">Raderar cache-fil för publik nyckelring</string>
<string name="msg_con_delete_secret">Raderar cache-fil för privat nyckelring</string>
@@ -632,31 +740,58 @@
<item quantity="other">Ã…terimporterar %d privata nycklar</item>
</plurals>
<string name="msg_con_reimport_secret_skip">Inga privata nycklar att återimportera, hoppar över…</string>
+ <!--Edit Key (higher level than modify)-->
+ <string name="msg_ed">Utför nyckeloperation</string>
+ <string name="msg_ed_caching_new">Cachar ny lösenordsfras</string>
+ <string name="msg_ed_error_key_not_found">Nyckel hittades inte!</string>
+ <string name="msg_ed_success">Nyckeloperation lyckades</string>
+ <!--Promote key-->
+ <string name="msg_pr_error_already_secret">Nyckeln är redan en privat nyckel!</string>
+ <string name="msg_pr_error_key_not_found">Nyckel hittades inte!</string>
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_divert">Det finns (ännu) inte stöd för att redigera NFC-nycklar!</string>
<string name="msg_ek_error_dummy">Kan inte redigera nyckelring med en rensad huvudnyckel!</string>
<string name="msg_ek_error_not_found">Nyckel hittades inte!</string>
<!--Messages for DecryptVerify operation-->
+ <string name="msg_dc_askip_no_key">Data inte krypterade med känd nyckel, hoppar över…</string>
+ <string name="msg_dc_askip_not_allowed">Data inte krypterade med tillåten nyckel, hoppar över…</string>
<string name="msg_dc_asym">Hittade block med asymmetriskt krypterad data för nyckel %s</string>
<string name="msg_dc_clear_decompress">Packar upp komprimerad data</string>
+ <string name="msg_dc_clear_meta_file">Filnamn: %s</string>
+ <string name="msg_dc_clear_meta_mime">MIME-typ: %s</string>
+ <string name="msg_dc_clear_meta_size">Filstorlek: %s</string>
+ <string name="msg_dc_clear_signature_bad">Signaturkontroll INTE OK!</string>
<string name="msg_dc_clear_signature_check">Verifierar signaturdata</string>
+ <string name="msg_dc_clear_signature_ok">Signaturkontroll OK</string>
<string name="msg_dc_clear_signature">Sparar signaturdata till senare</string>
<string name="msg_dc_clear">Bearbetar klartextdata</string>
+ <string name="msg_dc_error_extract_key">Okänt fel vid upplåsning av nyckel</string>
+ <string name="msg_dc_error_integrity_check">Fel vid integritetskontroll!</string>
<string name="msg_dc_ok_meta_only">Endast metadata krävdes, hoppar över dekryptering</string>
+ <string name="msg_dc_ok">OK</string>
+ <string name="msg_dc_pass_cached">Använder lösenordsfras från cache</string>
<string name="msg_dc_prep_streams">Förbereder strömmar för dekryptering</string>
+ <string name="msg_dc">Startar dekrypteringsoperation…</string>
+ <string name="msg_dc_sym_skip">Symmetrisk data inte tillåten, hoppar över…</string>
<string name="msg_dc_sym">Hittade block med symmetriskt krypterad data</string>
<string name="msg_dc_unlocking">LÃ¥ser upp privat nyckel</string>
<!--Messages for SignEncrypt operation-->
- <string name="msg_se_asymmetric">Förbereder publika nycklar för kryptering</string>
- <string name="msg_se_compressing">Förbereder kompression</string>
- <string name="msg_se_encrypting">Krypterar data</string>
- <string name="msg_se_error_bad_passphrase">Dålig lösenordsfras!</string>
- <string name="msg_se_error_key_sign">Den valda signeringsnyckeln kan inte signera data!</string>
- <string name="msg_se_error_pgp">Internt PGP-fel!</string>
- <string name="msg_se_sigcrypting">Krypterar data med signatur</string>
- <string name="msg_se_symmetric">Förbereder symmetrisk kryptering!</string>
+ <string name="msg_se_success">Signering/kryptering lyckades!</string>
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_pse_asymmetric">Förbereder publika nycklar för kryptering</string>
+ <string name="msg_pse_compressing">Förbereder komprimering</string>
+ <string name="msg_pse_encrypting">Krypterar data</string>
+ <string name="msg_pse_error_bad_passphrase">Dålig lösenordsfras!</string>
+ <string name="msg_pse_error_nfc">NFC datafel!</string>
+ <string name="msg_pse_error_no_passphrase">Ingen lösenordsfras angiven!</string>
+ <string name="msg_pse_error_pgp">Internt OpenPGP-fel!</string>
+ <string name="msg_pse_signing_cleartext">Skapar signatur i klartext</string>
+ <string name="msg_pse_sigcrypting">Krypterar data med signatur</string>
+ <string name="msg_pse_symmetric">Förbereder symmetrisk kryptering</string>
<string name="msg_crt_error_master_not_found">Huvudnyckel hittades inte!</string>
<string name="msg_crt_error_nothing">Inga nycklar certifierade!</string>
+ <string name="msg_crt_error_unlock">Fel vid upplåsning av huvudnyckel!</string>
+ <string name="msg_crt">Certifierar nyckelringar</string>
<string name="msg_crt_save">Sparar certifierad nyckel %s</string>
<string name="msg_crt_saving">Sparar nyckelringar</string>
<string name="msg_crt_unlock">LÃ¥ser upp huvudnyckel</string>
@@ -666,12 +801,25 @@
<item quantity="one">Importerar nyckel</item>
<item quantity="other">Importerar %d nycklar</item>
</plurals>
- <string name="msg_import_partial">Import lyckades, med fel!</string>
+ <string name="msg_import_fetch_keyserver">Hämtar från nyckelserver: %s</string>
+ <string name="msg_import_fetch_keyserver_ok">Nyckelhämtning lyckades</string>
+ <string name="msg_import_keyserver">Använder nyckelserver %s</string>
+ <string name="msg_import_fingerprint_ok">Kontroll av fingeravtyck OK</string>
+ <string name="msg_import_merge">Slår ihop data som tagits emot</string>
+ <string name="msg_import_error">Importoperation misslyckades!</string>
+ <string name="msg_import_partial">Importoperation lyckades, med fel!</string>
+ <string name="msg_import_success">Importoperation lyckades!</string>
+ <plurals name="msg_export">
+ <item quantity="one">Exporterar en nyckel</item>
+ <item quantity="other">Exporterar %d nycklar</item>
+ </plurals>
<string name="msg_export_all">Exporterar alla nycklar</string>
<string name="msg_export_public">Exporterar publik nyckel %s</string>
<string name="msg_export_secret">Exporterar privat nyckel %s</string>
+ <string name="msg_export_error_fopen">Fel vid öppning av fil!</string>
+ <string name="msg_export_error_no_uri">Ingen URI specifierad!</string>
<string name="msg_export_error_db">Databasfel!</string>
- <string name="msg_export_success">Export lyckades</string>
+ <string name="msg_export_success">Exportoperation lyckades</string>
<string name="msg_del_error_empty">Inget att radera!</string>
<string name="msg_del_error_multi_secret">Privata nycklar kan bara raderas var för sig!</string>
<plurals name="msg_del">
@@ -679,7 +827,18 @@
<item quantity="other">Raderar %d nycklar</item>
</plurals>
<string name="msg_del_key">Raderar nyckel %s</string>
+ <string name="msg_del_key_fail">Misslyckades med att radera nyckel %s</string>
+ <plurals name="msg_del_ok">
+ <item quantity="one">Raderade nyckel</item>
+ <item quantity="other">Raderade %d nycklar</item>
+ </plurals>
+ <plurals name="msg_del_fail">
+ <item quantity="one">Misslyckades med att radera en nyckel</item>
+ <item quantity="other">Misslyckades med att radera %d nycklar</item>
+ </plurals>
+ <string name="msg_acc_saved">Konto sparat</string>
<string name="msg_download_success">Hämtning lyckades!</string>
+ <string name="msg_download_no_valid_keys">Inga giltiga nycklar hittades i fil/urklipp!</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">en del av den inlästa filen är ett giltigt OpenPGP-objekt men inte en OpenPGP-nyckel</item>
<item quantity="other">delar av den inlästa filen är giltiga OpenPGP-objekt men inte OpenPGP-nycklar</item>
@@ -690,10 +849,17 @@
<string name="passp_cache_notif_keys">Cachade lösenordsfraser:</string>
<string name="passp_cache_notif_clear">Rensa cache</string>
<string name="passp_cache_notif_pwd">Lösenordsfras</string>
+ <!--First Time-->
+ <string name="first_time_text1">Ta tillbaka din integritet med OpenKeychain!</string>
+ <string name="first_time_create_key">Skapa min nyckel!</string>
+ <string name="first_time_import_key">Importera från fil</string>
+ <string name="first_time_skip">Hoppa över inställning</string>
<!--unsorted-->
- <string name="section_cert">Certifikatdetaljer</string>
+ <string name="section_cert">Certifikatinformation</string>
<string name="label_user_id">Identitet</string>
+ <string name="unknown_uid">&lt;okänd&gt;</string>
<string name="empty_certs">Inga certifikat för den här nyckeln</string>
+ <string name="section_uids_to_certify">Identiteter för</string>
<string name="label_revocation">Anledning till återkallelse</string>
<string name="label_verify_status">Verifieringsstatus</string>
<string name="label_cert_type">Typ</string>
@@ -709,9 +875,32 @@
<string name="error_no_encrypt_subkey">Ingen krypteringsundernyckel tillgänglig!</string>
<string name="info_no_manual_account_creation">Skapa inte OpenKeychain-konton manuellt. \nFör mer information, se Hjälp.</string>
<string name="contact_show_key">Visa nyckel (%s)</string>
+ <string name="swipe_to_update">Dra nedåt för att uppdatera från nyckelserver</string>
<string name="error_no_file_selected">Välj åtminstone en fil att kryptera!</string>
+ <string name="error_multi_not_supported">Att spara flera filer stöds ej. Detta är en begränsning i nuvarande Android.</string>
<string name="key_colon">Nyckel:</string>
- <!--First Time-->
- <string name="first_time_create_key">Skapa min nyckel!</string>
- <string name="first_time_skip">Hoppa över inställning</string>
+ <string name="user_id_none"><![CDATA[<none>]]></string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <string name="enter_passphrase">Ange lösenordsfras</string>
+ <string name="passphrase">Lösenordsfras</string>
+ <string name="noPassphrase">Ingen lösenordsfras</string>
+ <string name="passphrases_match">Lösenordsfraser stämmer överens</string>
+ <string name="passphrase_saved">Lösenordsfras sparad</string>
+ <string name="passphrase_invalid">Lösenordsfras ogiltig</string>
+ <string name="missing_passphrase">Lösenordsfras saknas</string>
+ <string name="passphrase_again">Igen</string>
+ <string name="lockpattern">Låsmönster</string>
+ <string name="lockpatternNFC">NFC + Låsmönster</string>
+ <string name="unlock_method">Upplåsningmetod</string>
+ <string name="set_passphrase">Sätt lösenordsfras</string>
+ <string name="draw_lockpattern">Dra låsmönster</string>
+ <string name="nfc_title">NFC</string>
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+ <string name="nfc_wrong_tag">Fel Tag. Försök igen.</string>
+ <string name="enable_nfc">Vänligen aktivera NFC i dina inställningar</string>
+ <string name="no_nfc_support">Denna enhet stöder inte NFC</string>
+ <string name="unlocked">Upplåst</string>
+ <string name="nfc_settings">Inställningar</string>
</resources>
diff --git a/OpenKeychain/src/main/res/values-tr/strings.xml b/OpenKeychain/src/main/res/values-tr/strings.xml
index 83f996392..194224708 100644
--- a/OpenKeychain/src/main/res/values-tr/strings.xml
+++ b/OpenKeychain/src/main/res/values-tr/strings.xml
@@ -8,19 +8,16 @@
<string name="title_select_secret_key">Anahtarını Seç</string>
<string name="title_encrypt_text">Metni Åžifrele</string>
<string name="title_encrypt_files">Dosyaları Şifrele</string>
- <string name="title_decrypt">Çözümle</string>
- <string name="title_authentication">Parola</string>
+ <string name="title_decrypt">Şifre çöz</string>
<string name="title_add_subkey">Alt anahtar ekle</string>
<string name="title_edit_key">Anahtarı düzenle</string>
- <string name="title_preferences">Seçenekler</string>
<string name="title_cloud_search_preferences">Bulut Arama Seçenekleri</string>
<string name="title_api_registered_apps">Uygulamalar</string>
- <string name="title_key_server_preference">Anahtar Sunucusu Seçenekleri</string>
<string name="title_change_passphrase">Parolayı Değiştir</string>
- <string name="title_share_fingerprint_with">Parmakizini ÅŸu ÅŸekilde paylaÅŸ...</string>
- <string name="title_share_key">Anahtarı şu şekilde paylaş...</string>
- <string name="title_share_file">Dosyayı şu şekilde paylaş...</string>
- <string name="title_share_message">Mesajı şu şekilde paylaş...</string>
+ <string name="title_share_fingerprint_with">Parmak izini paylaÅŸ...</string>
+ <string name="title_share_key">Anahtarı paylaş...</string>
+ <string name="title_share_file">Dosyayı paylaş...</string>
+ <string name="title_share_message">Mesajı paylaş...</string>
<string name="title_encrypt_to_file">Dosyaya Åžifrele</string>
<string name="title_decrypt_to_file">Dosyaya Çözümle</string>
<string name="title_import_keys">Anahtarları Al</string>
@@ -29,11 +26,13 @@
<string name="title_export_keys">Anahtarları Ver</string>
<string name="title_key_not_found">Anahtar Bulunamadı</string>
<string name="title_send_key">Anahtar Sunucusuna Yükle</string>
- <string name="title_certify_key">Kimlikleri DoÄŸrula</string>
+ <string name="title_certify_key">Kimlikleri Tasdikle</string>
<string name="title_key_details">Anahtar Detayları</string>
<string name="title_help">Yardım</string>
<string name="title_log_display">Günlük</string>
<string name="title_create_key">Anahtar OluÅŸtur</string>
+ <string name="title_exchange_keys">Anahtarları Değiş Tokuş Et</string>
+ <string name="title_advanced_key_info">GeliÅŸmiÅŸ Anahtar Bilgisi</string>
<!--section-->
<string name="section_user_ids">Kimlikler</string>
<string name="section_keys">Alt anahtarlar</string>
@@ -42,21 +41,22 @@
<string name="section_defaults">Varsayılanlar</string>
<string name="section_advanced">GeliÅŸmiÅŸ</string>
<string name="section_passphrase_cache">Parola Önbelleği</string>
- <string name="section_certify">DoÄŸrula</string>
+ <string name="section_certify">Tasdik et</string>
<string name="section_actions">Eylemler</string>
<string name="section_share_key">Anahtar</string>
- <string name="section_certification_key">Anahtarınız sertifikalama için kullanıldı</string>
+ <string name="section_certification_key">Tasdik işlemi için kullanılan anahtarınız</string>
<string name="section_upload_key">Anahtarı Eşitle</string>
<string name="section_key_server">Anahtar Sunucusu</string>
- <string name="section_fingerprint">Parmakizi</string>
- <string name="section_key_to_certify">DoÄŸrulanacak anahtar</string>
+ <string name="section_fingerprint">Parmak izi</string>
+ <string name="section_key_to_certify">Tasdik edilecek anahtar</string>
<string name="section_decrypt_files">Dosyalar</string>
<string name="section_decrypt_text">Metin</string>
+ <string name="section_certs">Sertifikalar</string>
<!--button-->
- <string name="btn_decrypt_verify_file">Dosyayı çözümle, doğrula ve kaydet</string>
- <string name="btn_decrypt_verify_message">Mesajı çözümle ve doğrula</string>
- <string name="btn_encrypt_file">Dosyayı şifrele ve kaydet</string>
- <string name="btn_encrypt_share_file">Dosyayı şifrele ve paylaş</string>
+ <string name="btn_decrypt_verify_file">Şifreyi çöz, doğrula ve dosyayı kaydet</string>
+ <string name="btn_decrypt_verify_message">Şifreyi çöz ve mesajı doğrula</string>
+ <string name="btn_encrypt_file">Şifrele ve dosyayı kaydet</string>
+ <string name="btn_encrypt_share_file">Şifrele ve dosyayı paylaş</string>
<string name="btn_save">Kaydet</string>
<string name="btn_do_not_save">Ä°ptal</string>
<string name="btn_delete">Sil</string>
@@ -66,24 +66,24 @@
<string name="btn_next">Ä°leri</string>
<string name="btn_back">Geri</string>
<string name="btn_lookup_key">Anahtarı ara</string>
- <string name="btn_share_encrypted_signed">Mesajı şifrele ve paylaş</string>
- <string name="btn_view_cert_key">Sertifikalama anahtarını görüntüle</string>
+ <string name="btn_share_encrypted_signed">Şifrele ve mesajı paylaş</string>
+ <string name="btn_view_cert_key">Tasdikleme anahtarını görüntüle</string>
<string name="btn_create_key">Anahtar oluÅŸtur</string>
<string name="btn_add_files">Dosya(lar) ekle</string>
- <string name="btn_add_share_decrypted_text">Çözümlenmiş metni paylaş</string>
- <string name="btn_decrypt_clipboard">Panodan çözümle</string>
+ <string name="btn_add_share_decrypted_text">Şifresi çözülmüş metni paylaş</string>
<string name="btn_decrypt_and_verify">ve imzaları doğrula</string>
- <string name="btn_decrypt_files">Dosyaları çözümle</string>
+ <string name="btn_decrypt_files">Dosyaların şifresini çöz</string>
<!--menu-->
<string name="menu_preferences">Ayarlar</string>
<string name="menu_help">Yardım</string>
<string name="menu_export_key">Dosyaya ver</string>
<string name="menu_delete_key">Anahtar sil</string>
<string name="menu_create_key">Anahtarımı oluştur</string>
+ <string name="menu_import_existing_key">Dosyadan al</string>
<string name="menu_search">Ara</string>
- <string name="menu_beam_preferences">Huzme ayarları</string>
+ <string name="menu_beam_preferences">NFC ayarları</string>
<string name="menu_key_edit_cancel">Ä°ptal</string>
- <string name="menu_encrypt_to">Buraya ÅŸifrele...</string>
+ <string name="menu_encrypt_to">Åžuna ÅŸifrele...</string>
<string name="menu_select_all">Hepsini seç</string>
<string name="menu_add_keys">Anahtar ekle</string>
<string name="menu_export_all_keys">Tüm anahtarları ver</string>
@@ -95,22 +95,25 @@
<string name="label_file_colon">Dosya:</string>
<string name="label_no_passphrase">Parola Yok</string>
<string name="label_passphrase">Parola</string>
- <string name="label_unlock">Kilit Açılıyor...</string>
+ <string name="label_unlock">Kilit açılıyor...</string>
<string name="label_passphrase_again">Parolayı Tekrarla</string>
<string name="label_algorithm">Algoritma</string>
+ <string name="label_ascii_armor">ASCII formatında dosyalar</string>
+ <string name="label_file_ascii_armor">ASCII formatında çıktıları etkinleştir</string>
<string name="label_write_version_header">Diğerlerinin OpenKeychain kullandığını bilmesine izin ver</string>
- <string name="label_use_default_yubikey_pin">Yubikey PIN\'i varsayılan kullan</string>
- <string name="label_use_num_keypad_for_yubikey_pin">Yubikey PIN için numerik tuş takımını kullan</string>
- <string name="label_label_use_default_yubikey_pin_summary">NFC üzerinden Yunikeys\'e ulaşmak için varsayılan PIN (123456) kullanılıyor</string>
+ <string name="label_write_version_header_summary">OpenPGP imzalarına, şifrelenmiş metinlere ve dışa aktarılmış anahtarlara \'OpenKeychain v2.7\' yazar</string>
+ <string name="label_use_default_yubikey_pin">Varsayılan YubiKey PIN\'ini kullan</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">YubiKey PIN\'i için sayısal klavyeyi kullan</string>
+ <string name="label_label_use_default_yubikey_pin_summary">NFC üzerinden YubiKey\'e ulaşmak için varsayılan PIN\'i (123456) kullanır</string>
<string name="label_asymmetric_from">Ä°mzalayan:</string>
- <string name="label_to">Buraya ÅŸifrele:</string>
+ <string name="label_to">Åžuna ÅŸifrele:</string>
<string name="label_delete_after_encryption">Şifreleme sonrası dosyayı sil</string>
- <string name="label_delete_after_decryption">Çözümleme sonrası sil</string>
+ <string name="label_delete_after_decryption">Şifre çözme sonrasında sil</string>
<string name="label_encryption_algorithm">Şifreleme algoritması</string>
- <string name="label_hash_algorithm">Hash algoritması</string>
+ <string name="label_hash_algorithm">Özet algoritması</string>
<string name="label_symmetric">Parolayla ÅŸifrele</string>
<string name="label_passphrase_cache_ttl">Önbellek zamanı</string>
- <string name="label_passphrase_cache_subs">Altanahtar parola önbelleği</string>
+ <string name="label_passphrase_cache_subs">Parolaları altanahtarlara göre önbellekle</string>
<string name="label_message_compression">Mesaj sıkıştırma</string>
<string name="label_file_compression">Dosya sıkıştırma</string>
<string name="label_keyservers">Anahtar Sunucuları</string>
@@ -124,8 +127,10 @@
<string name="label_name">Ä°sim</string>
<string name="label_comment">Yorum</string>
<string name="label_email">Eposta</string>
- <string name="label_fingerprint">Parmakizi</string>
- <string name="expiry_date_dialog_title">Son kullanma tarihini ayarla</string>
+ <string name="label_send_key">Bulut ile eÅŸitle</string>
+ <string name="label_fingerprint">Parmak izi</string>
+ <string name="expiry_date_dialog_title">Zaman aşımı tarihini ayarla</string>
+ <string name="label_first_keyserver_is_used">(Listelenen ilk anahtar sunucu tercih edilecektir)</string>
<string name="label_preferred">tercih edilen</string>
<string name="user_id_no_name">&lt;isimsiz&gt;</string>
<string name="none">&lt;hiçbiri&gt;</string>
@@ -133,8 +138,8 @@
<string name="can_encrypt">ÅŸifreleyebilir</string>
<string name="can_sign">imzalayabilir</string>
<string name="can_certify">tasdikleyebilir</string>
- <string name="can_certify_not">doÄŸrulanamaz</string>
- <string name="expired">tarihi geçmiş</string>
+ <string name="can_certify_not">tasdikleyemez</string>
+ <string name="expired">zaman aşımına uğramış</string>
<string name="revoked">yürürlükten kaldırılmış</string>
<plurals name="n_keys">
<item quantity="one">1 anahtar</item>
@@ -169,10 +174,10 @@
<string name="error">Hata</string>
<string name="error_message">Hata: %s</string>
<!--key flags-->
- <string name="flag_certify">DoÄŸrula</string>
- <string name="flag_sign">Ä°mzala</string>
- <string name="flag_encrypt">Åžifrele</string>
- <string name="flag_authenticate">Yetkilendir</string>
+ <string name="flag_certify">Tasdikleme</string>
+ <string name="flag_sign">Ä°mzalama</string>
+ <string name="flag_encrypt">Åžifreleme</string>
+ <string name="flag_authenticate">Kimlik kanıtlama</string>
<!--sentences-->
<string name="wrong_passphrase">Yanlış parola.</string>
<string name="no_filemanager_installed">Uyumlu dosya yöneticisi yüklenmedi.</string>
@@ -180,55 +185,76 @@
<string name="passphrase_must_not_be_empty">Lütfen bir parola girin.</string>
<string name="passphrase_for_symmetric_encryption">Simetrik ÅŸifreleme.</string>
<string name="passphrase_for">\'%s\' için bir parola girin</string>
+ <string name="nfc_text">YubiKey\'inizi cihazınızın arkasında tutun.</string>
<string name="file_delete_confirmation">Silmek istediÄŸinize emin misiniz\n%s?</string>
<string name="file_delete_successful">Başarıyla silindi.</string>
<string name="no_file_selected">Önce bir dosya seçin.</string>
<string name="encrypt_sign_successful">Başarıyla imzalandı ve/veya şifrelendi.</string>
- <string name="encrypt_sign_clipboard_successful">Panoya başarıyla imzalandı ve/veya şifrelendi.</string>
+ <string name="encrypt_sign_clipboard_successful">Kopyalama önbelleğine başarıyla imzalandı ve/veya şifrelendi.</string>
<string name="enter_passphrase_twice">Parolanızı iki kere girin.</string>
<string name="select_encryption_key">En az bir şifreleme anahtarı seçiniz.</string>
- <string name="select_encryption_or_signature_key">En az bir adet şifreleme anahtarı veya imza anahtarı seçiniz.</string>
- <string name="key_deletion_confirmation_multi">Seçilen tüm açık anahtarları silmek istiyor musunuz?\nBu işlemi geri alamazsınız!</string>
- <string name="public_key_deletetion_confirmation">\'%s\' genel anahtarını gerçekten silmek istiyor musunuz?\nBu geri alınamaz!</string>
- <string name="key_exported">1 anahtar başarıyla verildi.</string>
- <string name="keys_exported">%d anahtar başarıyla verildi.</string>
- <string name="no_keys_exported">Hiç anahtar verilmedi.</string>
+ <string name="select_encryption_or_signature_key">En az bir şifreleme anahtarı veya imza anahtarı seçiniz.</string>
+ <string name="specify_file_to_encrypt_to">Lütfen şifreleme sonucu hangi dosyanın oluşturulması gerektiğini belirtin.\nUYARI: Eğer dosya mevcutsa üzerine yazılacaktır.</string>
+ <string name="specify_file_to_decrypt_to">Lütfen şifre çözme sonucu hangi dosyanın oluşturulması gerektiğini belirtin.\nUYARI: Eğer dosya mevcutsa üzerine yazılacaktır.</string>
+ <string name="specify_file_to_export_to">Lütfen dışa aktarım için hangi dosyanın kullanılması gerektiğini belirtin.\nUYARI: Eğer dosya mevcutsa üzerine yazılacaktır.</string>
+ <string name="key_deletion_confirmation_multi">Seçilen tüm genel anahtarları gerçekten silmek istiyor musunuz?\nBu işlemi geri alamazsınız!</string>
+ <string name="secret_key_deletion_confirmation">\'%s\' ÖZEL anahtarını gerçekten silmek istiyor musunuz?\nBu işlemi geri alamazsınız!</string>
+ <string name="public_key_deletetion_confirmation">\'%s\' genel anahtarını gerçekten silmek istiyor musunuz?\nBu işlemi geri alamazsınız!</string>
+ <string name="also_export_secret_keys">Özel anahtarları da dışa aktar</string>
+ <string name="reinstall_openkeychain">Android için bilinen bir hataya denk geldiniz. Eğer kişilerinizi anahtarlarla eşlemek istiyorsanız, lütfen OpenKeychain uygulamasını yeniden yükleyin.</string>
+ <string name="key_exported">1 anahtar başarıyla dışa aktarıldı.</string>
+ <string name="keys_exported">%d anahtar başarıyla dışa aktarıldı.</string>
+ <string name="no_keys_exported">Hiçbir anahtar dışa aktarılmadı.</string>
<string name="key_creation_el_gamal_info">Not: sadece alt anahtarlar ElGamal destekler.</string>
<string name="key_not_found">Anahtar %08X bulunamadı.</string>
- <string name="list_empty">Liste boÅŸ!</string>
+ <plurals name="bad_keys_encountered">
+ <item quantity="one">%d bozuk özel anahtar yok sayıldı. Muhtemelen\n --export-secret-subkeys\nseçeneği ile dışa aktardınız. Onun yerine \n --export-secret-keys\nkullandığınıza emin olun.</item>
+ <item quantity="other">%d bozuk özel anahtar yok sayıldı. Muhtemelen\n --export-secret-subkeys\nseçeneği ile dışa aktardınız. Onun yerine \n --export-secret-keys\nkullandığınıza emin olun.</item>
+ </plurals>
+ <string name="list_empty">Bu liste boÅŸ!</string>
<string name="nfc_successful">Anahtar NFC Beam ile başarıyla gönderildi!</string>
- <string name="key_copied_to_clipboard">Anahtar panoya kopyalandı!</string>
- <string name="fingerprint_copied_to_clipboard">Parmakizi panoya kopyalandı!</string>
- <string name="key_too_big_for_sharing">Anatar bu yolla paylaşılamayacak kadar büyük!</string>
- <string name="text_copied_to_clipboard">Metin panoya kopyalandı!</string>
+ <string name="key_copied_to_clipboard">Anahtar kopyalama önbelleğine kopyalandı!</string>
+ <string name="fingerprint_copied_to_clipboard">Parmak izi kopyalama önbelleğine kopyalandı!</string>
+ <string name="select_key_to_certify">Lütfen tasdikleme için kullanılacak bir anahtar seçin!</string>
+ <string name="key_too_big_for_sharing">Anahtar bu yolla paylaşılamayacak kadar büyük!</string>
+ <string name="text_copied_to_clipboard">Metin kopyalama önbelleğine kopyalandı!</string>
<!--errors
no punctuation, all lowercase,
they will be put after "error_message", e.g. "Error: file not found"-->
- <string name="error_file_delete_failed">\'%s\' silme başarısız</string>
+ <string name="error_file_delete_failed">\'%s\' silmesi başarısız oldu</string>
<string name="error_file_not_found">dosya bulunamadı</string>
+ <string name="error_no_secret_key_found">uygun bir özel anahtar bulunamadı</string>
<string name="error_external_storage_not_ready">harici depolama hazır değil</string>
- <string name="error_key_size_minimum512bit">anahtar uzunluğu en az 512bit olmalı</string>
+ <string name="error_key_size_minimum512bit">anahtar boyutu en az 512bit olmalı</string>
<string name="error_unknown_algorithm_choice">bilinmeyen algoritma seçimi</string>
- <string name="error_user_id_no_email">eposta bulunamadı</string>
+ <string name="error_user_id_no_email">herhangi bir eposta bulunamadı</string>
<string name="error_key_needs_a_user_id">en az bir kimlik gerekli</string>
<string name="error_no_signature_passphrase">parola verilmedi</string>
<string name="error_no_signature_key">imza anahtarı verilmedi</string>
+ <string name="error_invalid_data">Geçerli olan şifrelenmiş ya da imzalanmış OpenPGP içeriği yok!</string>
<string name="error_integrity_check_failed">Bütünlük kontrolü başarısız! Veri değiştirilmiş!</string>
<string name="error_wrong_passphrase">yanlış parola</string>
+ <string name="error_could_not_extract_private_key">özel anahtar çıkarılamadı</string>
<!--errors without preceeding Error:-->
<string name="error_jelly_bean_needed">Android\'in NFC Beam özelliğini kullanabilmek için Android 4.1 kullanmalısınız!</string>
<string name="error_nfc_needed">Cihazınız NFC desteklemiyor!</string>
<string name="error_nothing_import">Anahtar bulunamadı!</string>
- <string name="error_generic_report_bug">Genel bir hata oluştu. Lütfen OpenKeychain için bir hata raporu oluşturun.</string>
+ <string name="error_contacts_key_id_missing">Kişilerden anahtar ID getirme işlemi başarısız!</string>
+ <string name="error_generic_report_bug">Genel bir hata oluştu, lütfen OpenKeychain için yeni bir hata raporu oluşturun.</string>
<!--results shown after decryption/verification-->
<string name="decrypt_result_no_signature">İmzalanmadı</string>
<string name="decrypt_result_invalid_signature">Geçersiz imza!</string>
- <string name="decrypt_result_signature_uncertified">İmzalayan (doğrulanmadı!):</string>
+ <string name="decrypt_result_signature_uncertified">Ä°mzalayan (tasdik edilmemiÅŸ!):</string>
<string name="decrypt_result_signature_certified">Ä°mzalayan:</string>
+ <string name="decrypt_result_signature_expired_key">Anahtar zaman aşımına uğramış!</string>
+ <string name="decrypt_result_signature_revoked_key">Anahtar yürürlükten kaldırılmış!</string>
+ <string name="decrypt_result_signature_missing_key">Bilinmeyen açık anahtar</string>
<string name="decrypt_result_encrypted">Åžifrelendi</string>
<string name="decrypt_result_not_encrypted">Åžifrelenmedi</string>
<string name="decrypt_result_action_show">Göster</string>
<string name="decrypt_result_action_Lookup">Araştır</string>
+ <string name="decrypt_invalid_text">Ya imza geçersiz ya da anahtar yürürlükten kaldırılmış/zaman aşımına uğramış. Metni kimin yazdığından emin olamazsınız. Yine de görüntülemek istiyor musunuz?</string>
+ <string name="decrypt_invalid_button">Tehlikelerin farkındayım, görüntüle!</string>
<!--Add keys-->
<string name="add_keys_my_key">Anahtarım:</string>
<!--progress dialogs, usually ending in '…'-->
@@ -236,38 +262,52 @@
<string name="progress_cancel">Ä°ptal</string>
<string name="progress_cancelling">iptal ediliyor...</string>
<string name="progress_saving">kaydediliyor...</string>
- <string name="progress_importing">alıyor...</string>
- <string name="progress_exporting">veriyor...</string>
+ <string name="progress_importing">içe aktarılıyor...</string>
+ <string name="progress_exporting">dışa aktarılıyor...</string>
<string name="progress_uploading">yükleniyor...</string>
<string name="progress_building_key">anahtar oluÅŸturuluyor...</string>
+ <string name="progress_building_master_key">ana anahtarlık oluşturuluyor...</string>
<string name="progress_generating_rsa">yeni RSA anahtarı oluşturuluyor...</string>
<string name="progress_generating_dsa">yeni DSA anahtarı oluşturuluyor...</string>
<string name="progress_generating_elgamal">yeni ElGamal anahtarı oluşturuluyor...</string>
<string name="progress_generating_ecdsa">yeni ECDSA anahtarı oluşturuluyor...</string>
<string name="progress_generating_ecdh">yeni ECDH anahtarı oluşturuluyor...</string>
- <string name="progress_modify_subkeyadd">alt anahtar ekleniyor...</string>
+ <string name="progress_modify">anahtarlık değiştiriliyor...</string>
+ <string name="progress_modify_unlock">anahtarlık açılıyor...</string>
+ <string name="progress_modify_adduid">kullanıcı IDleri ekleniyor...</string>
+ <string name="progress_modify_revokeuid">kullanıcı IDleri yürürlükten kaldırılıyor...</string>
+ <string name="progress_modify_primaryuid">birincil kullanıcı IDsi değiştiriliyor...</string>
+ <string name="progress_modify_subkeychange">altanahtarlar deÄŸiÅŸtiriliyor...</string>
+ <string name="progress_modify_subkeyrevoke">altanahtarlar yürürlükten kaldırılıyor...</string>
+ <string name="progress_modify_subkeystrip">altanahtarlar çıkarılıyor...</string>
+ <string name="progress_modify_subkeyadd">altanahtarlar ekleniyor...</string>
<string name="progress_modify_passphrase">parola deÄŸiÅŸtiriliyor...</string>
<plurals name="progress_exporting_key">
- <item quantity="one">anahtar veriliyor...</item>
- <item quantity="other">anahtarlar veriliyor...</item>
+ <item quantity="one">anahtar dışa aktarılıyor...</item>
+ <item quantity="other">anahtarlar dışa aktarılıyor...</item>
</plurals>
- <string name="progress_extracting_signature_key">imza anahtarı veriliyor...</string>
- <string name="progress_extracting_key">anahtarlar veriliyor...</string>
+ <string name="progress_extracting_signature_key">imza anahtarı çıkarılıyor...</string>
+ <string name="progress_extracting_key">anahtar çıkarılıyor...</string>
+ <string name="progress_preparing_streams">akışlar hazırlanıyor...</string>
<string name="progress_encrypting">veri ÅŸifreleniyor...</string>
- <string name="progress_decrypting">veri çözümleniyor...</string>
+ <string name="progress_decrypting">veri şifresi çözülüyor...</string>
<string name="progress_preparing_signature">imza hazırlanıyor...</string>
<string name="progress_generating_signature">imza oluÅŸturuluyor...</string>
<string name="progress_processing_signature">imza iÅŸleniyor...</string>
<string name="progress_verifying_signature">imza doğrulanıyor...</string>
<string name="progress_signing">imzalanıyor...</string>
- <string name="progress_certifying">doğrulanıyor...</string>
+ <string name="progress_certifying">tasdikleniyor...</string>
<string name="progress_reading_data">veri okunuyor...</string>
<string name="progress_finding_key">anahtar bulunuyor...</string>
+ <string name="progress_decompressing_data">sıkıştırılmış veri açılıyor...</string>
<string name="progress_verifying_integrity">bütünlük doğrulanıyor...</string>
+ <string name="progress_deleting_securely">\'%s\' güvenlice siliniyor...</string>
<string name="progress_deleting">anahtarlar siliniyor...</string>
+ <string name="progress_con_saving">birleştir: önbelleğe kaydediliyor...</string>
+ <string name="progress_con_reimport">birleştir: yeniden içe aktarılıyor...</string>
<!--action strings-->
- <string name="hint_keyserver_search_hint">Ä°sim/E-Posta/Anahtar KimliÄŸi...</string>
- <string name="hint_cloud_search_hint">İsim/E-Posta/Kanıt/Anahtar...</string>
+ <string name="hint_keyserver_search_hint">Ä°sim/Eposta/Anahtar ID...</string>
+ <string name="hint_cloud_search_hint">İsim/Eposta/Kanıt/Anahtar...</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>
@@ -278,6 +318,9 @@
<string name="key_size_4096">4096</string>
<string name="key_size_8192">8192</string>
<string name="key_size_custom">Özel anahtar boyutu</string>
+ <string name="key_size_custom_info">Özel anahtar boyutunu yazın (bit):</string>
+ <string name="key_size_custom_info_rsa">RSA anahtar boyutu 1024\'ten büyük olmalı ve en çok 16384 olabilir. Ek olarak 8 in katı olmalı.</string>
+ <string name="key_size_custom_info_dsa">DSA anahtar boyutu en az 512 olmalı ve en çok 1024 olabilir. Ek olarak 64 ün katı olmalı.</string>
<!--elliptic curve names-->
<string name="key_curve_nist_p256">NIST P-256</string>
<string name="key_curve_nist_p384">NIST P-384</string>
@@ -292,31 +335,34 @@
<!--Help-->
<string name="help_tab_start">BaÅŸla</string>
<string name="help_tab_faq">SSS</string>
- <string name="help_tab_wot">Web of Trust</string>
+ <string name="help_tab_wot">Güven Ağı</string>
<string name="help_tab_nfc_beam">NFC Beam</string>
<string name="help_tab_changelog">Sürüm Notları</string>
<string name="help_tab_about">Hakkında</string>
<string name="help_about_version">Sürüm:</string>
<!--Import-->
<string name="import_tab_keyserver">Anahtar Sunucusu</string>
- <string name="import_tab_cloud">Bulut Arama</string>
- <string name="import_tab_direct">Dosya/Pano</string>
- <string name="import_tab_qr_code">QR Kod/NFC</string>
- <string name="import_import">Seçili anahtarları al</string>
+ <string name="import_tab_cloud">Bulutta Ara</string>
+ <string name="import_tab_direct">Dosya/Kopyalama önbelleği</string>
+ <string name="import_tab_qr_code">QR Kodu/NFC</string>
+ <string name="import_import">Seçili anahtarları içe aktar</string>
+ <string name="import_qr_code_wrong">QR Kodu hatalı! Lütfen tekrar deneyin!</string>
<string name="import_qr_code_too_short_fingerprint">Parmak izi çok kısa (&lt; 16 karakter)</string>
+ <string name="import_qr_code_button">QR Kodu Tara</string>
<!--Generic result toast-->
- <string name="view_log">Günlüğü Görüntüle</string>
+ <string name="with_warnings">, uyarılarla</string>
+ <string name="with_cancelled">, iptal edilene kadar</string>
<!--Import result toast-->
<plurals name="import_keys_added_and_updated_1">
- <item quantity="one">Anahtar başarıyla alındı</item>
- <item quantity="other">%1$d anahtar başarıyla alındı</item>
+ <item quantity="one">Anahtar başarıyla içe aktarıldı</item>
+ <item quantity="other">%1$d anahtar başarıyla içe aktarıldı</item>
</plurals>
<plurals name="import_keys_with_errors">
<item quantity="one">Bir anahtar için alma başarısız.</item>
- <item quantity="other">%d anahtar için alma başarısız!</item>
+ <item quantity="other">%d anahtar için içe aktarma başarısız!</item>
</plurals>
- <string name="import_error_nothing">Alınacak bir şey yok.</string>
- <string name="import_error_nothing_cancelled">Alma iptal edildi.</string>
+ <string name="import_error_nothing">İçe aktarılacak bir şey yok.</string>
+ <string name="import_error_nothing_cancelled">İçe aktarma iptal edildi.</string>
<!--Delete result toast-->
<string name="delete_nothing">Silinecek bir ÅŸey yok.</string>
<string name="delete_cancelled">Silme iÅŸlemi iptal edildi.</string>
@@ -340,7 +386,6 @@
<string name="api_settings_start">Uygulamayı başlat</string>
<string name="api_settings_delete_account">Hesabı sil</string>
<string name="api_settings_package_name">Paket Adı</string>
- <string name="api_settings_accounts">Hesaplar</string>
<string name="api_settings_settings">Ayarlar</string>
<string name="api_settings_key">Hesap anahtarı:</string>
<string name="api_register_allow">EriÅŸime izin ver</string>
@@ -373,6 +418,12 @@
<string name="key_view_tab_share">PaylaÅŸ</string>
<string name="key_view_tab_keys">Alt anahtarlar</string>
<string name="key_view_tab_certs">Sertifikalar</string>
+ <string name="user_id_info_revoked_title">Yürürlükten kaldırılmış</string>
+ <string name="user_id_info_revoked_text">Bu kimlik anahtar sahibi tarafından yürürlükten kaldırılmış. Artık geçerli değil.</string>
+ <string name="user_id_info_certified_title">TasdiklenmiÅŸ</string>
+ <string name="user_id_info_certified_text">Bu kimlik sizin tarafınızdan tasdiklendi.</string>
+ <string name="user_id_info_uncertified_title">TasdiklenmemiÅŸ</string>
+ <string name="user_id_info_uncertified_text">Bu kimlik henüz tasdiklenmemiş. Bu kimliğin belirli bir kişiye ait olduğundan emin olamazsınız.</string>
<string name="user_id_info_invalid_title">Geçersiz</string>
<string name="user_id_info_invalid_text">Bu kimlikle ilgili yanlış olan bazı şeyler var!</string>
<!--Edit key-->
@@ -380,6 +431,10 @@
<string name="edit_key_action_add_identity">Kimlik Ekle</string>
<string name="edit_key_action_add_subkey">Alt anahtar Ekle</string>
<string name="edit_key_edit_user_id_title">Bir eylem seç!</string>
+ <string-array name="edit_key_edit_user_id">
+ <item>Birincil Kimliğe geç</item>
+ <item>Kimliği Yürürlükten Kaldır</item>
+ </string-array>
<string name="edit_key_edit_subkey_title">Bir eylem seç!</string>
<string name="edit_key_new_subkey">yeni alt anahtar</string>
<string name="edit_key_select_flag">Lütfen en az bir bayrak seçiniz!</string>
@@ -392,16 +447,15 @@
<string name="create_key_final_text">Åžu kimliÄŸi girdiniz:</string>
<string name="create_key_final_robot_text">Anahtar oluşturma biraz zaman alabilir, bu sırada bir çay için...</string>
<string name="create_key_rsa">(3 alt anahtar, RSA, 4096 bit)</string>
+ <string name="create_key_custom">(özel anahtar yapılandırması)</string>
<string name="create_key_text">Tam isminizi, e-posta adresinizi girin ve bir parola seçin.</string>
<string name="create_key_hint_full_name">Tam Ad, örneğin: Max Mustermann</string>
<string name="create_key_edit">Anahtar yapılandırmasını değiştir.</string>
<!--View key-->
+ <string name="view_key_revoked">Bu anahtar yürürlükten kaldırıldı!</string>
<string name="view_key_expired">Bu anahtarın son kullanma tarihi geçmiş!</string>
<!--Navigation Drawer-->
<string name="nav_keys">Anahtarlar</string>
- <string name="nav_encrypt_text">Metni ÅŸifrele</string>
- <string name="nav_encrypt_files">Dosyaları şifrele</string>
- <string name="nav_decrypt">Çözümle</string>
<string name="nav_apps">Uygulamalar</string>
<string name="my_keys">Anahtarlarım</string>
<!--hints-->
@@ -420,6 +474,7 @@
<string name="msg_ip_delete_old_ok">Eski anahtarları veritabanından sil</string>
<string name="msg_ip_prepare">Veritabanı işlemleri hazırlanıyor</string>
<string name="msg_ip_master">Ana anahtar %s iÅŸleniyor</string>
+ <string name="msg_ip_uid_cert_error">Sertifika iÅŸlenirken hata!</string>
<!--Import Secret log entries-->
<string name="msg_is_db_exception">Veritabanı hatası!</string>
<!--Keyring Canonicalization log entries-->
@@ -432,12 +487,21 @@
<!--modifySecretKeyRing-->
<string name="msg_mf_subkey_new_id">Yeni alt anahtar ID: %s</string>
<!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<string name="msg_ek_error_not_found">Anahtar bulunamadı!</string>
<!--Messages for DecryptVerify operation-->
+ <string name="msg_dc_error_no_data">Akış içinde şifrelenmiş veri bulunamadı!</string>
+ <string name="msg_dc_error_no_key">Akış içinde bilinen özel anahtar ile şifrelenmiş veri bulunamadı!</string>
+ <string name="msg_dc_prep_streams">Çözümleme için akışlar hazırlanıyor</string>
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<string name="msg_crt_warn_not_found">Anahtar bulunamadı!</string>
+ <string name="msg_import_keyserver">%s anahtar sunucusu kullanılıyor</string>
+ <string name="msg_import_fingerprint_ok">Parmakizi kontrolü TAMAM</string>
<string name="msg_export_all">Tüm anahtarları dışa aktarma</string>
+ <string name="msg_export_error_uri_open">URI akışı açılırken hata!</string>
<string name="msg_export_error_db">Veritabanı hatası!</string>
<string name="msg_export_error_io">Giriş/çıkış hatası!</string>
<string name="msg_export_success">Dışa aktarma işlemi başarılı</string>
@@ -447,22 +511,39 @@
<!--PassphraseCache-->
<string name="passp_cache_notif_clear">Önbelleği Temizle</string>
<string name="passp_cache_notif_pwd">Parola</string>
+ <!--First Time-->
+ <string name="first_time_text1">Gizliliğinizi OpenKeychain ile geri alın!</string>
+ <string name="first_time_create_key">Anahtarımı oluştur</string>
+ <string name="first_time_import_key">Dosyadan içe aktar</string>
+ <string name="first_time_skip">Kurulumu Atla</string>
<!--unsorted-->
<string name="section_cert">Sertifika Detayları</string>
<string name="label_user_id">Kimlik</string>
<string name="unknown_uid">&lt;bilinmeyen&gt;</string>
<string name="empty_certs">Bu anahtar için sertifika yok</string>
+ <string name="label_revocation">Yürürlükten Kaldırma Nedeni</string>
<string name="label_verify_status">DoÄŸrulama Durumu</string>
<string name="label_cert_type">Tip</string>
<string name="error_key_not_found">Anahtar bulunamadı!</string>
+ <string name="error_key_processing">Anahtar iÅŸlenirken hata!</string>
+ <string name="key_stripped">çıkartıldı</string>
+ <string name="key_divert">AkıllıKart/NFC için yönlendir</string>
<string name="key_no_passphrase">parola yok</string>
<string name="key_unavailable">mevcut deÄŸil</string>
+ <string name="secret_cannot_multiple">Kendi anahtarlarınız yalnızca teker teker silinebilir!</string>
<string name="title_view_cert">Sertifika Ayrıntılarını Görüntüle</string>
<string name="unknown_algorithm">bilinmeyen</string>
<string name="can_sign_not">imzalanamadı</string>
+ <string name="error_no_encrypt_subkey">Şifreleme için kullanılabilecek altanahtar mevcut değil!</string>
+ <string name="info_no_manual_account_creation">OpenKeychain-hesaplarını kendiniz oluşturmayın.\nDaha fazla bilgi için Yardım bölümüne bakın.</string>
<string name="contact_show_key">Anahtarı göster (%s)</string>
+ <string name="swipe_to_update">Anahtar sunucudan güncelleme almak için parmağınızı aşağıya doğru kaydırın</string>
+ <string name="error_no_file_selected">Şifrelemek için en az bir dosya seçin!</string>
+ <string name="error_multi_not_supported">Birden çok dosyanın kaydedilmesi desteklenmiyor. Bu şu anki Android\'in bir kısıtlamasıdır.</string>
<string name="key_colon">Anahtar:</string>
- <!--First Time-->
- <string name="first_time_create_key">Anahtarımı oluştur</string>
- <string name="first_time_skip">Kurulumu Atla</string>
+ <string name="exchange_description">Anahtar değiş tokuşu başlatmak için sağ taraftan katılımcıların sayısını seçin ve \"Değiş tokuşu başlat\" tuşuna tıklayın.\n\nSadece istenilen katılımcıların değişim işleminde olduğundan ve parmak izlerinin doğruluğundan emin olmak için size iki soru daha sorulacak.</string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml
index 67230fbed..a8e4ac3b4 100644
--- a/OpenKeychain/src/main/res/values-uk/strings.xml
+++ b/OpenKeychain/src/main/res/values-uk/strings.xml
@@ -2,16 +2,17 @@
<resources>
<!--GENERAL: Please put all strings inside quotes as described in example 1 on
http://developer.android.com/guide/topics/resources/string-resource.html (scroll down to "Escaping apostrophes and quotes").-->
+ <string name="app_name">OpenKeychain</string>
<!--title-->
<string name="title_select_recipients">Вибрати ключі</string>
<string name="title_select_secret_key">Виберіть ваш ключ</string>
+ <string name="title_encrypt_text">Зашифрувати текÑт…</string>
+ <string name="title_encrypt_files">Зашифрувати файли</string>
<string name="title_decrypt">Розшифрувати</string>
- <string name="title_authentication">Парольна фраза</string>
<string name="title_add_subkey">Додати підключ</string>
<string name="title_edit_key">Редагувати ключ</string>
- <string name="title_preferences">ÐалаштуваннÑ</string>
+ <string name="title_cloud_search_preferences">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ…Ð¼Ð°Ñ€Ð½Ð¾Ð³Ð¾ пошуку</string>
<string name="title_api_registered_apps">Програми</string>
- <string name="title_key_server_preference">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñервера ключів</string>
<string name="title_change_passphrase">Змінити парольну фразу</string>
<string name="title_share_fingerprint_with">ПоділитиÑÑ Ð²Ñ–Ð´Ð±Ð¸Ñ‚ÐºÐ¾Ð¼ із…</string>
<string name="title_share_key">ПоділитиÑÑ ÐºÐ»ÑŽÑ‡ÐµÐ¼ з…</string>
@@ -20,6 +21,7 @@
<string name="title_encrypt_to_file">Зашифрувати до файлу</string>
<string name="title_decrypt_to_file">Розшифрувати до файлу</string>
<string name="title_import_keys">Імпортувати ключі</string>
+ <string name="title_add_keys">Додати ключі</string>
<string name="title_export_key">ЕкÑпортувати ключ</string>
<string name="title_export_keys">ЕкÑпортувати ключі</string>
<string name="title_key_not_found">Ключ не знайдено</string>
@@ -29,17 +31,27 @@
<string name="title_help">Довідка</string>
<string name="title_log_display">Журнал</string>
<string name="title_create_key">Створити ключ</string>
+ <string name="title_exchange_keys">ОбмінÑти ключі</string>
+ <string name="title_advanced_key_info">Додаткова Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ ключ</string>
<!--section-->
<string name="section_user_ids">СутноÑÑ‚Ñ–</string>
<string name="section_keys">Підключі</string>
+ <string name="section_cloud_search">Хмарний пошук</string>
<string name="section_general">Загальне</string>
<string name="section_defaults">Типове</string>
<string name="section_advanced">Додаткове</string>
+ <string name="section_passphrase_cache">Кеш парольної фрази</string>
+ <string name="section_certify">Сертифікувати</string>
<string name="section_actions">Дії</string>
+ <string name="section_share_key">Ключ</string>
<string name="section_certification_key">Ваш ключ викориÑтаний Ð´Ð»Ñ Ñертифікації</string>
+ <string name="section_upload_key">Синхронізувати ключ</string>
<string name="section_key_server">Сервер ключів</string>
<string name="section_fingerprint">Відбиток</string>
<string name="section_key_to_certify">Ключ Ð´Ð»Ñ Ñертикації</string>
+ <string name="section_decrypt_files">Файли</string>
+ <string name="section_decrypt_text">ТекÑÑ‚</string>
+ <string name="section_certs">Сертифікати</string>
<!--button-->
<string name="btn_decrypt_verify_file">Розшифрувати, перевірити та зберегти файл</string>
<string name="btn_decrypt_verify_message">Розшифрувати Ñ– перевірити повідомленнÑ</string>
@@ -58,12 +70,16 @@
<string name="btn_view_cert_key">ПереглÑнути ключ Ñертифікації</string>
<string name="btn_create_key">Створити ключ</string>
<string name="btn_add_files">Додати файл(и)</string>
+ <string name="btn_add_share_decrypted_text">Поширити розшифрований текÑÑ‚</string>
+ <string name="btn_decrypt_and_verify">Ñ– перевірити підпиÑи</string>
+ <string name="btn_decrypt_files">Розшифрувати файли</string>
<!--menu-->
<string name="menu_preferences">Параметри</string>
<string name="menu_help">Довідка</string>
<string name="menu_export_key">ЕкÑпорт до файлу</string>
<string name="menu_delete_key">Вилучити ключ</string>
<string name="menu_create_key">Створити мій ключ</string>
+ <string name="menu_import_existing_key">Імпорт з файлу</string>
<string name="menu_search">Пошук</string>
<string name="menu_beam_preferences">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ</string>
<string name="menu_key_edit_cancel">СкаÑувати</string>
@@ -79,11 +95,27 @@
<string name="label_file_colon">Файл:</string>
<string name="label_no_passphrase">Без парольної фрази</string>
<string name="label_passphrase">Парольна фраза</string>
+ <string name="label_unlock">РозблоковуєтьÑÑ…</string>
<string name="label_passphrase_again">Повторити пароль</string>
<string name="label_algorithm">Ðлгоритм</string>
<string name="label_ascii_armor">Файл ASCII Armor</string>
+ <string name="label_file_ascii_armor">Увімкнути ASCII Armor</string>
<string name="label_write_version_header">Ðехай інші дізнаютьÑÑ, що ви кориÑтуєтеÑÑ OpenKeychain</string>
<string name="label_write_version_header_summary">Ðапишіть \'OpenKeychain v2.7\' Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñів, зашифрованого текÑту та екÑпортованих ключів OpenPGP</string>
+ <string name="label_use_default_yubikey_pin">Вживати типовий YubiKey PIN</string>
+ <string name="label_use_num_keypad_for_yubikey_pin">Вживати цифрову клавіатуру Ð´Ð»Ñ YubiKey PIN</string>
+ <string name="label_label_use_default_yubikey_pin_summary">ВживаєтьÑÑ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¸Ð¹ PIN (123456) Ð´Ð»Ñ Ð´Ð¾Ñтупу до YubiKey чреез NFC</string>
+ <string name="label_asymmetric_from">ПідпиÑано:</string>
+ <string name="label_to">Зашифрувати до:</string>
+ <string name="label_delete_after_encryption">Вилучити файл піÑÐ»Ñ ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ</string>
+ <string name="label_delete_after_decryption">Вилучити піÑÐ»Ñ Ñ€Ð¾Ð·ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ</string>
+ <string name="label_encryption_algorithm">Ðлгоритм шифруваннÑ</string>
+ <string name="label_hash_algorithm">Хеш алгоритм</string>
+ <string name="label_symmetric">Зашифрувати з парольною фразою</string>
+ <string name="label_passphrase_cache_ttl">Кешувати чаÑ</string>
+ <string name="label_passphrase_cache_subs">Кешувати парольні фрази за підключем</string>
+ <string name="label_message_compression">СтиÑÐ½ÐµÐ½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ</string>
+ <string name="label_file_compression">СтиÑÐ½ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ</string>
<string name="label_keyservers">Сервери ключів</string>
<string name="label_key_id">ІД ключа</string>
<string name="label_creation">СтвореннÑ</string>
@@ -95,8 +127,11 @@
<string name="label_name">Ðазва</string>
<string name="label_comment">Коментар</string>
<string name="label_email">Ел. пошта</string>
+ <string name="label_send_key">Синхронізувати із хмарою</string>
<string name="label_fingerprint">Відбиток</string>
<string name="expiry_date_dialog_title">Задати термін дії</string>
+ <string name="label_first_keyserver_is_used">(Перший наведений Ñервер ключів Ñ” бажаний)</string>
+ <string name="label_preferred">бажаний</string>
<string name="user_id_no_name">&lt;без імені&gt;</string>
<string name="none">&lt;жоден&gt;</string>
<string name="no_key">&lt;без ключа&gt;</string>
@@ -152,6 +187,7 @@
<string name="passphrase_must_not_be_empty">Будь лаÑка, введіть парольну фразу.</string>
<string name="passphrase_for_symmetric_encryption">Симетричне шифруваннÑ.</string>
<string name="passphrase_for">Введіть парольну фразу Ð´Ð»Ñ \'%s\'</string>
+ <string name="file_delete_confirmation">Ви Ñправді хочете вилучити\n%s?</string>
<string name="file_delete_successful">УÑпішно вилучено.</string>
<string name="no_file_selected">Виберіть Ñпершу файл.</string>
<string name="encrypt_sign_successful">УÑпішно підпиÑано та/або перевірено.</string>
@@ -159,18 +195,33 @@
<string name="enter_passphrase_twice">Введіть двічі парольну фразу.</string>
<string name="select_encryption_key">Виберіть принаймні один ключ шифруваннÑ.</string>
<string name="select_encryption_or_signature_key">Виберіть принаймні один ключ ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ ключ підпиÑу.</string>
+ <string name="specify_file_to_encrypt_to">Будь лаÑка, виберіть файл Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ.\nУВÐГÐ! Якщо файл Ñ–Ñнує, то він буде перепиÑаний.</string>
+ <string name="specify_file_to_decrypt_to">Будь лаÑка, виберіть файл Ð´Ð»Ñ Ñ€Ð¾Ð·ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ.\nУВÐГÐ! Якщо файл Ñ–Ñнує, то він буде перепиÑаний.</string>
+ <string name="specify_file_to_export_to">Будь лаÑка, виберіть файл Ð´Ð»Ñ ÐµÐºÑпорту.\nУВÐГÐ! Якщо файл Ñ–Ñнує, то він буде перепиÑаний.</string>
+ <string name="key_deletion_confirmation_multi">Ви Ñправді хочете вилучити уÑÑ– вибрані відкриті ключі?\nВи не зможете це відмінити!</string>
+ <string name="secret_key_deletion_confirmation">Ви Ñправді хочете вилучити Ñекретний ключ \'%s\'?\nВи не зможете це відмінити!</string>
+ <string name="public_key_deletetion_confirmation">Ви Ñправді хочете вилучити відкритий ключ \'%s\'?\nВи не зможете це відмінити!</string>
<string name="also_export_secret_keys">Також екÑпортувати Ñекретні ключі</string>
<string name="key_exported">УÑпішно екÑпортовано 1 ключ.</string>
<string name="keys_exported">УÑпішно екÑпортовано %d ключів.</string>
<string name="no_keys_exported">Жодного ключа не екÑпортовано.</string>
<string name="key_creation_el_gamal_info">Примітка: лише підключі підтримують ElGamal.</string>
<string name="key_not_found">Ðе можливо знайти ключ %08X.</string>
+ <plurals name="bad_keys_encountered">
+ <item quantity="one">%d поганий Ñекретний ключ проігнорований. Можливо ви екÑпортували з параметром\n
+ --export-secret-subkeys\nЗробіть ваш екÑпорт з --export-secret-keys\n натоміÑÑ‚ÑŒ.</item>
+ <item quantity="few">%d погані Ñекретні ключі проігноровані. Можливо ви екÑпортували з параметром\n
+ --export-secret-subkeys\nЗробіть ваш екÑпорт з --export-secret-keys\n натоміÑÑ‚ÑŒ.</item>
+ <item quantity="other">%d поганих Ñекретних ключів проігноровано. Можливо ви екÑпортували з параметром\n
+ --export-secret-subkeys\nЗробіть ваш екÑпорт з --export-secret-keys\n натоміÑÑ‚ÑŒ.</item>
+ </plurals>
<string name="list_empty">Цей ÑпиÑок - порожній!</string>
<string name="nfc_successful">УÑпішно надіÑлано ключ через промінь NFC!</string>
<string name="key_copied_to_clipboard">Ключ вже Ñкопійовано у буфер обміну!</string>
<string name="fingerprint_copied_to_clipboard">Відбиток вже Ñкопійовано до буфера обміну!</string>
<string name="select_key_to_certify">Будь лаÑка, виберіть ключ Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ñƒ Ñертифікації!</string>
<string name="key_too_big_for_sharing">Ключ надто великий Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ÑпоÑобу поширеннÑ!</string>
+ <string name="text_copied_to_clipboard">ТекÑÑ‚ вже Ñкопійовано у буфер обміну!</string>
<!--errors
no punctuation, all lowercase,
they will be put after "error_message", e.g. "Error: file not found"-->
@@ -193,8 +244,18 @@
<string name="error_nothing_import">Ключ не знайдено!</string>
<string name="error_generic_report_bug">ТрапилаÑÑ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð° помилка, будь лаÑка, Ñтворіть новий звіт про помилку Ð´Ð»Ñ OpenKeychain.</string>
<!--results shown after decryption/verification-->
+ <string name="decrypt_result_no_signature">Ðе підпиÑано</string>
<string name="decrypt_result_invalid_signature">Ðевірний підпиÑ!</string>
+ <string name="decrypt_result_signature_uncertified">ПідпиÑано (не Ñертифіковано)</string>
+ <string name="decrypt_result_signature_expired_key">Термін дії ключа минув!</string>
+ <string name="decrypt_result_signature_revoked_key">Ключ вже відкликано!</string>
+ <string name="decrypt_result_signature_missing_key">Ðевідомий відкритий ключ</string>
+ <string name="decrypt_result_encrypted">Зашифровано</string>
+ <string name="decrypt_result_not_encrypted">Ðезашифровано</string>
+ <string name="decrypt_result_action_show">Показати</string>
+ <string name="decrypt_result_action_Lookup">Шукати</string>
<!--Add keys-->
+ <string name="add_keys_my_key">Мій ключ:</string>
<!--progress dialogs, usually ending in '…'-->
<string name="progress_done">Готово.</string>
<string name="progress_cancel">СкаÑувати</string>
@@ -284,7 +345,6 @@
<string name="import_qr_code_wrong">Ðевірний штрих-код! Спробуйте знову!</string>
<string name="import_qr_code_too_short_fingerprint">Відбиток надто короткий (&lt; 16 Ñимволів)</string>
<!--Generic result toast-->
- <string name="view_log">ПереглÑнути журнал</string>
<!--Import result toast-->
<plurals name="import_keys_added_and_updated_1">
<item quantity="one">УÑпішно імпортовано ключ.</item>
@@ -307,7 +367,10 @@
<item quantity="other">УÑпішно оновлено %1$d ключів%2$s.</item>
</plurals>
<string name="import_error_nothing">Ðема що імпортувати.</string>
+ <string name="import_error_nothing_cancelled">Імпорт ÑкаÑовано.</string>
<!--Delete result toast-->
+ <string name="delete_nothing">Ðема що вилучати.</string>
+ <string name="delete_cancelled">ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ ÑкаÑована.</string>
<!--Certify result toast-->
<!--Intent labels-->
<string name="intent_decrypt_file">Розшифрувати файл з OpenKeychain</string>
@@ -329,7 +392,7 @@
<string name="api_settings_delete_account">Видалити профіль</string>
<string name="api_settings_package_name">Ðазва пакунку</string>
<string name="api_settings_package_signature">SHA-256 підпиÑку пакунку</string>
- <string name="api_settings_accounts">Облікові запиÑи</string>
+ <string name="api_settings_settings">Параметри</string>
<string name="api_settings_accounts_empty">Ðемає облікового запиÑу приєднаного до цієї програми.</string>
<string name="api_register_allow">Дозволити доÑтуп</string>
<string name="api_register_disallow">Ðе дозволити доÑтуп</string>
@@ -348,17 +411,25 @@
<item quantity="few">%d ключі вибрано.</item>
<item quantity="other">%d ключів вибрано.</item>
</plurals>
+ <string name="key_list_empty_text1">Ключ не знайдено!</string>
+ <string name="key_list_filter_show_all">Показати уÑÑ– ключі</string>
<!--Key view-->
<string name="key_view_action_edit">Редагувати ключ</string>
+ <string name="key_view_action_encrypt">Зашифрувати текÑÑ‚</string>
+ <string name="key_view_action_encrypt_files">файли</string>
<string name="key_view_action_certify">Сертифікувати ÑутноÑÑ‚Ñ–</string>
<string name="key_view_action_update">Оновити із Ñервера ключів</string>
<string name="key_view_action_share_with">ПоділитиÑÑ Ñ–Ð·â€¦</string>
+ <string name="key_view_action_share_nfc">ПоділитиÑÑ Ñ‡ÐµÑ€ÐµÐ· NFC</string>
+ <string name="key_view_action_upload">Вивантажити на Ñервер ключів</string>
<string name="key_view_tab_main">ОÑновна інформаціÑ</string>
<string name="key_view_tab_share">ПоділитиÑÑ</string>
<string name="key_view_tab_keys">Підключі</string>
<string name="key_view_tab_certs">Сертифікати</string>
<string name="user_id_info_revoked_title">Відхилено</string>
<string name="user_id_info_revoked_text">Ð¦Ñ ÑутніÑÑ‚ÑŒ вже відкликана влаÑником ключа. Вона більше не дійÑна.</string>
+ <string name="user_id_info_certified_title">Сертифіковано</string>
+ <string name="user_id_info_uncertified_title">ÐеÑертифіковано</string>
<string name="user_id_info_invalid_title">ÐедійÑна</string>
<string name="user_id_info_invalid_text">ЩоÑÑŒ неправильне у цій ÑутноÑÑ‚Ñ–!</string>
<!--Edit key-->
@@ -368,7 +439,10 @@
<string name="edit_key_edit_user_id_title">Виберіть дію!</string>
<string name="edit_key_edit_user_id_revoked">Ð¦Ñ ÑутніÑÑ‚ÑŒ вже відкликана. Це не можна ÑкаÑувати.</string>
<string name="edit_key_edit_subkey_title">Виберіть дію!</string>
+ <string name="edit_key_new_subkey">новий підключ</string>
<string name="edit_key_select_flag">Будь лаÑка, виберіть хоча б один прапор!</string>
+ <string name="edit_key_error_add_identity">Додати хоча б одну ÑутніÑÑ‚ÑŒ!</string>
+ <string name="edit_key_error_add_subkey">Додати хоча б один підключ!</string>
<!--Create key-->
<string name="create_key_upload">Відвантажити ключ на Ñервер ключів</string>
<string name="create_key_empty">Це поле - обов\'Ñзкове</string>
@@ -386,6 +460,7 @@
<string name="drawer_close">Закрити панель навігації</string>
<string name="my_keys">Мої ключі</string>
<!--hints-->
+ <string name="encrypt_content_edit_text_hint">Ðабрати текÑÑ‚</string>
<!--certs-->
<string name="cert_default">типово</string>
<string name="cert_none">жоден</string>
@@ -397,12 +472,17 @@
<string name="cert_verify_error">Помилка!</string>
<string name="cert_verify_unavailable">ÐедоÑтупний ключ</string>
<!--LogType log messages. Errors should have _ERROR_ in their name and end with a !-->
+ <string name="msg_internal_error">Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°!</string>
+ <string name="msg_cancelled">ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ ÑкаÑована.</string>
<!--Import Public log entries-->
<string name="msg_ip_apply_batch">ЗаÑтоÑовуєтьÑÑ Ð¿Ð°ÐºÐµÑ‚Ð½Ð° Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð²Ñтавки.</string>
<string name="msg_ip_bad_type_secret">Спробували імпортувати Ñекретну в\'Ñзку Ñк публічну. Це вада. Будь лаÑка, відправте звіт!</string>
<string name="msg_ip_delete_old_fail">Ðема вилученого Ñтарого ключа (ÑтворюєтьÑÑ Ð½Ð¾Ð²Ð¸Ð¹?)</string>
<string name="msg_ip_delete_old_ok">Вилучений Ñтарий ключ з бази даних</string>
<string name="msg_ip_encode_fail">ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑ Ñ‡ÐµÑ€ÐµÐ· помилку кодуваннÑ</string>
+ <string name="msg_ip_error_io_exc">ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑ Ñ‡ÐµÑ€ÐµÐ· помилку введеннÑ/виведеннÑ</string>
+ <string name="msg_ip_error_op_exc">ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑ Ñ‡ÐµÑ€ÐµÐ· помилку бази даних</string>
+ <string name="msg_ip_error_remote_ex">ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑ Ñ‡ÐµÑ€ÐµÐ· внутрішню помилку</string>
<string name="msg_ip">ІмпортуєтьÑÑ Ð¿ÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð° в\'Ñзка %s</string>
<string name="msg_ip_insert_keyring">ШифруютьÑÑ Ð´Ð°Ð½Ñ– із в\'Ñзки</string>
<string name="msg_ip_insert_keys">ÐналізуютьÑÑ ÐºÐ»ÑŽÑ‡Ñ–</string>
@@ -423,12 +503,14 @@
<item quantity="few">ІгноруєтьÑÑ %s Ñертифікати, виданих невідомими відкритими ключами</item>
<item quantity="other">ІгноруєтьÑÑ %s Ñертифікатів, виданих невідомими відкритими ключами</item>
</plurals>
+ <string name="msg_ip_uid_revoked">ІД кориÑтувача відхилене</string>
<string name="msg_is_bad_type_public">Спробували імпортувати публічну в\'Ñзку Ñк Ñекретну. Це вада. Будь лаÑка, відправте звіт!</string>
<string name="msg_is_bad_type_uncanon">Спробували імпортувати в\'Ñзку без канонізації. Це вада. Будь лаÑка, відправте звіт!</string>
<!--Import Secret log entries-->
<string name="msg_is">ІмпортуєтьÑÑ Ñекретний ключ %s</string>
<string name="msg_is_db_exception">Помилка бази даних!</string>
<string name="msg_is_importing_subkeys">ОпрацьовуютьÑÑ Ñекретні підключі</string>
+ <string name="msg_is_error_io_exc">Помилка ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²â€™Ñзки</string>
<string name="msg_is_pubring_generate">ГенеруєтьÑÑ Ð¿ÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð° в\'Ñзка із Ñекретної</string>
<string name="msg_is_success_identical">Ð’\'Ñзка не міÑтить нових даних. Ðема що робити.</string>
<string name="msg_is_success">УÑпішно імпортована Ñекретна в\'Ñзка</string>
@@ -456,12 +538,12 @@
<string name="msg_mg_secret">Ð—Ð»Ð¸Ñ‚Ñ‚Ñ Ñƒ Ñекретну в\'Ñзку %s</string>
<string name="msg_mg_new_subkey">ДодаєтьÑÑ Ð½Ð¾Ð²Ð¸Ð¹ підключ %s</string>
<string name="msg_mg_found_new">Знайдено %s нових Ñертифікатів у в\'Ñзці</string>
+ <string name="msg_mg_unchanged">Ðема що зливати</string>
<!--createSecretKeyRing-->
<string name="msg_cr">ГенеруєтьÑÑ Ð½Ð¾Ð²Ð¸Ð¹ оÑновний ключ</string>
<string name="msg_cr_error_no_master">Ðе вказано параметрів оÑновного ключа!</string>
<string name="msg_cr_error_no_certify">ОÑновний ключ повинен мати прапорець certify!</string>
<string name="msg_cr_error_keysize_512">Розмір ключа має бути більшим або рівним 512!</string>
- <string name="msg_cr_error_internal_pgp">Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° PGP!</string>
<!--modifySecretKeyRing-->
<string name="msg_mr">ЗмінюєтьÑÑ Ð²\'Ñзка %s</string>
<string name="msg_mf_error_encode">ВинÑток шифруваннÑ!</string>
@@ -469,23 +551,46 @@
<string name="msg_mf_error_keyid">Ðемає ІД ключа. Це Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°! Будь лаÑка, надішліть звіт про ваду!</string>
<string name="msg_mf_error_integrity">Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° - збій перевірки ціліÑноÑÑ‚Ñ–!</string>
<string name="msg_mf_error_master_none">Ðе знайдено оÑновного Ñертифікату Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ð¹! (УÑе відкликано?)</string>
+ <string name="msg_mf_error_noexist_primary">Вказаний поганий ІД первинного кориÑтувача!</string>
+ <string name="msg_mf_error_noexist_revoke">Вказаний поганий ІД первинного кориÑтувача!</string>
+ <string name="msg_mf_error_revoked_primary">ІД відхилених кориÑтувачів не може бути первинним!</string>
<string name="msg_mf_error_sig">ВинÑток підпиÑу!</string>
<string name="msg_mf_master">ЗмінюютьÑÑ Ð¾Ñнові Ñертифікації</string>
+ <string name="msg_mf_primary_replace_old">ЗамінюєтьÑÑ Ñертифікат ІД попереднього первинного кориÑтувача</string>
+ <string name="msg_mf_primary_new">ГенеруєтьÑÑ Ð½Ð¾Ð²Ð¸Ð¹ Ñертифікат Ð´Ð»Ñ Ð†Ð” нового первинного кориÑтувача</string>
<string name="msg_mf_subkey_change">ЗмінюєтьÑÑ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ %s</string>
<string name="msg_mf_error_subkey_missing">Спробували працювати із втраченим підключем %s!</string>
+ <string name="msg_mf_subkey_new">ДодаєтьÑÑ Ð½Ð¾Ð²Ð¸Ð¹ підключ типу %s</string>
<string name="msg_mf_subkey_new_id">Ðовий ід підключа: %s</string>
<string name="msg_mf_error_past_expiry">Дата Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð´Ñ–Ñ— не може бути у минулому!</string>
<string name="msg_mf_subkey_revoke">ВідкликаєтьÑÑ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ %s</string>
<string name="msg_mf_success">УÑпішно модифіковано в\'Ñзку</string>
+ <string name="msg_mf_uid_add">ДодаєтьÑÑ Ñ–Ð´ кориÑтувача %s</string>
+ <string name="msg_mf_uid_primary">ЗмінюєтьÑÑ Ð¿ÐµÑ€Ð²Ð¸Ð½Ð½Ðµ ІД кориÑтувача на %s</string>
+ <string name="msg_mf_uid_revoke">Ð’Ñ–Ð´Ñ…Ð¸Ð»ÐµÐ½Ð½Ñ Ð†Ð” кориÑтувача %s</string>
<string name="msg_mf_uid_error_empty">ІД кориÑтувача не повинно бути порожнім!</string>
<string name="msg_mf_unlock_error">Помилка Ñ€Ð¾Ð·Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²\'Ñзки!</string>
<string name="msg_mf_unlock">РозблоковуєтьÑÑ Ð²\'Ñзка</string>
<!--Consolidate-->
+ <string name="msg_con_save_secret">Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñекретних в\'Ñзок</string>
+ <string name="msg_con_save_public">Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿ÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð¸Ñ… в\'Ñзок</string>
+ <string name="msg_con_db_clear">ÐžÑ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð±Ð°Ð·Ð¸ даних</string>
+ <string name="msg_con_error_db">Помилка Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð±Ð°Ð·Ð¸ даних!</string>
<string name="msg_con_error_public">Помилка повторного імпорту публічних ключів!</string>
<string name="msg_con_error_secret">Помилка повторного імпорту Ñекретних ключів!</string>
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
+ <string name="msg_ek_error_not_found">Ключ не знайдено!</string>
<!--Messages for DecryptVerify operation-->
+ <string name="msg_dc_clear_meta_file">Ðазва файла: %s</string>
+ <string name="msg_dc_clear_meta_mime">Тип MIME: %s</string>
+ <string name="msg_dc_clear_meta_size">Розмір файла: %s</string>
+ <string name="msg_dc_clear_meta_time">Ð§Ð°Ñ Ð·Ð¼Ñ–Ð½Ð¸: %s</string>
+ <string name="msg_dc_error_integrity_check">Помилка перевірки ціліÑноÑÑ‚Ñ–!</string>
+ <string name="msg_dc_ok">Гаразд</string>
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<plurals name="error_import_non_pgp_part">
<item quantity="one">чаÑтина завантаженого файлу Ñ” вірним об\'єктом OpenPGP, але не ключем OpenPGP</item>
<item quantity="few">чаÑтини завантаженого файлу Ñ” вірним об\'єктом OpenPGP, але не ключем OpenPGP</item>
@@ -496,6 +601,10 @@
<string name="passp_cache_notif_n_keys">OpenKeychain має %d кешованих парольних фраз</string>
<string name="passp_cache_notif_keys">Кешовані парольні фрази:</string>
<string name="passp_cache_notif_clear">ОчиÑтити кеш</string>
+ <!--First Time-->
+ <string name="first_time_text1">Заберіть вашу приватніÑÑ‚ÑŒ із OpenKeychain!</string>
+ <string name="first_time_create_key">Створити мій ключ</string>
+ <string name="first_time_skip">ПропуÑтити уÑтановку</string>
<!--unsorted-->
<string name="section_certifier_id">Ким підпиÑаний</string>
<string name="section_cert">Дані Ñертифікату</string>
@@ -514,8 +623,8 @@
<string name="can_sign_not">не можна підпиÑати</string>
<string name="error_no_encrypt_subkey">Жодний підключ ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ´Ð¾Ñтупний!</string>
<string name="contact_show_key">Показати ключ (%s)</string>
- <!--First Time-->
- <string name="first_time_text1">Заберіть вашу приватніÑÑ‚ÑŒ із OpenKeychain!</string>
- <string name="first_time_create_key">Створити мій ключ</string>
- <string name="first_time_skip">ПропуÑтити уÑтановку</string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-v11/styles_keychaintheme.xml b/OpenKeychain/src/main/res/values-v11/styles_keychaintheme.xml
deleted file mode 100644
index 0b6c4c4f5..000000000
--- a/OpenKeychain/src/main/res/values-v11/styles_keychaintheme.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Generated with http://android-holo-colors.com -->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
- <style name="ButtonKeychainTheme" parent="android:Widget.Holo.Light.Button">
- <item name="android:background">@drawable/keychaintheme_btn_default_holo_light</item>
- </style>
-
- <style name="ImageButtonKeychainTheme" parent="android:Widget.Holo.Light.ImageButton">
- <item name="android:background">@drawable/keychaintheme_btn_default_holo_light</item>
- </style>
-
- <style name="SpinnerKeychainTheme" parent="android:Widget.Holo.Light.Spinner">
- <item name="android:background">@drawable/keychaintheme_spinner_background_holo_light</item>
- <item name="android:dropDownSelector">@drawable/keychaintheme_list_selector_holo_light</item>
- </style>
-
- <style name="ProgressBarKeychainTheme" parent="android:Widget.Holo.Light.ProgressBar.Horizontal">
- <item name="android:progressDrawable">@drawable/keychaintheme_progress_horizontal_holo_light</item>
- <item name="android:indeterminateDrawable">@drawable/keychaintheme_progress_indeterminate_horizontal_holo_light</item>
- </style>
-
- <style name="SectionHeader">
- <item name="android:drawableBottom">@drawable/section_header</item>
- <item name="android:drawablePadding">4dp</item>
- <item name="android:layout_marginTop">8dp</item>
- <item name="android:paddingLeft">8dp</item>
- <item name="android:textAllCaps">true</item>
- <item name="android:textStyle">bold</item>
- <item name="android:textColor">@color/emphasis</item>
- <item name="android:textSize">14sp</item>
- </style>
-
-</resources>
diff --git a/OpenKeychain/src/main/res/values-v11/themes_keychaintheme.xml b/OpenKeychain/src/main/res/values-v11/themes_keychaintheme.xml
deleted file mode 100644
index 4f13f81c6..000000000
--- a/OpenKeychain/src/main/res/values-v11/themes_keychaintheme.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Generated with http://android-holo-colors.com -->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
- <style name="KeychainTheme" parent="@style/_KeychainTheme"/>
-
- <style name="_KeychainTheme" parent="Theme.AppCompat.Light">
-
- <item name="android:editTextBackground">@drawable/keychaintheme_edit_text_holo_light</item>
-
- <item name="android:listChoiceIndicatorMultiple">@drawable/keychaintheme_btn_check_holo_light</item>
-
- <item name="android:buttonStyle">@style/ButtonKeychainTheme</item>
-
- <item name="android:imageButtonStyle">@style/ImageButtonKeychainTheme</item>
-
- <item name="android:dropDownSpinnerStyle">@style/SpinnerKeychainTheme</item>
-
- <item name="android:progressBarStyleHorizontal">@style/ProgressBarKeychainTheme</item>
-
- <item name="android:listChoiceBackgroundIndicator">@drawable/keychaintheme_list_selector_holo_light</item>
-
- <item name="android:activatedBackgroundIndicator">@drawable/keychaintheme_activated_background_holo_light</item>
-
- <item name="android:fastScrollThumbDrawable">@drawable/apptheme_fastscroll_thumb_holo</item>
-
- <item name="android:selectableItemBackground">@drawable/keychaintheme_list_selector_holo_light</item>
-
- </style>
-
-</resources>
diff --git a/OpenKeychain/src/main/res/values-v21/dimens.xml b/OpenKeychain/src/main/res/values-v21/dimens.xml
new file mode 100644
index 000000000..7e07ae0f9
--- /dev/null
+++ b/OpenKeychain/src/main/res/values-v21/dimens.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!--
+ Status bar height according to
+ http://www.google.com/design/spec/layout/structure.html#structure-system-bars
+ -->
+ <dimen name="statusbar_height">24dp</dimen>
+ <!-- 120dp + statusbar_height -->
+ <dimen name="big_toolbar">141dp</dimen>
+ <dimen name="huge_toolbar">243dp</dimen>
+</resources> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/values-v21/themes.xml b/OpenKeychain/src/main/res/values-v21/themes.xml
new file mode 100644
index 000000000..b47026e5b
--- /dev/null
+++ b/OpenKeychain/src/main/res/values-v21/themes.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <style name="KeychainTheme" parent="KeychainTheme.Base">
+ <item name="android:windowTranslucentStatus">true</item>
+
+ <!-- enable window content transitions -->
+ <item name="android:windowContentTransitions">true</item>
+ <item name="android:windowAllowEnterTransitionOverlap">true</item>
+ <item name="android:windowAllowReturnTransitionOverlap">true</item>
+ <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
+ <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
+
+ </style>
+</resources> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/values-zh-rTW/strings.xml b/OpenKeychain/src/main/res/values-zh-rTW/strings.xml
index 744aac20d..daa0a171b 100644
--- a/OpenKeychain/src/main/res/values-zh-rTW/strings.xml
+++ b/OpenKeychain/src/main/res/values-zh-rTW/strings.xml
@@ -9,13 +9,10 @@
<string name="title_encrypt_text">加密文字</string>
<string name="title_encrypt_files">加密檔案</string>
<string name="title_decrypt">解密</string>
- <string name="title_authentication">å£ä»¤</string>
<string name="title_add_subkey">新增å­é‡‘é‘°</string>
<string name="title_edit_key">編輯金鑰</string>
- <string name="title_preferences">å好設定</string>
- <string name="title_cloud_search_preferences">雲端檢索設定</string>
+ <string name="title_cloud_search_preferences">雲端查詢設定</string>
<string name="title_api_registered_apps">應用程å¼</string>
- <string name="title_key_server_preference">金鑰伺æœå™¨è¨­å®š</string>
<string name="title_change_passphrase">變更å£ä»¤</string>
<string name="title_share_fingerprint_with">分享指紋…</string>
<string name="title_share_key">分享金鑰…</string>
@@ -24,6 +21,7 @@
<string name="title_encrypt_to_file">加密到檔案</string>
<string name="title_decrypt_to_file">解密到檔案</string>
<string name="title_import_keys">匯入金鑰</string>
+ <string name="title_add_keys">新增金鑰</string>
<string name="title_export_key">匯出金鑰</string>
<string name="title_export_keys">匯出所有金鑰</string>
<string name="title_key_not_found">找ä¸åˆ°é‡‘é‘°</string>
@@ -33,13 +31,16 @@
<string name="title_help">說明</string>
<string name="title_log_display">紀錄</string>
<string name="title_create_key">建立金鑰</string>
+ <string name="title_exchange_keys">交æ›é‡‘é‘°</string>
+ <string name="title_advanced_key_info">進階資訊</string>
<!--section-->
<string name="section_user_ids">身份</string>
<string name="section_keys">å­é‡‘é‘°</string>
- <string name="section_cloud_search">雲端檢索</string>
+ <string name="section_cloud_search">雲端查詢</string>
<string name="section_general">一般</string>
<string name="section_defaults">é è¨­</string>
<string name="section_advanced">進階</string>
+ <string name="section_passphrase_cache">å£ä»¤å¿«å–</string>
<string name="section_certification_key">用來簽署的ç§é‘°</string>
<string name="section_key_server">金鑰伺æœå™¨</string>
<string name="section_fingerprint">指紋</string>
@@ -65,7 +66,6 @@
<string name="btn_create_key">建立金鑰</string>
<string name="btn_add_files">加入檔案</string>
<string name="btn_add_share_decrypted_text">解密並分享訊æ¯</string>
- <string name="btn_decrypt_clipboard">解密剪貼簿的內容</string>
<string name="btn_decrypt_and_verify">並且驗證簽å</string>
<string name="btn_decrypt_files">解密檔案</string>
<!--menu-->
@@ -74,6 +74,7 @@
<string name="menu_export_key">匯出到檔案</string>
<string name="menu_delete_key">刪除金鑰</string>
<string name="menu_create_key">建立金鑰</string>
+ <string name="menu_import_existing_key">從檔案匯入</string>
<string name="menu_search">æœå°‹</string>
<string name="menu_beam_preferences">Beam 設定</string>
<string name="menu_key_edit_cancel">å–消</string>
@@ -91,8 +92,6 @@
<string name="label_algorithm">演算法</string>
<string name="label_write_version_header">讓別人知é“我在使用OpenKeychain</string>
<string name="label_write_version_header_summary">在簽åã€å¯†æ–‡èˆ‡åŒ¯å‡ºçš„金鑰裡寫入\'OpenKeychain v2.7\'</string>
- <string name="label_use_default_yubikey_pin">使用é è¨­çš„Yubikey PIN</string>
- <string name="label_label_use_default_yubikey_pin_summary">使用é è¨­çš„PIN (123456)來通éŽNFCå­˜å–Yubikeys</string>
<string name="label_asymmetric_from">ç°½å自:</string>
<string name="label_to">加密給:</string>
<string name="label_delete_after_encryption">加密後刪除檔案</string>
@@ -100,6 +99,7 @@
<string name="label_encryption_algorithm">加密演算法</string>
<string name="label_hash_algorithm">雜湊演算法</string>
<string name="label_symmetric">使用å£ä»¤åŠ å¯†</string>
+ <string name="label_passphrase_cache_ttl">å¿«å–時間</string>
<string name="label_message_compression">訊æ¯å£“縮</string>
<string name="label_file_compression">檔案壓縮</string>
<string name="label_keyservers">金鑰伺æœå™¨</string>
@@ -113,6 +113,7 @@
<string name="label_name">åå­—</string>
<string name="label_comment">註記</string>
<string name="label_email">Email</string>
+ <string name="label_send_key">與雲端åŒæ­¥</string>
<string name="label_fingerprint">指紋</string>
<string name="expiry_date_dialog_title">設定效期</string>
<string name="can_encrypt">å¯ä»¥åŠ å¯†</string>
@@ -151,28 +152,62 @@
<string name="flag_authenticate">é©—è­‰</string>
<!--sentences-->
<string name="wrong_passphrase">å£ä»¤éŒ¯èª¤ã€‚</string>
+ <string name="no_filemanager_installed">找ä¸åˆ°ç›¸å®¹çš„檔案管ç†å“¡ã€‚</string>
+ <string name="passphrases_do_not_match">å£ä»¤ä¸ç›¸ç¬¦ã€‚</string>
+ <string name="passphrase_must_not_be_empty">請輸入å£ä»¤ã€‚</string>
<string name="passphrase_for_symmetric_encryption">å°ç¨±åŠ å¯†ã€‚</string>
+ <string name="file_delete_confirmation">你確定è¦åˆªé™¤\n%s?</string>
<string name="file_delete_successful">刪除æˆåŠŸã€‚</string>
+ <string name="no_file_selected">è«‹å…ˆé¸æ“‡æª”案。</string>
+ <string name="encrypt_sign_successful">æˆåŠŸç°½å並/或加密。</string>
+ <string name="encrypt_sign_clipboard_successful">æˆåŠŸç°½å並/或加密到剪貼簿。</string>
+ <string name="enter_passphrase_twice">é‡è¤‡è¼¸å…¥å£ä»¤</string>
+ <string name="select_encryption_key">é¸æ“‡è‡³å°‘一把加密金鑰。</string>
+ <string name="select_encryption_or_signature_key">é¸æ“‡è‡³å°‘一把加密或簽å金鑰。</string>
+ <string name="specify_file_to_encrypt_to">è«‹é¸æ“‡è¦å°‡æª”案加密到哪。\n警告:已經存在的檔案將被覆蓋。</string>
+ <string name="specify_file_to_decrypt_to">è«‹é¸æ“‡è¦å°‡æª”案解密到哪。\n警告:已經存在的檔案將被覆蓋。</string>
+ <string name="specify_file_to_export_to">è«‹é¸æ“‡è¦å°‡æª”案匯出到哪。\n警告:已經存在的檔案將被覆蓋。</string>
+ <string name="key_deletion_confirmation_multi">你確定è¦åˆªé™¤é¸æ“‡çš„公鑰?\n此動作無法復原ï¼</string>
+ <string name="secret_key_deletion_confirmation">你確定è¦åˆªé™¤å¯†é‘°\'%s\'?\n此動作無法復原ï¼</string>
+ <string name="public_key_deletetion_confirmation">你確定è¦åˆªé™¤å…¬é‘°\'%s\'?\n此動作無法復原ï¼</string>
<string name="also_export_secret_keys">一併匯出ç§é‘°</string>
<string name="key_exported">æˆåŠŸåŒ¯å‡º 1 把金鑰。</string>
<string name="keys_exported">æˆåŠŸåŒ¯å‡º %d 把金鑰。</string>
<string name="nfc_successful">NFC Beam發é€é‡‘é‘°æˆåŠŸ!</string>
<string name="key_copied_to_clipboard">金鑰已複製到剪貼簿!</string>
<string name="fingerprint_copied_to_clipboard">指紋已複製到剪貼簿!</string>
+ <string name="select_key_to_certify">è«‹é¸æ“‡è¦ç”¨ä¾†èªè­‰çš„金鑰ï¼</string>
<string name="key_too_big_for_sharing">金鑰太大無法使用此方å¼åˆ†äº«!</string>
<string name="text_copied_to_clipboard">文字已複製到剪貼簿!</string>
<!--errors
no punctuation, all lowercase,
they will be put after "error_message", e.g. "Error: file not found"-->
+ <string name="error_file_delete_failed">刪除%s失敗</string>
<string name="error_file_not_found">找ä¸åˆ°æª”案</string>
<string name="error_no_secret_key_found">沒有é©åˆçš„ç§é‘°</string>
<string name="error_external_storage_not_ready">外部儲存空間尚未就緒</string>
<string name="error_key_size_minimum512bit">金鑰長度必須大於512ä½å…ƒ</string>
+ <string name="error_user_id_no_email">沒有找到電å­éƒµä»¶</string>
+ <string name="error_key_needs_a_user_id">需è¦è‡³å°‘一個身分識別</string>
+ <string name="error_no_signature_passphrase">沒有æä¾›å£ä»¤</string>
+ <string name="error_no_signature_key">找ä¸åˆ°ç°½å金鑰</string>
+ <string name="error_integrity_check_failed">完整性檢查失敗ï¼è³‡æ–™å·²è¢«ä¿®æ”¹ï¼</string>
<string name="error_wrong_passphrase">å£ä»¤éŒ¯èª¤</string>
+ <string name="error_could_not_extract_private_key">無法抽å–ç§é‘°</string>
<!--errors without preceeding Error:-->
+ <string name="error_jelly_bean_needed">需è¦Android 4.1以上æ‰èƒ½ä½¿ç”¨NFC Beam功能ï¼</string>
<string name="error_nfc_needed">您的è£ç½®ä¸æ”¯æ´NFC!</string>
+ <string name="error_nothing_import">找ä¸åˆ°é‡‘é‘°ï¼</string>
<!--results shown after decryption/verification-->
+ <string name="decrypt_result_no_signature">尚未簽å</string>
<string name="decrypt_result_invalid_signature">無效的簽章!</string>
+ <string name="decrypt_result_signature_expired_key">金鑰已éŽæœŸï¼</string>
+ <string name="decrypt_result_signature_revoked_key">金鑰已被撤銷ï¼</string>
+ <string name="decrypt_result_signature_missing_key">未知的公鑰</string>
+ <string name="decrypt_result_encrypted">已加密</string>
+ <string name="decrypt_result_not_encrypted">未加密</string>
+ <string name="decrypt_invalid_text">ç°½å無效或是金鑰已經éŽæœŸ/被撤銷,無法確èªè¨Šæ¯å…§å®¹çš„作者。是å¦ç¹¼çºŒé¡¯ç¤ºï¼Ÿ</string>
+ <string name="decrypt_invalid_button">我明白這樣åšçš„風險,顯示它ï¼</string>
<!--Add keys-->
<!--progress dialogs, usually ending in '…'-->
<string name="progress_done">完æˆã€‚</string>
@@ -182,43 +217,240 @@
<string name="progress_importing">匯入中…</string>
<string name="progress_exporting">匯出中…</string>
<string name="progress_uploading">正在上傳…</string>
+ <string name="progress_generating_rsa">正在產生新的RSA金鑰…</string>
+ <string name="progress_generating_dsa">正在產生新的DSA金鑰…</string>
+ <string name="progress_generating_elgamal">正在產生新的ElGamal金鑰…</string>
+ <string name="progress_generating_ecdsa">正在產生新的ECDSA金鑰…</string>
+ <string name="progress_generating_ecdh">正在產生新的ECDH金鑰…</string>
+ <string name="progress_modify">正在變更鑰匙圈…</string>
+ <string name="progress_modify_unlock">正在解鎖鑰匙圈…</string>
+ <string name="progress_modify_adduid">正在新增使用者身份…</string>
+ <string name="progress_modify_revokeuid">正在撤銷使用者身份…</string>
+ <string name="progress_modify_primaryuid">正在變更主è¦ä½¿ç”¨è€…身份…</string>
+ <string name="progress_modify_subkeychange">正在變更å­é‡‘鑰…</string>
+ <string name="progress_modify_subkeyrevoke">正在撤銷å­é‡‘鑰…</string>
+ <string name="progress_modify_subkeyadd">正在新增å­é‡‘鑰…</string>
+ <string name="progress_modify_passphrase">正在變更å£ä»¤â€¦</string>
+ <plurals name="progress_exporting_key">
+ <item quantity="other">正在匯出金鑰…</item>
+ </plurals>
+ <string name="progress_extracting_signature_key">正在抽å–ç°½å金鑰…</string>
+ <string name="progress_extracting_key">正在抽å–金鑰…</string>
+ <string name="progress_preparing_streams">正在準備串æµâ€¦</string>
+ <string name="progress_encrypting">正在加密資料…</string>
+ <string name="progress_decrypting">正在解密資料…</string>
+ <string name="progress_preparing_signature">正在準備簽å…</string>
+ <string name="progress_generating_signature">正在產生簽å…</string>
+ <string name="progress_processing_signature">正在處ç†ç°½å…</string>
+ <string name="progress_verifying_signature">正在驗證簽å…</string>
+ <string name="progress_signing">ç°½å中…</string>
+ <string name="progress_certifying">正在èªè­‰â€¦</string>
+ <string name="progress_reading_data">正在讀å–資料…</string>
+ <string name="progress_finding_key">正在尋找金鑰…</string>
+ <string name="progress_decompressing_data">正在解壓縮…</string>
+ <string name="progress_verifying_integrity">正在驗證完整性…</string>
+ <string name="progress_deleting">正在刪除金鑰…</string>
<!--action strings-->
<!--key bit length selections-->
+ <string name="key_size_512">512</string>
+ <string name="key_size_768">768</string>
+ <string name="key_size_1024">1024</string>
+ <string name="key_size_1536">1536</string>
+ <string name="key_size_2048">2048</string>
+ <string name="key_size_3072">3072</string>
+ <string name="key_size_4096">4096</string>
+ <string name="key_size_8192">8192</string>
+ <string name="key_size_custom">自訂金鑰長度</string>
<!--elliptic curve names-->
+ <string name="key_curve_nist_p256">NIST P-256</string>
+ <string name="key_curve_nist_p384">NIST P-384</string>
+ <string name="key_curve_nist_p521">NIST P-521</string>
<!--not in for now, see SaveKeyringParcel
<string name="key_curve_bp_p256">"Brainpool P-256"</string>
<string name="key_curve_bp_p384">"Brainpool P-384"</string>
<string name="key_curve_bp_p512">"Brainpool P-512"</string>-->
<!--compression-->
+ <string name="compression_fast">å¿«</string>
+ <string name="compression_very_slow">éžå¸¸æ…¢</string>
<!--Help-->
+ <string name="help_tab_start">快速上手</string>
+ <string name="help_tab_faq">常見å•é¡Œ</string>
+ <string name="help_tab_wot">信任網</string>
+ <string name="help_tab_nfc_beam">NFC Beam</string>
+ <string name="help_tab_changelog">更新紀錄</string>
+ <string name="help_tab_about">關於</string>
+ <string name="help_about_version">版本:</string>
<!--Import-->
+ <string name="import_tab_keyserver">金鑰伺æœå™¨</string>
+ <string name="import_tab_cloud">雲端查詢</string>
+ <string name="import_tab_direct">檔案/剪貼簿</string>
+ <string name="import_tab_qr_code">二維æ¢ç¢¼/NFC</string>
+ <string name="import_import">匯入é¸æ“‡çš„金鑰</string>
+ <string name="import_qr_code_button">掃æ二維æ¢ç¢¼</string>
<!--Generic result toast-->
<!--Import result toast-->
+ <plurals name="import_keys_added_and_updated_1">
+ <item quantity="other">æˆåŠŸåŒ¯å…¥%1$d金鑰</item>
+ </plurals>
+ <plurals name="import_keys_added_and_updated_2">
+ <item quantity="other">並更新%1$d金鑰%2$s。</item>
+ </plurals>
+ <plurals name="import_keys_added">
+ <item quantity="other">æˆåŠŸåŒ¯å…¥%1$d金鑰%2$s。</item>
+ </plurals>
+ <plurals name="import_keys_updated">
+ <item quantity="other">æˆåŠŸæ›´æ–°%1$d金鑰%2$s。</item>
+ </plurals>
+ <string name="import_error_nothing">沒有æ±è¥¿å¯ä»¥åŒ¯å…¥ã€‚</string>
+ <string name="import_error_nothing_cancelled">匯入已å–消。</string>
<!--Delete result toast-->
+ <string name="delete_nothing">沒有æ±è¥¿å¯ä»¥åˆªé™¤ã€‚</string>
+ <string name="delete_cancelled">刪除已å–消。</string>
<!--Certify result toast-->
<!--Intent labels-->
+ <string name="intent_decrypt_file">使用OpenKeychain解密檔案</string>
+ <string name="intent_import_key">匯入金鑰至OpenKeychain</string>
+ <string name="intent_send_encrypt">使用OpenKeychain加密</string>
+ <string name="intent_send_decrypt">使用OpenKeychain解密</string>
<!--Remote API-->
+ <string name="api_no_apps">沒有已註冊的應用程å¼ï¼\n\n支æ´çš„第三方應用程å¼è«‹åƒè€ƒèªªæ˜Žæ–‡ä»¶ã€‚</string>
+ <string name="api_settings_show_info">顯示進階資訊</string>
+ <string name="api_settings_hide_info">éš±è—進階資訊</string>
+ <string name="api_settings_show_advanced">顯示進階設定</string>
+ <string name="api_settings_hide_advanced">éš±è—進階設定</string>
+ <string name="api_settings_no_key">沒有é¸æ“‡é‡‘é‘°</string>
+ <string name="api_settings_select_key">é¸æ“‡é‡‘é‘°</string>
+ <string name="api_settings_create_key">為此帳戶建立金鑰</string>
+ <string name="api_settings_save">儲存</string>
+ <string name="api_settings_save_msg">帳戶已儲存</string>
+ <string name="api_settings_cancel">å–消</string>
+ <string name="api_settings_revoke">撤銷存å–</string>
+ <string name="api_settings_start">開啟應用程å¼</string>
+ <string name="api_settings_delete_account">移除帳戶</string>
+ <string name="api_settings_settings">設定</string>
+ <string name="api_settings_key">帳戶金鑰:</string>
+ <string name="api_settings_accounts_empty">沒有帳戶被指派給這個應用程å¼ã€‚</string>
+ <string name="api_create_account_text">這個帳戶尚未設置金鑰,請指派一個ç¾æœ‰é‡‘鑰或是建立新的。\n應用程å¼åªèƒ½ä½¿ç”¨é€™é‚Šæ‰€é¸çš„金鑰進行解密/ç°½å。</string>
+ <string name="api_update_account_text">此帳戶指定的金鑰已被刪除,請é‡æ–°é¸æ“‡ä¸€å€‹ã€‚\n應用程å¼åªèƒ½ä½¿ç”¨é€™é‚Šæ‰€é¸çš„金鑰進行解密/ç°½å。</string>
+ <string name="api_register_text">應用程å¼è©¦åœ–以您的å義加/解密訊æ¯ä¸¦ç°½å,是å¦å…許存å–?\n\n警告:如果你ä¸çŸ¥é“為什麼出ç¾é€™å€‹ç•«é¢ï¼Œè«‹æ‹’絕存å–ï¼ä½ å¯ä»¥ç¨å¾Œåœ¨ã€æ‡‰ç”¨ç¨‹å¼ã€žç•«é¢æ’¤éŠ·å­˜å–。</string>
+ <string name="api_register_allow">å…許存å–</string>
+ <string name="api_register_disallow">拒絕存å–</string>
+ <string name="api_error_wrong_signature">ç°½å檢查失敗ï¼ä½ æ˜¯å¦å¾žå…¶ä»–來æºå®‰è£æ­¤æ‡‰ç”¨ï¼Ÿå¦‚果你確定這ä¸æ˜¯å€‹æ”»æ“Šï¼Œæ’¤éŠ·ä¸¦é‡æ–°è¨»å†Šæ‡‰ç”¨ç¨‹å¼åˆ°OpenKeychain。</string>
<!--Share-->
+ <string name="share_qr_code_dialog_title">以二維æ¢ç¢¼åˆ†äº«</string>
+ <string name="share_nfc_dialog">以NFC分享</string>
<!--Key list-->
+ <string name="key_list_empty_text1">找ä¸åˆ°é‡‘é‘°ï¼</string>
<!--Key view-->
+ <string name="key_view_action_edit">編輯金鑰</string>
+ <string name="key_view_action_encrypt">加密文字</string>
+ <string name="key_view_action_encrypt_files">檔案</string>
+ <string name="key_view_action_upload">上傳到金鑰伺æœå™¨</string>
+ <string name="key_view_tab_main">摘è¦</string>
+ <string name="key_view_tab_share">分享</string>
+ <string name="key_view_tab_keys">å­é‡‘é‘°</string>
+ <string name="user_id_info_revoked_title">已撤銷</string>
+ <string name="user_id_info_revoked_text">這個身分識別被金鑰æŒæœ‰äººæ’¤éŠ·ï¼Œå·²ä¸å†æœ‰æ•ˆã€‚</string>
+ <string name="user_id_info_certified_title">å·²èªè­‰</string>
+ <string name="user_id_info_certified_text">這個身分識別已經éŽä½ çš„èªè­‰ã€‚</string>
+ <string name="user_id_info_uncertified_title">未èªè­‰</string>
+ <string name="user_id_info_uncertified_text">這個身分識別尚未經éŽèªè­‰ï¼Œä½ ä¸èƒ½ç¢ºèªé€™å€‹èº«åˆ†è­˜åˆ¥æ˜¯å¦å±¬æ–¼çœŸçš„æŸå€‹äººã€‚</string>
+ <string name="user_id_info_invalid_title">無效</string>
<!--Edit key-->
+ <string name="edit_key_action_change_passphrase">變更å£ä»¤</string>
+ <string name="edit_key_action_add_identity">新增身分識別</string>
+ <string name="edit_key_action_add_subkey">新增å­é‡‘é‘°</string>
+ <string-array name="edit_key_edit_user_id">
+ <item>變更為主身分識別</item>
+ <item>撤銷身分識別</item>
+ </string-array>
+ <string name="edit_key_edit_user_id_revoked">這個身分識別已被撤銷。此動作無法還原。</string>
+ <string-array name="edit_key_edit_subkey">
+ <item>變更到期日</item>
+ <item>撤銷å­é‡‘é‘°</item>
+ <item>Strip Subkey</item>
+ </string-array>
+ <string name="edit_key_error_add_identity">新增至少一組身分識別ï¼</string>
+ <string name="edit_key_error_add_subkey">新增至少一組å­é‡‘é‘°ï¼</string>
<!--Create key-->
+ <string name="create_key_upload">上傳到金鑰伺æœå™¨</string>
+ <string name="create_key_empty">必填欄ä½</string>
+ <string name="create_key_passphrases_not_equal">å£ä»¤ä¸ç›¸ç¬¦</string>
+ <string name="create_key_final_robot_text">建立金鑰å¯èƒ½éœ€è¦ä¸€é»žæ™‚間,來æ¯å’–å•¡å§â€¦</string>
+ <string name="create_key_text">輸入你的全åã€é›»å­éƒµä»¶ï¼Œä¸¦é¸æ“‡ä¸€çµ„å£ä»¤ã€‚</string>
<!--View key-->
+ <string name="view_key_revoked">這把金鑰已被撤銷ï¼</string>
+ <string name="view_key_expired">這把金鑰已經éŽæœŸï¼</string>
<!--Navigation Drawer-->
+ <string name="nav_keys">金鑰</string>
+ <string name="nav_apps">應用程å¼</string>
+ <string name="my_keys">我的金鑰</string>
<!--hints-->
<!--certs-->
<!--LogType log messages. Errors should have _ERROR_ in their name and end with a !-->
<!--Import Public log entries-->
<!--Import Secret log entries-->
+ <string name="msg_is_db_exception">資料庫錯誤ï¼</string>
+ <string name="msg_is_merge_public">將匯入的資料åˆä½µè‡³å…¬é‘°é‘°åŒ™åœˆ</string>
+ <string name="msg_is_merge_secret">將匯入的資料åˆä½µè‡³å¯†é‘°é‘°åŒ™åœˆ</string>
+ <string name="msg_is_pubring_generate">從密鑰鑰匙圈產生公鑰鑰匙圈</string>
+ <string name="msg_is_success_identical">鑰匙圈沒有新資料,ä¸å¿…進行æ“作</string>
+ <string name="msg_is_success">æˆåŠŸåŒ¯å…¥å¯†é‘°é‘°åŒ™åœˆ</string>
<!--Keyring Canonicalization log entries-->
<!--Keyring merging log entries-->
<!--createSecretKeyRing-->
<!--modifySecretKeyRing-->
<!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
+ <string name="msg_ek_error_not_found">找ä¸åˆ°é‡‘é‘°ï¼</string>
<!--Messages for DecryptVerify operation-->
+ <string name="msg_dc_error_invalid_siglist">找ä¸åˆ°æœ‰æ•ˆçš„ç°½å資訊ï¼</string>
+ <string name="msg_dc">開始解密…</string>
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
+ <string name="msg_crt_warn_not_found">找ä¸åˆ°é‡‘é‘°ï¼</string>
+ <string name="msg_crt_warn_cert_failed">產生èªè­‰å¤±æ•—ï¼</string>
+ <string name="msg_crt_warn_save_failed">儲存失敗ï¼</string>
+ <string name="msg_crt_upload_success">æˆåŠŸä¸Šå‚³é‡‘鑰到伺æœå™¨</string>
+ <string name="msg_import_fetch_error">無法å–得金鑰ï¼(網路å•é¡Œï¼Ÿ)</string>
+ <string name="msg_import_fetch_keybase">從keybase.ioå–回:%s</string>
+ <string name="msg_import_fetch_keyserver_error">無法從keybaseå–得金鑰ï¼</string>
+ <string name="msg_import_fetch_keyserver">從金鑰伺æœå™¨å–回:%s</string>
+ <string name="msg_import_fetch_keyserver_ok">æˆåŠŸå–得金鑰</string>
+ <string name="msg_import_keyserver">使用金鑰伺æœå™¨%s</string>
+ <string name="msg_import_fingerprint_ok">指紋檢查正確</string>
+ <string name="msg_import_merge">正在åˆä½µå–得的資料</string>
+ <string name="msg_export_error_db">資料庫錯誤ï¼</string>
+ <string name="msg_export_error_io">輸入/輸出錯誤ï¼</string>
+ <string name="msg_export_success">匯出處ç†æˆåŠŸ</string>
+ <string name="msg_del_error_empty">沒有æ±è¥¿å¯ä»¥åˆªé™¤ï¼</string>
+ <string name="msg_del_error_multi_secret">密鑰åªèƒ½åˆ†åˆ¥åˆªé™¤ï¼</string>
+ <string name="msg_acc_saved">帳戶已儲存</string>
+ <string name="msg_download_success">下載æˆåŠŸï¼</string>
+ <string name="msg_download_no_valid_keys">在檔案/剪貼簿中找ä¸åˆ°æœ‰æ•ˆçš„金鑰ï¼</string>
+ <string name="msg_download_query_failed">查詢金鑰的時候發生錯誤。</string>
<!--PassphraseCache-->
- <!--unsorted-->
+ <string name="passp_cache_notif_n_keys">OpenKeychainå¿«å–了%d個å£ä»¤</string>
+ <string name="passp_cache_notif_keys">已快å–çš„å£ä»¤ï¼š</string>
+ <string name="passp_cache_notif_clear">清除快å–</string>
+ <string name="passp_cache_notif_pwd">å£ä»¤</string>
<!--First Time-->
+ <!--unsorted-->
+ <string name="empty_certs">這把金鑰未經éŽèªè­‰</string>
+ <string name="certs_text">åªæœ‰æœ‰æ•ˆçš„自簽署èªè­‰ä»¥åŠç¶“由你的金鑰簽署的有效èªè­‰æœƒè¢«é¡¯ç¤ºåœ¨é€™ã€‚</string>
+ <string name="label_revocation">撤銷原因</string>
+ <string name="error_key_not_found">找ä¸åˆ°é‡‘é‘°ï¼</string>
+ <string name="key_no_passphrase">沒有å£ä»¤</string>
+ <string name="key_unavailable">無法使用</string>
+ <string name="title_view_cert">查看èªè­‰å…§å®¹</string>
+ <string name="unknown_algorithm">未知</string>
+ <string name="error_no_encrypt_subkey">沒有å¯ä¾›åŠ å¯†çš„å­é‡‘é‘°ï¼</string>
+ <string name="info_no_manual_account_creation">è«‹ä¸è¦è‡ªè¡Œå»ºç«‹OpenKeychain帳戶。\n更多資訊請åƒè€ƒèªªæ˜Žã€‚</string>
+ <string name="exchange_description">è¦ç™¼èµ·é‡‘鑰交æ›ï¼Œå…ˆåœ¨å³é‚Šé¸æ“‡èˆ‡æœƒäººæ•¸ï¼Œç„¶å¾Œé»žé¸ã€é–‹å§‹äº¤æ›ã€žã€‚\n\n接下來會詢å•ä½ å…©å€‹å•é¡Œï¼Œä»¥ç¢ºä¿æœƒè­°æˆå“¡èˆ‡äº¤æ›çš„指紋是正確的。</string>
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values-zh/strings.xml b/OpenKeychain/src/main/res/values-zh/strings.xml
index e9bdae446..1c0e0c396 100644
--- a/OpenKeychain/src/main/res/values-zh/strings.xml
+++ b/OpenKeychain/src/main/res/values-zh/strings.xml
@@ -7,11 +7,8 @@
<string name="title_encrypt_text">加密文本</string>
<string name="title_encrypt_files">加密文件</string>
<string name="title_decrypt">解密</string>
- <string name="title_authentication">密ç </string>
<string name="title_edit_key">编辑密钥</string>
- <string name="title_preferences">å‚æ•°</string>
<string name="title_api_registered_apps">已注册应用</string>
- <string name="title_key_server_preference">密钥æœåŠ¡å™¨å好</string>
<string name="title_change_passphrase">å˜æ›´å¯†ç </string>
<string name="title_share_fingerprint_with">分享签å</string>
<string name="title_share_key">分享密钥</string>
@@ -57,7 +54,6 @@
<string name="btn_create_key">创建密钥</string>
<string name="btn_add_files">添加密钥</string>
<string name="btn_add_share_decrypted_text">添加并分享加密åŽçš„文本</string>
- <string name="btn_decrypt_clipboard">从剪贴æ¿å¤åˆ¶å¹¶è§£å¯†</string>
<string name="btn_decrypt_and_verify">解密并验è¯</string>
<string name="btn_decrypt_files">解密文件</string>
<!--menu-->
@@ -231,10 +227,17 @@
<!--createSecretKeyRing-->
<!--modifySecretKeyRing-->
<!--Consolidate-->
+ <!--Edit Key (higher level than modify)-->
+ <!--Promote key-->
<!--Other messages used in OperationLogs-->
<!--Messages for DecryptVerify operation-->
<!--Messages for SignEncrypt operation-->
+ <!--Messages for PgpSignEncrypt operation-->
<!--PassphraseCache-->
- <!--unsorted-->
<!--First Time-->
+ <!--unsorted-->
+ <!--Passphrase wizard-->
+ <!--TODO: rename all the things!-->
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
</resources>
diff --git a/OpenKeychain/src/main/res/values/attr.xml b/OpenKeychain/src/main/res/values/attr.xml
index 5dfa03987..98ce1c364 100644
--- a/OpenKeychain/src/main/res/values/attr.xml
+++ b/OpenKeychain/src/main/res/values/attr.xml
@@ -6,4 +6,13 @@
<attr name="unFoldedLabel" format="string" />
</declare-styleable>
+ <declare-styleable name="AspectRatioImageView">
+ <attr name="aspectRatio" format="float" />
+ <attr name="aspectRatioEnabled" format="boolean" />
+ <attr name="dominantMeasurement">
+ <enum name="width" value="0" />
+ <enum name="height" value="1" />
+ </attr>
+ </declare-styleable>
+
</resources> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/values/colors.xml b/OpenKeychain/src/main/res/values/colors.xml
index a21f949d1..c49e06b4b 100644
--- a/OpenKeychain/src/main/res/values/colors.xml
+++ b/OpenKeychain/src/main/res/values/colors.xml
@@ -1,8 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <color name="emphasis">#aa66cc</color>
- <color name="emphasis_dark">#9933cc</color>
+ <!-- Main theme colors -->
+
+ <!-- green colors from OpenKeychain logo bottom right -->
+ <!-- your app branding color for the app bar -->
+ <color name="primary">#7bad45</color>
+ <!-- darker variant for the status bar and contextual app bars -->
+ <color name="primary_dark">#6c983d</color>
+ <!-- theme UI controls like checkboxes and text fields -->
+ <color name="accent">#2196F3</color>
+
+ <!-- Other colors -->
+
+ <color name="primary_light">#C8E6C9</color>
+ <color name="fab">@color/accent</color>
+ <color name="fab_pressed">#1976D2</color>
+ <color name="primary_text">#212121</color>
+ <color name="secondary_text">#727272</color>
+ <color name="icons">#FFFFFF</color>
+ <color name="divider">#B6B6B6</color>
+
+ <color name="header_text">#212121</color>
+ <!-- item selection, search highlight -->
+ <color name="emphasis">@color/accent</color>
+
<color name="bg_gray">#cecbce</color>
<color name="tertiary_text_light">#808080</color>
<color name="alert">#ffdd3333</color>
@@ -10,14 +32,33 @@
<color name="holo_gray_light">#33999999</color>
<color name="holo_gray_bright">#33CCCCCC</color>
- <!-- http://developer.android.com/design/style/color.html -->
- <color name="android_red_light">#ffff4444</color>
- <color name="android_red_dark">#ffCC0000</color>
- <color name="android_orange_light">#ffffbb33</color>
- <color name="android_orange_dark">#ffFF8800</color>
- <color name="android_green_light">#ff99cc00</color>
- <color name="android_green_dark">#ff669900</color>
- <color name="android_purple_light">#ffaa66cc</color>
- <color name="android_purple_dark">#ff9933CC</color>
+ <!-- tabs -->
+ <color name="tab_text">#70FFFFFF</color>
+ <color name="tab_text_selected">#FFFFFF</color>
+ <color name="tab_indicator">#FFFFFF</color>
+
+
+ <!-- floating action buttons -->
+ <color name="black_semi_transparent">#B2000000</color>
+ <color name="background">#e5e5e5</color>
+ <color name="half_black">#808080</color>
+ <color name="white">#fafafa</color>
+ <color name="white_pressed">#f1f1f1</color>
+
+ <!--
+ http://www.google.com/design/spec/style/color.html#color-color-palette
+ light = normal color
+ dark = 900
+
+ exception: green
+ -->
+ <color name="android_red_light">#f44336</color>
+ <color name="android_red_dark">#b71c1c</color>
+ <color name="android_orange_light">#ff9800</color>
+ <color name="android_orange_dark">#e65100</color>
+ <color name="android_green_light">@color/primary</color>
+ <color name="android_green_dark">@color/primary_dark</color>
+ <color name="android_purple_light">#673ab7</color>
+ <color name="android_purple_dark">#311b92</color>
</resources>
diff --git a/OpenKeychain/src/main/res/values/dimens.xml b/OpenKeychain/src/main/res/values/dimens.xml
index e1a7749f0..434a0a171 100644
--- a/OpenKeychain/src/main/res/values/dimens.xml
+++ b/OpenKeychain/src/main/res/values/dimens.xml
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <dimen name="drawer_size">240dp</dimen>
- <dimen name="drawer_content_padding">0dp</dimen>
+ <!-- on Android < 5, we do not color the status bar, thus 0dp! -->
+ <dimen name="statusbar_height">0dp</dimen>
+ <dimen name="big_toolbar">120dp</dimen>
+ <dimen name="huge_toolbar">222dp</dimen>
</resources> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index cac38c361..f43b4e623 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -14,13 +14,13 @@
<string name="title_encrypt_text">"Encrypt Text"</string>
<string name="title_encrypt_files">"Encrypt Files"</string>
<string name="title_decrypt">"Decrypt"</string>
- <string name="title_authentication">"Passphrase"</string>
+ <string name="title_unlock">"Unlock Key"</string>
<string name="title_add_subkey">"Add subkey"</string>
<string name="title_edit_key">"Edit Key"</string>
- <string name="title_preferences">"Preferences"</string>
+ <string name="title_preferences">"Settings"</string>
<string name="title_cloud_search_preferences">"Cloud Search Preferences"</string>
<string name="title_api_registered_apps">"Apps"</string>
- <string name="title_key_server_preference">"Keyserver Preference"</string>
+ <string name="title_key_server_preference">"Keyservers"</string>
<string name="title_change_passphrase">"Change Passphrase"</string>
<string name="title_share_fingerprint_with">"Share fingerprint with…"</string>
<string name="title_share_key">"Share key with…"</string>
@@ -41,6 +41,7 @@
<string name="title_create_key">"Create Key"</string>
<string name="title_exchange_keys">"Exchange Keys"</string>
<string name="title_advanced_key_info">"Advanced Key Info"</string>
+ <string name="title_keys">"Keys"</string>
<!-- section -->
<string name="section_user_ids">"Identities"</string>
@@ -64,6 +65,8 @@
<string name="section_decrypt_files">"Files"</string>
<string name="section_decrypt_text">"Text"</string>
<string name="section_certs">"Certificates"</string>
+ <string name="section_encrypt">"Encrypt"</string>
+ <string name="section_decrypt">"Decrypt"</string>
<!-- button -->
<string name="btn_decrypt_verify_file">"Decrypt, verify, and save file"</string>
@@ -78,15 +81,19 @@
<string name="btn_export_to_server">"Upload To Keyserver"</string>
<string name="btn_next">"Next"</string>
<string name="btn_back">"Back"</string>
+ <string name="btn_no">"No"</string>
+ <string name="btn_match">"Fingerprints are matching"</string>
<string name="btn_lookup_key">"Lookup key"</string>
<string name="btn_share_encrypted_signed">"Encrypt and share message"</string>
<string name="btn_view_cert_key">"View certification key"</string>
<string name="btn_create_key">"Create key"</string>
<string name="btn_add_files">"Add file(s)"</string>
<string name="btn_add_share_decrypted_text">"Share decrypted text"</string>
- <string name="btn_decrypt_clipboard">"Decrypt from clipboard"</string>
+ <string name="btn_decrypt_clipboard">"Decrypt text from clipboard"</string>
<string name="btn_decrypt_and_verify">"and verify signatures"</string>
<string name="btn_decrypt_files">"Decrypt files"</string>
+ <string name="btn_encrypt_files">"Encrypt files"</string>
+ <string name="btn_encrypt_text">"Encrypt text"</string>
<!-- menu -->
<string name="menu_preferences">"Settings"</string>
@@ -96,13 +103,16 @@
<string name="menu_create_key">"Create my key"</string>
<string name="menu_import_existing_key">"Import from file"</string>
<string name="menu_search">"Search"</string>
+ <string name="menu_nfc_preferences">"NFC settings"</string>
<string name="menu_beam_preferences">"Beam settings"</string>
<string name="menu_key_edit_cancel">"Cancel"</string>
<string name="menu_encrypt_to">"Encrypt to…"</string>
<string name="menu_select_all">"Select all"</string>
<string name="menu_add_keys">"Add keys"</string>
+ <string name="menu_search_cloud">"Search cloud"</string>
<string name="menu_export_all_keys">"Export all keys"</string>
<string name="menu_advanced">"Show advanced info"</string>
+ <string name="menu_certify_fingerprint">"Verify via fingerprint comparison"</string>
<!-- label -->
<string name="label_message">"Message"</string>
@@ -208,7 +218,8 @@
<string name="passphrase_must_not_be_empty">"Please enter a passphrase."</string>
<string name="passphrase_for_symmetric_encryption">"Symmetric encryption."</string>
<string name="passphrase_for">"Enter passphrase for '%s'"</string>
- <string name="yubikey_pin">"Enter PIN to access YubiKey for '%s'"</string>
+ <string name="pin_for">"Enter PIN for '%s'"</string>
+ <string name="yubikey_pin_for">"Enter PIN to access YubiKey for '%s'"</string>
<string name="nfc_text">"Hold YubiKey against the back of your device."</string>
<string name="file_delete_confirmation">"Are you sure you want to delete\n%s?"</string>
<string name="file_delete_successful">"Successfully deleted."</string>
@@ -268,7 +279,8 @@
<!-- errors without preceeding Error: -->
<string name="error_jelly_bean_needed">"You need Android 4.1 to use Android's NFC Beam feature!"</string>
- <string name="error_nfc_needed">"NFC is not available on your device!"</string>
+ <string name="error_nfc_needed">"NFC must be enabled!"</string>
+ <string name="error_beam_needed">"Beam must be enabled!"</string>
<string name="error_nothing_import">"No keys found!"</string>
<string name="error_contacts_key_id_missing">"Retrieving the key ID from contacts failed!"</string>
<string name="error_generic_report_bug">"A generic error occurred, please create a new bug report for OpenKeychain."</string>
@@ -311,6 +323,7 @@
<string name="progress_modify_unlock">"unlocking keyring…"</string>
<string name="progress_modify_adduid">"adding user IDs…"</string>
+ <string name="progress_modify_adduat">"adding user attributes…"</string>
<string name="progress_modify_revokeuid">"revoking user IDs…"</string>
<string name="progress_modify_primaryuid">"changing primary user ID…"</string>
<string name="progress_modify_subkeychange">"modifying subkeys…"</string>
@@ -395,9 +408,10 @@
<string name="import_qr_code_wrong">"QR Code malformed! Please try again!"</string>
<string name="import_qr_code_too_short_fingerprint">"Fingerprint is too short (&lt; 16 characters)"</string>
<string name="import_qr_code_button">"Scan QR Code"</string>
+ <string name="import_qr_code_text">"Place your camera over the QR Code!"</string>
<!-- Generic result toast -->
- <string name="view_log">"View Log"</string>
+ <string name="view_log">"Details"</string>
<string name="with_warnings">", with warnings"</string>
<string name="with_cancelled">", until cancelled"</string>
@@ -470,7 +484,6 @@
<string name="intent_send_decrypt">"Decrypt with OpenKeychain"</string>
<!-- Remote API -->
- <string name="api_no_apps">"No registered apps!\n\nA list of supported third-party applications can be found in 'Help'!"</string>
<string name="api_settings_show_info">"Show advanced information"</string>
<string name="api_settings_hide_info">"Hide advanced information"</string>
<string name="api_settings_show_advanced">"Show advanced settings"</string>
@@ -486,7 +499,9 @@
<string name="api_settings_delete_account">"Delete account"</string>
<string name="api_settings_package_name">"Package Name"</string>
<string name="api_settings_package_signature">"SHA-256 of Package Signature"</string>
- <string name="api_settings_accounts">"Accounts"</string>
+ <string name="api_settings_accounts">"Accounts (deprecated API)"</string>
+ <string name="api_settings_advanced">"Advanced Information"</string>
+ <string name="api_settings_allowed_keys">"Allowed Keys"</string>
<string name="api_settings_settings">"Settings"</string>
<string name="api_settings_key">"Account key:"</string>
<string name="api_settings_accounts_empty">"No accounts attached to this app."</string>
@@ -529,7 +544,7 @@
<string name="key_view_tab_share">"Share"</string>
<string name="key_view_tab_keys">"Subkeys"</string>
<string name="key_view_tab_certs">"Certificates"</string>
- <string name="key_view_tab_trust">"Trust this key?"</string>
+ <string name="key_view_tab_keybase">"Keybase.io"</string>
<string name="user_id_info_revoked_title">"Revoked"</string>
<string name="user_id_info_revoked_text">"This identity has been revoked by the key owner. It is no longer valid."</string>
<string name="user_id_info_certified_title">"Certified"</string>
@@ -617,14 +632,16 @@
<string name="create_key_edit">"Change key configuration"</string>
<!-- View key -->
- <string name="view_key_revoked">"This key has been revoked!"</string>
- <string name="view_key_expired">"This key is expired!"</string>
+ <string name="view_key_revoked">"Revoked: Key must not be used anymore!"</string>
+ <string name="view_key_expired">"Expired: The contact needs to extend the keys validity!"</string>
+ <string name="view_key_expired_secret">"Expired: You can extend the keys validity by editing it!"</string>
+ <string name="view_key_my_key">"My Key"</string>
+ <string name="view_key_verified">"Verified Key"</string>
+ <string name="view_key_unverified">"Unverified: Scan QR Code to verify key!"</string>
<!-- Navigation Drawer -->
<string name="nav_keys">"Keys"</string>
- <string name="nav_encrypt_text">"Encrypt text"</string>
- <string name="nav_encrypt_files">"Encrypt files"</string>
- <string name="nav_decrypt">"Decrypt"</string>
+ <string name="nav_encrypt_decrypt">"Encrypt/Decrypt"</string>
<string name="nav_apps">"Apps"</string>
<string name="drawer_open">"Open navigation drawer"</string>
<string name="drawer_close">"Close navigation drawer"</string>
@@ -726,6 +743,23 @@
<string name="msg_ip_uid_reorder">"Re-ordering user IDs"</string>
<string name="msg_ip_uid_processing">"Processing user ID %s"</string>
<string name="msg_ip_uid_revoked">"User ID is revoked"</string>
+
+ <string name="msg_ip_uat_processing_image">"Processing user attribute of type image"</string>
+ <string name="msg_ip_uat_processing_unknown">"Processing user attribute of unknown type"</string>
+ <string name="msg_ip_uat_cert_bad">"Encountered bad certificate!"</string>
+ <string name="msg_ip_uat_cert_error">"Error processing certificate!"</string>
+ <string name="msg_ip_uat_cert_nonrevoke">"Already have a non-revokable certificate, skipping."</string>
+ <string name="msg_ip_uat_cert_old">"Certificate is older than previous, skipping."</string>
+ <string name="msg_ip_uat_cert_new">"Certificate is more recent, replacing previous."</string>
+ <string name="msg_ip_uat_cert_good">"Found good certificate by %1$s"</string>
+ <string name="msg_ip_uat_cert_good_revoke">"Found good certificate revocation by %1$s"</string>
+ <plurals name="msg_ip_uat_certs_unknown">
+ <item quantity="one">"Ignoring one certificate issued by an unknown public key"</item>
+ <item quantity="other">"Ignoring %s certificates issued by unknown public keys"</item>
+ </plurals>
+ <string name="msg_ip_uat_classifying">"Classifying user attributes"</string>
+ <string name="msg_ip_uat_revoked">"User attribute is revoked"</string>
+
<string name="msg_is_bad_type_public">"Tried to import public keyring as secret. This is a bug, please file a report!"</string>
<string name="msg_is_bad_type_uncanon">"Tried to import a keyring without canonicalization. This is a bug, please file a report!"</string>
@@ -741,6 +775,7 @@
<string name="msg_is_subkey_nonexistent">"Subkey %s unavailable in secret key"</string>
<string name="msg_is_subkey_ok">"Marked secret subkey %s as available"</string>
<string name="msg_is_subkey_empty">"Marked secret subkey %s as available, with empty passphrase"</string>
+ <string name="msg_is_subkey_pin">"Marked secret subkey %s as available, with PIN"</string>
<string name="msg_is_subkey_stripped">"Marked secret subkey %s as stripped"</string>
<string name="msg_is_subkey_divert">"Marked secret subkey %s as 'divert to smartcard/NFC'"</string>
<string name="msg_is_success_identical">"Keyring contains no new data, nothing to do"</string>
@@ -754,13 +789,16 @@
<string name="msg_kc_error_master_algo">"The master key uses an unknown (%s) algorithm!"</string>
<string name="msg_kc_error_dup_key">"Subkey %s occurs twice in keyring. Keyring is malformed, not importing!"</string>
<string name="msg_kc_master">"Processing master key"</string>
- <string name="msg_kc_revoke_bad_err">"Removing bad keyring revocation certificate"</string>
- <string name="msg_kc_revoke_bad_local">"Removing keyring revocation certificate with "local" flag"</string>
- <string name="msg_kc_revoke_bad_time">"Removing keyring revocation certificate with future timestamp"</string>
- <string name="msg_kc_revoke_bad_type">"Removing master key certificate of unknown type (%s)"</string>
- <string name="msg_kc_revoke_bad_type_uid">"Removing user ID certificate in bad position"</string>
- <string name="msg_kc_revoke_bad">"Removing bad keyring revocation certificate"</string>
+ <string name="msg_kc_master_bad_type">"Removing master key certificate of unknown type (%s)"</string>
+ <string name="msg_kc_master_bad_local">"Removing master key certificate with "local" flag"</string>
+ <string name="msg_kc_master_bad_err">"Removing bad master key certificate"</string>
+ <string name="msg_kc_master_bad_time">"Removing keyring revocation certificate with future timestamp"</string>
+ <string name="msg_kc_master_bad_type_uid">"Removing user ID certificate in bad position"</string>
+ <string name="msg_kc_master_bad">"Removing bad master key certificate"</string>
+ <string name="msg_kc_master_local">"Removing master key certificate with "local" flag"</string>
<string name="msg_kc_revoke_dup">"Removing redundant keyring revocation certificate"</string>
+ <string name="msg_kc_notation_dup">"Removing redundant notation certificate"</string>
+ <string name="msg_kc_notation_empty">"Removing empty notation certificate"</string>
<string name="msg_kc_sub">"Processing subkey %s"</string>
<string name="msg_kc_sub_bad">"Removing invalid subkey binding certificate"</string>
<string name="msg_kc_sub_bad_err">"Removing bad subkey binding certificate"</string>
@@ -800,8 +838,23 @@
<string name="msg_kc_uid_revoke_old">"Removing outdated revocation certificate for user ID '%s'"</string>
<string name="msg_kc_uid_no_cert">"No valid self-certificate found for user ID '%s', removing from ring"</string>
<string name="msg_kc_uid_remove">"Removing invalid user ID '%s'"</string>
- <string name="msg_kc_uid_dup">"Removing duplicate user ID '%s'. The secret key contained two of them. This may result in missing certificates!"</string>
+ <string name="msg_kc_uid_dup">"Removing duplicate user ID '%s'. The keyring contained two of them. This may result in missing certificates!"</string>
<string name="msg_kc_uid_warn_encoding">"User id does not verify as UTF-8!"</string>
+ <string name="msg_kc_uat_jpeg">"Processing user attribute of type JPEG"</string>
+ <string name="msg_kc_uat_unknown">"Processing user attribute of unknown type"</string>
+ <string name="msg_kc_uat_bad_err">"Removing bad self certificate for user attribute"</string>
+ <string name="msg_kc_uat_bad_local">"Removing user attribute certificate with 'local' flag"</string>
+ <string name="msg_kc_uat_bad_time">"Removing user attribute with future timestamp"</string>
+ <string name="msg_kc_uat_bad_type">"Removing user attribute certificate of unknown type (%s)"</string>
+ <string name="msg_kc_uat_bad">"Removing bad self certificate for user attribute"</string>
+ <string name="msg_kc_uat_cert_dup">"Removing outdated self certificate for user attribute"</string>
+ <string name="msg_kc_uat_dup">"Removing duplicate user attribute. The keyring contained two of them. This may result in missing certificates!"</string>
+ <string name="msg_kc_uat_foreign">"Removing foreign user attribute certificate by"</string>
+ <string name="msg_kc_uat_revoke_dup">"Removing redundant revocation certificate for user attribute"</string>
+ <string name="msg_kc_uat_revoke_old">"Removing outdated revocation certificate for user attribute"</string>
+ <string name="msg_kc_uat_no_cert">"No valid self-certificate found for user attribute, removing from ring"</string>
+ <string name="msg_kc_uat_remove">"Removing invalid user attribute"</string>
+ <string name="msg_kc_uat_warn_encoding">"User id does not verify as UTF-8!"</string>
<!-- Keyring merging log entries -->
<string name="msg_mg_error_secret_dummy">"New public subkey found, but secret subkey dummy generation is not supported!"</string>
@@ -822,7 +875,7 @@
<string name="msg_cr_error_keysize_512">"Key size must be greater or equal 512!"</string>
<string name="msg_cr_error_no_curve">"No key size specified! This is a programming error, please file a bug report!"</string>
<string name="msg_cr_error_no_keysize">"No elliptic curve specified! This is a programming error, please file a bug report!"</string>
- <string name="msg_cr_error_internal_pgp">"Internal PGP error!"</string>
+ <string name="msg_cr_error_internal_pgp">"Internal OpenPGP error!"</string>
<string name="msg_cr_error_unknown_algo">"Unknown algorithm selected! This is a programming error, please file a bug report!"</string>
<string name="msg_cr_error_flags_dsa">"Bad key flags selected, DSA cannot be used for encryption!"</string>
<string name="msg_cr_error_flags_elgamal">"Bad key flags selected, ElGamal cannot be used for signing!"</string>
@@ -831,6 +884,7 @@
<!-- modifySecretKeyRing -->
<string name="msg_mr">"Modifying keyring %s"</string>
+ <string name="msg_mf_error_divert_serial">"The serial number of a divert-to-card key must be 16 bytes! This is a programming error, please file a bug report!"</string>
<string name="msg_mf_error_encode">"Encoding exception!"</string>
<string name="msg_mf_error_fingerprint">"Actual key fingerprint does not match the expected one!"</string>
<string name="msg_mf_error_keyid">"No key ID. This is an internal error, please file a bug report!"</string>
@@ -838,13 +892,16 @@
<string name="msg_mf_error_master_none">"No master certificate found to operate on! (All revoked?)"</string>
<string name="msg_mf_error_noexist_primary">"Bad primary user ID specified!"</string>
<string name="msg_mf_error_noexist_revoke">"Bad user ID for revocation specified!"</string>
+ <string name="msg_mf_error_restricted">"Tried to execute restricted operation without passphrase! This is a programming error, please file a bug report!"</string>
<string name="msg_mf_error_revoked_primary">"Revoked user IDs cannot be primary!"</string>
<string name="msg_mf_error_null_expiry">"Expiry time cannot be "same as before" on subkey creation. This is a programming error, please file a bug report!"</string>
<string name="msg_mf_error_passphrase_master">"Fatal error decrypting master key! This is likely a programming error, please file a bug report!"</string>
- <string name="msg_mf_error_pgp">"Internal PGP error!"</string>
+ <string name="msg_mf_error_pgp">"Internal OpenPGP error!"</string>
<string name="msg_mf_error_sig">"Signature exception!"</string>
<string name="msg_mf_master">"Modifying master certifications"</string>
- <string name="msg_mf_passphrase">"Changing passphrase for keyring…"</string>
+ <string name="msg_mf_notation_empty">"Adding empty notation packet"</string>
+ <string name="msg_mf_notation_pin">"Adding PIN notation packet"</string>
+ <string name="msg_mf_passphrase">"Changing passphrase for keyring"</string>
<string name="msg_mf_passphrase_key">"Re-encrypting subkey %s with new passphrase"</string>
<string name="msg_mf_passphrase_empty_retry">"Setting new passphrase failed, trying again with empty old passphrase"</string>
<string name="msg_mf_passphrase_fail">"Passphrase for subkey could not be changed! (Does it have a different one from the other keys?)"</string>
@@ -862,6 +919,9 @@
<string name="msg_mf_uid_primary">"Changing primary user ID to %s"</string>
<string name="msg_mf_uid_revoke">"Revoking user ID %s"</string>
<string name="msg_mf_uid_error_empty">"User ID must not be empty!"</string>
+ <string name="msg_mf_uat_error_empty">"User attribute must not be empty!"</string>
+ <string name="msg_mf_uat_add_image">"Adding user attribute of type image"</string>
+ <string name="msg_mf_uat_add_unknown">"Adding user attribute of unknown type"</string>
<string name="msg_mf_unlock_error">"Error unlocking keyring!"</string>
<string name="msg_mf_unlock">"Unlocking keyring"</string>
@@ -883,6 +943,7 @@
<string name="msg_con_error_public">"Error reimporting public keys!"</string>
<string name="msg_con_error_secret">"Error reimporting secret keys!"</string>
<string name="msg_con_recover">"Resuming consolidation process"</string>
+ <string name="msg_con_recursive">"Skipping recursive consolidation"</string>
<string name="msg_con_recover_unknown">"Resuming consolidation process from unknown state"</string>
<plurals name="msg_con_reimport_public">
<item quantity="one">"Reimporting one public key"</item>
@@ -897,6 +958,21 @@
<string name="msg_con_warn_delete_public">"Exception deleting public cache file"</string>
<string name="msg_con_warn_delete_secret">"Exception deleting secret cache file"</string>
+ <!-- Edit Key (higher level than modify) -->
+ <string name="msg_ed">"Performing key operation"</string>
+ <string name="msg_ed_caching_new">"Caching new passphrase"</string>
+ <string name="msg_ed_error_no_parcel">"Missing SaveKeyringParcel! (this is a bug, please report)"</string>
+ <string name="msg_ed_error_key_not_found">"Key not found!"</string>
+ <string name="msg_ed_fetching">"Fetching key to modify (%s)"</string>
+ <string name="msg_ed_success">"Key operation successful"</string>
+
+ <!-- Promote key -->
+ <string name="msg_pr">"Promoting public key to secret key"</string>
+ <string name="msg_pr_error_already_secret">"Key is already a secret key!"</string>
+ <string name="msg_pr_error_key_not_found">"Key not found!"</string>
+ <string name="msg_pr_fetching">"Fetching key to modify (%s)"</string>
+ <string name="msg_pr_success">"Key successfully promoted"</string>
+
<!-- Other messages used in OperationLogs -->
<string name="msg_ek_error_divert">"Editing of NFC keys is not (yet) supported!"</string>
<string name="msg_ek_error_dummy">"Cannot edit keyring with stripped master key!"</string>
@@ -906,11 +982,13 @@
<string name="msg_dc_askip_no_key">"Data not encrypted with known key, skipping…"</string>
<string name="msg_dc_askip_not_allowed">"Data not encrypted with allowed key, skipping…"</string>
<string name="msg_dc_asym">"Found block of asymmetrically encrypted data for key %s"</string>
+ <string name="msg_dc_charset">"Found charset header: '%s'"</string>
<string name="msg_dc_clear_data">"Processing literal data"</string>
<string name="msg_dc_clear_decompress">"Unpacking compressed data"</string>
<string name="msg_dc_clear_meta_file">"Filename: %s"</string>
<string name="msg_dc_clear_meta_mime">"MIME type: %s"</string>
<string name="msg_dc_clear_meta_size">"Filesize: %s"</string>
+ <string name="msg_dc_clear_meta_size_unknown">"Filesize is unknown"</string>
<string name="msg_dc_clear_meta_time">"Modification time: %s"</string>
<string name="msg_dc_clear_signature_bad">"Signature check NOT OK!"</string>
<string name="msg_dc_clear_signature_check">"Verifying signature data"</string>
@@ -920,11 +998,12 @@
<string name="msg_dc_error_bad_passphrase">"Error unlocking key, bad passphrase!"</string>
<string name="msg_dc_error_extract_key">"Unknown error unlocking key!"</string>
<string name="msg_dc_error_integrity_check">"Integrity check error!"</string>
+ <string name="msg_dc_error_integrity_missing">"Missing integrity check! This can happen because the encrypting application is out of date, or from a downgrade attack."</string>
<string name="msg_dc_error_invalid_siglist">"No valid signature data found!"</string>
<string name="msg_dc_error_io">"Encountered IO Exception during operation!"</string>
<string name="msg_dc_error_no_data">"No encrypted data found in stream!"</string>
<string name="msg_dc_error_no_key">"No encrypted data with known secret key found in stream!"</string>
- <string name="msg_dc_error_pgp_exception">"Encountered PGP Exception during operation!"</string>
+ <string name="msg_dc_error_pgp_exception">"Encountered OpenPGP Exception during operation!"</string>
<string name="msg_dc_integrity_check_ok">"Integrity check OK!"</string>
<string name="msg_dc_ok_meta_only">"Only metadata was requested, skipping decryption"</string>
<string name="msg_dc_ok">"OK"</string>
@@ -954,29 +1033,43 @@
<string name="msg_vl_ok">"OK"</string>
<!-- Messages for SignEncrypt operation -->
- <string name="msg_se_asymmetric">"Preparing public keys for encryption"</string>
- <string name="msg_se_clearsign_only">"Signing of cleartext input not supported!"</string>
- <string name="msg_se_compressing">"Preparing compression"</string>
- <string name="msg_se_encrypting">"Encrypting data"</string>
- <string name="msg_se_error_bad_passphrase">"Bad passphrase!"</string>
- <string name="msg_se_error_io">"Encountered IO Exception during operation!"</string>
- <string name="msg_se_error_key_sign">"Selected signing key cannot sign data!"</string>
- <string name="msg_se_error_sign_key">"Error fetching signing key!"</string>
- <string name="msg_se_error_nfc">"NFC data error!"</string>
- <string name="msg_se_error_no_passphrase">"No passphrase provided!"</string>
- <string name="msg_se_error_pgp">"Internal PGP error!"</string>
- <string name="msg_se_error_sig">"Encountered PGP signature exception!"</string>
- <string name="msg_se_error_unlock">"Unknown error unlocking key!"</string>
- <string name="msg_se_key_ok">"Encrypting for key: %s"</string>
- <string name="msg_se_key_unknown">"Missing key for encryption: %s"</string>
- <string name="msg_se_key_warn">"Bad key for encryption: %s"</string>
- <string name="msg_se_ok">"Sign/Encrypt operation successful!"</string>
- <string name="msg_se_pending_nfc">"NFC token required, requesting user input…"</string>
- <string name="msg_se_pending_passphrase">"Passphrase required, requesting user input…"</string>
- <string name="msg_se_signing">"Signing data (without encryption)"</string>
- <string name="msg_se_sigcrypting">"Encrypting data with signature"</string>
- <string name="msg_se">"Starting sign and/or encrypt operation"</string>
- <string name="msg_se_symmetric">"Preparing symmetric encryption"</string>
+ <string name="msg_se">"Starting sign/encrypt operation"</string>
+ <string name="msg_se_input_bytes">"Processing input from byte array"</string>
+ <string name="msg_se_input_uri">"Processing input from uri"</string>
+ <string name="msg_se_error_no_input">"No input given!"</string>
+ <string name="msg_se_error_input_uri_not_found">"Error opening Uri for reading!"</string>
+ <string name="msg_se_error_output_uri_not_found">"Error opening Uri for writing!"</string>
+ <string name="msg_se_error_too_many_inputs">"More inputs than outputs specified! This is probably a programming error, please report!"</string>
+ <string name="msg_se_warn_output_left">"Got outputs left but no inputs. This is probably a programming error, please report!"</string>
+ <string name="msg_se_success">"Sign/encrypt operation successful"</string>
+
+ <!-- Messages for PgpSignEncrypt operation -->
+ <string name="msg_pse_asymmetric">"Preparing public keys for encryption"</string>
+ <string name="msg_pse_clearsign_only">"Signing of cleartext input not supported!"</string>
+ <string name="msg_pse_compressing">"Preparing compression"</string>
+ <string name="msg_pse_encrypting">"Encrypting data"</string>
+ <string name="msg_pse_error_bad_passphrase">"Bad passphrase!"</string>
+ <string name="msg_pse_error_hash_algo">"Requested hashing algorithm is not supported by this key!"</string>
+ <string name="msg_pse_error_io">"Encountered IO Exception during operation!"</string>
+ <string name="msg_pse_error_key_sign">"Selected signing key cannot sign data!"</string>
+ <string name="msg_pse_error_sign_key">"Error fetching signing key!"</string>
+ <string name="msg_pse_error_nfc">"NFC data error!"</string>
+ <string name="msg_pse_error_no_passphrase">"No passphrase provided!"</string>
+ <string name="msg_pse_error_pgp">"Internal OpenPGP error!"</string>
+ <string name="msg_pse_error_sig">"Encountered OpenPGP signature exception!"</string>
+ <string name="msg_pse_error_unlock">"Unknown error unlocking key!"</string>
+ <string name="msg_pse_key_ok">"Encrypting for key: %s"</string>
+ <string name="msg_pse_key_unknown">"Missing key for encryption: %s"</string>
+ <string name="msg_pse_key_warn">"Bad key for encryption: %s"</string>
+ <string name="msg_pse_ok">"Sign/Encrypt operation successful!"</string>
+ <string name="msg_pse_pending_nfc">"NFC token required, requesting user input…"</string>
+ <string name="msg_pse_pending_passphrase">"Passphrase required, requesting user input…"</string>
+ <string name="msg_pse_signing">"Signing data (without encryption)"</string>
+ <string name="msg_pse_signing_cleartext">"Creating cleartext signature"</string>
+ <string name="msg_pse_signing_detached">"Creating detached signature"</string>
+ <string name="msg_pse_sigcrypting">"Encrypting data with signature"</string>
+ <string name="msg_pse">"Starting sign and/or encrypt operation"</string>
+ <string name="msg_pse_symmetric">"Preparing symmetric encryption"</string>
<string name="msg_crt_certifying">"Generating certifications"</string>
<string name="msg_crt_certify_all">"Certifying all user IDs for key %s"</string>
@@ -984,6 +1077,7 @@
<item quantity="one">"Certifying one user ID for key %2$s"</item>
<item quantity="other">"Certifying %1$d user IDs for key %2$s"</item>
</plurals>
+ <string name="msg_crt_error_self">"Cannot issue self-certificate like this!"</string>
<string name="msg_crt_error_master_not_found">"Master key not found!"</string>
<string name="msg_crt_error_nothing">"No keys certified!"</string>
<string name="msg_crt_error_unlock">"Error unlocking master key!"</string>
@@ -1015,6 +1109,7 @@
<string name="msg_import_fingerprint_ok">"Fingerprint check OK"</string>
<string name="msg_import_merge">"Merging retrieved data"</string>
<string name="msg_import_error">"Import operation failed!"</string>
+ <string name="msg_import_error_io">"Import operation failed due to i/o error!"</string>
<string name="msg_import_partial">"Import operation successful, with errors!"</string>
<string name="msg_import_success">"Import operation successful!"</string>
@@ -1032,6 +1127,7 @@
<string name="msg_export_error_storage">"Storage is not ready for writing!"</string>
<string name="msg_export_error_db">"Database error!"</string>
<string name="msg_export_error_io">"Input/output error!"</string>
+ <string name="msg_export_error_key">"Error preprocessing key data!"</string>
<string name="msg_export_success">"Export operation successful"</string>
<string name="msg_del_error_empty">"Nothing to delete!"</string>
@@ -1074,6 +1170,12 @@
<string name="passp_cache_notif_clear">"Clear Cache"</string>
<string name="passp_cache_notif_pwd">"Passphrase"</string>
+ <!-- First Time -->
+ <string name="first_time_text1">"Take back your privacy with OpenKeychain!"</string>
+ <string name="first_time_create_key">"Create my key"</string>
+ <string name="first_time_import_key">"Import from file"</string>
+ <string name="first_time_skip">"Skip Setup"</string>
+
<!-- unsorted -->
<string name="section_certifier_id">"Certifier"</string>
<string name="section_cert">"Certificate Details"</string>
@@ -1083,6 +1185,8 @@
<string name="certs_text">"Only validated self-certificates and validated certificates created with your keys are displayed here."</string>
<string name="section_uids_to_certify">"Identities for "</string>
<string name="certify_text">"The keys you are importing contain “identitiesâ€: names and emails. Select exactly those for certification which match what you expected."</string>
+ <string name="certify_fingerprint_text">"Compare the displayed fingerprint, character by character, with the one displayed on your partners device."</string>
+ <string name="certify_fingerprint_text2">"Do the displayed fingerprints match?"</string>
<string name="label_revocation">"Revocation Reason"</string>
<string name="label_verify_status">"Verification Status"</string>
<string name="label_cert_type">"Type"</string>
@@ -1104,11 +1208,34 @@
<string name="error_multi_not_supported">"Saving of multiple files not supported. This is a limitation on current Android."</string>
<string name="key_colon">"Key:"</string>
<string name="exchange_description">"To start a key exchange, choose the number of participants on the right side, then hit the “Start exchange†button.\n\nYou will be asked two more questions to make sure only the right participants are in the exchange and their fingerprints are correct."</string>
-
- <!-- First Time -->
- <string name="first_time_text1">"Take back your privacy with OpenKeychain!"</string>
- <string name="first_time_create_key">"Create my key"</string>
- <string name="first_time_import_key">"Import from file"</string>
- <string name="first_time_skip">"Skip Setup"</string>
+ <string name="btn_start_exchange">"Start exchange"</string>
+ <string name="user_id_none"><![CDATA[<none>]]></string>
+
+ <!-- Passphrase wizard -->
+ <!-- TODO: rename all the things! -->
+ <string name="title_unlock_method">Choose an unlock method</string>
+ <!--<string name="enter_passphrase_twice">Enter passphrase twice</string>-->
+ <string name="enter_passphrase">Enter passphrase</string>
+ <string name="passphrase">Passphrase</string>
+ <string name="noPassphrase">No passphrase</string>
+ <string name="no_passphrase_set">No passphrase set</string>
+ <string name="passphrases_match">Passphrases do match</string>
+ <string name="passphrase_saved">Passphrase saved</string>
+ <string name="passphrase_invalid">Passphrase invalid</string>
+ <string name="missing_passphrase">Missing passphrase</string>
+ <string name="passphrase_again">Again</string>
+ <string name="lockpattern">Lockpattern</string>
+ <string name="lockpatternNFC">NFC + Lockpattern</string>
+ <string name="unlock_method">Unlock method</string>
+ <string name="set_passphrase">Set passphrase</string>
+ <string name="draw_lockpattern">Draw lockpattern</string>
+ <string name="nfc_title">NFC</string>
+ <!--<string name="nfc_text">Please place a NFC tag near your device</string>-->
+ <string name="nfc_wrong_tag">Wrong Tag. Please try again.</string>
+ <string name="enable_nfc">Please activate NFC in your settings</string>
+ <string name="no_nfc_support">This device does not support NFC</string>
+ <string name="nfc_write_succesful">Successfully written on NFC tag</string>
+ <string name="unlocked">Unlocked</string>
+ <string name="nfc_settings">Settings</string>
</resources>
diff --git a/OpenKeychain/src/main/res/values/styles.xml b/OpenKeychain/src/main/res/values/styles.xml
index 27cd1546a..8d8797bf0 100644
--- a/OpenKeychain/src/main/res/values/styles.xml
+++ b/OpenKeychain/src/main/res/values/styles.xml
@@ -1,23 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <!-- Used in Android < 4 -->
- <style name="KeychainTheme" parent="@style/Theme.AppCompat.Light">
- <item name="android:alertDialogStyle">@style/CustomDialogTheme</item>
- </style>
-
- <!-- Ugly fix to make content background of Dialogs on Android < 4 white not black! -->
- <style name="CustomDialogTheme" parent="@android:style/Theme.Dialog">
- <item name="android:fullDark">@drawable/popup_full_bright</item>
- <!--<item name="android:topDark">@android:drawable/popup_full_dark</item>-->
- <item name="android:centerDark">@drawable/popup_center_bright</item>
- <!--<item name="android:bottomDark">@android:drawable/popup_bottom_dark</item>-->
- <!--<item name="fullBright">@android:drawable/popup_full_bright</item>-->
- <!--<item name="topBright">@android:drawable/popup_top_bright</item>-->
- <!--<item name="centerBright">@android:drawable/popup_center_bright</item>-->
- <!--<item name="bottomBright">@android:drawable/popup_bottom_bright</item>-->
- <!--<item name="bottomMedium">@android:drawable/popup_bottom_medium</item>-->
- <!--<item name="centerMedium">@android:drawable/popup_center_medium</item>-->
+ <style name="CardViewHeader">
+ <item name="android:drawableBottom">@drawable/cardview_header</item>
+ <item name="android:drawablePadding">16dp</item>
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:paddingLeft">16dp</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">@color/header_text</item>
+ <item name="android:textSize">17sp</item>
</style>
<style name="SectionHeader">
@@ -26,7 +17,7 @@
<item name="android:layout_marginTop">8dp</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:textStyle">bold</item>
- <item name="android:textColor">@color/emphasis</item>
+ <item name="android:textColor">@color/header_text</item>
<item name="android:textSize">14sp</item>
</style>
@@ -34,4 +25,9 @@
<item name="android:background">@drawable/selector_transparent_button</item>
</style>
+ <style name="FabMenuStyle">
+ <item name="android:background">@drawable/fab_label_background</item>
+ <item name="android:textColor">@color/white</item>
+ </style>
+
</resources> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/values/themes.xml b/OpenKeychain/src/main/res/values/themes.xml
new file mode 100644
index 000000000..c87895c01
--- /dev/null
+++ b/OpenKeychain/src/main/res/values/themes.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <style name="KeychainTheme" parent="KeychainTheme.Base" />
+
+ <style name="KeychainTheme.Base" parent="Theme.AppCompat.Light">
+ <item name="colorPrimary">@color/primary</item>
+ <item name="colorPrimaryDark">@color/primary_dark</item>
+ <item name="colorAccent">@color/accent</item>
+
+ <item name="android:windowNoTitle">true</item>
+ <!-- remove actionbar, we use toolbar! -->
+ <item name="windowActionBar">false</item>
+ <!-- multi selection should overlay Toolbar! http://stackoverflow.com/a/26450875 -->
+ <item name="windowActionModeOverlay">true</item>
+ <item name="searchViewStyle">@style/MySearchViewStyle</item>
+
+ <!-- Navigation Drawer library -->
+ <item name="drawerType">@integer/DRAWERTYPE_IMAGE</item>
+ <!-- dark action bar... -->
+ <item name="theme">@style/ThemeOverlay.AppCompat.Dark</item>
+ <!-- ...but light popup menu (white background) -->
+ <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
+ <item name="drawerColor">#fafafa</item>
+ <item name="singleAccount">false</item>
+ <item name="sectionStyle">@style/MaterialSectionTheme.Light</item>
+ <item name="subheaderStyle">@style/MaterialSubheaderTheme.Light</item>
+ <item name="multipaneSupport">false</item>
+ <item name="rippleBackport">false</item>
+ <item name="uniqueToolbarColor">false</item>
+ </style>
+
+ <!-- http://android-developers.blogspot.de/2014/10/appcompat-v21-material-design-for-pre.html -->
+ <style name="MySearchViewStyle" parent="Widget.AppCompat.SearchView">
+ <!-- Background for the search query section (e.g. EditText) -->
+ <!--<item name="queryBackground">...</item>-->
+ <!-- Background for the actions section (e.g. voice, submit) -->
+ <!--<item name="submitBackground">...</item>-->
+ <!-- Close button icon -->
+ <item name="closeIcon">@drawable/ic_close_white_24dp</item>
+ <!-- Search button icon -->
+ <!--<item name="searchIcon">...</item>-->
+ <!-- Go/commit button icon -->
+ <!--<item name="goIcon">...</item>-->
+ <!-- Voice search button icon -->
+ <!--<item name="voiceIcon">...</item>-->
+ <!-- Commit icon shown in the query suggestion row -->
+ <!--<item name="commitIcon">...</item>-->
+ <!-- Layout for query suggestion rows -->
+ <!--<item name="suggestionRowLayout">...</item>-->
+ </style>
+</resources> \ No newline at end of file
diff --git a/OpenKeychain/src/main/res/xml/preference_headers.xml b/OpenKeychain/src/main/res/xml/preference_headers.xml
index dd7f1c3e6..347394b06 100644
--- a/OpenKeychain/src/main/res/xml/preference_headers.xml
+++ b/OpenKeychain/src/main/res/xml/preference_headers.xml
@@ -1,8 +1,8 @@
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
- android:fragment="org.sufficientlysecure.keychain.ui.PreferencesActivity$CloudSearchPrefsFragment"
+ android:fragment="org.sufficientlysecure.keychain.ui.SettingsActivity$CloudSearchPrefsFragment"
android:title="@string/section_cloud_search" />
<header
- android:fragment="org.sufficientlysecure.keychain.ui.PreferencesActivity$AdvancedPrefsFragment"
+ android:fragment="org.sufficientlysecure.keychain.ui.SettingsActivity$AdvancedPrefsFragment"
android:title="@string/section_advanced" />
</preference-headers>
diff --git a/OpenKeychain/src/main/res/xml/preference_headers_legacy.xml b/OpenKeychain/src/main/res/xml/preference_headers_legacy.xml
deleted file mode 100644
index 47b0a0920..000000000
--- a/OpenKeychain/src/main/res/xml/preference_headers_legacy.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <Preference
- android:title="@string/section_general" >
- <intent
- android:action="org.sufficientlysecure.keychain.ui.PREFS_GEN" />
- </Preference>
- <Preference
- android:title="@string/section_advanced" >
- <intent
- android:action="org.sufficientlysecure.keychain.ui.PREFS_ADV" />
- </Preference>
-</PreferenceScreen>
diff --git a/README.md b/README.md
index 7338f1071..991757169 100644
--- a/README.md
+++ b/README.md
@@ -33,17 +33,16 @@ Development mailinglist at http://groups.google.com/d/forum/openpgp-keychain-dev
1. Get all external submodules with ``git submodule update --init --recursive``
2. Have Android SDK "tools", "platform-tools", and "build-tools" directories in your PATH (http://developer.android.com/sdk/index.html)
3. Open the Android SDK Manager (shell command: ``android``).
-Expand the Tools directory and select "Android SDK Build-tools (Version 19.1)".
+Expand the Tools directory and select "Android SDK Build-tools (Version 21.1.1)".
Expand the Extras directory and install "Android Support Repository"
-Select everything for the newest SDK Platform (API-Level 19)
+Select everything for the newest SDK Platform (API-Level 21)
4. Export ANDROID_HOME pointing to your Android SDK
5. Execute ``./gradlew build``
6. You can install the app with ``adb install -r OpenKeychain/build/outputs/apk/OpenKeychain-debug-unaligned.apk``
### Run Tests
1. Use OpenJDK instead of Oracle JDK
-2. Execute ``./prepare-tests.sh``
-3. Execute ``./gradlew build``
+3. Execute ``./gradlew test``
### Build API Demo with Gradle
@@ -221,6 +220,10 @@ Some parts and some libraries are Apache License v2, MIT X11 License (see below)
* StickyListHeaders
https://github.com/emilsjolander/StickyListHeaders
Apache License v2
+
+* https://github.com/jpardogo/PagerSlidingTabStrip
+
+* https://github.com/journeyapps/zxing-android-embedded
### Images
* icon.svg
diff --git a/Resources/graphics/create_key_robot.svg b/Resources/graphics/create_key_robot.svg
deleted file mode 100644
index 7301dc5bb..000000000
--- a/Resources/graphics/create_key_robot.svg
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="45"
- height="45"
- id="svg4316"
- version="1.1"
- inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="create_key_robot.svg">
- <defs
- id="defs4318" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="5.6"
- inkscape:cx="19.859075"
- inkscape:cy="10.23901"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="2558"
- inkscape:window-height="1419"
- inkscape:window-x="0"
- inkscape:window-y="19"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata4321">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1007.3622)">
- <g
- id="g3761">
- <path
- id="path5399"
- d="m 22.166071,1009.3123 c -5.613738,0 -10.131173,4.5175 -10.131173,10.1312 l 0,18.6956 c 0,5.6138 4.517435,10.1365 10.131173,10.1365 l 0.6677,0 c 5.613732,0 10.131173,-4.5227 10.131173,-10.1365 l 0,-18.6956 c 0,-5.6137 -4.517441,-10.1312 -10.131173,-10.1312 l -0.6677,0 z m 0.336476,3.3649 c 4.044517,0 7.223786,3.1791 7.223786,7.1291 l 0,14.9628 c 0,3.95 -3.179269,7.1292 -7.223786,7.1292 -4.044516,0 -7.229038,-3.1792 -7.229038,-7.1292 l 0,-14.9628 c 0,-3.95 3.184522,-7.1291 7.229038,-7.1291 z"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#669900;stroke-width:1.74663651;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <rect
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#669900;stroke-width:1.74663651;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect5401"
- width="33.961983"
- height="24.945528"
- x="5.5190063"
- y="1025.4666"
- rx="0.79848224"
- ry="0.79848224" />
- <path
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#669900;stroke-width:1.74663651;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 11.109664,1043.5389 c 2.495006,2.065 6.666898,3.4226 11.392966,3.4226 4.725665,0 8.89263,-1.3579 11.387713,-3.4226 z"
- id="path5403"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cscc" />
- <path
- sodipodi:type="arc"
- style="color:#000000;fill:none;stroke:#669900;stroke-width:9.60078144;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path5405"
- sodipodi:cx="307.48431"
- sodipodi:cy="407.66223"
- sodipodi:rx="9.388834"
- sodipodi:ry="9.388834"
- d="m 316.87315,407.66223 a 9.388834,9.388834 0 1 1 -18.77767,0"
- transform="matrix(0.1819265,0,0,0.1819265,-43.957774,964.33702)"
- sodipodi:start="0"
- sodipodi:end="3.1415927"
- sodipodi:open="true" />
- <path
- d="m 316.87315,407.66223 a 9.388834,9.388834 0 1 1 -18.77767,0 9.388834,9.388834 0 1 1 18.77767,0 z"
- sodipodi:ry="9.388834"
- sodipodi:rx="9.388834"
- sodipodi:cy="407.66223"
- sodipodi:cx="307.48431"
- id="path5407"
- style="color:#000000;fill:#669900;fill-opacity:1;fill-rule:nonzero;stroke:#669900;stroke-width:9.60078144000000044;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc"
- transform="matrix(0.1819265,0,0,0.1819265,-21.704758,965.01923)" />
- </g>
- </g>
-</svg>
diff --git a/Resources/graphics/first_time_1.png b/Resources/graphics/first_time_1.png
deleted file mode 100644
index 1f340df5c..000000000
--- a/Resources/graphics/first_time_1.png
+++ /dev/null
Binary files differ
diff --git a/Resources/graphics/first_time_1.svg b/Resources/graphics/first_time_1.svg
deleted file mode 100644
index 1f40c5ff3..000000000
--- a/Resources/graphics/first_time_1.svg
+++ /dev/null
@@ -1,351 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="512"
- height="512"
- id="svg4325"
- version="1.1"
- inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="ok_start.svg">
- <defs
- id="defs4327" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1.979899"
- inkscape:cx="405.16912"
- inkscape:cy="246.12576"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="2558"
- inkscape:window-height="1419"
- inkscape:window-x="0"
- inkscape:window-y="19"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata4330">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-540.36218)">
- <path
- sodipodi:type="arc"
- style="opacity:0.59999999999999998;fill:#9933cc;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path4501"
- sodipodi:cx="227.53687"
- sodipodi:cy="246.58241"
- sodipodi:rx="225.51656"
- sodipodi:ry="225.51656"
- d="m 453.05342,246.58241 a 225.51656,225.51656 0 1 1 -451.0331106,0 225.51656,225.51656 0 1 1 451.0331106,0 z"
- transform="translate(28.463135,549.77977)" />
- <path
- sodipodi:type="star"
- style="color:#000000;fill:#ffffff;fill-opacity:0.16256157;fill-rule:nonzero;stroke:none;stroke-width:1.76498926;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path7021"
- sodipodi:sides="25"
- sodipodi:cx="237.45834"
- sodipodi:cy="671.60583"
- sodipodi:r1="60.973591"
- sodipodi:r2="37.364418"
- sodipodi:arg1="0.87061839"
- sodipodi:arg2="0.99902889"
- inkscape:flatsided="false"
- inkscape:rounded="0"
- inkscape:randomized="0"
- d="m 276.74691,718.23402 -19.06996,-15.20673 6.23968,23.51249 -14.68908,-19.47149 0.19632,24.32554 -9.38523,-22.51278 -5.85936,23.61014 -3.49167,-24.13951 -11.54688,21.41122 2.62127,-24.24948 -16.50886,17.86696 8.56952,-22.83575 -20.43354,13.20005 13.97931,-19.98717 -23.0743,7.70373 18.51073,-15.88272 -24.26522,1.72335 21.87906,-10.7803 -23.93146,-4.3653 23.87263,-5.00052 -22.094,-10.17967 24.36621,1.09346 -18.8683,-15.35441 23.32877,7.11874 -14.45703,-19.56438 20.8255,12.69672 -9.13738,-22.54504 17.01368,17.47692 -3.24358,-24.10913 12.13283,21.15898 2.85402,-24.15834 6.48963,23.51155 8.77228,-22.6896 0.43867,24.38679 14.13936,-19.79518 -5.63987,23.72973 18.61801,-15.65696 -11.36402,21.58163 21.92682,-10.53495 -16.37414,18.07749 23.85789,-4.75101 -20.35541,13.43747 24.28988,1.33147 -23.05767,7.95313 23.19564,7.33029 -24.31112,1.96905 20.64393,12.86851 -24.03703,-4.13873 16.7951,17.59816 -22.2526,-9.98648 z"
- transform="matrix(2.3346891,0,0,2.3346891,-297.98143,-788.87687)"
- inkscape:transform-center-x="0.48070196"
- inkscape:transform-center-y="0.080663394" />
- <rect
- ry="14.623538"
- rx="14.623538"
- y="778.16095"
- x="189.31395"
- height="91.847595"
- width="133.37183"
- id="rect3529"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 254.33815,626.00818 c -27.93766,0 -50.4195,22.48185 -50.4195,50.41951 l 0,93.04182 c 0,27.93768 22.48184,50.44562 50.4195,50.44562 l 3.3229,0 c 27.93773,0 50.4195,-22.50794 50.4195,-50.44562 l 0,-93.04182 c 0,-27.93766 -22.48177,-50.41951 -50.4195,-50.41951 l -3.3229,0 z m 1.67456,16.74544 c 20.12817,0 35.95034,15.82142 35.95034,35.47939 l 0,74.46486 c 0,19.65806 -15.82217,35.47941 -35.95034,35.47941 -20.1282,0 -35.97658,-15.82135 -35.97658,-35.47941 l 0,-74.46486 c 0,-19.65797 15.84838,-35.47939 35.97658,-35.47939 z"
- id="path3531" />
- <rect
- ry="3.9737797"
- rx="3.9737797"
- y="706.40234"
- x="171.49129"
- height="124.14557"
- width="169.01746"
- id="rect3533"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="cscc"
- inkscape:connector-curvature="0"
- id="path3535"
- d="m 199.31408,796.34234 c 12.41682,10.27683 33.179,17.03328 56.69903,17.03328 23.51804,0 44.25559,-6.75787 56.67285,-17.03328 z"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- transform="matrix(0.90538746,0,0,0.90538746,-76.624431,405.57604)"
- d="m 316.87315,407.66223 a 9.388834,9.388834 0 1 1 -18.77767,0 9.388834,9.388834 0 1 1 18.77767,0 z"
- sodipodi:ry="9.388834"
- sodipodi:rx="9.388834"
- sodipodi:cy="407.66223"
- sodipodi:cx="307.48431"
- id="path3537"
- style="color:#000000;fill:#4b4f2f;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.55131245;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- <path
- transform="matrix(0.90538746,0,0,0.90538746,36.007648,405.57604)"
- sodipodi:type="arc"
- style="color:#000000;fill:#4b4f2f;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.55131245;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path3539"
- sodipodi:cx="307.48431"
- sodipodi:cy="407.66223"
- sodipodi:rx="9.388834"
- sodipodi:ry="9.388834"
- d="m 316.87315,407.66223 a 9.388834,9.388834 0 1 1 -18.77767,0 9.388834,9.388834 0 1 1 18.77767,0 z" />
- <g
- id="g10754"
- transform="matrix(0.83727181,0,0,0.83727181,829.92363,-416.95697)"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <g
- id="g5737-8"
- transform="translate(-898.12108,631.20806)"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <rect
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect5739-5"
- width="29.344997"
- height="96.371902"
- x="153.20558"
- y="918.29181"
- rx="0.84849852"
- ry="0.95320696" />
- <path
- sodipodi:nodetypes="cscc"
- inkscape:connector-curvature="0"
- id="path5741-6"
- d="m 192.11794,916.83294 c -7.43536,-12.87842 -23.7891,-17.26042 -36.66754,-9.82505 -12.87845,7.43537 -17.26039,23.78913 -9.82503,36.66755 z"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- ry="3"
- rx="3"
- y="1010.0776"
- x="133.00574"
- height="11.311689"
- width="69.74469"
- id="rect5743-2"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 145.00574,916.83294 c 7.43536,-12.87842 23.7891,-17.26042 36.66754,-9.82505 12.87845,7.43537 17.26039,23.78913 9.82503,36.66755 z"
- id="path5745-2"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cscc" />
- <rect
- ry="7.1440544"
- rx="7.1440544"
- y="968.78937"
- x="145.20558"
- height="14.288109"
- width="45.344997"
- id="rect5747-2"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
- <g
- id="g5749-5"
- transform="matrix(-1,0,0,1,-472.81628,631.20806)"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <rect
- ry="0.95320696"
- rx="0.84849852"
- y="918.29181"
- x="153.20558"
- height="96.371902"
- width="29.344997"
- id="rect5751-5"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 192.11794,916.83294 c -7.43536,-12.87842 -23.7891,-17.26042 -36.66754,-9.82505 -12.87845,7.43537 -17.26039,23.78913 -9.82503,36.66755 z"
- id="path5753-0"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cscc" />
- <rect
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect5755-0"
- width="69.74469"
- height="11.311689"
- x="133.00574"
- y="1010.0776"
- rx="3"
- ry="3" />
- <path
- sodipodi:nodetypes="cscc"
- inkscape:connector-curvature="0"
- id="path5757-1"
- d="m 145.00574,916.83294 c 7.43536,-12.87842 23.7891,-17.26042 36.66754,-9.82505 12.87845,7.43537 17.26039,23.78913 9.82503,36.66755 z"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect5759-7"
- width="45.344997"
- height="14.288109"
- x="145.20558"
- y="968.78937"
- rx="7.1440544"
- ry="7.1440544" />
- </g>
- </g>
- <g
- transform="matrix(0.83727181,0,0,0.83727181,84.650265,61.513651)"
- id="g5697-5"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="path5699-6"
- d="m 326.98547,847.70808 57.45819,0 0,-73.83379 -10,0 0,61.83379 -47.45819,0"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect5703-1"
- width="9.4107542"
- height="42.249756"
- x="305.50339"
- y="821.53503"
- rx="4.7053771"
- ry="4.7053771" />
- <path
- inkscape:connector-curvature="0"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 390.56742,727.10519 c -6.09957,0 -11,4.90043 -11,11 l 0,10.15625 -10.15625,0 c -6.09957,0 -11,4.90043 -11,11 0,6.09957 4.90043,11 11,11 l 21.15625,0 c 6.09957,0 11,-4.90043 11,-11 l 0,-21.15625 c 0,-6.09957 -4.90043,-11 -11,-11 z"
- id="path5705-8" />
- <rect
- ry="2.1935852"
- rx="4.0765176"
- y="771.6814"
- x="369.11923"
- height="12.20938"
- width="21.740107"
- id="rect5707-1"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- ry="2.9156427"
- rx="7.0489321"
- y="829.57007"
- x="318.22556"
- height="26.179665"
- width="14.097864"
- id="rect5709-1"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- id="g5711-2"
- transform="translate(-34.057657,-0.65450616)"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <path
- inkscape:connector-curvature="0"
- id="path5713-1"
- d="m 404.77705,825.97291 -9.16957,15.86559 9.16957,15.84038 18.38979,0 9.19491,-15.84038 -9.19491,-15.86559 -18.38979,0 z"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- id="path5715-3"
- d="m 413.97195,836.00644 c 3.23493,0 5.85942,2.61224 5.85942,5.83206 0,3.21983 -2.62449,5.83207 -5.85942,5.83207 -3.23494,0 -5.85943,-2.61224 -5.85943,-5.83207 0,-3.21982 2.62449,-5.83206 5.85943,-5.83206 z"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
- </g>
- <g
- transform="matrix(-0.83727181,0,0,-0.83727181,427.34978,1471.4837)"
- id="g10957"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="path10959"
- d="m 326.98547,847.70808 57.45819,0 0,-73.83379 -10,0 0,61.83379 -47.45819,0"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect10961"
- width="9.4107542"
- height="42.249756"
- x="305.50339"
- y="821.53503"
- rx="4.7053771"
- ry="4.7053771" />
- <path
- inkscape:connector-curvature="0"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 390.56742,727.10519 c -6.09957,0 -11,4.90043 -11,11 l 0,10.15625 -10.15625,0 c -6.09957,0 -11,4.90043 -11,11 0,6.09957 4.90043,11 11,11 l 21.15625,0 c 6.09957,0 11,-4.90043 11,-11 l 0,-21.15625 c 0,-6.09957 -4.90043,-11 -11,-11 z"
- id="path10963" />
- <rect
- ry="2.1935852"
- rx="4.0765176"
- y="771.6814"
- x="369.11923"
- height="12.20938"
- width="21.740107"
- id="rect10965"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- ry="2.9156427"
- rx="7.0489321"
- y="829.57007"
- x="318.22556"
- height="26.179665"
- width="14.097864"
- id="rect10967"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- id="g10969"
- transform="translate(-34.057657,-0.65450616)"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <path
- inkscape:connector-curvature="0"
- id="path10971"
- d="m 404.77705,825.97291 -9.16957,15.86559 9.16957,15.84038 18.38979,0 9.19491,-15.84038 -9.19491,-15.86559 -18.38979,0 z"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- id="path10973"
- d="m 413.97195,836.00644 c 3.23493,0 5.85942,2.61224 5.85942,5.83206 0,3.21983 -2.62449,5.83207 -5.85942,5.83207 -3.23494,0 -5.85943,-2.61224 -5.85943,-5.83207 0,-3.21982 2.62449,-5.83206 5.85943,-5.83206 z"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.92158127;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
- </g>
- <rect
- ry="12.863822"
- rx="12.863822"
- y="836.96265"
- x="214.05772"
- height="25.727644"
- width="83.8843"
- id="rect5685-1"
- style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#4b4f2f;stroke-width:4.12070131;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
-</svg>
diff --git a/Resources/graphics/ic_action_nfc.svg b/Resources/graphics/ic_action_nfc.svg
deleted file mode 100644
index 23ec040ff..000000000
--- a/Resources/graphics/ic_action_nfc.svg
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="32"
- height="32"
- id="svg2"
- version="1.1"
- inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="ic_action_nfc.svg">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="7.9195959"
- inkscape:cx="55.015233"
- inkscape:cy="28.459126"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1918"
- inkscape:window-height="1179"
- inkscape:window-x="0"
- inkscape:window-y="19"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1020.3622)">
- <path
- style="fill:#333333;fill-opacity:1;opacity:0.6"
- d="m 5.8721355,1048.2554 c -0.4529966,-0.1375 -0.740227,-0.4023 -0.9002787,-0.8301 -0.1191051,-0.3184 -0.1207083,-0.4654 -0.1210019,-11.0625 -2.937e-4,-10.087 0.00614,-10.7582 0.1054687,-11.0385 0.1209465,-0.3414 0.3739125,-0.6212 0.714231,-0.7901 0.2298623,-0.1143 0.4666295,-0.1167 10.3597324,-0.1167 9.762967,0 10.132027,0 10.33542,0.1119 0.293646,0.1565 0.533124,0.3907 0.668434,0.6537 0.11192,0.2176 0.115013,0.517 0.115013,11.171 l 0,10.9473 -0.158878,0.292 c -0.170555,0.3133 -0.479601,0.5651 -0.810206,0.6599 -0.246895,0.071 -20.0747083,0.072 -20.3079261,0 z m 16.2976125,-2.4107 c 0.23156,-0.072 0.233209,-0.075 0.197176,-0.3243 -0.01999,-0.1382 -0.06539,-0.3531 -0.100895,-0.4778 -0.05999,-0.2104 -0.07395,-0.2212 -0.197176,-0.1528 -0.08059,0.045 -0.380826,0.075 -0.765398,0.075 -0.599986,0 -0.648397,-0.012 -0.934105,-0.1829 -0.791251,-0.4824 -0.931603,-1.6091 -0.289037,-2.3203 0.358193,-0.3965 0.834326,-0.478 2.00208,-0.3427 0.130096,0.016 0.159263,-0.024 0.265386,-0.3525 0.06557,-0.203 0.10323,-0.411 0.08367,-0.4619 -0.09945,-0.2592 -1.822581,-0.2986 -2.442687,-0.055 -0.730348,0.2858 -1.380503,1.0115 -1.523992,1.7009 -0.163151,0.7839 0.03489,1.6739 0.487021,2.1889 0.242512,0.2762 0.819987,0.6217 1.231169,0.7366 0.365786,0.1023 1.625695,0.083 1.986785,-0.03 z m -11.484429,-1.5922 -0.01861,-1.6494 0.305471,0.5797 c 0.168009,0.3188 0.590546,1.0543 0.938971,1.6343 l 0.633498,1.0547 0.627916,0 0.627916,0 0.01577,-2.3655 0.01577,-2.3653 -0.579954,0 -0.579953,0 0.02229,1.4971 0.02229,1.497 -0.393102,-0.7287 c -0.216208,-0.4008 -0.449401,-0.81 -0.518211,-0.9095 -0.137702,-0.199 -0.444752,-0.7018 -0.671555,-1.0998 l -0.145965,-0.2561 -0.718026,0 -0.7180255,0 0,2.3805 0,2.3804 0.5760585,0 0.576058,0 -0.01861,-1.6494 z m 5.254566,0.7169 0,-0.9325 0.888907,-0.017 0.888907,-0.017 0.0176,-0.467 0.01761,-0.4671 -0.906507,0 -0.906509,0 0,-0.4806 0,-0.4806 0.949172,-0.017 0.949173,-0.017 0.0176,-0.467 0.01761,-0.4671 -1.569422,0 -1.569421,0 0,2.3806 0,2.3804 0.602649,0 0.602648,0 0,-0.9326 z m 6.273699,-6.4951 c 0.263993,-0.1748 0.61016,-0.8748 0.983357,-1.9885 0.326831,-0.9753 0.423664,-1.4032 0.58101,-2.5681 0.146707,-1.0861 0.146304,-1.9076 -0.0016,-3.0218 -0.154191,-1.1622 -0.252803,-1.6038 -0.569457,-2.5496 -0.370747,-1.1074 -0.703918,-1.8019 -0.957103,-1.995 -0.398108,-0.3037 -1.035569,-0.1671 -1.308366,0.2804 -0.1709,0.2803 -0.152866,0.4134 0.144075,1.0638 0.748762,1.6401 1.136923,3.7484 0.996979,5.4153 -0.126969,1.5121 -0.448209,2.7968 -1.003437,4.0129 -0.286491,0.6275 -0.3029,0.8042 -0.103013,1.1092 0.247511,0.3778 0.853068,0.4959 1.237432,0.2414 z m -3.212265,-1.1548 c 0.08951,-0.047 0.234524,-0.162 0.322265,-0.2561 0.350427,-0.3759 0.948601,-2.1223 1.142298,-3.335 0.09437,-0.5908 0.09141,-2.0711 -0.0054,-2.6818 -0.199949,-1.2618 -0.839385,-3.0751 -1.195876,-3.3914 -0.324129,-0.2875 -0.671846,-0.3307 -1.031906,-0.1284 -0.496876,0.2792 -0.547131,0.6948 -0.179059,1.4805 0.135063,0.2883 0.343972,0.8922 0.464242,1.342 0.21768,0.8142 0.218674,0.8235 0.218674,2.0533 0,1.2298 -9.28e-4,1.2392 -0.218674,2.0533 -0.120272,0.4497 -0.325465,1.0465 -0.45599,1.3258 -0.315221,0.6747 -0.334073,0.7469 -0.256435,0.9821 0.160477,0.4864 0.778774,0.7737 1.195836,0.5557 z m -3.174159,-1.6681 c 0.186492,-0.1329 0.54841,-0.7896 0.691807,-1.2555 0.508888,-1.6532 0.377076,-3.2602 -0.388485,-4.7361 -0.327298,-0.6311 -0.615499,-0.8731 -1.039587,-0.8731 -0.674978,0 -0.899355,0.6963 -0.495246,1.5367 0.24473,0.5091 0.384292,1.1084 0.42106,1.808 0.03924,0.7467 -0.04997,1.3559 -0.198551,1.3559 -0.07304,0 -2.190719,-1.4926 -4.081753,-2.877 -1.1019127,-0.8066 -1.3287251,-0.9434 -1.5671351,-0.9452 -0.4533423,0 -0.7275993,0.4736 -0.9154451,1.5925 -0.1551399,0.924 -0.097393,1.9682 0.1566469,2.8324 0.1502703,0.5113 0.2975533,0.7419 0.6027144,0.9438 0.2927514,0.1937 0.5593056,0.2103 0.8029728,0.051 0.3564331,-0.2345 0.4157281,-0.6689 0.2187151,-1.6023 -0.1185758,-0.5619 -0.1563702,-1.0842 -0.083696,-1.1568 0.048046,-0.048 0.316088,0.09 0.775803,0.3986 0.396405,0.2664 2.231928,1.5694 3.043374,2.1604 1.077365,0.7846 1.270646,0.8934 1.587716,0.8936 0.19986,10e-5 0.347904,-0.04 0.469094,-0.1259 z"
- id="path3047"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/Resources/graphics/ic_action_qr_code.svg b/Resources/graphics/ic_action_qr_code.svg
deleted file mode 100644
index ebd147888..000000000
--- a/Resources/graphics/ic_action_qr_code.svg
+++ /dev/null
@@ -1,826 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
-
-<svg
- xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- version="1.1"
- id="Layer_1"
- x="0px"
- y="0px"
- width="48px"
- height="48px"
- viewBox="0 0 48 48"
- enable-background="new 0 0 48 48"
- xml:space="preserve"
- inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="ic_action_qr_code.svg"><metadata
- id="metadata231"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
- id="defs229"><linearGradient
- id="linearGradient4069"
- osb:paint="solid"><stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop4071" /></linearGradient>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<clipPath
- id="SVGID_61_"><use
- height="1052.3622"
- width="744.09448"
- y="0"
- x="0"
- style="overflow:visible"
- xlink:href="#SVGID_60_"
- overflow="visible"
- id="use374" /></clipPath><clipPath
- id="clipPath4193"><use
- height="1052.3622"
- width="744.09448"
- y="0"
- x="0"
- style="overflow:visible"
- xlink:href="#SVGID_60_"
- overflow="visible"
- id="use4195" /></clipPath><clipPath
- id="clipPath4197"><use
- height="1052.3622"
- width="744.09448"
- y="0"
- x="0"
- style="overflow:visible"
- xlink:href="#SVGID_60_"
- overflow="visible"
- id="use4199" /></clipPath><defs
- id="defs370"><rect
- height="96"
- width="96"
- y="2723.54"
- x="280.80499"
- id="SVGID_60_" /></defs><clipPath
- id="clipPath4204"><use
- id="use4206"
- overflow="visible"
- xlink:href="#SVGID_60_"
- style="overflow:visible"
- x="0"
- y="0"
- width="744.09448"
- height="1052.3622" /></clipPath></defs><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="2558"
- inkscape:window-height="1419"
- id="namedview227"
- showgrid="false"
- inkscape:zoom="33.823274"
- inkscape:cx="28.208613"
- inkscape:cy="27.105695"
- inkscape:window-x="0"
- inkscape:window-y="19"
- inkscape:window-maximized="1"
- inkscape:current-layer="Layer_1" />
-
-<path
- id="path376"
- d="m 341.16,2774.61 c 0,6.84 -5.543,12.385 -12.379,12.385 -6.84,0 -12.388,-5.545 -12.388,-12.385 0,-6.836 5.548,-12.381 12.388,-12.381 6.836,0 12.379,5.545 12.379,12.381"
- clip-path="url(#SVGID_61_)"
- inkscape:connector-curvature="0"
- style="fill:#333333;opacity:0.6"
- transform="matrix(0.42353916,0,0,0.42353916,-118.77231,-1156.4378)" /><path
- id="path378"
- d="m 362.412,2750.991 h -22.85 v -2.568 -3.051 h -21.309 v 3.051 2.568 c 0,0 -2.291,-0.037 -4.234,0 -1.943,0.032 -4.135,0.76 -4.135,0.76 l -14.708,4.752 c 0,0 0.034,2.062 0,3.537 -0.039,1.473 0,34.598 0,34.598 v 3.08 c 0,0 67.155,-0.01 67.235,0 0.084,0.01 0,-1.379 0,-3.08 v -40.566 -3.081 z m -33.631,41.713 c -9.998,0 -18.097,-8.102 -18.097,-18.092 0,-9.992 8.099,-18.096 18.097,-18.096 9.99,0 18.092,8.104 18.092,18.096 0,9.991 -8.102,18.092 -18.092,18.092"
- clip-path="url(#SVGID_61_)"
- inkscape:connector-curvature="0"
- style="fill:#333333;opacity:0.6"
- transform="matrix(0.42353916,0,0,0.42353916,-118.77231,-1156.4378)" /><polygon
- id="polygon380"
- points="308.727,2747.183 308.727,2748.132 308.727,2749.421 297.969,2753.065 297.969,2748.132 297.969,2747.183 "
- clip-path="url(#SVGID_61_)"
- style="fill:#333333;opacity:0.6"
- transform="matrix(0.42353916,0,0,0.42353916,-118.77231,-1156.4378)" /><rect
- style="fill-opacity:1;stroke:none;opacity:1;fill:#f2f2f2"
- id="rect3233"
- width="21.671467"
- height="21.582771"
- x="20.961897"
- y="21.184147" /><g
- id="g3200"><rect
- x="23.795828"
- y="23.795828"
- width="0.94412446"
- height="2.8319604"
- id="rect25"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="24.739952"
- y="23.795828"
- width="0.94412446"
- height="2.8319604"
- id="rect39"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="25.684488"
- y="23.795828"
- width="0.94371146"
- height="2.8319604"
- id="rect55"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="23.795828"
- y="37.011505"
- width="0.94412446"
- height="2.8319604"
- id="rect33"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="24.739952"
- y="37.011505"
- width="0.94412446"
- height="2.8319604"
- id="rect49"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="25.684488"
- y="37.011505"
- width="0.94371146"
- height="2.8319604"
- id="rect61"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- width="0.94371146"
- height="6.6080451"
- id="rect5"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- x="21.907991"
- y="21.907991" /><rect
- x="22.851704"
- width="0.94412446"
- height="0.94371146"
- id="rect13"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="22.851704"
- y="27.571913"
- width="0.94412446"
- height="0.94412446"
- id="rect15"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="23.795828"
- width="0.94412446"
- height="0.94371146"
- id="rect23"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="23.795828"
- y="27.571913"
- width="0.94412446"
- height="0.94412446"
- id="rect27"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="24.739952"
- width="0.94412446"
- height="0.94371146"
- id="rect37"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="24.739952"
- y="27.571913"
- width="0.94412446"
- height="0.94412446"
- id="rect41"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="25.684488"
- width="0.94371146"
- height="0.94371146"
- id="rect53"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="25.684488"
- y="27.571913"
- width="0.94371146"
- height="0.94412446"
- id="rect57"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="26.628201"
- width="0.94371146"
- height="0.94371146"
- id="rect65"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="26.628201"
- y="27.571913"
- width="0.94371146"
- height="0.94412446"
- id="rect67"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="27.571913"
- width="0.94412446"
- height="6.6080451"
- id="rect75"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- y="35.124081"
- width="0.94371146"
- height="6.6080451"
- id="rect11"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- x="21.907991" /><rect
- x="22.851704"
- y="35.124081"
- width="0.94412446"
- height="0.94371146"
- id="rect19"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="22.851704"
- y="40.788002"
- width="0.94412446"
- height="0.94412446"
- id="rect21"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="23.795828"
- y="35.124081"
- width="0.94412446"
- height="0.94371146"
- id="rect31"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="23.795828"
- y="40.788002"
- width="0.94412446"
- height="0.94412446"
- id="rect35"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="24.739952"
- y="35.124081"
- width="0.94412446"
- height="0.94371146"
- id="rect47"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="24.739952"
- y="40.788002"
- width="0.94412446"
- height="0.94412446"
- id="rect51"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="25.684488"
- y="35.124081"
- width="0.94371146"
- height="0.94371146"
- id="rect59"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="25.684488"
- y="40.788002"
- width="0.94371146"
- height="0.94412446"
- id="rect63"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="26.628201"
- y="35.124081"
- width="0.94371146"
- height="0.94371146"
- id="rect71"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="26.628201"
- y="40.788002"
- width="0.94371146"
- height="0.94412446"
- id="rect73"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="27.571913"
- y="35.124081"
- width="0.94412446"
- height="6.6080451"
- id="rect83"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.011505"
- y="23.795828"
- width="0.9445374"
- height="2.8319604"
- id="rect163"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.956043"
- y="23.795828"
- width="0.94371146"
- height="2.8319604"
- id="rect177"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="38.900169"
- y="23.795828"
- width="0.9445374"
- height="2.8319604"
- id="rect191"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="35.124081"
- width="0.94371146"
- height="6.6080451"
- id="rect141"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="36.067795"
- width="0.94371146"
- height="0.94371146"
- id="rect151"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="36.067795"
- y="27.571913"
- width="0.94371146"
- height="0.94412446"
- id="rect153"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.011505"
- width="0.9445374"
- height="0.94371146"
- id="rect161"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="37.011505"
- y="27.571913"
- width="0.9445374"
- height="0.94412446"
- id="rect165"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.956043"
- width="0.94371146"
- height="0.94371146"
- id="rect175"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="37.956043"
- y="27.571913"
- width="0.94371146"
- height="0.94412446"
- id="rect179"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="38.900169"
- width="0.9445374"
- height="0.94371146"
- id="rect189"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="38.900169"
- y="27.571913"
- width="0.9445374"
- height="0.94412446"
- id="rect193"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="39.844704"
- width="0.9432984"
- height="0.94371146"
- id="rect203"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="39.844704"
- y="27.571913"
- width="0.9432984"
- height="0.94412446"
- id="rect205"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="40.788002"
- width="0.94412446"
- height="6.6080451"
- id="rect217"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- y="29.459747"
- width="0.94371146"
- height="1.8882489"
- id="rect7"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- x="21.907991" /><rect
- x="22.851704"
- y="33.235832"
- width="0.94412446"
- height="0.9445374"
- id="rect17"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="23.795828"
- y="30.403872"
- width="0.94412446"
- height="2.8315473"
- id="rect29"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="24.739952"
- y="30.403872"
- width="0.94412446"
- height="0.94412446"
- id="rect43"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="24.739952"
- y="32.292122"
- width="0.94412446"
- height="1.8882489"
- id="rect45"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="26.628201"
- y="31.347998"
- width="0.94371146"
- height="0.94412446"
- id="rect69"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="27.571913"
- y="29.459747"
- width="0.94412446"
- height="0.94412446"
- id="rect77"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="27.571913"
- y="31.347998"
- width="0.94412446"
- height="0.94412446"
- id="rect79"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="27.571913"
- y="33.235832"
- width="0.94412446"
- height="0.9445374"
- id="rect81"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="28.516037"
- y="30.403872"
- width="0.94412446"
- height="1.8882489"
- id="rect85"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="29.460161"
- y="22.851704"
- width="0.94412446"
- height="2.8319604"
- id="rect87"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="29.460161"
- y="27.571913"
- width="0.94412446"
- height="7.5521693"
- id="rect89"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="29.460161"
- y="40.788002"
- width="0.94412446"
- height="0.94412446"
- id="rect91"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="30.404285"
- width="0.94371146"
- height="0.94371146"
- id="rect93"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="30.404285"
- y="25.684076"
- width="0.94371146"
- height="0.94412446"
- id="rect95"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="30.404285"
- y="32.292122"
- width="0.94371146"
- height="2.8319604"
- id="rect97"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="30.404285"
- y="36.067795"
- width="0.94371146"
- height="0.94371146"
- id="rect99"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="30.404285"
- y="37.956043"
- width="0.94371146"
- height="3.7760847"
- id="rect101"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="31.347998"
- y="24.739952"
- width="0.94412446"
- height="0.94371146"
- id="rect103"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="31.347998"
- y="29.459747"
- width="0.94412446"
- height="2.8319604"
- id="rect107"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="32.292122"
- width="0.94371146"
- height="0.94371146"
- id="rect113"
- style="opacity:0.6;fill:#333333;fill-opacity:1"
- y="21.907991" /><rect
- x="32.292122"
- y="28.516037"
- width="0.94371146"
- height="0.94371146"
- id="rect117"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="32.292122"
- y="31.347998"
- width="0.94371146"
- height="0.94412446"
- id="rect119"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="32.292122"
- y="34.18037"
- width="0.94371146"
- height="0.94371146"
- id="rect121"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="32.292122"
- y="36.067795"
- width="0.94371146"
- height="0.94371146"
- id="rect123"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="32.292122"
- y="40.788002"
- width="0.94371146"
- height="0.94412446"
- id="rect125"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="33.235832"
- y="22.851704"
- width="0.94412446"
- height="1.8882489"
- id="rect127"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="33.235832"
- y="25.684076"
- width="0.94412446"
- height="5.6643338"
- id="rect129"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="33.235832"
- y="34.18037"
- width="0.94412446"
- height="4.7197962"
- id="rect131"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="34.179958"
- y="33.235832"
- width="0.94412446"
- height="1.8882489"
- id="rect135"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="34.179958"
- y="36.067795"
- width="0.94412446"
- height="0.94371146"
- id="rect137"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="34.179958"
- y="40.788002"
- width="0.94412446"
- height="0.94412446"
- id="rect139"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="35.124081"
- y="31.347998"
- width="0.94371146"
- height="0.94412446"
- id="rect145"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="35.124081"
- y="38.900169"
- width="0.94371146"
- height="0.9445374"
- id="rect149"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="36.067795"
- y="30.403872"
- width="0.94371146"
- height="2.8315473"
- id="rect155"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="36.067795"
- y="36.067795"
- width="0.94371146"
- height="1.8882489"
- id="rect157"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.011505"
- y="33.235832"
- width="0.9445374"
- height="0.9445374"
- id="rect169"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.011505"
- y="35.124081"
- width="0.9445374"
- height="1.8874229"
- id="rect171"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.011505"
- y="37.956043"
- width="0.9445374"
- height="3.7760847"
- id="rect173"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.956043"
- y="29.459747"
- width="0.94371146"
- height="0.94412446"
- id="rect181"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.956043"
- y="31.347998"
- width="0.94371146"
- height="1.8874229"
- id="rect183"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.956043"
- y="36.067795"
- width="0.94371146"
- height="0.94371146"
- id="rect185"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="37.956043"
- y="39.844704"
- width="0.94371146"
- height="0.9432984"
- id="rect187"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="38.900169"
- y="29.459747"
- width="0.9445374"
- height="3.7760847"
- id="rect195"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="38.900169"
- y="34.18037"
- width="0.9445374"
- height="0.94371146"
- id="rect197"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="38.900169"
- y="36.067795"
- width="0.9445374"
- height="0.94371146"
- id="rect199"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="38.900169"
- y="37.956043"
- width="0.9445374"
- height="2.8311343"
- id="rect201"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="39.844704"
- y="29.459747"
- width="0.9432984"
- height="0.94412446"
- id="rect207"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="39.844704"
- y="31.347998"
- width="0.9432984"
- height="2.8319604"
- id="rect209"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="39.844704"
- y="35.124081"
- width="0.9432984"
- height="0.94371146"
- id="rect211"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="39.844704"
- y="40.788002"
- width="0.9432984"
- height="0.94412446"
- id="rect215"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="40.788002"
- y="32.292122"
- width="0.94412446"
- height="0.94371146"
- id="rect219"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="40.788002"
- y="36.067795"
- width="0.94412446"
- height="1.8882489"
- id="rect223"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /><rect
- x="40.788002"
- y="38.900169"
- width="0.94412446"
- height="0.9445374"
- id="rect225"
- style="opacity:0.6;fill:#333333;fill-opacity:1" /></g></svg> \ No newline at end of file
diff --git a/Resources/graphics/ic_launcher.png b/Resources/graphics/ic_launcher.png
deleted file mode 100644
index a7b133eb9..000000000
--- a/Resources/graphics/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/Resources/graphics/originals/ic_action_nfc/NFC.png b/Resources/graphics/originals/ic_action_nfc/NFC.png
deleted file mode 100644
index 96af64049..000000000
--- a/Resources/graphics/originals/ic_action_nfc/NFC.png
+++ /dev/null
Binary files differ
diff --git a/Resources/graphics/update-drawables.sh b/Resources/graphics/update-drawables.sh
deleted file mode 100755
index b8d2ffc88..000000000
--- a/Resources/graphics/update-drawables.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/bash
-
-APP_DIR=../../OpenKeychain/src/main
-LDPI_DIR=$APP_DIR/res/drawable-ldpi
-MDPI_DIR=$APP_DIR/res/drawable-mdpi
-HDPI_DIR=$APP_DIR/res/drawable-hdpi
-XDPI_DIR=$APP_DIR/res/drawable-xhdpi
-XXDPI_DIR=$APP_DIR/res/drawable-xxhdpi
-XXXDPI_DIR=$APP_DIR/res/drawable-xxxhdpi
-PLAY_DIR=./
-
-
-# Launcher Icon:
-# -----------------------
-# ldpi: 36x36
-# mdpi: 48x48
-# hdpi: 72x72
-# xhdpi: 96x96
-# xxhdpi: 144x144.
-# xxxhdpi 192x192.
-# google play: 512x512
-
-NAME="ic_launcher"
-
-inkscape -w 36 -h 36 -e "$LDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 48 -h 48 -e "$MDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 72 -h 72 -e "$HDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 96 -h 96 -e "$XDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 144 -h 144 -e "$XXDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 192 -h 192 -e "$XXXDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 512 -h 512 -e "$PLAY_DIR/$NAME.png" $NAME.svg
-
-# Actionbar Icons
-# -----------------------
-# mdpi: 32x32
-# hdpi: 48x48
-# xhdpi: 64x64
-# xxhdpi: 96x96
-
-for NAME in "ic_action_nfc" "ic_action_qr_code" "ic_action_safeslinger" "ic_action_search_cloud"
-do
-echo $NAME
-inkscape -w 32 -h 32 -e "$MDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 48 -h 48 -e "$HDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 64 -h 64 -e "$XDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 96 -h 96 -e "$XXDPI_DIR/$NAME.png" $NAME.svg
-done
-
-for NAME in status*.svg
-do
-echo $NAME
-inkscape -w 24 -h 24 -e "$MDPI_DIR/${NAME%%.*}.png" $NAME
-inkscape -w 32 -h 32 -e "$HDPI_DIR/${NAME%%.*}.png" $NAME
-inkscape -w 48 -h 48 -e "$XDPI_DIR/${NAME%%.*}.png" $NAME
-inkscape -w 64 -h 64 -e "$XXDPI_DIR/${NAME%%.*}.png" $NAME
-done
-
-for NAME in key_flag*.svg
-do
-echo $NAME
-inkscape -w 24 -h 24 -e "$MDPI_DIR/${NAME%%.*}.png" $NAME
-inkscape -w 32 -h 32 -e "$HDPI_DIR/${NAME%%.*}.png" $NAME
-inkscape -w 48 -h 48 -e "$XDPI_DIR/${NAME%%.*}.png" $NAME
-inkscape -w 64 -h 64 -e "$XXDPI_DIR/${NAME%%.*}.png" $NAME
-done
-
-for NAME in "create_key_robot"
-do
-echo $NAME
-inkscape -w 48 -h 48 -e "$MDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 64 -h 64 -e "$HDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 96 -h 96 -e "$XDPI_DIR/$NAME.png" $NAME.svg
-inkscape -w 128 -h 128 -e "$XXDPI_DIR/$NAME.png" $NAME.svg
-done \ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 17e112d68..f8e6afc27 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,13 +5,18 @@ buildscript {
dependencies {
// NOTE: Always use fixed version codes not dynamic ones, e.g. 0.7.3 instead of 0.7.+, see README for more information
- classpath 'com.android.tools.build:gradle:1.0.0-rc3'
+ classpath 'com.android.tools.build:gradle:1.0.0'
}
}
allprojects {
repositories {
jcenter()
+
+ maven {
+ // for https://github.com/journeyapps/zxing-android-embedded
+ url "http://dl.bintray.com/journeyapps/maven"
+ }
}
}
diff --git a/extern/minidns b/extern/minidns
-Subproject f3a19080f15e220fbacab5045c1f15fd12513b3
+Subproject 969ffd2951fcaa07f46b441936a0c0fd4502daf
diff --git a/extern/openkeychain-api-lib b/extern/openkeychain-api-lib
-Subproject 0cdbf32231739eac47999be71d6d01fc2837518
+Subproject 88c00479329c1aa892bef052f3f8830067c386d
diff --git a/extern/openpgp-api-lib b/extern/openpgp-api-lib
-Subproject e0ad1086a55eab66d963b4d5c6ca5544b454ef2
+Subproject c866dc22bcfa004ec2c46bc86c08694e76d1058
diff --git a/extern/safeslinger-exchange b/extern/safeslinger-exchange
-Subproject 80beccbe1b95437040b201a37f40cdb50053c06
+Subproject 96f7c893565e3a8badd740b2035beea87d8bffb
diff --git a/extern/spongycastle b/extern/spongycastle
-Subproject 375084d55341b575274e49d9a69fa4cf9356682
+Subproject 939914d9ffd1e8cc2710de6c600c9ccfc86aa54
diff --git a/prepare-tests.sh b/prepare-tests.sh
deleted file mode 100755
index 623c4a233..000000000
--- a/prepare-tests.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# This script installs a plugin which is necessary to run OpenKeychain's tests
-# into the local maven repository, then puts a line to include the -Test
-# subproject into settings.gradle
-
-echo "checking jdk runtime.."
-if ! java -version 2>&1 | grep OpenJDK; then
- echo "tests will only run on openjdk, see readme for details!" >&2
- return
-fi
-
-#tmpdir="$(mktemp -d)"
-#(
-# cd "$tmpdir";
-# git clone https://github.com/nenick/gradle-android-test-plugin.git
-# cd gradle-android-test-plugin
-# echo "rootProject.name = 'gradle-android-test-plugin-parent'" > settings.gradle
-# echo "include ':gradle-android-test-plugin'" >> settings.gradle
-# ./gradlew :gradle-android-test-plugin:install
-#)
-#rm -rf "$tmpdir"
-
-echo -n "ok, adding tests to include list.. "
-if grep OpenKeychain-Test settings.gradle >/dev/null ; then
- echo " already in."
-else
- echo "include ':OpenKeychain-Test'" >> settings.gradle
- echo "ok"
-fi
diff --git a/settings.gradle b/settings.gradle
index b51bdc94d..d12c56b58 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,8 +3,6 @@ include ':extern:openpgp-api-lib'
include ':extern:openkeychain-api-lib'
include ':extern:html-textview'
include ':extern:StickyListHeaders:library'
-include ':extern:zxing-qr-code'
-include ':extern:zxing-android-integration'
include ':extern:spongycastle:core'
include ':extern:spongycastle:pg'
include ':extern:spongycastle:pkix'
@@ -14,3 +12,5 @@ include ':extern:minidns'
include ':extern:KeybaseLib:Lib'
include ':extern:TokenAutoComplete:library'
include ':extern:safeslinger-exchange'
+include ':extern:android-lockpattern:code'
+include ':OpenKeychain-Test'