Encrypted Images is distributed under the MIT Lice2nse. [](https://opensource.org/licenses/MIT)
2. [Supperted Characters and Encryption Information](#supported-characters)
3. [Min and Max Characters Requirements](#min--max-requirements)
4. [Encrypting Text]()
- [Encryption Settings](#encryption-settings)
5. [Decrypting Text]()
6. [Encoding Images](#encoding-images)
- [Styles](#styles)
- [Watermarks](#watermarks)
- [Watermark Settings](#watermark-settings)
- [Gradient Settings](#gradient-settings)
7. [Decoding Images](#decoding-images)
8. [Functions](#functions)
## Introduction
`encrypted_images` is a Rust crate that allows you to perform plainttext to encryption and then into images as well as from encrypted image to cipher text to decrpyted original text. It supports advanced options of security, watermarking, customized gradient outputs, and output positioning styles.
+ `input`&str: This is the text you want to encrypt. It is protected against timing attacks by default but in its default form is only intended for novelty use where the actual encrpytion process is less important, such as encrypting a wallet address to encode as an image. The data is not sensative so novelty use is accepted. For security, optional perameters should be used.
### Encryption Settings
+ `key` Option<&str>: Our default key is prebuilt into the encryption process. It is only intended for novelty usage. If you are seeking true encrpyted image security this key should be changed to a key of 16 characters in length.
+ `strength` Option<&str>: Because this crate works for both novelty and true encryption, the default strength is not secure.
- default: This setting is the default option if None us used. It allows for novelty usage. This will return the exact same encrypted cipher from the same input every time.
- advanced: Advanced will return a different cipher from the same input every time. This protects against comparison attacks.
## Encoding Images
Image encoding has 9 parameters, 6 are Options. Although you can convert any text to image it must first be base64 encoded. Not encoding to base64 may cause decoding to fail. All options are defined below.
+ `ciphertext`&str: The base64 encoded text you wish to encrypt.
+ `style`&str: The orientation you wish to output the image
+ `watermark`&str: The watermark you wish to use
### Styles
These are the style choices. A style must be selected. For standard usage h should be used.
- h: This is the default upright position of an image. First character of cipher is pixel (0,0)
- h2: This is the image flipped vertically so the bottom row contains cipher. Changes direction of gradient. Firch Character of cipher is pixel (height, 0)
- v: This is the image flipped 90 degrees so the veritical left column contains cipher. Changes direction of gradient. First character of cipher is pixel (0,width)
- v2: This is the image flipped 270 degrees and flipped vertically so the veritical right column contains cipher. Changes direction of gradient. First character of cipher is pixel (0,0)
### Watermarks
These are the choices for watermarks. A watermark must be selected. If you do not wish to use a watermark use the "empty" choice.
- empty: no watermark
- bitcoin: default bitcoin watermark
- ethereum: default ethereum watermark
- cardano: default cardano watermark
- base64 encoded watermark: custom watermark
#### Watermark Settings
When using a custom base64 watermark, these are the optional setting you have. These settings MUST be present when using a custom watermark. They have no effect on default watermarks and should be set to None.
+ `a` Option<u8> (Range 0 - 255): Used to adjust the alpha change of an image. We do this through a very customized method that adjusts the type of alpha based on the image used. In images with transparent background, it only adjusts the alpha change of the background. If the image has no full transparancy as its background, alpha is applied to the image as a whote.
+ `w` Option<u32>: Width of watermark. Should not excede the width of the image. The watermark will always be placed at the center of the image.
+ `h` Option<u32>: Height of watermark. Should not excede the heigth of the image. The watermark will always be placed at the center of the image.
### Gradient Settings
Gradient settings are entirely optional. Configuring them is tricky to manipulate. Each of these values are turned into gradient with out custom gradient formula. Results may not be as expected. If you wish to use the defaults, set these to None.
+ `r` Option<u8> (Range 0 - 255): r represents the first color of the gradient pattern. Understand this represents the "r" of rgb, not an actual color. Play with the r, g and b values to create various unique gradients.
+ `g` Option<u8> (Range 0 - 255): g represents the first color of the gradient pattern. Understand this represents the "g" of rgb, not an actual color. Play with the r, g and b values to create various unique gradients.
+ `b` Option<u8> (Range 0 - 255): b represents the first color of the gradient pattern. Understand this represents the "b" of rgb, not an actual color. Play with the r, g and b values to create various unique gradients.
## Decoding Images
Decoding is straight forword. It only offers a single paramenter. That parameter is the encoded image. The orientation style of the image does not matter as long as as it matches one of the styles from the image encoding process.
use encrypted_images::encryption::images::create_img;
fn main() {
let ciphertext = "VkdocGN5QkpjeUJRYkE9PZNY2MOW01NWpSxCtFG6acHuAWun+CElPQ/IIwd0gy+D+IiBqB/5+qo8Jr9bMBOwoih3amCtjXlkAlRKHX5fhqI=";
let style = "h";
let watermark = "iVBORw0KGgoAAAANSUhEUgAACqMAAAqjCAYAAACgs6lKAAAACXBIWXMAAAsTAAALEwEAmpwYAAAgAElEQVR42uzau69cVxnG4WMcKaQgJA0EEBIQQxRm5jgkokgBBKhTnpJI3EwVoVDgKJ49mtJtSrcpLVGlNB2GiJJbKMOlgihKFPvMHluyh3PkAEl8O5dv1uy1vueRfv/ALtanLb1bq9VqS5I0zAA4vHG3/NW461eStIlGXf/WpFue2dlZnfQiAwAAAADEsSGQpIHvnHwESTJGBWiJMaqkgfSXyWyxs/fXfcLLDAAAAABwfDYEkmSMKkkyRgUoxhhV0qCaLv5wa5QKAAAAAMBx2BBIkjGqJMkYFaAYY1RJA+13o2n/Pa80AAAAAMDR2BBIkjGqJMkYFaAYY1RJA+/ydtd/y2sNAAAAAHA4NgSSZIwqSTJGBSjGGFVSJV3anu8+7dUGAAAAADgYGwJJMkaVJBmjAhRjjCqpom7uvVkXt6fLJ7zeAAAAAAD3ZkMgScaokiRjVIBijFElVdiN/VHqeLp83CsOAAAAAHBnNgSSZIwqSTJGBSjGGFVSxV0fdf2F0+cWX/CaAwAAAAB8lA2BJBmjSpKMUQGKMUaV1EDX9kepo/nVx7zqAAAAAAC32BBIkjGqJMkYFaAYY1RJDXV1NFuen7z83qNedwAAAAAgOxsCSTJGlSQZowIUY4wqqcHe3x+lnpqvHvbKAwAAAABZ2RBIkjGqJMkYFaAYY1RJDff2ZLo4++xLq4e89gAAAABANjYEkmSMKkkyRgUoxhhVUoL+tT9KPfXi6kGvPgAAAACQhQ2BJBmjSpKMUQGKMUaVlKi/T7rlmefmqwe8/gAAAABA62wIJMkYVZJkjApQjDGqpIT9ddT1L+zsrE66AgAAAABAq2wIJMkYVZJkjApQjDGqpKxNuv7Pk9liZ+9P/4RrAAAAAAC0xoZAkoxRJUnGqADFGKNKSt+s//1otnzeRQAAAAAAWmJDIEnGqJIkY1SAYoxRJel/o9Tfjmb9d10GAAAAAKAFNgSSZIwqSTJGBSjGGFWSbuvSqNv9pgsBAAAAANTMhkCSjFElScaoAMUYo0rS3UepX+92v+FSAAAAAAA1siGQJGNUSZIxKkAxxqiSdM9u7L2TF0/Pl19zMQAAAACAmtgQSJIxqiTJGBWgGGNUSTr4KHU8XT7ucgAAAAAANbAhkCRjVEmSMSpAMcaoknSoro+6/sIT893PuyAAAAAAwJDZEEiSMaokyRgVoBhjVEk6UrvjbvHq+JWrn3VJAAAAAIAhsiGQJGNUSZIxKkAxxqiSdKyujGbL80/N333ERQEAAAAAhsSGQJKMUSVJxqgAxRijSlJI74xn/fzUfPWwywIAAAAADIENgSQZo0qSjFEBijFGlaTQ3p5MF2effWn1kAsDAAAAAGySDYEkGaNKkoxRAYoxRpWktfTP8XT581Mvrh50aQAAAACATbAhkCRjVEmSMSpAMcaokrTW/jbplmd2dlYnXRwAAAAAoCQbAkkyRpUkGaMCFGOMKklFenPU9S9szVefcHkAAAAAgBJsCCTJGFWSZIwKUIwxqiQVbNr/aTJb7GxtrU64QAAAAADAOtkQSJIxqiTJGBWgGGNUSdpAs/6N0Wz5vCsEAAAAAKyLDYEkGaNKkoxRAYoxRpWkjXZ50vXfcY0AAAAAgGg2BJJkjCpJMkYFKMYYVZIG0aVJt/uMqwQAAAAARLEhkCRjVEmSMSpAMcaokjSYbo67xeuj7vpp1wkAAAAAOC4bAkkyRpUkGaMCFGOMKkmD68be23zxyenyq64UAAAAAHBUNgSSZIwqSTJGBSjGGFWSBtv18bR/bTJffsW1AgAAAAAOy4ZAkoxRJUnGqADFGKNK0uC7Nur6C0++svs5VwsAAAAAOCgbAkkyRpUkGaMCFGOMKknVtDvuFq9uz698xvUCAAAAAO7HhkCSjFElScaoAMUYo0pSdV0ZzZbnn5q/+4grBgAAAADcjQ2BJBmjSpKMUQGKMUaVpGp7Zzzr50/8cvUp1wwAAAAA+DgbAkkyRpUkGaMCFGOMKknV9+/JdHH2S/PVJ101AAAAAOC/bAgkyRhVkmSMClCMMaokNdM/Jt3yzHPz1QOuGwAAAABgQyBJxqiSJGNUgGKMUSWprUZd/9b+KHVnZ3XSlQMAAACAvGwIJMkYVZJkjApQjDGqJDXbm5PZYmdra3XCtQMAAACAfGwIJMkYVZJkjApQjDGqJDXfH2+NUgEAAACATGwIJMkYVZJkjApQjDGqJCVp1r+xPeu/7/IBAAAAQA42BJJkjCpJMkYFKMYYVZLSdXlyrv+2CwgAAAAAbbMhkCRjVEmSMSpAMcaokpS2S9vz3addQgAAAABokw2BJBmjSpKMUQGKMUaVpNTdHHeL18fza9suIgAAAAC0xYZAkoxRJUnGqADFGKNKkva6sXcPLo7my1MuIwAAAAC0wYZAkoxRJUnGqADFGKNKkj7U9fG0f2172n/ZhQQAAACAutkQSJIxqiTJGBWgGGNUSdIdujbq+guj+dXHXEoAAAAAqJMNgSQZo0qSjFEBijFGlSTdo6uj2fL85OX3HnUxAQAAAKAuNgSSZIwqSTJGBSjGGFWSdIDe3x+lPnN29WmXEwAAAADqYEMgScaokiRjVIBijFElSQdt1PW/djkBAAAAoA42BJJkjCpJMkYFKMYYVZJ04Gb9b1xOAAAAAKiDDYEkGaNKkoxRAYoxRpUkGaMCAAAAQHtsCCTJGFWSZIwKUIwxqiTJGBUAAAAA2mNDIEnGqJIkY1SAYoxRJUnGqAAAAADQHhsCSTJGlSQZowIUY4wqSTJGBQAAAID22BBIkjGqJMkYFaAYY1RJkjEqAAAAALTHhkCSjFElScaoAMUYo0qSjFEBAAAAoD02BJJkjCpJMkYFKMYYVZJkjAoAAAAA7bEhkCRjVEmSMSpAMcaokiRjVAAAAABojw2BJBmjSpKMUQGKMUaVJBmjAgAAAEB7bAgkyRhVkmSMClCMMaokyRgVAAAAANpjQyBJxqiSJGNUgGKMUSVJxqgAAAAA0B4bAkkyRpUkGaMCFGOMKkkyRgUAAACA9tgQSJIxqiTJGBWgGGNUSZIxKgAAAAC0x4ZAkoxRJUnGqADFGKNKkoxRAQAAAKA9NgSSZIwqSTJGBSjGGFWSZIwKAAAAAO2xIZAkY1RJkjEqQDHGqJIkY1QAAAAAaI8NgSQZo0qSjFEBijFGlSQZowIAAABAe2wIJMkYVZJkjApQjDGqJMkYFQAAAADaY0MgScaokiRjVIBijFElScaoAAAAANAeGwJJMkaVJBmjAhRjjCpJMkYFAAAAgPbYEEiSMaokyRgVoBhjVEmSMSoAAAAAtMeGQJKMUSVJxqgAxRijSpKMUQEAAACgPTYEkmSMKkkyRgUoxhhVkmSMCgAAAADtsSGQJGNUSZIxKkAx41n/g3HX3zCykiQZowIAAABAO2wIJMkYVZJkjApQ1GTW/9AgVZJkjAoAAAAA7bAhkCRjVEmSMSpAcQapkiRjVAAAAABohw2BJBmjSpKMUQE2wiBVkmSMCgAAAABtsCGQJGNUSZIxKsDGGKRKkoxRAQAAAKB+NgSSZIwqSTJGBdgog1RJkjEqAAAAANTNhkCSjFElScaoABtnkCpJMkYFAAAAgHrZEEiSMaokyRgVYBAMUiVJxqgAAAAAUCcbAkkyRpUkGaMCDIZBqiTJGBUAAAAA6mNDIEnGqJIkY1SAQTFIlSQZowIAAABAXWwIJMkYVZJkjAowOAapkiRjVAAAAACohw2BJBmjSpKMUQEGadz1PzJIlSRjVAAAAABg+GwIJMkYVZJkjAowWAapkmSMCgAAAAAMnw2BJBmjSpKMUQEGzSBVkoxRAQAAAIBhsyGQJGNUSZIxKsDgGaRKkjEqAAAAADBcNgSSZIwqSTJGBaiCQaokGaMCAAAAAMNkQyBJxqiSJGNUgGoYpEqSMSoAAAAAMDw2BJJkjCpJMkYFqIpBqiQZowIAAAAAw2JDIEnGqJIkY1SA6hikSpIxKgAAAAAwHDYEkmSMKk
let r = Some(100);
let g = Some(134);
let b = Some(137);
let a = Some(0);
let w = Some(32);
let h = Some(32);
if let Some(encoded_image) = create_img(ciphertext, style, watermark, r, g, b, a, w, h) {
Decode an image and extracts original text from it.
`cargo run --example decode_image`
```rust
use encrypted_images::decryption::images::decode_image_and_extract_text;
fn main() {
let encoded_image = "iVBORw0KGgoAAAANSUhEUgAAAGwAAABsCAYAAACPZlfNAAA3rklEQVR4nO3deWxcW34n9u9dat+ryFpY3JeiJGqhpLfoLXS3uttre2L3xJPxuB0HjoNkepAgHiQzCBIgSJwAGTjOJJ5BkHiWbJ7ECyaDAJN0HMNu9/L6vX79+kmiRFEiRZHFnSyyWFVk7XWrbr7n3kOyROm9fpjpf9jgARqtEsmqOudz7zm/haqnBAffNT0791Bqt+DpuYFSyo2ku4bmsg70FgBzGb7CHezmPoQjM4Kx517kMh24Fx9j72YAsUeDyI0r6Dyeh3PYiajnFvaDDxF8cITmyDiqmgdOVYFurMLwDqL9YB7m7V4E9DhaB1U0nq0AYyOIu3cAbxnlfAwlNYmwaw3G5iX09jqwGK0i0VJgrurojD9EalbF83oT3jf5+L2rqCWz8IWAWovfV7+K7aGniK1cw+7ABzAdExBDM57Dlb2B1ugWQo0+1NseNHJP4U31o7q9wb+PQTOXoO/2w3cURiVQRDO2Dn9ZQb0QQaCdxm6fHwllB2XnPlqOHiSLKeR8B/BWttCshaDGQmgq86g33oTb+z2ohhNeZRp5Zx3hj+egD4asuV1a0rAe0BB161jn2l/yOfl6V9Eq1LBqLCEZu4Zm04CSmEXKOYAV5y4C2QwOJupQAgPvmL7cPRRaLfgIVngJLItA4Q1sS7AJgu0QzLv0BLs3fOgl2M4JmBs9nmnkCBYmWH3kFWAPn8K8GUOIYA0B9nwVGBniawqwKg7zEWtSx2AJgj3tAsP4HFKPVDwjmP91HcZ7V7rA6kjVr2CTYL0E234BbAWe7DU0PhVsGc7dPngIViNY3QLTCBY6AUsR7FCC9RFsx2eDGQSDBfaUYK8T7PsE018JdoVgqwTrIdgqwa4E3Kj4rthgnSXEI8dgj5B2pvG8G8zf/7YZ2L+HfKOFAMHyL4GtIVR4DZsSbJJgWwTzLy9g+5oHCYJtnYB5Efdcxw7BogSrjrwCbG4R5o0IIgSrCbCVdWBoAH0WWB3FvD2pY7AUwea7wNTxeaQeq1ggWPC2jub7l1CLH4M1ka5fwjrBEgTbfAFsFb7sFGqfCpaFezcJF8EaBKvGBJiDYIETsDTBihKsn2BbEqxDsI4Ftkiw2wT7AcHUV4JdJdgKweIEWyHY1ZAXFc8lGwxL6Akdgz3GgDOFZ91gvvRbZujgHvZqLYQkWPwFsA1ECrewLsEuE2yDYMHsM2xOuXi1D2LjBMyPpOcqtgjW86CC8sjoy2DzSzCvhRAjWEWArW4CA2n0W2BNHOQD1qSOwdIEm+sC08efIvVExROChW/qqH8vg1rPMZiBgXoGqwRLEWz9BbB1TvoyKp8KtgbvbhwOgrUIVrbAXATzWWB7EuxAgg0SbEOCgWCGBbaEZuMmnN57BOOUXgF2nWDPCZYk2HOCXY/4UXFlbDB1CdHAMdgTDDkTWHB2gXn77piR4j3sEiwStcF6XgDbQqwwjdV9go2PYIpgawQLrz3H+mUH0gRbE2BPCDYYRJ/nCjYIFn9Qw+HI8MtgT5dhTgXQS7CjA4KtbwPpFAYtMAP7eZ81qWOwAQnW27LBnOOLSC2oeEyw6A0d1e+PoxY9ButgqD6OFYKlCbY68CHBxiCGZmwilJ3E0aeCbcC/2wONYG2CHcY2JZjHAstLsH0JNkywNZ8NphKsGeP/lGUYjRvQvQ8IxqODYAWCBbvApgn2jGB9BHuWu4fpSBAVx7gNpi8h7DsGW8CIsxdPusE8qTfN2OE9bBMsFrbBoi+A7fD/rmPlgGCjI7hGsCzBohsrWJ3UMECwrABbIFh/GP28tdcIlnzQQHFk8GWwxSzMyz4kCFYSYJu7QCqBYQusg1zeY00qLMGGJFisZYO5x5eQeqbiEcF6ruko/2AUtfAxGI/D+iieE2yAYCsDHxFshFwCbBuR7ARKnwq2heBuFArBTIIVY9sSzGWBFSRYToKNEizrs8F0gtUtsCw6jWtQvQ8JZlhgJYL5u8BuEWyBYP0EW+BxdCvCIEcbtcGcSwh6jsGeYcwZw+NuMHfyDbO3fA+btTZ6g9cssPALYDkkClfxvPgRHMNDuEGw5UwHPVurWJlQMESw5XGCPXsKZ18Yg54MsgTre9DCwQgX4yzY0hrMSQ9SBCsIsO09MLLAqAUG7ORd1qSOwUYkWKRlg3nHl5F6rmKWYPEpHYf3hlELHoOpGKsP4xnBhgj2fOBjgg2RS4DtIpYdQ+FTwXYQ3iUWwRSCHcR2JZjDAitJsB0JNk6wZQnmJFjVAlsDGlOcyxzBGMkS7Ihg3i6w1wj2hGCDBHty8ACvCTBl2AZzL8HvOgZ7jglnBI+6wVyJ181E9R7WayYS/ikLLPgC2D5ShSt4dvgxHIMDuLnixdJ4B/GddTwfMzFCsCUB9nwRzmQYw55xLBOs/0Eb+yN9L4Mtb8CccCFNsLwA283zdWIYt8BUbOUd1qSOwcYkWKhlg/nHszyfVNwnWPKyjuKDQdT8x2A6JuqDWCDYCMGeDdwn2ADE0Iw99GZHkP9UsByiu0G0CaYRbD+2J8E0C+xIgm1JsAzBliSYm2BlC2wDauMyOt55gtUtsArB3B/PE8w+n99Y1vDYp3FX0fG4+BBvCDBz0AbzLsHrOAZbwaQzhNluMGf8NTNVv4fVmoKU97IF5n8B7ADpwiUslO/D0Z/G7VUvFkc7SOY28WykjTGCLQqwlSU442GMekaxRLDBByZyI8mXwbJbMMccGCDYngDb42vEIshYYDo28po1qWOwCQkWaCkWWHB8DalVFR8TrG9Sx8HDftS8x2BOTNb78YRgYyvXsDAwC8WRJhegGHkkskPY+wSwNsEUXpw9u360COYgWC6Wl2CKBVaRYBsS7BLBFiWYl2CHFhi3x8Yk5/oUqlG1wGrOOpwfPyWYfT7fyWp45NG4q+h4dDiHOwKs3W+D+Zfg1o7BVnHZGcB9CVacIJij97aZbgowDSn3pAXmfQGsiIFCBgvVWWh9Kby+7sXT4Q769rd5JbcwQbCnBMPqMvSeMMY9w1gk2PADBTsj8ZfB1nZgjmgYItiuAMuXgEgIlywwJ9byCo7UJIISbFKC+Vo2WHh8A6l1FR8RrH9Cx/5cH2ruYzA3Ltf78JhgExbYI04wRS5OwygglR3A7ieAmQQzeXHGd71oEMxlgRXgtcBMC6wmwdYI1pZgTyWYvxbimSfAduBsTKDpXSRY2QJrEEz/eJFgHmtud9Y0zLo07ioEK8/bYK0+GyzIC185BlvHlNOHjyXY4QTB9J5b5oAhwBzMqicsMPcLYIcYKowz7+Hkkwm8uenF/GAH/Qe7eDLQwCTB5gmmrmehRsPIeAhIsNEHGrZGel4G28jBHFIwQrBtAVY4AkIBXLHA3MjmTVTUJPdxG+yyBPO0bLDo+BZSmyo+JNjgmI7cfJJX8DGYF1P1JB4RbNICe0ywBLmAtlFCOpvG9ieAKQRr8+JM7rpRI5jHAivBbYG1LbCGBMsSzJRg8xIsSLADCywHd2MMdW5tqnFogbUIpn7MKsqgy5rbnQ0N9x0adxWCVZ/aYI2kDRbm95nHYJu45vTgIwlWniCYFrtpDnUe2GD6mAXmfAGsjJHCKBaaj2HGe/HWthdz/R3mIHt4nK7h8mOCjRJsk4dtOIxLnn7ME2z8oQMbQ1HUCaarXWBbnOyAiTGCbQqwUgUI+HDVAmNAk2+jpibhlWBTEszVssF6xneQ2lbxAcGGR3TsPGUCrh+D+XGtHsfs0FNcXhFgTwjWSy4BdkSwFDY/AUyzwA4JxjIRwXwW2BGcFhiLCgRrSbBl5z6f9xTMTbAwwfYJZij7BBsh2DJggV1Hm2C4zx2o32HN7c6Who81jbsKweqLNliNpbqSAFuG2p6SYNu44XThQ+cewcZRnSCYGp02R/DQBlN5KBNMfwGsirHCMBaMJ2j3xPAOt4yHfR0MH+bxKFXB1BOCDROMk+4Ew7ji6cMcwTJzLqwNhNEkmNoNtnMAM93GBMHWBdhRDfB5cN0C82Mp30JDTcItwa5JMEfLBouP55DaVfFdgo0O6dha7OEiZC
if let Some(extracted_text) = decode_image_and_extract_text(encoded_image) {
println!("Extracted text: {}", extracted_text);
} else {
println!("Image decoding or text extraction failed.");
}
}
```
### Advanced Usage
1: Encrypt and Create Image
```rust
use encrypted_images::encryption::text::encrypts;
use encrypted_images::encryption::images::create_img;
fn main() {
let key = Some("your_secret_key");
let ciphertext = "This is a secret message.";
let style = "h";
let encrypted = encrypts(ciphertext, key.clone(), None).unwrap();
use encrypted_images::decryption::images::decode_image_and_extract_text;
use encrypted_images::decryption::text::decrypts;
fn main() {
let encoded_image = "iVBORw0KGgoAAAANSUhEUgAAAGwAAABsCAYAAACPZlfNAAA4QElEQVR4nO3cCWxkW3of9v+tfV+4FZcii1uxuDR7ff36db/uWTySxlomkjyyLNtyFFtWAjhQHMAxbMCOk0hAEiNRAmQBLBmCEjuIbdiwDFluy/LzeGY4zfdev252s5trcSkuRbKqyGIVi7Uv9/p/7r1FFl9TM2PLtkCBBxhMo8l363znd+453/kOm9K33v6OEh69i+2SGT1H80gflJEo22EZrgOHfkCaxD3/N/Gi24qRzU4M92fxNGrA47t3MD+ThtO6gLByE8oDP14v23Cz9DtYyN3EQ8cxZt8fwyhOsA4v3n/1r7FYA1LKNEzWdgxb12Hfn8C65UB9RnDsEUqnc7Dt+xC7GULtRQGVh05Mf2sR0a/cxy3I8ORfYmbDgScP7uCj2Tge+qN4Fm9g+sltxL7pQdFzCFt7HfePV/GduoJ7RuAFbqDWtY3e4BhES36yCrvdCWNmEnnjt2E03QAG1yC3yah9asDjL7yP56+WMXUnCMO/iqLQ60P2NI6MpOBul4TF3bu4VXPh+fhnKG8r6DGU1ZgePWiD9GkGL2sxRB6H4X4xhznnVyGfPoOpOgZFqaIytArb1jRQr6njU2zksWgH8jfG4fg4ipFqDW/bHHBJFeDYjmrPLVgGsyjbn6FueAzDTBHSz/7Ye9dgVwnsT//ovWuwqwT2p37k7jXYVQL7kz985xrsKoH9zB+9fQ12lcD+xFdvXYNdJbCf/qGb12BXCeyP/+D0NdhVAvupH7hxDXaVwL7+lalrsKsE9sf+yOQ12FUC+8kvT1yDXSWwn/jS+DXYVQL78S9GrsGuEth/8oWxa7CrBPa1J+FrsKsE9mOPR6/BrhLYj344cg12lcB+5NHwNdhVAvvhh0PXYFcJ7I9+MHgNdpXAvvogdA12lcB+6P2Ba7CrBPaD9/uvwa4S2A+8F7wGu0pgX7nXdw12lcD+yN3ea7CrBPblOz3XYFcJ7Eu3u6/BrhLYF28FrsGuEtgXbnZdg10lsCfTnddgVwns8Y2Oa7CrBPbhVPs12FUCezTZdg12lcAeTvivwa4S2AfjvmuwqwT2IOK9BrtKYO+Pea7BrhLY/bD7Dw3Yz//EEt4bLuA0VcYv/mZdBct2hbGMxB8esPdGXX9owH7pz8/jg+Ei9hIyfubXq/ixbgl/5eetZAL+l/kgZpPeqw92b8T5hwbs7/yVF+jx1fFqsaH84m9WpZ+fMuLP/qSFXMBf+ngIGzn71Qe7O+y4cmA/8aUIfm56DscnDczvykrB2Se9eubHr/zny6QB/sW3avilb9fw175owo98QQP7+r8YR12Rrj7YnSH7lQP7hR8ZwJ++uUSGy1vmRFZWD2Vp0GdAd4cB8RzwF56N8yu4+mC3B21XDuzPfHUYDwOrGO2swGqRyPC9W6pkwrf2PPiN3zxGoX6FwW6FrFcOrLmHPemI4ie+bFIejxu/PzW2clXBr89Y8I9+59bVBLs5YPmDA0sQzPQ9wGYI9uXLwUTSMT1hwJ//AW2fEi2VN+BXfz2HA4+Er4aMCI97MNlb5Vcutv/1Hw7g779Y/u5g/5pg3f8Rwfj3b33fA2y63/wHB5YimOF7gD0j2Bd/b7CvfcmMH7xpIoHWXuxa8P//xtGFg/OPf2kbf/2LBn71vGXzJnzll7LfHexbBOv6jwgmE8yjg2UJFrgE7EbQ9AcHdkQwfA+wjwn25PcG+69+2opwD2X09o/mHXj2Tw4ugIlKx9/+uhvvB4r8jvP2xb9ximLtu4DNEKzjErAGwcb+A4CBYC4djEeQauclYFN9xn//YHmC2b4PsGOCyd8D7FOCffh7g/1f/7WTQ3/e/uY33Dj49u47YL/2dQ8+6L4Idu8v5yAZvwvYM4K1XQKmEGz09wHGN0mMzztgBoI5dLA8wdqbYB8T7JEGNtlr+PcPViSY5fsAyxKs/j3APiPYw8vBvj66jr/2nzo49OftF/6BH46lzQtgt+/s4Nd+3ARTy6oY3bPjp/+3xHdfEjmIBd8lYBLBhn8fYHyTxPi8A2YimE0HKxLM3wT7lGAfaGATPdK7YFWCDf4+wMoEM30fYDmCVb8H2EuCPbgc7C882MQv/Bgj/lzbPagjnpchFRR09jiVkUD9nSzyr/4/IfzzN/MXwT4z4PHjFrBPCea5BMxIsMHfBxjfJDE+74BZCGbRwfjSVL1NsM8I9r4GNt6Nd8HqBBv4PsCeEcz8ebDfxUL1Bh4avg+wvA7GZ7wDNkewBwR7RbD7l4P98g9v4Wsf2jj833/bTMr4vz8y4eP5KeQbTOsNLWAvDXj8qAXsM4K5mmASwRQNzEywgX9LMIlgIR2Mb5IYnwtgnBwqmEkH40tTdTfBXhLsPQ0sEhBv2O0WsCoSshWWYCvYtwlmfhfsY4IZlwh2owXsIyzUJ/EQnwf7lg42dQ5W1MH4jODYBxfBXhPsPsHmCXbvcrC//bO7eH/iPKVfSxrxWdyMG46cEug1SQFvyxqot1JVwW9824C/+y91MLSAvTLg8QctYC8J5hBg++dge7c1sGATrKrGdAbWINgjAfaaYD+ogdV1sH6C7ehgHJ8LYJwcKphBB+NLU3U2wV4R7K4GNtYl9rCbLWB1XkaYYeltBfsOwYzvgn1KMGmFYJMtYN/AgjyOh/LnwWZ0sIlzsLIOxmcEx96/CPaGYPcI9pZgdy4H++2/uI+BwHlK/w8+seNXntl5H7bBPUzCjwYMmHgQwJ/4oAjL587Wv/GNDuVX/vmqZJRbwOYNePx+C9grgtkEWOIc7OCmBtb7GTSwuhrTGZhCsA8E2BuCfUUDk3WwPoLFdTCOzwUwTg4VDDqYTDB7E2yeYLeZBBEs3CmyxBstYDISBiMs3a1gswST3gX7jGBKlGDjLWDfxALG8LD+ebBnOljkHKyqg/EZwbH3LoItEOwOwRYJdutysDf/YwoSB7LZfuk3XfinG2aCxVQwLekYxZ27u/g7f/zi0lmpSfjiL3PQ8hPnYG8NePxeC9g8wSwCLHUOlryhgXU3wWQ1pjMwiWDvC7AFgn1ZA+N4qGA9BNvXwTg+F8A4OVQwWQcDwaxNsLcEuwnDxwQb7RDnsMkWMCBhkmDpagX7hGDKu2AvCdZYJxg7dAb2bSwYRvGw+nmwj3WwMM7A6joYnxEcu3sRbIlgtwi2TLDpd8E217bwW38py8DO25/5W14sn0oE224BG1bT+n/2Z30Y9bMDLe2n/o8cVrfDwIAOtmhgXC1gbwlmEmBH52CHkxpYVxNMi+kMzEiw9wTYEsG+qIEZOD4CjPVPW0IH4/gUFYJZdTBODhWsroMZCGZugi0S7AaTIIKNtItKx3gLmAEJiwJLR70F7DnBGu+CvSJYbZNgoy1g38GCicXZ8ufBPtXBRs7BZB2MzwiO3b4ItkKwaYKtEmxKA+uuvcTuiQOBgVvw1Tfx3/5kgcN+3j78H/wMTiaYOIc1wQZVsG/+F170uhr8rvP2U//nKVa2R4CgDrZswOPbLWCLBDMIsONzsPS4BtZBsF2CwaDGdAZmJthdAbZCsCcamEkH6yRYSgfj+BQlgpl1ME4OFayqg5kIZmyCLRNskkkQwYbbRC1xrAXMhIStAQsDwKFXB3tBsNq7YPMEq2whLA1Dud8Em8WCZRAPi58H+0wDk4ZgMutg0MH4jODYTQ0sQbAbBIsSbIpgawSb0MC+0DGPP/cDXEMuaeWqhIf/vQ+St0GwvRawAfy5rx3gv3li5Xedtzrt7vx3J5Aro0CvDrZqwOObLWDLBIMAy56DZcY0sDaC7RFMNqkxPbpPsM90sNsCLEqwDzUwiw7Wvgbb0RQxCMbxKRoJxj6qYJwcKlhZB7MQTGqCrRJsnEkQwYb8olo/eg6WtBCsBouPUR26oYHNEazyLthbAbZDsEEo95pgn2DBNqB2aPa9VrCXWOQgpaQQTEYdzNAE20Fw9IYGliLYJMHWCTZBsA2CRTSw/+zGAr48fXHgP9/2shJqp3WsZxUMuCSlvdMktbsUfuVi+923Lvzi39uHsT4MdK9pYGsGPL7RAr