lsd0009

LSD0009: The GNU Taler Protocol
Log | Files | Refs | README

commit 9c03927d864fafd51116f9f4cad18c2a4ea1cdd8
parent 6adcaa7cbafacd045ae01d9f6664da233d4aacdd
Author: Mikolai Gütschow <mikolai.guetschow@tu-dresden.de>
Date:   Tue, 12 Aug 2025 16:06:25 +0200

protocol: migrate withdrawal to Florian-suggested structure

Diffstat:
Mdraft-guetschow-taler-protocol.md | 107+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mdraft-guetschow-taler-protocol.xml | 370+++++++++++++++++++++++++++++++++++++++++--------------------------------------
2 files changed, 248 insertions(+), 229 deletions(-)

diff --git a/draft-guetschow-taler-protocol.md b/draft-guetschow-taler-protocol.md @@ -390,91 +390,100 @@ Output: out = uint32(len(msg)) | uint32(purpose) | msg ~~~ -// todo: explain persist, check +// todo: explain persist, check, knows, sum ## Withdrawal -The wallet creates `n > 0` coins and requests `n` signatures from the exchange, -attributing value to the coins according to `n` chosen denominations. +The wallet generates `n > 0` coins (`coin[i]`) and requests `n` signatures (`blind_sig[i]`) from the exchange, +attributing value to the coins according to `n` chosen denominations (`denom[i]`). The total value and withdrawal fee (defined by the exchange per denomination) must be smaller or equal to the amount stored in the single reserve used for withdrawal. -The symbol `*` in front of a certain part means that it is repeated `n` times for the `n` coins, -where `?*` denotes the index number `0 <= ?* < n`. ~~~ wallet exchange -knows *denom.pub knows *denom.priv +knows denom[i].pub knows denom[i].priv | | -reserve = EdDSA-Keygen() | -persist (reserve, value) | ++----------------------------+ | +| (1) reserve key generation | | ++----------------------------+ | | | |----------- (bank transfer) ----------->| | (subject: reserve.pub, amount: value) | | | - | persist (reserve.pub, value) + | +------------------------------+ + | | persist (reserve.pub, value) | + | +------------------------------+ | | -master_secret = random(256) | -persist master_secret | -*(coin, blind_secret) = GenerateCoin(master_secret, ?*) | -*coin.h_denom = SHA-512(uint32(0) | uint32(1) | denom.pub) -*blind_coin = RSA-FDH-Blind(SHA-512(coin.pub), blind_secret, denom.pub) -sig0 = EdDSA-Sign(reserve.priv, msg0) | ++----------------------------------+ | +| (2) coin generation and blinding | | ++----------------------------------+ | | | |-------------- /withdraw -------------->| - | (reserve.pub, *coin.h_denom, | - | *blind_coin, sig) | + | (reserve.pub, coin[i].h_denom, | + | blind_coin[i], sig0) | | | - | *denom = Denom-Lookup(coin.h_denom) - | check *denom.pub known and not withdrawal-expired - | check EdDSA-Verify(reserve.pub, msg, sig) - | check reserve KYC status ok or not needed - | check reserve.balance >= sum(*denom.value + *denom.fee_withdraw) - | reserve.balance -= sum(*denom.value + *denom.fee_withdraw) - | *blind_sig = RSA-FDH-Sign(blind_coin, denom.priv) - | persist withdrawal + | +-------------------------------+ + | | (3) coin issuance and signing | + | +-------------------------------+ | | - |<------------ *blind_sig ---------------| + |<----------- blind_sig[i] --------------| | | -*coin.sig = RSA-FDH-Unblind(blind_sig, blind_secret, denom.pub) -check *RSA-FDH-Verify(SHA-512(coin.pub), coin.sig, denom.pub) -persist *(coin, blind_secret) ++---------------------+ | +| (4) coin unblinding | | ++---------------------+ | ~~~ -where `msg0` is formed as follows: +where (for RSA, without age-restriction) ~~~ -msg0 = Sign-Msg(WALLET_RESERVE_WITHDRAW, - ( sum(*denom.value) | sum(*denom.fee_withdraw) - | SHA-512( *(SHA-512(denom.pub) | uint32(0x1) | blind_coin) ) - | uint256(0x0) - | uint32(0x0) | uint32(0x0) )) +(1) reserve key generation (wallet) + +reserve = EdDSA-Keygen() +persist (reserve, value) ~~~ -The wallet derives coins and blinding secrets using `GenerateCoin` from a master secret and an integer index. +The wallet derives coins and blinding secrets using a HKDF from a master secret per withdrawal and an integer index. This is strictly speaking an implementation detail since the master secret is never revealed to any other party, and might be chosen to be implemented differently. ~~~ -GenerateCoin(secret, idx) -> (coin, bks) +(2) coin generation and blinding (wallet) -Inputs: - secret secret to derive coin from - idx coin index - -Output: - coin private-public keypair of the coin - bks random blinding key secret of length 32 bytes +master_secret = random(256) +persist master_secret +coin_seed[i] = HKDF(uint32(i), master_secret, "taler-withdrawal-coin-derivation", 64) +blind_secret[i] = coin_seed[i][32:] +coin[i].priv = coin_seed[i][:32] +coin[i].pub = EdDSA-GetPub(coin[i].priv) +coin[i].h_denom = SHA-512(uint32(0) | uint32(1) | denom[i].pub) +blind_coin[i] = RSA-FDH-Blind(SHA-512(coin[i].pub), blind_secret[i], denom[i].pub) +msg0 = Sign-Msg(WALLET_RESERVE_WITHDRAW, + ( sum(denom[i].value) | sum(denom[i].fee_withdraw) + | SHA-512( SHA-512(denom[i].pub) | uint32(0x1) | blind_coin[i] ) + | uint256(0x0) | uint32(0x0) | uint32(0x0) )) +sig0 = EdDSA-Sign(reserve.priv, msg0) ~~~ -`coin` and `blind_secret` are calculated as follows: +~~~ +(3) coin issuance and signing (exchange) +denom[i] = Denom-Lookup(coin[i].h_denom) +check denom[i].pub known and not withdrawal-expired +check EdDSA-Verify(reserve.pub, msg, sig) +check reserve KYC status ok or not needed +check reserve.balance >= sum(denom[i].value + denom[i].fee_withdraw) +reserve.balance -= sum(denom[i].value + denom[i].fee_withdraw) +blind_sig[i] = RSA-FDH-Sign(blind_coin[i], denom[i].priv) +persist withdrawal ~~~ -tmp = HKDF(uint32(idx), master_secret, "taler-withdrawal-coin-derivation", 64) -(coin.priv, bks) = (tmp[:32], tmp[32:]) -coin.pub = EdDSA-GetPub(coin.priv) + ~~~ +(4) coin unblinding (wallet) -(for RSA, without age-restriction) +coin[i].sig = RSA-FDH-Unblind(blind_sig[i], blind_secret[i], denom[i].pub) +check RSA-FDH-Verify(SHA-512(coin[i].pub), coin[i].sig, denom[i].pub) +persist (coin[i], blind_secret[i]) +~~~ ## Payment diff --git a/draft-guetschow-taler-protocol.xml b/draft-guetschow-taler-protocol.xml @@ -423,93 +423,102 @@ Output: out = uint32(len(msg)) | uint32(purpose) | msg ]]></artwork></figure> -<t>// todo: explain persist, check</t> +<t>// todo: explain persist, check, knows, sum</t> </section> </section> <section anchor="withdrawal"><name>Withdrawal</name> -<t>The wallet creates <spanx style="verb">n &gt; 0</spanx> coins and requests <spanx style="verb">n</spanx> signatures from the exchange, -attributing value to the coins according to <spanx style="verb">n</spanx> chosen denominations. +<t>The wallet generates <spanx style="verb">n &gt; 0</spanx> coins (<spanx style="verb">coin[i]</spanx>) and requests <spanx style="verb">n</spanx> signatures (<spanx style="verb">blind_sig[i]</spanx>) from the exchange, +attributing value to the coins according to <spanx style="verb">n</spanx> chosen denominations (<spanx style="verb">denom[i]</spanx>). The total value and withdrawal fee (defined by the exchange per denomination) -must be smaller or equal to the amount stored in the single reserve used for withdrawal. -The symbol <spanx style="verb">*</spanx> in front of a certain part means that it is repeated <spanx style="verb">n</spanx> times for the <spanx style="verb">n</spanx> coins, -where <spanx style="verb">?*</spanx> denotes the index number <spanx style="verb">0 &lt;= ?* &lt; n</spanx>.</t> +must be smaller or equal to the amount stored in the single reserve used for withdrawal.</t> <figure><artwork><![CDATA[ wallet exchange -knows *denom.pub knows *denom.priv +knows denom[i].pub knows denom[i].priv | | -reserve = EdDSA-Keygen() | -persist (reserve, value) | ++----------------------------+ | +| (1) reserve key generation | | ++----------------------------+ | | | |----------- (bank transfer) ----------->| | (subject: reserve.pub, amount: value) | | | - | persist (reserve.pub, value) + | +------------------------------+ + | | persist (reserve.pub, value) | + | +------------------------------+ | | -master_secret = random(256) | -persist master_secret | -*(coin, blind_secret) = GenerateCoin(master_secret, ?*) | -*coin.h_denom = SHA-512(uint32(0) | uint32(1) | denom.pub) -*blind_coin = RSA-FDH-Blind(SHA-512(coin.pub), blind_secret, denom.pub) -sig0 = EdDSA-Sign(reserve.priv, msg0) | ++----------------------------------+ | +| (2) coin generation and blinding | | ++----------------------------------+ | | | |-------------- /withdraw -------------->| - | (reserve.pub, *coin.h_denom, | - | *blind_coin, sig) | + | (reserve.pub, coin[i].h_denom, | + | blind_coin[i], sig0) | | | - | *denom = Denom-Lookup(coin.h_denom) - | check *denom.pub known and not withdrawal-expired - | check EdDSA-Verify(reserve.pub, msg, sig) - | check reserve KYC status ok or not needed - | check reserve.balance >= sum(*denom.value + *denom.fee_withdraw) - | reserve.balance -= sum(*denom.value + *denom.fee_withdraw) - | *blind_sig = RSA-FDH-Sign(blind_coin, denom.priv) - | persist withdrawal + | +-------------------------------+ + | | (3) coin issuance and signing | + | +-------------------------------+ | | - |<------------ *blind_sig ---------------| + |<----------- blind_sig[i] --------------| | | -*coin.sig = RSA-FDH-Unblind(blind_sig, blind_secret, denom.pub) -check *RSA-FDH-Verify(SHA-512(coin.pub), coin.sig, denom.pub) -persist *(coin, blind_secret) ++---------------------+ | +| (4) coin unblinding | | ++---------------------+ | ]]></artwork></figure> -<t>where <spanx style="verb">msg0</spanx> is formed as follows:</t> +<t>where (for RSA, without age-restriction)</t> <figure><artwork><![CDATA[ -msg0 = Sign-Msg(WALLET_RESERVE_WITHDRAW, - ( sum(*denom.value) | sum(*denom.fee_withdraw) - | SHA-512( *(SHA-512(denom.pub) | uint32(0x1) | blind_coin) ) - | uint256(0x0) - | uint32(0x0) | uint32(0x0) )) +(1) reserve key generation (wallet) + +reserve = EdDSA-Keygen() +persist (reserve, value) ]]></artwork></figure> -<t>The wallet derives coins and blinding secrets using <spanx style="verb">GenerateCoin</spanx> from a master secret and an integer index. +<t>The wallet derives coins and blinding secrets using a HKDF from a master secret per withdrawal and an integer index. This is strictly speaking an implementation detail since the master secret is never revealed to any other party, and might be chosen to be implemented differently.</t> <figure><artwork><![CDATA[ -GenerateCoin(secret, idx) -> (coin, bks) - -Inputs: - secret secret to derive coin from - idx coin index - -Output: - coin private-public keypair of the coin - bks random blinding key secret of length 32 bytes +(2) coin generation and blinding (wallet) + +master_secret = random(256) +persist master_secret +coin_seed[i] = HKDF(uint32(i), master_secret, "taler-withdrawal-coin-derivation", 64) +blind_secret[i] = coin_seed[i][32:] +coin[i].priv = coin_seed[i][:32] +coin[i].pub = EdDSA-GetPub(coin[i].priv) +coin[i].h_denom = SHA-512(uint32(0) | uint32(1) | denom[i].pub) +blind_coin[i] = RSA-FDH-Blind(SHA-512(coin[i].pub), blind_secret[i], denom[i].pub) +msg0 = Sign-Msg(WALLET_RESERVE_WITHDRAW, + ( sum(denom[i].value) | sum(denom[i].fee_withdraw) + | SHA-512( SHA-512(denom[i].pub) | uint32(0x1) | blind_coin[i] ) + | uint256(0x0) | uint32(0x0) | uint32(0x0) )) +sig0 = EdDSA-Sign(reserve.priv, msg0) ]]></artwork></figure> -<t><spanx style="verb">coin</spanx> and <spanx style="verb">blind_secret</spanx> are calculated as follows:</t> - <figure><artwork><![CDATA[ -tmp = HKDF(uint32(idx), master_secret, "taler-withdrawal-coin-derivation", 64) -(coin.priv, bks) = (tmp[:32], tmp[32:]) -coin.pub = EdDSA-GetPub(coin.priv) +(3) coin issuance and signing (exchange) + +denom[i] = Denom-Lookup(coin[i].h_denom) +check denom[i].pub known and not withdrawal-expired +check EdDSA-Verify(reserve.pub, msg, sig) +check reserve KYC status ok or not needed +check reserve.balance >= sum(denom[i].value + denom[i].fee_withdraw) +reserve.balance -= sum(denom[i].value + denom[i].fee_withdraw) +blind_sig[i] = RSA-FDH-Sign(blind_coin[i], denom[i].priv) +persist withdrawal ]]></artwork></figure> -<t>(for RSA, without age-restriction)</t> +<figure><artwork><![CDATA[ +(4) coin unblinding (wallet) + +coin[i].sig = RSA-FDH-Unblind(blind_sig[i], blind_secret[i], denom[i].pub) +check RSA-FDH-Verify(SHA-512(coin[i].pub), coin[i].sig, denom[i].pub) +persist (coin[i], blind_secret[i]) +]]></artwork></figure> </section> <section anchor="payment"><name>Payment</name> @@ -737,7 +746,7 @@ msg3 = Sign-Msg(EXCHANGE_CONFIRM_DEPOSIT, -<?line 603?> +<?line 612?> <section anchor="change-log"><name>Change log</name> @@ -755,133 +764,134 @@ Education and Research (BMBF) within the project Concrete Contracts.</t> </back> <!-- ##markdown-source: -H4sIAAAAAAAAA81ca1vbSpL+rl/Rh3yRGcvYJuEk3nDOEiCBTTB5gExmNsNi -WWrbGmTJq0vAJ+H8sv22f2zfqu7WxZhbQrLjhwdLre7q6rpXdcuO41ife2Ld -srIgC2VPrJxMpHjT/yBO3FAm4n0SZ7EXhyuWH3uRO0UPP3FHmTPOZZZ6k/jC -yaijM9MdLc/N5DhO5j0RRKPYsoJZ0hNZkqdZt91+0e5aF3FyPk7ifEY9fDmT -+BdlVpol0p3W287lHL39niWEI3gevvKS+SyLx4k7m8y5QXpuOuGrmTufYmRq -WU8+yyiXPeuJEImcxT0xybJZ2ltbGwdZaxzlkcxacTJeC1O/DcRaaF6jziHw -T7OyO54v6b5mWW6eTeIEuDmYWQhFnIPgPA7dQLz53/9R5OFnGNgTJx92xE4i -U6xMfIiCzzJJg2wu4pE4kd4kisN4POfe7nCYyM80wPTnZiKQBGJ7MpxO4jD7 -Aw0t0WnzQw+gerXuXuwDnx2n3WlvvNAteZQRY97IZOpGajI5dYOwJ6YK71bB -1n/PcsdX4Fq+tKwoxpgMWBMzjl5vd9vmotN+qi+fPd94oS83uuvcuvd25zWw -ONxvddr4a/+69uLX5866s/G063Seopfz69n6U3Q83jsu+m20u8/X+vvHJ63X -+++PW53nbecpBAniVOBgWY7jgFKggetllvWPT+Lk1Ufxj1P1YBr4fgisn4h9 -LDn2cy8L4qjW7ZW8cBMpsomb4V+QCgh4TrIjcJ1mQRgKklQniEi2xyBFKtzI -F1N3DkpGmRtEQiZJnKQt60MqBcDM4zwR8UUkkiA9/4Vm78eZq2Z2xGDFHXor -AwGKxhAxTCpFGGQycUPibRCNxQA9BkJGxDtfuKnYOt7e3xefmN6nBMMVX8Ww -DgPIkM5FPBGJkysugmwihtQ/lJHtNhYmldEYz4H/cE5tGELNdGMQcWnszPX/ -UyaxPW+KRRC1vk3xB7o56E5YZ3F1EsCeq2kI4jDIUvuyMVgbcBNd1sBOgyiY -ghxRPh3C+GAwjVhTaEbSAw/cZE5TQKXBEeIWj8vDLJiFUqDRC1KiQxDBDAHG -Jc2b446WsTjfYD4Aom6aiTQYR8Eo8FxApDkNUQyYwWXJFxAO1oCEQ9EBFgo9 -7GEwRhc/cKOGmbOzoVZL1+vd8nrjaXndfVbp9KzDvUgE5X/nwWeYPFpirJfQ -2eA1qL72erd6t/G0egeo1VvA5dsmCJfOpEdKFM4JzQQyHU/teYUyrlCN4VyM -ZQT5zLDoFPiAAFJzFCRS4rgqhsKexr7oA8Iat9SaauxVbAKVWVTXhLycxRFW -GBSyezMnCS/Sv2FTAHYexqJPGrZd+oLAg7sKpgEtjhzA4sM9OAnxOo/YFnCH -JzA7Ww5oJb48SScuLq4s688//7R0sz1Nxw3h/CYm5F+s/WiWZz02m3hAX0AO -TWJKgjlm2mi5fydeiu5/bXRE7GWS3NFhnhWDCRoD0cP8YAyXQ6NHwSVorWEQ -vu/gLDbFetfAIeSsAQFgISGqxgyZRpvFwHDMIJHHUq1UPG11muIZ/dugf0TF -jVaXRnzSpvq0VZIDsqLIgYsKOUg0v5Mcne6zx6HHxtN704NWc50eXaJHl+ix -bujx9BZ6MFVtBDFsaX3T3Cjo5PCzOrUeQ4AejWILEnRS0kkTz4sTMg1x5KfG -hI+CBDCLkcYkXqevL0dBpAzjly9acK56ihiZnM4wf1WCLMZ+U9CjT+3eeudU -IQVnWfXH8YxMD1kAPxiNyACMknhqIK1pQa/M/QkxxCldKMMNOwBXwnPBjuYS -LCWbcKBJtoXwjUyPNkbbMO3aJuwdbG2Ds5OpazhKLQ4R00ZE2gTilxlzFaQA -X2YEQPFlT/PFqxkexmGkDY9yzpqIdT7VBAQzsYCk0ktkxreldLiZ9ltmJPUk -tEqR8t3M5WgggbEmr6mG1uUIaAj9rXm6gJHSLzxm9fLc0MtDVoEF0utA8FQT -+S2w3ZEJHBgvecHoUlBIBD73R1dKFmk6QLphmLBpREPkqZpNpSYBxWO4TTO3 -6kE+6UD01GJCw09r+SFPWuMEBCpOWFh2LzmMZEuwezmjrzSTM1pkmo9JtfQy -CY/TnjWgb0ePGhBeqRiwkEA6IZzwsxeTAF7MdCSQi/0gwANhe6MWlIZl7arR -0uKGQXbqhllT7L89aHIi1RTvWOQO3x5oMUkVC6kfs5DFkGJJamCJF7Yrojhy -tAgpr64eNf6NB5efYISuGdxu/DlAkINJVSAsOfxwTbAHAsP4UryHsJfGAcGK -HYOUUi9E6eCiG1rqySiuIUjRM4kqkdmdlfEABSYUg4ki0o+jBSxtBGhiiGBb -hZxaWBVuDe77Tvcs408t2wuoETu1RVyY4uWm6D57tgq7tymedzbajbrKHOoF -3wTXxpTvNOjGNWtLo68p0igOw/gi1Rbz/dFbzFyVsFIWGsp67CkDauyvXfWM -DYvmKACQ5NkAWZGiRRDs3KquQqNtVNU5iH3kSy5pX6ysK2twzeyzMl81leku -bB3ELk8iVlTCio07SRWCfFJh3Efg5RgBW3RbEN+vKAZhY/ebYkE/litH33D1 -ZuA1Jfr/1qJ7qNFP0KOHyXuNmf2KyEM68NyEGYDDPsSXGDhlwTGXQUpuOES+ -MTRC5qpqBZl55ciDP0hXMsZXS4PpsSnalh8L3AQho/tS9BXul1oPFo0pkmid -nmkYjaZKUu1+o1GsepM72Zy09huUP5VlFEz7l03RMYqCRD9yXoUBOHGMTNKF -1JtoYteHNem84F7Lexwdbzmvd/bgEZPUdUb+5IrbEX3ms1mcZETuigelKfUQ -CqeaYpYPwRRWAAyuK4AJM3WgyG2qv6B56Rpyw9EFxCklTij55BwrT6FBJF66 -m8nXhKzLCKblWUZ5GDrQDqqNsKslQMAg/gx6qWlbfR1TYMxiTFFw3+i5iviU -cXGA0dXVdXPJ/NwUK4okW+L1ySz9+MuKxQq8afisuGtQaDRKCag9kZr9eGz6 -lpfSonVuFtgV4IwxYm6wMSqVAFwm00PFHV6xVjwOZSjOprDdHbsUxkDooUqB -F8Sgu2YO4FvDuQD9ghHrnY6PpRgnkiuV4Nt0SkEyEm3okpshprHHnt8g4qs5 -iYMDgywTvdOqyZHDQZe0h+dpTZw4vq2KEzoweYYkyIQOCY42jNXcpZpw/BiR -M5HrMpEjLJeJ3JIw9rtE7pWhAsYWAldrBfrswcETziqAzcpdUsRMqEgRmwID -tM42blVG4E7WLbME/3rsNAktYwTOUISu1eBuHhpDqllorOkSDnJytCmWmVEr -KR8s0wsrOZPokVCdyxgGVe4qrItFq0EXdFxVedjC85Kv5AuusZUabRqHSTG/ -YWkajOssZdDmG8YEdoXqmBR3uGXwVPPPGh5Ugvmo7hQfOe2SdzNS9ys46dc5 -CQyE/lZejjjDGMKO6Qk1L9FlSVpZ5xSB21TjieAafV9T1KymStIP0XCpsuh2 -GxDvoS5mGTymXMy/qNrkkVGYEtPbUvc6je+W+CD6jD74L5OUq1TJcpEnqq0K -1f9Gmf+rcWZ1/qhmpYvMo4dasyWSNzI0Z3eAQT+YD1mSyyZlAYQLFSgoTwju -xZVHtmLA1PDjLjtlKzibtLpK6rcduohSnGPam0wSqrVTPKNqL6qwXuwOc3C7 -AyjZfGai2q0pxcmWpb5BikSWuzbVOg5VZ+OUq/aqeunMYtgulWGlVp0rA24d -0CAKgigvi+SYNwULgzdzk6zY1AJVhZcniYy8edPiTZ8ReWTE0gOdeAKTPNJ7 -PuCumOSRnwDDaRCG6AZVtjvSed64ASZHV+a2wGzd6XT09p03cWlGqmAGtK1d -RHIlFIRjHycykiSlpspFz82uelNNjPAumZdULHf8IjFwmc4kVZbZY1JNLZWq -6oh3vWuaDRnoidnqo20i/dig1hjoWvhJAGXL3OkMDN4apnGYU7m2aLzGYBCi -stklLiYSHWgfrV5qttTGn4dcWHrclga0zzTovPi17bQ7+BPtdq/dFtu7xycD -YVP/D/39vwk5i71Jo8VhNue8yDZVxj5oX75e+AxK3FKxwpReaVkvf3Eca20N -aPhxD4yS3jnn8FLyBiw4y8h6mXUkQyVl37JiaHohatWlfhPuCIk09o7zm96m -qGSUW2ForGJaCwpKjQP60BAuA7liIl3avtRb2lowA3RCxk0UsFy9p5CqUKUo -OyBwTaC4kCysO5FjKKkktYGbf7PV39IibH160/8QwTEWOIr3alx6ahdHMtzI -rR6yUJdOYTVT3XJWtrQm2TSEa+J5k3lL0Lp5eU4ilUXV+KV6vcibOm2IEXNV -ZWEjSLpfIGpgiTTOE6+GX5C1+PhJC0hobINsjQ5kLMG1wAmC8yTqdjumrksk -cA7SsaEcZ4zL/ZvuUfFlpqVObCyKiL3MJypGwZDa8tILW5rRjZpMLPdiyChn -oYR2G0g2NPImCHWHRgWnZSGG8jTaANGhBFp5xSYVsvSVvTQDLfQSfimk/G5G -R2ZSpEisqOx0PkKI/cS9cEOVbl9QrIucWCXHYhCJ30SbTE4QqeMbCe1jpxk9 -GpTU1XtLZFpALATKYwnDnmVJMMzZ9Sjd1BtjGpoH28DhH+3PA5o3wQoqiTiV -a5SGZ3FW6DchcVFgLUYS5DWVVKhOFQXetayCa1jTHBk/EV8H9UiPsCDA0agp -4w2Jj5PSi8CgjkMuRcjks649UGJVoqEN0Xw6jEMxWB3QSFAkytR5Ek8mfN6F -PetUulGqS7lc3YRxkqxwRAQ2j8XGCpOFqNW0tDX8fbV+JoCi1ktz4GPQFi83 -xe+r4qWIBlppqmVLzd07P4aA1nkEERSrTMMW4p6bBtT7IQJeqJdCLO/5+WoZ -Mm+KXX8HodlbOR9D4Bt3j9TyLWwNoqmrzHeP/HZsFxuc8iPsoRudI6YFv0ek -95Vnvy2Z007z4T/hK3tG0ojiJp7oFWt5TGxv6rlISYWJwuA7pp+6ZHbPdKq3 -qfcC6LDN7TwqWVuHcJ85V21SoKZKNvXABuZ+o4/mbOOpXQPbhAY1aCQNbE3O -WKore/Da5LYr5rdD14WWNKxVNRsBqOSGqtxkwDB06l3HrVmFAwPbLhSByxoF -Q6Bk7P/ay0j3gySahHrNWD1Rf7BMovlTl6EaUZv3wbZCS05sq+v9Gbqwavi/ -Q9/Ouzg+z2d2dRn3VwkVIVfsKRnOiH0a7XuVDsWBzw7ggh4IWQmKrgTU6G7K -Ag/F1Vjjt3/fpjgwQ0Yfn5PbJHxVnP9tEFtDN3QpUfkNaXY+tTVRlJP/i6ER -3PuZocr9UV+cwnn8KbRUqvJarfBYFdfSId4fsjF1pTA8opC/rOlyZRF1ZXa+ -R7GUitcpY4qHxYS3GD2tJAt1rSVm08xTG23It9Tuq8BYh1JkPG8NuqkD2X2T -dnzcevdu9+TsaPd49+ivu2cf90/2do62PjaZVvY1ESOfUGm7LmdfC5cCbM1l -uZTSvbQv2cGUktUQBoI5Atu+bFebeFC7sXDXqGys6VjQ53plWonwi6qsolmK -eJe336oOc6DifVf7Y1O85Z30snLOsSmFxqAxHwpPAi8L55Swu+d89Bl9KVWa -FsUYXyJQDnUJgysbtQkCOsZMRR5K4ZFQ8h6gG81FjL6qcqUrStNgPOFIX2cV -KucqZqPdc3OqKZzrULkWEhjBDPxLTjGNOJ2njYVKt45F9DcmUjRlkjKd1PkD -/5L1g1uZMvXkkduFMPsDTllYnblBYmpn1KtWQ9fHKW4vpa939RlylWx6zEGu -u1W1Y8AFmdsK3RmfReQTAVqsiDpNsRA+rahXWirejGZ0/OJk2kqTD9poXeZI -huhKtVRM8am33j1tCrpa7/ZOYRC0yheR0BuZvc+H5XAt1jalTTAbTbadlDIj -+XbgDFjwOP+jnPe9esfl29OjqUwoP8p0emRub06QFvtRgqTaVHl71TD/xrFF -Vk1v6GTxTwh7LhB+nOk9WR2nd7rPH+7G1Ol+cDbweTvOk+YoVRafy+j3ZjnT -96QWiw2FoxM2Y9D6gvnVjFfVTOx7HF0Uk5V6aJ5aTWcYAsvDfef8dmwXG4qA -numTrn1RdAr8qzUvdIOpuCOup4+tF0ARpiLuz47OJ2ckPsYqFaKk9aT5jRis -GF11CGJZnNSG675Ai7NaZdWb3iAZ5bC5vnR9GF+p5d/c3j+YjiN16HazKuFK -wVi/tLB/GwlKe6MI3Kys4JsA3r7qh2YlZvEtXiSdhefFPph4LaPC/P1g22bA -3Hvg9Xy+5hR0Qv+D4v0C3abC47Hi/SWpZ9UlqkWpORvLRi5nxu1znhzuHPaE -HyNIko4Cw0eF1Bkmbvh9+UiTF5Tbd5uCAr5jGar3W+wCny+FFrBawW+oaama -n/tSHLjJ+U6AkFNQQmGtYoWdOndXKxHOKsjQWV6sQYbAW7gYrNBrfSHCUWqj -SwxXJcJMSQWoUvKs8bYpDMSbvNFPciQwwoWY3epI6GPfiPTPcCRKiHS+xmi0 -qiJSCAWLwv3LBArsjoJomwU+xGB07zIY3R9lMBRbGYXF1h9uMLosyN0Fg3Et -fW+KAevVQL2GRo1dlcfclNRPziqesygquLA5dIb6P44P+4UuIV2+VgM42D3a -3tvqn5xtH/ZPjra2T8hDFgMsRmZJzWD7cL9/trP7/vB4/8TUCyqY3JjHE3I6 -kS8kUIc8X+u1VD2o9IzGX1cbF7ywHrNqBL1eFNPCajpde0B7jdXUZwFjUI+4 -sZR477f+frCL78O3dfKpNK6SvYlK9oaYLkZKPFdbgLp8QUdvyOY36u+/ydp5 -PDr4wk5FHRrikxlUiKAaJu/mudFcSdXCuZGWtRdfUMGB30Tw4jz0i9PHuuso -5+1lpP301oKk99dhBCfBTB8sUfkPbwJp+23JyKW8e0xwHM/lLfbcm5CsruQR -B994ukJVVrN5lOhyiYZGRQ9d8sBkBJPOedJbE/pgjP4dhyIRBhn1SXi90Unl -gs+Bn/N7EAFttPIZJM3yampseLx2n/R4YefQ3N6VGpf9ytT4vml1WU3XA1Xk -Lyq5AFmSqqDpjqXPLBwwl7VMgWDRcN2+9ErHW3cF14Zu5k0cM+NdeyiVcKQM -wWvBc3NBq6+WIF6uvSnqtlbR5ibEhaGmoVA1Xb91yd9OrJt6Lt+IKbz1D9mR -0cAfvh2zYKwfOT8tPo+UqGoq1Fxyja7GLXd09PlQyDcU8xfnaHwvQWoAF7cG -HoYzsZ+Ovab0azp02va+w01MbmQnkXTQhaqkyblD0B6QLwIVPw/pzGTlJMG9 -hxuzelYGA5RdXdgPCkDX6wFozVazUKw/fgDK8zaXLeAHBaBVT6UWxZK+fnsA -un7X/tF6NfzZ/RtFP292KXZ8vX90cGtAeD3cq0ZXOihbQp/KyOuFpTtDwaX5 -j3CWRH+LW1jFKJWdLsSGZufpCf2KRJ7QDzdt08FkX/9GQap/W2iHf1voidin -E5CLPfpxRL9CQOIxdPkAm9hWB73CeEx3Wx5Z71D6Y/UjVl966mCU9DdXRm6Y -ypWr2jy8M8U/RHPBr6rz64IqtOOjWvo8mfq9J/Fa+vxjQwf8xmVCYaW16+f6 -rVHyGEcylS5WLexXB69eqzeFy4iSzvbQmmiTRNIFMwKR1/8B/uo+hUVMAAA= +H4sIAAAAAAAAA808W1vbSpLv+hV9yIvMsXyDcBJvyCzhEtgEkw/IZGYzLG5L +bVuDLHl1AXwSzi/bt/1jW1XdLbWEMCaXs8OXL7Zb1dXVda/qth3Hsa77bMOy +Uj8NRJ+tnU8Fezv4yM55IGL2IY7SyI2CNcuL3JDPAMKL+Th1JplIE3ca3Tgp +AjpzBWi5PBWTKF70mR+OI8vy53GfpXGWpL1O52WnZ91E8dUkjrI5QnhiLuC/ +MLWSNBZ8Vh67EguA9voWYw6jdeidGy/maTSJ+Xy6oAHh8mRK7+Z8MYOZiWU9 +uxZhJvrWM8ZiMY/6bJqm86Tfbk/8tDUJs1CkrSietIPE6wBhLRhuI3AA9Cdp +AQ7Pa8DblsWzdBrFQJsDKzMmmXPsX0UB99nb//0fyR56BhP77PzjHtuLRQI7 +Yx9D/1rEiZ8uWDRm58KdhlEQTRYEzUejWFzjBA1Pw8ggAYQdimA2jYL0dxho +sW6HHrqAql8CdyMP6NlzOt3O1ks1koUpCuatiGc8lIuJGfeDPptJulu5WP89 +zRxPomt5wrLCCOakQDUK4/Rgt9fRb7qdTfX2+Yutl+rtVm+DRg/f7R0AFSdH +rW4H/nV+a7/87YWz4Wxt9pzuJkA5v11ubALg2eFZDrfV6b1oD47OzlsHRx/O +Wt0XHWcTFAnUKafBshzHAU4BD7ibWtY/PrPzN5/YPy7kg5nveQFQ/YwdwZYj +L3NTPwpLYG/EDY8FS6c8hf/8hIGCZ6g7DN4nqR8EDDXV8UPU7QmwImE89NiM +L4CTYcr9kIk4juKkZX1MBAM0iyiLWXQTsthPrn7B1QdRyuXKDhuu8ZG7NmTA +0QhUDBYVLPBTEfMAZeuHEzYEiCETIcrOYzxhO2e7R0fsM/H7AnFw9pWNyjiA +GLS5kBZCdeLsxk+nbITwgQht3qgsKsIJPAf6Rwscgyk4jB80IRznzrn3nyKO +7EWTVVGUYJvsdwBzABypTiNzEcC9kMsgxpGfJvZtY9ge0hC+LaGd+aE/A3aE +2WwEzgcm44y2JDMULsiAxwtcAkwaJILSonlZkPrzQDAYdP0E+eCH4IYAxy2u +m8En3EZ1veFiCITyJGWJPwn9se9ywIhraqZoNMPbQi7AOPAGqBySD+ChAMIe ++RMA8XweNvSa3S25W3y/0Sveb20W73vPDaDnXYJCFRT/nfnX4PJwi5HaQneL +9iBh7Y2e+Wlr0/wEWM2PgJc+NoFxyVy4aETBAsmMQaejmb0wOMOZHAwWbCJC +0M8UNp0APcAAoSQKLJLquM5GzJ5FHhsAhjaNlIZK4pViAi6TqraZuJ1HIezQ +z3X3YUkiXWh/oyYD3FkQsQFa2G4RC3wXwpU/83FzGACqDw8hSLCDLCRfQADP +wO3sOMAr9uVZMuXw5s6y/vjjD0sN27Nk0mDOazbF+GIdhfMs7ZPbhAf4AsTB +EJuhYk6IN0rv37NXrPdfW10WuanAcHSSpflkxEZI1DTPn0DIwdlj/xZ4rXAg +ve8hWGyzjZ7Gg8RZQ0RASoJcjQgzztabAccxB408E3KnbLPVbbLn+N8W/odc +3Gr1cMZn5aovWgU7QFckO+CNwQ5Uze9kR7f3/MfwY2tzZX7gbu7zo4f86CE/ +NjQ/Npfwg7hqQxJDntbTw42cTw49K3PrRyjQD+NYRYPOCz4p5rlRjK4hCr1E +u/CxHwPOfKZ2iff564mxH0rH+OWLUpy7vmRGKmZzWN/UIIuo32b46HOnv9G9 +kERBsDTjcTRH14MewPPHY3QA4ziaaUxtpejG2p8hh7jAN9Jxgx+AUEJrgR/N +BIgUfcKxYtkOpG/oepQz2gXXrnzC4fHOLkh2OuNaojjiIDNtyEibQPhtSlIF +VoBc5ohAyuVQycUtOR6iYawcjwzOiollOZUUBFYiBUmEG4uUPhbawVMVt/RM +hESyCpXyeMopG4jBWWPUlFPLegRkMPWqZFqhSNoXPCbzcnngZgGZQIX1KhG8 +UEx+B9TuiRgCGG254nQxKUQGX3njO6mLuBxgemAas3FGg2WJXE2WJj7mY/Ax +SbkZQT6rRPTCIkZDnFb6g5G0JAlQqCgmZdm/pTSSPMH+7RxfklTMcZNJNkHT +UttEOi761hBfHTVriHQlbEhKAtoJyglx9mbqQxTTgIiyCgcKPGS2O26B0ZCu +3TVaSt1gkp3wIG2yo3fHTSqkmuw9qdzJu2OlJokUIcKRCEkNMZfEAdJ4ZnMW +RqGjVEhGdfmo8W80ufjzxwCaQtiNrn1IcmBRmQgLSj+4TvaAweB8Md+DtBfn +AYGGHwMtRSjI0kGKPLDkk3FUIhCzZ1RVZDOfF/kAJiaYg7E804/CCpU2JGhs +BMm2TDmVskraGgT7XkEW+afS7QppKE7lEStLvNpmvefP18HvbbMX3a1Oo2wy +J2rDD+G1Ycn3CnXjnrfF2fcMaRwFQXSTKI/54fQdrGxqWKELDek9DqUD1f7X +NiNjw8I1cgSoeTagNLSoioKCmxkqFNnaVJ3jyIN6iaP1RdK7kgWX3D4Z811T +uu7c14HaZXFIhopUkXNHrYIkH00YPocgywkkbOGyJH5gGAZSYw+arGIf9cYx +0FJ9GHnJiP6/rWgFM/oT7Ohp+l4S5sBQedAOeK7TDMBDMcQTMHFGiqPf+gmG +4QDqjZFWMi67FejmZSD3f0dbSYlepQ0aYpt1LC9i8MEPiNxXbCBpv1V2UHWm +UESr8kzhaDRlkWoPGo1819sEZFPROmhg/VS0UWDZX7dZVxsKFPqh8ybwQRJn +UEly0HqdTex74E26LwmqHuL0bMc52DuEiBgn3Bl70zsah+wzm8+jOEV2GxEU +l1RTMJ1qsnk2AqGQAcDksgHoNFMlijQm4Rmui+9Bbyi7AHVKUBJSP6nGyhKw +IFQvBabrNSbKOgLL0irjLAgcsA7sjVCoRURAQXQN/JLLtgYqp4A51Zwil762 +c5nxSefiAEV3d/fdJclzm61Jluywg/N58umXNYsMeFvLWUpXk9BoFBpQeiKU ++OGxhi3eCgv3uZ1Tl6PTzoikQc6oMAKQMroebO7QjpXhUSqDeTam7XzCMY0B +pQdT8l0/Ar4r4QB+a7RgwD9/THan8mPBJrGgTiXIbTbDJBkKbbAlnkJOY09c +r4HMl2uiBIeaWGJ6t1XSI4eSLmGPrpKSOlF+a6oTABB7RqjISA4qjnKMZu1i +Fhw/R+V05lqnckhlncrVpLHfpXJvNBdgbq5wpVEgnyI4yISqCqBm7TEtIiEY +WkSuQCMti41GpRN4VHR1nuBfT5y6oCWKQDKYoSszeFyG2pEqEWpvWiNBKo62 +WZ0bteLiQZ1dWPGlAIgY+1zaMch2V+5dLNwNgADguqzDKs8LuWIsuCdWHLRx +HiwK62uRJv6kLFJCrV/BmYBfwT4m5h28SJ5K8VnhA5MgOcpPUo5UdonHBang +ckl6ZUkCBUy9yiiHkiEKwY+pBZUsAaSmrCxLCtFty/nIcEW+pziqd2Oy9GM4 +qjUWNW4DxhXMRW+D5hSb+Rc1myzUBlNQuqx0L/P4cY33w2uAgf9FnFCXKq5X +eeTaOpPwD+r8X3UwK8tHDktbJBk91ZvVaN5Y85zCAUz6yXJI40w0sQpAWrBB +gXWCv5JUfrAXA0q1PB7zU7bEs427M0q/3YBDluKc4dlkHGOvHfMZ2XuRjfX8 +dJiS2z3Aki7mOqvdmWGebFnyFVgRi+LUxuzjYHc2SqhrL7uXzjwC3yUrrMQq +S2VIo0OchEkQ1mWhmNChYO7w5jxO80Mt4CpzszgWobtoWnToM8aIDLn0UBWe +QEkWqjMfkC6bZqEXA4UzPwgADEzZ7grnReMBnJRd6Y85ZRtOt6uO79wpxxWx +g+njsXaeyRVYIB37NBWhQC3VXS58rk/Vm3JhSO/iRcHF4sQvZENOfEatsvQZ +kxxqyVJVZbwbPT2s2YBP9FEfHhOpx5q0xlD1ws99MLaUz+Yg4J1REgUZtmvz +wXsCBkYYh13sZioAAM/Ryq1mSx78uVALC5fGEh/PmYbdl791nE4X/rFOp9/p +sN39s/MhsxH+4+Dob0zMI3faaFGaTTUvVJuyYh92bg8qf8OCtoStEafXWtar +XxzHareBDC/qg6CEe0U1vBB0AAuSJWLd1DoVgdSyb9kxWHquauZWv4l2SIkU +9Y7zWh1TGBXlThBor5iUkoLC4oB8sBBqA3E2FRyPL9WRtlJMH4Cg4kYOWFyd +KSQyVcnbDpC4xmC4oFmw71hMwEgFmg2E+bc7gx2lwtbnt4OPIQTGnEb2Qc5L +Luz8SgYPuXnJQr51cq+ZqJHLYqQ1TWcBhCZaN160GO6btufEQnpURV+i9gt1 +U7cDakRSlVXYGDTdywnVuFgSZbFbos9PW3T9pAVEKGr9tI0XMmpozWkCxXkW +9npd3ddFFjjHyURzjirG+vimIIxYpkfKzIZNIbPrYqIUFDhSW9y6QUsJulHS +ifooBhXlPBBg3RqTDRb5EIZyQMOGU12KISONckB4KQF3bvikXJe+UpQmpLld +QlwKsL6b45WZBEokMtQmuwphAUgWshkFoE+g0F7Mb3ggS+8bzHvT/AwbjDNk +r1kHHRCU28we4utn/2LYIJ2I8YQ7SRFsWPAd4Si3Qt2TwBSY0QsBXyGnngiI +AWka+6OMopQ0Y3WGJpfiLrgRyhTxKB/Qu1PYrFGz02mEPaTPtIj0DGmU5n4B +SbzJd8jGAsSiO7BgciY9dNpp4m5YsyxJSWiqGICyCrYLeBSd0umDpURxEX3A +EU8CamGI+Fr1LLAgK8hQim22FhXXH/3TxFokRaa33oLspH5CFQ7y1EpXE5Rn +xb+v1q/Okr9fl838CulAI2cKJo5KwzAYL6Hge9b89n1WB4wVmT3i4RXkrDxM +xmjXxrPXNWvaSTb6J8TCvt48ykrnC33VEf+x1NbDLeUjcHJFNF+1Q2F2aUM6 +X/pzqamhb7nCLFEbUtJeg7yPqZ10f0YXrbV0fM+a377P6kB5OdbWDoeVH9Qp +Kf6Vxam8fGt6Sb6j+Ti10t+reVSMdho/ZZ/1cI9JYHX9tjeUDvhJknHMqnlY +JHJ/Nj01FN6b+cqUuxl3K6L/HinU72eJ/81nAkc3FUezcLkh/bA1KRWSpYSN +wReq/SZFYEypIDmDdBfP7WQpJ8Pxkvhky/AMgBpgm+17e2c7zjuxADi7YVWd +onaIxZmGCvEetYoSneOYvkU2wxJIGeiGqDwvprwJzzgwd9X9MkxVjLSGzjKL +3iX2tG4xF4LUkq7l4kaDBZZM/IpQAywmq7O8HPYE1DGBKiKptiyt5+NFUiyz +sYiClJ5OYXi4YBHAyt6Bquln/mRKOZNK1mTWm6+G55f6XkmwUInQo0634L8k +61KRta3OlfHiZiGCEoyFiOG98NAc1MGmSp/9RrMM3GRr8l5+wVsH5ztefr1m +rUm3BZSR0SyJ2Fzn80avf2FpF4o5VxWgv9EzACB50wr1VqQfspFtzm1YFWds +3AxTO+kYRUEX35uJoaZWYTHalvIkROMyyMGT3fIOmxWUUG90kA5dnH3aef9+ +//zydP9s//Sv+5efjs4P9053PjXJ49hYbdg5gry1UhqF3PxS812eJ37Nt5m/ +KRFR7LlzS7su71Mj0feFO7ed0pR7nxoNbJx3clnQiUIeFUESVHp2lE2T5i4N +FbbO1kFxNeGAfA/fOu+j6Cqb2xXRgqypnVJK7DGHlxaB1yQM3YQSz4fKQ82R +RKuGcCmY6+6wxq692Lu/72KZn2YJi66wukH8so1ThmyNeEDbe71dI0r2K3tA +itXpztOml0JZobYkl0q6UapwCl9QMMsQWk00KjyMFog8Qqkeg5gUPWojkoWV +Tn29tRmrVrHkkSXfa2XZvPvMPsjv8Xx7eTkTMWpsqspL/fGx8rKAw/JSjskW +/joxetncvB2A30JKo5+eJwIzwGYu1bmzih/d3ovGyvO1QOQ3GLaZ7Xt05OgK +fV0sja5E+JdmsdLqyB/fVp7sMZsoaH2B9eWKd2Y1+j3JXhihtVaTnFVmauYQ +Bhn6Vlzz26mtDmj+tIk/SfuL5JPv3bXdgPszxaSHCiH6s9UG0H1K5prb//nl +DGPTS1QfnbLkqqTspPmNFKxpW3UQY9GAVXnNqkjz+2hFZx+/JTPOwDF5gnvg +oYTSf/1xZdzYgaWLxdumhksDI/tSyv5tLCj8jWRw09jBNyFcvuvVWSqjhd58 +izaJ9/1ps09mXkubML0+2bdpNCtPvJ84lYKCzpxWRVf9e6Tm1eTKtkOp6v0e +U63Jq8yQKDdVbXUYM+uFsXzN85O9kz7zomwUCEeioetQ8p4WDfylfuY6ZQhN +VhxRbrNdGDkTgfwOj53T8yW3AjIriBtyWTyxyDzBjnl8tedDUcewhLbWYYfd +snQpsCvRrgMbunXRAWjyBB1Tw2RJXusLMg7THJXx3hUEEycloq9m2mPIFhZT +GB+KRn9SIAEnnKvZ0kCCf/aDRP8ZgUQqEebdmoyWqSK5UpAqrIx1XaLdkxht +vcGnOIzeYw6j97MchhQrkXCvvfSzHUaPFLlXcRhGw2qIXmXYZEOyq6H8qh0O +9oZ0eP7QaeH00oiceZnBwefgPfH/ODsZ5LbUwFZKpYI/3j/dPdwZnF/ungzO +T3d2zzFC5hMsIqam4t89ORpc7u1/ODk7OtfVvkFJufw2KnIkTtXguQaqlOer +LBt0TawmFZFRx2tzsBKF1Zx1rehQY64TMqowlbJqoHsP8DzVLH0qFDeo/dGr +Zd6Hnb8f78Prybsy+0i+ttGBZEYHEnK6KPDdhTyuVH1CvF6EPr9R/o6fKN05 +xMs9FFTkxSi6fYKtPizk6eSRhwupVZW7MS3rMLrBlh5928KNssDLb1gr0HFG +R+hpRN/MEPgdfXCCU3+uLs/I+ocOwpT/tkTIsTidIB7H5XSNIHOnqKtrWUjJ +Nzxdw1aDPkCLVUNSYcO2omoqwmKIE++y4jdD1OUf9VsVeTMX2Khu+6tDWazo +r30vo+96+GHSkveslMjN0ljLuL1KeVw5edUfHyuNC7iiNF61rFaKCVBqosz8 +mVELoCcxFU0BFjEzD8DUR9YNgqrjWr51A3DpyWh7xFN36ugVTadaezJapCNF +Cl5KnpsVq76rIbzYe5OVfa3kzUOEM81NzSGzXF+65W9n1kOQ67qtW2oN5tHa +dIZPrScKHaq0ERXyvIe4MtqKs/7B9Wn+94MKVcWFUkgu8VWH5a7KPp+K+YH2 +XnWNxvcypISwaBPKHuHTaEbx49XeBH8xCG8Urzpd5+Rad2KBN3TwECW+chDb +E+pFIMXLArwXatymWHm6dquXRTKA1dWN/aQEdKOcgJZ8NSnFxo9PQGndZt0G +flICakYquSnS9I3lCejG0otpCGCmP/t/w+zn7T7mjgdHp8dLE8L76Z6ZXamk +rIY/xsz7jaVHU8Ha+oc5Ndlf9fApnyWr00pu2NDtd/yljCzGH6faxcvXnjrJ +TNTvJ+3R7yc9Y0d4y7MKMYhC/KUFVI8Rd6/oJ1rkpbQgmuCnHRe9dyC8ifyh +ri99+Ws/wtteG/MgEWt3pXXo7Jd+bOeGvo5PX4mUqR1d9FZ33+RvWrED4dEP +Kh3Tt0pjTCutfS9zi6PYU5EIDrtm9pvjNwfy29BFRon3m3BPeCAh8A0JAjKv +/wPrnFD5KU0AAA== -->