From 3e824759fdaa82a40f485ccf4e56b97cd80bb8ef Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Tue, 1 Feb 2022 15:16:33 -0800 Subject: [PATCH] Wallet tutorial: more polish --- .../build-a-wallet/py/5_send_xrp.py | 6 +-- .../py/6_verification_and_polish.py | 9 +++- .../build-a-desktop-wallet-in-python.md | 42 +++++++++--------- img/python-wallet-6-err.png | Bin 22815 -> 23051 bytes 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/content/_code-samples/build-a-wallet/py/5_send_xrp.py b/content/_code-samples/build-a-wallet/py/5_send_xrp.py index e555bec438..5b510b08cc 100644 --- a/content/_code-samples/build-a-wallet/py/5_send_xrp.py +++ b/content/_code-samples/build-a-wallet/py/5_send_xrp.py @@ -202,9 +202,7 @@ class SendXRPDialog(wx.Dialog): def on_to_edit(self, event): """ - When the user edits the "To" field, check that the address is well- - formatted. If it's an X-address, fill in the destination tag and disable - it. + When the user edits the "To" field, check that the address is valid. """ v = self.txt_to.GetValue().strip() @@ -565,9 +563,11 @@ class TWaXLFrame(wx.Frame): resp = dlg.ShowModal() if resp != wx.ID_OK: print("Send XRP canceled") + dlg.Destroy() return paydata = dlg.get_payment_data() + dlg.Destroy() self.run_bg_job(self.worker.send_xrp(paydata)) notif = wx.adv.NotificationMessage(title="Sending!", message = f"Sending a payment for {paydata['amt']} XRP!") diff --git a/content/_code-samples/build-a-wallet/py/6_verification_and_polish.py b/content/_code-samples/build-a-wallet/py/6_verification_and_polish.py index f8bcfc6828..61b0d9359f 100644 --- a/content/_code-samples/build-a-wallet/py/6_verification_and_polish.py +++ b/content/_code-samples/build-a-wallet/py/6_verification_and_polish.py @@ -338,7 +338,12 @@ class SendXRPDialog(wx.Dialog): destination address. """ # Keep existing error message if there is one - err_msg = self.err_to.GetToolTip().GetTip().strip() + try: + err_msg = self.err_to.GetToolTip().GetTip().strip() + except RuntimeError: + # This method can be called after the dialog it belongs to has been + # closed. In that case, there's nothing to do here. + return if not dest_status["funded"]: err_msg = ("Warning: this account does not exist. The payment will " @@ -723,9 +728,11 @@ class TWaXLFrame(wx.Frame): resp = dlg.ShowModal() if resp != wx.ID_OK: print("Send XRP canceled") + dlg.Destroy() return paydata = dlg.get_payment_data() + dlg.Destroy() self.run_bg_job(self.worker.send_xrp(paydata)) notif = wx.adv.NotificationMessage(title="Sending!", message = f"Sending a payment for {paydata['amt']} XRP!") diff --git a/content/tutorials/build-apps/build-a-desktop-wallet-in-python.md b/content/tutorials/build-apps/build-a-desktop-wallet-in-python.md index f7c852e168..bfa48a63a6 100644 --- a/content/tutorials/build-apps/build-a-desktop-wallet-in-python.md +++ b/content/tutorials/build-apps/build-a-desktop-wallet-in-python.md @@ -185,7 +185,7 @@ In the `XRPLMonitorThread` class, rename and update the `watch_xrpl()` method as {{ include_code("_code-samples/build-a-wallet/py/3_account.py", language="py", start_with="async def watch_xrpl", end_before="async def on_connected") }} -The newly renamed `watch_xrpl_account()` method now it takes an address and optional wallet and saves them for later. (The GUI thread provides these based on user input.) This method also adds a new case for [transaction stream messages](subscribe.html#transaction-streams). When it sees a new transaction, the worker does not yet do anything with the transaction itself, but it uses that as a trigger to get the account's latest XRP balance and other info using the [account_info method][]. When _that_ response arrives, the worker passes the account data to the GUI for display. +The newly renamed `watch_xrpl_account()` method now takes an address and optional wallet and saves them for later. (The GUI thread provides these based on user input.) This method also adds a new case for [transaction stream messages](subscribe.html#transaction-streams). When it sees a new transaction, the worker does not yet do anything with the transaction itself, but it uses that as a trigger to get the account's latest XRP balance and other info using the [account_info method][]. When _that_ response arrives, the worker passes the account data to the GUI for display. Still in the `XRPLMonitorThread` class, update the `on_connected()` method as follows: @@ -217,22 +217,22 @@ Add a new `prompt_for_account()` method to the `TWaXLFrame` class: The constructor calls this method to prompt the user for their [address](accounts.html#addresses) or [master seed](cryptographic-keys.html#seed), then processes the user input to decode whatever value the user put in, and use it accordingly. With wxPython, you usually follow this pattern with dialog boxes: -1. Create a new dialog, such as [`wx.TextEntryDialog`](https://docs.wxpython.org/wx.TextEntryDialog.html). +1. Create a new instance of a dialog class, such as a [`wx.TextEntryDialog`](https://docs.wxpython.org/wx.TextEntryDialog.html). 2. Use `showModal()` to display it to the user and get a return code based on which button the user clicked. -3. If the user clicked OK, get a value the user input, in this, whatever text the user entered in the box. -4. Destroy the dialog. +3. If the user clicked OK, get a value the user input. This example gets the text the user entered in the box. +4. Destroy the dialog instance. If you forget to do this, the application can leak memory whenever the user opens a new dialog. -From there, the code branches based on whether the input is a classic address, X-address, seed, or not a valid value at all. Assuming the value decodes successfully, it updates the `wx.StaticText` widgets with both the classic and X-address equivalents of the address and returns them. (As noted above, the constructor passes these values to the worker thread.) +From there, the `prompt_for_account()` code branches based on whether the input is a classic address, X-address, seed, or not a valid value at all. Assuming the value decodes successfully, it updates the `wx.StaticText` widgets with both the classic and X-address equivalents of the address and returns them. (As noted above, the constructor passes these values to the worker thread.) **Tip:** This code exits if the user inputs an invalid value, but you could rewrite it to prompt again or display a different message to the user. -This code also does something unusual: it binds an _event handler_, which is a method that is called whenever a certain type of thing happens in the GUI, usually based on the user's actions. In this case, the trigger is `wx.EVT_TEXT` on the dialog, which triggers immediately when the user types or pastes anything into the dialog's text box. +This code also binds an _event handler_, which is a method that is called whenever a certain type of thing happens to a particular part of the GUI, usually based on the user's actions. In this case, the trigger is `wx.EVT_TEXT` on the dialog, which triggers immediately when the user types or pastes anything into the dialog's text box. Add the following method to `TWaXLFrame` class to define the handler: {{ include_code("_code-samples/build-a-wallet/py/3_account.py", language="py", start_with="def toggle_dialog_style", end_before="def prompt_for_account") }} -Event handlers generally take one positional argument, a [`wx.Event` object](https://docs.wxpython.org/wx.Event.html) which is provided by the GUI toolkit and describes the exact event that occurred. In this case, the handler uses this object to find out what value the user input. If the input looks like a master seed (it starts with the letter "s"), the handler switches the dialog to a "password" style that masks the user input, so people viewing the user's screen won't see the secret. And, if the user erases it and switches back to inputting an address, it toggles the style back. +Event handlers generally take one positional argument, a [`wx.Event` object](https://docs.wxpython.org/wx.Event.html) which describes the exact event that occurred. In this case, the handler uses this object to find out what value the user input. If the input looks like a master seed (it starts with the letter "s"), the handler switches the dialog to a "password" style that masks the user input, so people viewing the user's screen won't see the secret. And, if the user erases it and switches back to inputting an address, the handler toggles the style back. Add the following lines **at the end of** the `update_ledger()` method: @@ -263,7 +263,7 @@ To test your wallet app with your own test account, first go to the [Testnet Fau At this point, your wallet shows the account's balance getting updated, but doesn't show you anything about the actual transactions that caused the updates. So, the next step is to display the account's transaction history (and keep it updated). -The new transaction history should be in a tab, like this: +The new transaction history displays in a new tab, like this: ![Screenshot: transaction history tab](img/python-wallet-4-main.png) @@ -275,7 +275,7 @@ First, add the following imports to get GUI classes for the table view and notif {{ include_code("_code-samples/build-a-wallet/py/4_tx_history.py", language="py", start_with="import wx.dataview", end_before="import asyncio") }} -Next, update the `watch_xrpl_account()` method of the worker class to pass transaction details to the GUI when you receive a transaction subscription message. This requires just one line: +Next, update the `watch_xrpl_account()` method of the worker class to pass transaction details to the GUI when you receive a transaction subscription message. This requires only one line: ```py wx.CallAfter(self.gui.add_tx_from_sub, message) @@ -289,7 +289,7 @@ Have the worker use the [account_tx method][] to look up the account's transacti {{ include_code("_code-samples/build-a-wallet/py/4_tx_history.py", language="py", start_with="# Get the first page of the account's transaction history", end_before="class AutoGridBagSizer") }} -**Note:** You may have to [paginate](markers-and-pagination.html) across multiple [account_tx][] requests and responses if you want the _complete_ list of transactions that affected an account since its creation. This example does not demonstrate pagination, so the app only displays the most recent transactions to affect the account. +**Note:** You may have to [paginate](markers-and-pagination.html) across multiple [account_tx][account_tx method] requests and responses if you want the _complete_ list of transactions that affected an account since its creation. This example does not demonstrate pagination, so the app only displays the most recent transactions to affect the account. Now, edit the `build_ui()` method of the `TWaXLFrame` class. **Update the beginning of the method** to add a new [`wx.Notebook`](https://docs.wxpython.org/wx.Notebook.html), which makes a "tabs" interface, and make the `main_panel` into the first tab, as follows: @@ -321,14 +321,14 @@ Lastly, add a similar method to the `TWaXLFrame` to add a single transaction to {{ include_code("_code-samples/build-a-wallet/py/4_tx_history.py", language="py", start_with="def add_tx_from_sub", end_before="if __name__") }} -As before, you can test your wallet app with your own test account if you use the [Testnet Faucet](xrp-testnet-faucet.html) and the [Transaction Sender](tx-sender.html). On the Faucet page, select **Get Testnet credentials** (or use the same credentials from before). Input either the address or secret when you open your wallet app. Then, on the Transaction Sender page, paste your address into the **Destination Address** field, click **Initialize**, click various transaction buttons to see how your wallet displays the results. +As before, you can test your wallet app with your own test account if you use the [Testnet Faucet](xrp-testnet-faucet.html) and the [Transaction Sender](tx-sender.html). On the Faucet page, select **Get Testnet credentials** (or use the same credentials from before). Input either the address or secret when you open your wallet app. On the Transaction Sender page, paste your address into the **Destination Address** field, click **Initialize**, then click various transaction buttons to see how your wallet displays the results. ### 5. Send XRP **Full code for this step:** [`5_send_xrp.py`]({{target.github_forkurl}}/tree/{{target.github_branch}}/content/_code-samples/build-a-wallet/py/5_send_xrp.py) -Until now, you've made the app able to view data from the ledger, and it's capable of showing the transactions an account has received. Now it's finally time to make the app capable of _sending_ transactions. For now, you can stick to just sending [direct XRP payments](direct-xrp-payments.html) because there are more complexities involved in sending [issued tokens](issued-currencies.html). +Until now, you've made the app able to view data from the ledger, and it's capable of showing the transactions an account has received. Now it's finally time to make the app capable of _sending_ transactions. For now, you can stick to sending [direct XRP payments](direct-xrp-payments.html) because there are more complexities involved in sending [issued tokens](issued-currencies.html). The main window gets a new "Send XRP" button: @@ -346,17 +346,17 @@ In the `XRPLMonitorThread` class, add the following lines to the `on_connected() {{ include_code("_code-samples/build-a-wallet/py/5_send_xrp.py", language="py", start_with="if self.wallet:", end_before="# Get the first page") }} -Add a new method to the `XRPLMonitorThread` class to send the actual XRP payment based on data the user provided, and alert the GUI when it has been sent: +Add a new method to the `XRPLMonitorThread` class to send an XRP payment based on data the user provides, and alert the GUI when it has been sent: {{ include_code("_code-samples/build-a-wallet/py/5_send_xrp.py", language="py", start_with="def send_xrp", end_before="class AutoGridBagSizer") }} -In this flow, the app sends the transaction without waiting for it to be confirmed by the consensus process. You should be careful to mark any results from the initial submission as "pending" or "tentative" since the actual result of the transaction isn't final until it's confirmed. Since the app is also subscribed to the account's transactions, it automatically gets notified when the transaction is confirmed. +In this flow, the app sends the transaction without waiting for it to be confirmed by the consensus process. You should be careful to mark any results from the initial submission as "pending" or "tentative" since the actual result of the transaction [isn't final until it's confirmed](finality-of-results.html). Since the app is also subscribed to the account's transactions, it automatically gets notified when the transaction is confirmed. Now, create a custom dialog for the user to input the necessary details for the payment: {{ include_code("_code-samples/build-a-wallet/py/5_send_xrp.py", language="py", start_with="class SendXRPDialog", end_before="def on_to_edit") }} -This subclass of [`wx.Dialog`](https://docs.wxpython.org/wx.Dialog.html) has several custom widgets, which are laid out using the `GridBagSizer` defined earlier. Notably, it has text boxes for the "To" address, the amount of XRP, and the [destination tag](source-and-destination-tags.html) to use, if any. (A destination tag is kind of like a phone extension for an XRP Ledger address: for addresses owned by individuals, you don't need it, but if the destination address has many users then you need to specify it so that the destination knows which recipient you intended. It's common to need a destination address to deposit at a cryptocurrency exchange.) The dialog also has **OK** and **Cancel** buttons, which automatically function to cancel or complete the dialog, although the "OK" button is labeled "Send" instead to make it clearer what the app does when the user clicks it. +This subclass of [`wx.Dialog`](https://docs.wxpython.org/wx.Dialog.html) has several custom widgets, which are laid out using the `GridBagSizer` defined earlier. Notably, it has text boxes for the "To" address, the amount of XRP, and the [destination tag](source-and-destination-tags.html) to use, if any. (A destination tag is kind of like a phone extension for an XRP Ledger address: for addresses owned by individuals, you don't need it, but if the destination address has many users then you need to specify it so that the destination knows which recipient you intended. It's common to need a destination tag to deposit at a cryptocurrency exchange.) The dialog also has **OK** and **Cancel** buttons, which automatically function to cancel or complete the dialog, although the "OK" button is labeled "Send" instead to make it clearer what the app does when the user clicks it. The `SendXRPDialog` constructor also binds two event handlers for when the user inputs text in the "to" and "destination tag" fields, so you need the definitions for those handlers to the same class. First, add `on_to_edit()`: @@ -375,7 +375,7 @@ Next, add the `on_dest_tag_edit()` handler, also as a method of the `SendXRPDial In other GUI toolkits, you might be able to use a dedicated number entry control for the Destination Tag field, but with wxPython there is only a generic text entry field, so the `on_dest_tag_edit()` handler makes it behave more like a number-only control by instantly deleting any non-numeric characters the user tries to enter in the field. -From here, you need to edit the `TWaXLFrame` class. First, in the `build_ui()` method, you need to add a new "Send XRP" button, bind it to a new event handler. Add the following lines: +From here, you need to edit the `TWaXLFrame` class. First, in the `build_ui()` method, you need to add a new "Send XRP" button, and bind it to a new event handler. Add the following lines: {{ include_code("_code-samples/build-a-wallet/py/5_send_xrp.py", language="py", start_with="# Send XRP button.", end_before="self.ledger_info =") }} @@ -425,7 +425,7 @@ You can now use your wallet to send XRP! You can even fund an entirely new accou Save the classic address and seed somewhere. -3. Open your wallet app and provide a **Secret** (seed) value from a [Testnet Faucet](xrp-testnet-faucet.html). +3. Open your wallet app and provide a **Secret** (seed) value from an already-funded address, such as one you got from the [Testnet Faucet](xrp-testnet-faucet.html). 4. Send at least the [base reserve](reserves.html) (currently 10 XRP) to the brand-new classic address you generated in the Python interpreter. @@ -464,11 +464,11 @@ In the `XRPLMonitorThread` class, add a new `check_destination()` method to chec This code uses [`xrpl.asyncio.account.get_account_info()`](https://xrpl-py.readthedocs.io/en/stable/source/xrpl.asyncio.account.html#xrpl.asyncio.account.get_account_info) to look up the account in the ledger; unlike using the client's `request()` method, `get_account_info()` raises an exception if the account is not found. -If the account _does_ exist, the code checks for the [`lsfDisallowXRP` flag](accountroot.html#accountroot-flags). Note that this is a "lsf" (ledger state flag) value because this is an object from the ledger state data; these are different than the flag values [AccountSet transaction][] uses to configure the same settings. +If the account _does_ exist, the code checks for the [`lsfDisallowXRP` flag](accountroot.html#accountroot-flags). Note that this is an "lsf" (ledger state flag) value because this is an object from the ledger state data; these are different than the flag values the [AccountSet transaction][] uses to configure the same settings. Finally, the code decodes the account's `Domain` field, if present, and performs domain verification using the method imported above. -**Caution:** The background check takes the Send XRP dialog (`dlg`) as a parameter, since each dialog is a separate instance, but does modify the dialog directly since that might not be threadsafe. (It _only_ uses `wx.CallAfter` to pass the results of the check back to the dialog.) +**Caution:** The background check takes the Send XRP dialog (`dlg`) as a parameter, since each dialog is a separate instance, but does not modify the dialog directly since that might not be threadsafe. (It _only_ uses `wx.CallAfter` to pass the results of the check back to the dialog.) After this, it's time to update the `SendXRPDialog` class to make it capable of displaying these errors. You can also set a more specific upper bound for how much XRP the account can actually send. Change the constructor to take a new parameter: @@ -511,7 +511,7 @@ You need to make a few small updates to configure the maximum send amount in the {{ include_code("_code-samples/build-a-wallet/py/6_verification_and_polish.py", language="py", start_with="# This account's total XRP reserve", end_before="self.build_ui()") }} -Then modify the `update_account()` method of the `TWaXLFrame` to save the latest calculated balance. Modify the last few lines to look like this: +Then modify the `update_account()` method of the `TWaXLFrame` to save the latest calculated reserve. Modify the last few lines to look like this: {{ include_code("_code-samples/build-a-wallet/py/6_verification_and_polish.py", language="py", start_with="# Display account reserve and", end_before="def enable_readwrite") }} @@ -541,7 +541,7 @@ To test X-addresses, try the following addresses: ## Next Steps -Now that you have a functional wallet, you can take it in several new directions. The following are just a few ideas: +Now that you have a functional wallet, you can take it in several new directions. The following are a few ideas: - You could support more of the XRP Ledger's [transaction types](transaction-types.html) including [tokens](issued-currencies.html) and [cross-currency payments](cross-currency-payments.html) - Allow the user to trade in the [decentralized exchange](decentralized-exchange.html) diff --git a/img/python-wallet-6-err.png b/img/python-wallet-6-err.png index ac5e132abd8da3d0659b1bcb908272678e9a16dc..0b945bb3810220cbd32a9cc84e7ed11d5c02a8ae 100644 GIT binary patch delta 16940 zcmZ{qRa70(wx)4+cMt9o91`5!-Gf7L-yuM7x8N?pgS%^RcXxJh_pY4NeaE;D%>!do z?5bsR&H4Y|s+?NL$a=`QcF>V~K`xoMNQJie>AcFtB>vg_C(sW|*Yf>U%Ba`&t}0M* zpm9N}isPy=(c_CJ^Vo(Q3ChO#*7yDS&?h&Fqs5G=bNCKU(oCGkOfmnME}!1u7whcK z7rS(Ocb>P4LUh%~t7G+gDev*=Lu<)*fe(J^doTO1p+nK~qA`E6o|9Eg#|4+6 zYqm2f{<_OLY18?$TOzAeS2Ua7MZl9Y`htqzHJ8xk?hvW57;+@v6FZ{sR_Xf;zNgdb zU+#OyWI?u}UmMdu)j>ut$FYyI$P=mzd?hV3H)rA1_v!YndBexavteO^)v}77-#0~b z-WjR_5opJ2|#4P(Nc=`nx#Y?pH(ON`@2UlmbiBjICXz z=h?DNi>v!#@J1-PX@C6Ka6y#7%2DD?+SlT=FKOLOo}A z@<;WRd>|I9@3N9yY*D>RK2^$BivP=BlqZbuXMT!pCH`YEMMZpnH%v|(9ZFUvOEa2N zH4WCX^c4gQe{Ll!pG7Vko+*7AA7kLy#ll{YGrzW^WRc45-Yu;n%lS)@J`j394Q*kj z?O~&SF;`;({4an~LJp zR&yjlR4XI3gYH+qmB5I+k=)a6LhhNaH!C zc!UEu=xV+DLIR06MBdU7jDf3qi9}%;Vu+db%=d~kAo)^}J9V*@2H)C|Zp!<_*TnmH z0R|BSZGMG*W|8#0LHlU#zji9v3n9xBH^P`fOT^)##iLC9mb;lFKRU_<2b|iFu}Uze zA*eox!`+W3G23E3DVDQwQuJw>peNK=@%Ap4XKvFCgc#7EHC)~oYZ#;vx**Q(x!fHm zv2*eHf}#U)Xqq5wo7qoW&IDg%Hj?Wx^&)q?f5`rbekA(+n{KhyRb4vYXqS@Tnr%NV zayOuaZKrdQigc3o%kct=Nsh2QNfMRiN0bgy$BT#ws@tDgOJeT6Mb1hwZPA`KG;%?E zf~!Tcf-npB`!0D}e`N;~xyxI!kXf$l?p+`v?m^w?!fh03ZD4r&)jHK0>AEbNF8l9; zQ)geVU-5-YWNeZWzK9t}P?(ofF|f}c>OznQ8Ngh`xOm(y&+P?VX)0dE%?GzScWgel zH5NK-rV>;=7FRlT`S>St@(=_pCq26Kkn_xUC(hK-MH_C;9ZEcUX58DRabu$Fu~(#n zhe2!|P7+t1(YLEQK3RUs$wHl9-W;IM!Q)*HTmBu7O{neFyzh;H_qPZ4LyY>Q=3f2Y8!>;4lLKtm35Ik}QlO3a2+lT|Pr`toD1pc?b875QF z*pK&Ao9DCWniP)iET(stSM{)O)bhS_5`z@7FfhH_IEkp*+$Kx!0wBlIiCbJn6LYD* zi(s}^X%w-IlRKdkL7>lVnJrhS^@@Z=cTTu{INxPGSEjJK!vTx9uVO>XK|m%@mYEWM zilyMlY>+t@;J|^K_4A0-r<+2rmvcqaoo&`7FU4Piv_GtvBklv6HqX8OQBWa4lLf&P zl4p!pmE)aj93!AR+nW&QrGB_j>;G;^i`mxc=kKEl!pBzw;IC83T@&HdAso^!Xv^blwg#{u^&SEwVHy=()ca+ zg^k;`Q?8#rpfpzwultiw=h2zOj?;jG{!FEEuI4|GXmFH|KL*Ps-oWp<%M2G*C8BEz z)kxt_p*^Xq=fDiQU?!5yRejF4Jd@8)5Drdz8NsAIw#Ew{KT~8vp1Gn*;-LNXCtRM& zlTv1z9AEqTlLI&~X0_Nmn1y<#i3{ThhttNla0b&Z#sI;a^~FR4Ye>iM+~X5SbBk4) zN8KHEUauCD(sWaHc+AVMM7Sg0WVL0y^86L1>^FX!cZpX9y9cxWWCD3 z@$Xl=2C&i_JT87n0qeN~lzqZ!6%lTkm8)~R^l;Pc@u?|w>)-jCsXt(1__*gYtcQDw z5a^j_PW@I42`s=CroOYFsSQ;JDPj>>s}{tEmDX6pKUFB!y6W}A(i|s4(kxlW@%Lh& zcS}B^Xhfai#i^I-CD7C-BPSY>=y^tysv;7ii)F8^VnRva8TI8bVq?bVD|*JXU^BO# z(&3rO>+LQ~k79m7tDf!A#47Tncn}lWIZQQ23l()J=5~-$(~)gnli7v_fe62$eNubs zo(vOB;DNCcX-Juw$400v)eMK&V9{$3i_@4&oYZGKda$3%`m@P zOkMHZe}lg%i=w90uM+A| z#Dz`aQDAGPVRhP|Qn>fCOF5)awDQ2C4a0Xrco8{P)0oeGqNfn=iGEIDUQ;n42<)pM zz=-~R#e0$JO8(djciTv_Q~K+4x(9~^@upYhxntiz z=A?v%D;SnA3wCrG3yHd2r@i#B!I(}eg;_UGxdM32Yl5`j>dAaG5Hvy6lJ~7Mj|%cA zNpYQoS;8`N`1-Sc7ndC*f}^^6P}(i8eRl3(DKtWL1&Ud;m;6gao0mZ zR@(|g7vpMwRDzk-{#45D%!puUL@{9(J5p5QbYORA<+iMpGx3i8hUf?=b8$wbXQ@+l(N=Htdrzt?$HA-@7IAwLe z)uyz&_Dm`5eIMFW9)Z3xPa3Qq$QR4t?`0;a$@HM9)BYUg!l> zg69G1kJS$J&E0e^63Yt#aa%$=19z_I8EH=IgW|8VZ3I_JIP9m3lq7~M8lnr@bfdUk||By z+Z^%k2qX_QpTSZ0AGhWWm3q_?;#stY`?*X%(Q^l7bFmn)OLBU!Ff_kSpoem%?+Wy| zF{ky94QJ2LO4h&r$jEInSEW}8VJOubW1B)2|0Z7qb^2=`LSGISo#j-=rjP~ltk#ZQ ztOyZ4{PQjg=3H`>5v%(lJYe*;71~DNPs(yhw4ZEM)C2)Wg z0PpC8sDcufT-sWs5C#92C0XGHT#Eb>IN#=!cm)wcj}u+8p(&YfL`Ww z6gYRV3xe!2fw)35<(F2Fi4K_#lR4&+lWR=W{Z3MDmbOI^{o?nnbk0w(KYq)^INYDZu?PfG^akFLKfZBYedlhpl z(H@(J(|5AaNb??JqY6&2!Nh{Zgq=EpdJyVp6;!M^B!(Fz*u&9hdH&5Sy_VcOR{TSb z5!HQ>RjAen+#)%vf=cSInG(%AnvltDW)e)NCoyHPNCrw&vP_JK!hGAzLA zgQ0s)n-yZq21JUrgycR6lCrQ{l^=3Z`{;6=jqG*lTvD$q8p8zEX2zuAMqk`05hEmc zI6#u-O1FoMmXr|SZUTe}Q;31PFC11o1i=9mvmBb($mF(%w#M-6we}o&LsXdJCpms& ztBKwa88rISBF2|R)i9qeOvSjqHQnt)sUv;cX)ow5j}D?PQQ=C%C5y86++RseW0wqu zJ^W4TEwx9FDh@Z8LVX3HjxwJouMh2i{sT0Ci6BeY{b{L@EPxh4nq4nw_KBR6Xt(ym zBr(~7yUs%50L^VC@uyl;x7c*S;e<@q0!|iU>sXlzQ@FJi*8R|WjttFC@nvgb*wlmScCGd^a$zKVw}4f#Tp$EX*@}4V{;=pqn1|aI)0+oAZ3kF zgr>!H(#_ZJE^Nim$_B_o{fWf6D5TbR{_b5$pZ;U z^V@Tpg$ePjblT~7Rz7@^rvMc;@?+G{56xIVZMk$5AoG@+f_a|Tn^dRZhbz7vDuk=B z-*Eoe6!KOXrLv7~X_w2GA8NAm`vuCW6#E|pnaywB)R&`EG=_GN$8 zRCMfPs;b?E4F)uz4a?=h1uW$k^(|V|Hqr*j-YN*l z8Vl-1Dw!9j-20}zet@<{!Ef$FVUe-7Qc8FV!gTz*T6?`te>MmDfwI2;O4_=qPu;m5 zl3`$*B+HQ$%Ch=5P~o1hC)zYJZTYA4aj@yi_ed32*P`~Q8(WDM<1f)mYU9-KQdahl zZFd3n&!M%WLxe(1X=}e*#C<39iAa+{1Ba~axgPm2V~E#}ewQK!ox+nZXW?A}lP_Bm zr+u`Lo2GY{$E7%dUx9)n2D}L=RM@Y;_U4#mM#@>(h*M}rk5#xNJ8-nzR&yn-L<*AWBu53D9G z8_9Rm3~BBP_E~L|U!8HGzR=b_qRNeSAYfqcOjFjwh=kIJ6tK5UNUO7H&H*Jz()x3W{Bmr}pn}s2+^p`r^tD-Y@(qv2Mz8UhOk}z#m+HZe?`g5)NHLBqDX-I zMaepLe`yez?zlw(bLkw`4uSU8+s42g^3wFW|A|Bu2cb=U>nF!S*9#PMn`{ZVnT_2=!dL6au4ubM$?oj-rUw(kg?z{qBQ2trs$ zBADsp-5Pf%;b!r-wN6hV8BFxJ@k?{|HZ)j>p_{|y=*Yl?)xOQem6_FOl$=!MSyn!% zbK?@D%+jFyBy2c_!1{@E*B{PZhd4qhAL$SjQ7VhdL|7lF+t6}CjfrNY{E1)_CbU}e z$(Dlw9S-zktM<>suc#^;0+#Ey;{!+@wuWGiN@RkO8reA9^)=G@L7J=qw|tqO$A=8e zd(1{EcKW1>rH3jPe{d)ho3EdBV}1Mm_+czxPWGy$E3$=Uy9Ec}1>;c<*7o5lYr4=u z9WfLhKQz=KH*+P+EIhuuH^qJvCC<4;^6_mFRB+~ld9e=vyulj>wZ?YxtLZRyQ^?}& z>d!~aI}#T#F2!}ur4;+=BFk$h6dup8%~}cBH*kp1ru1Z#V*RiNcM+K?PD^#mM25&K z%G7kT0M5$iHH^4~s>@HF*})7*9tsdrptc$si(eFQWAL16X4ZA2rDdgL`|+i}gON}& z`pH?q@vx_P9CA{*mZe5FrHRgVpEppUmV0?Eg=8V3ad{ON2AdKioAjiE4dg5H^QuY` zF4$DUPLSCPA?bg8K6I-ZeY4BZORk&Y#_VbelcqR~Xt;uZI!d&JMHQ75*^H z;j5@TTYv`7#3+U=E(pb8UCvM(kg7=TCUF*$9D!Gy(8zwY4{oW97V3s~Nrb)JUW~!h zqWXO{0$m;Kd~!@r`;t-F*8rrr6e7X4Z?EOz%_Rv}2Gl(zWKab(O zUurN6rDiBjuvA$Nx;e0gJ4moA#n185>v`5kp6>L^H4>B0{x$sNShLKJFXkvrAJkU2v zMCWlzIq%kic>KfO-&4;{sA=_FNiZlkMyUxEL6wDY{)a%2i~5KJ0RsU0@fSFfVSXL(U0o42=_Snc$#uAANDgB(`H0HdrQDU7*PPYozob*5~r z$gq|~Y+=U74vMQ&dP)9A0hP~w)}Kv}WNW_+?DWkKuLeCxy%jW~!WN=l{iNep zyBzw{hvzO&gAd`GV@)y9&9vfkUIODfc^wItuW?JV`VM`E?ABEu)=UKf0U4agL`VuM zqQZrb4C90OrGzITNz#BMS&CsBqD87;^aQU+lz@XT-P5qOHEA~AGoY&tul*V01@fz# zi<(tP-ba2D6%)|Q74}JF}0F3cU*Tk5?N(lhTR8t zc_&~~VY3N2W`B9_ApF*`HZO|Sot_IT2`eZoR_~0v)Y)$z&}Gurz0Q6K+0N{&9dp+c zmodSVkE0O#jQb(Ulv=7yDIx?XYsmj4sLGfsRjdk&fFDmK5N`Q4=)LEBS?_TKgviD~ z0xw`pa%c{Na0(TjzUxOWsI&`%AOfxJGiv+`nk%PpQBUs%;bwMsv|7T(|t0$TZp z{hunF!Vi1b-Oq&n>Uc+Ou&s;jEj*K7pCAftv_^=xwlD}-RPI_Q+uBwR@0^rf14Lsu zU23Z;NR%NUP+x5{blh|l6$H$k>IR9vLD5)PnVFec@tCt%@tAS4aI^EVv+#49nX#~& zvvZl5T7IEh%v<0pb0)hfUR^qdU*UIU-w-=6O>;0vZyJxE)6QZsR6l5UA#~v7!PcRan zCHc78xmZ6#e*GLR{gt@KS&EM}3{xm-I3IO6v@iAvhL}A;wLyDcWRY6HzTs?No^&CbNY^ z84Oc}A%=ixKp7m@jr-pZ7`I~D^9pUtfsbO+DrJ+Fu+E0YS|cG=N*Y4q%DG%}6UdY_ z&g;;Ng++#Sz6>>UZwbv2oQtKuT{n`xPtc>X0Z(EnnW{*zE6a%H7t*+hlfnl9ZD|?& zVk8o}aZgN88k^Yxnp*o~Gj-y|qnDPiA$+q{zg)G7ta-{P-6f=;GwBQ^2s^qbYS8QbVmIwffph5`MiKGA7r<( zPVBuu-*7_XzpCrk=f4hh4|+LseQ9+TZHhTpG%2CrL^C!!Ut8~w0?VpOVbXO9ALwbF zf62WLGGw<*TPr4hL2(OcX3FC*ohb;$&?aj}Un5g$8jc%!GlcSY$ybW#4e`o2jSSV)eF^&HQ9Wocx1qbXD_?~Ldm_7L(FS8WsP#V zh06-0ro{?HF1@?(ttQehHm-+?55do^<7}-uVfoW>zKrnEp>UO;EY=!g!ct#*Igd(D6mp;%_|SOs z;rgg(#+(9FYC4bx`k1rnQ8+8a7{`?{YrWpZvymrK_2~Hl1#o9dE)pX~%bBlcRsOBBJqmoknaYsn1WZw>ACndDGJoAIiY!yC%U-0owVR#* zN^HJmj+R&GQ_cCV@ZT2`LFp9IK`n#Fh7K0rrv7(YP{LwXcfyyRBPV9vjur< zV4!*61C4VCFg9%v0;Qvuz&Ao@tilh$7^uCQ0onAp|Euu)&n?p$Bhgqy{3Wv^XnC$kl?qN0h5j*jjoKq`=h7A+MdMU4;235$4^8xb`F zu4`x}OT~BNHWW=;PaV4f4?;9h-JcSZ-I5~*E^D_?CkI!eFoZ??z>yPcbSu)w_dmDI zNrkDhcEfc%&ShEtP2(mhTgnizgS2AjjbqUy$mh=*l=)(Ig%kl{eE?ScmV@um8#I0F z_?Iodqj(5+wpfuGBrM#q5KGMOvWGif&Qw;$X){BEgp5o)FyYpaJk%WsUH#;ZLd0Dv zHA*V%leDy?1BXT;TdYR!@H8m`~$`oJ;KrO|<>R{mG55-Z6d;R@AMC3NW z=e+f4p;BMlMv%LoGNe}Y*4tWV)}7h7GxN9k5U1Obifk`shAC2?q8NtOfU0ShX#vomepISLC9WAZP^J!C?;%ciq69)&! z-=*I{AZc=coUE$t80)ow=Tn8B?17==0nI(+>Ab~xLGr1rn1qB3$BV&FQR`=0i-p`& ztHD_A{5tZXj-eU7YsK&BNmB1dSx&>-A$oKhZ?Dg~wHAoFy1MmFo7rD?2Qi6=^c-8L zrDHBqyIzV65JYe1)cvlTWr z3Swzu2bLTP3d#WduoKCq^V#73c?gD=RD8W7}{wNbKZ1DSTh! zeQjkmnH@cE>rM)r^tV40o!n}nLbtHE7z+jb0UtCVWQ#de_aTyt-z#8|CvUMr6 zd7J`+2wA;j%+U7vxkLW`0RJ%~x@p5FvbmX$ii+xA=HRj#+v-CX-MiQZ_3a%TaC)8@ z2nh=t#tM5~n1syA!@$A09M60JzWkH#t69)SJYzy?>QJraD6qeUfHj2pIc}B0tlOLL zLEZ}(<{KZ)*o4(`ttAP+OE80a@l>TgFT~F7E}>|E5HvhmzX^MDilU6n)@jpbv3iNp z%XQAXTP2;SXbvHl73kmWuQWQy%gG@n(khxgUhVtcOiTZ3MInOW5b;Q}v>@K!?Q0^7^1wOOnvx5Sj1TZRZQv_}vW1 z!Fzjqxn+$0Pd8tE9n6Pf23A)yRvp`-s|?#*ZjMwlmFVK*Z|eqF8l1#UNTm^+*e+(UP1xP(M69 zdw$NE8(5+QU|5lOEH%sa_N$H2y}e>7Ecyp}j@Jj{!J(nX^T_n1H-@clrdN9-xU9VH zCmJ5-8{@!NbQQv{*%BB`k+ML9;jUpCq8gUdbO@%Dman=|$1PJvcxh@_-sd_qERAT&IC#(0HZLqwy)s+P{W z$LUJ)-kt@--PyXlmlxk?Dx2r4LKA2qd^<<6#NV1^AyPpx+sV@ebIju8ei>tT3%h(o0LthJ4esDd+7?q;I2Z$J{ZEFo} zZsq_GVPRt%(wWM+oy;MI_VqkoA9^38 zeR%*D^iLMS_5FRdn~`onKtTK5iXF3IYZ8zU%o_AKKm;hvdi7z^#Jsg8Jy1B3JwQ9p z=Uq9uxw$|}`@7bX2+VG)fR(tgjaDKfH!bZCU`t#qcD*IzvFJ@z8;iz}i=H(q0E_PZ zupJ5%WrcKZL=XtHb#M3U%Xs<#Q0#v%+bd)XrTLzBq&_@&ZTR0C+JDSgEpmN(dux9O zy*-bmafJek!tA#Wu)SY^NmtYQ$nNe=>Il?Jd@k3~kkfF^KIHgH{izmt=`kzpv|IpAb7`&RB18&+37`@o;LqtdS zY)kzf6(3Q%T~@|eR<`5J$LDzlA^|T{ngcsf+uzNyNpPu_E<7bKu*#W5*h(L(U#TQf zDN7(eIa$)tkt`$x_UQJ>#sAhxRC(|DaDjIO%}Wd^)Pmn!Ek^tc{b5F5R(6 zGt^(IWY$IgFk{J^VwtD%2C+6_6PKdQT$)zlXE!jt=zI)7__MoN%78v|AAv9yU80n@ zv*K8MyP{iX+SAbe^93*L)bv{HT;#@d8#9M7cdiVT@sj2yR)^>hzbF;VZxw#MQ;-BLO#8hq{oQb^$)SeoB)wUzjHJU$2 zOMX~PTihRE%2ER9AJYxXHSW3z0LxTi+(pL5#zw20t>EJ$pjG})EFl_9J9|=4p6uk@ zC6|qxkHS^W+gbwY2B=<~roAvqIU>>HRzb9Wm)~I=skPLW{}5D_Du(F$plBCN&pm6O z@?|MiXfb`vK+PB*1ePLl+Ip`j)o5pLB(XH6_<0^AdL>M(SU;2O^cPq2HU#{NzP#<+ zTxI}#8%RujL*yU@3k#Ycad@8Pdoji}DTVU+lvQszP`Z5BOdlNXEq0}ruVE*vp{8aN zV-t;Av=sHE&>af@CI5uYY%x!Z5_90{F!bW$Vroe3olf&IM(c9bW^?Hjb^k4$AiE`0ovF46gt@%E0 zJ7CRyHLq=qiG?LLLdX>@)u->&(Id|WS`V+TE||VQ)GTl0a9CNyYK~4DFw673KckQ6 z1?00K?*`^#Y-ng`umh^_%SGRs=ca%A)gLDNwdQzA@u$RuT0CQ8WgN-RC9^wVaQN); z`VsVfAp8@D{}U17+MprF%Ns)$kZz_6q|txb5`T+uOkn#%EbPNg?sowxRS*vTfIz+nud--mA-_kk(HrN1kCq0ei;J_!BkF$ zQ)e2#>p|`!ysAOPz_dj5Kr#qmTXV!E>Oin|(902RZwEd+m05Fpx4&GCk_dUlCDN&@ zCQ(#q`6l|k0=^~8$MtxI&C4s3n!BD~s(>s@DRS8_vnS}>3=q>2QjH%(-xU)5UpapO zdjmgWr{8+4dv=yQO9@O=Fb^KzJ8+b&UW`wujXW5SCO}c-N~h5TY|t%EGm?-0V_V>{ zo8HUIUxH{WDCmsc?L6^vhjjSOf31R*%I9~Ee>q%Ls}KIyH~n7&_5VO!KH|ydJE%s- zex7x)=^UKMBc#j>f7V*A-xB%W zBpX_R(`L+)J=%tk9jty6t*U`NB{TCkr!N1FnPZ^O+#J)>4mQi2aXfY&*Y9t}PK!4c z6;K;q=7j1cBE2k4YyDqxUi*_6Mjvlx4HHjn9=)BnXWy%S>^eYJnp!syfj-*vb$^32yttWLJi08hw8Uk1KVjVPb;8LKY}(n4 z<<)4lw**(&lJe++933&4v^#%{ThXyPiX_sB%Cvdp(a`0X_XbbuHrPV>-WA3rYj(G~ zCtlorY$a>6TMS1kk>5g^hIzdQq3YM3Ef)bxbA4=y+6ql;AaDmo=q#z z%F^K@3B~TXhM`rtqFR2aH7{UW`!+=0g{-VB+~!#lm*A4kVQ$qjF6zmeu}~Sr=YB$U zec(VrTg>wMSb zQ&R)c2rPZ7v17UO@^+u^)w-vz%{*gVJ{9uxH1GV$WrI7*qTy4HN-WvwPu}x1q*VRp z3s@{{^y_or4Eb#BT(|YcQm+ZE%Gt*-xGIwyJ0H^LZrS&7Cz3@6#N4%s-{^b)5s^P!32(&4`zGZoUYcM_5z9A^E#!NJ_SF@gfFFApt9O*Y&<24qT0eY~6P zMnKOHP;T}?Z-Bh_SJT<|k$4`(iuN{v@TS318o$l#((PKMiMVy`OgN40$ z0Iv2-h`T_I$p6=k;doCBq7&m|w{P*(U#|Yv-LpHJEHe2RCqEycxlRzoQ3xA^31AQt zk5(DhiiThL+-K8^BLSeq7$75w7b-ZgGFx)k2#LA$gc|>YK>ksa=Ip;7g5_Eci9awL zwW`*>uREp^$04hxPGkuV&HXC>DdHc^{lgikriCT{!dNx6(P@)4+Bx~{?pmS~Y$w+GaD3D7N7`!4+=s=LP{6};D5tczzo&a z)?VD-1FBhpNJ3-Og7e=sK-Bm2^vqCTHRl)C*45c;wDWIlY*=%1iqY8C%!1wMBgC|{ zQeYf~6NT&J)irS?RSPL4PCfjh;WRaifU!tA@R5MfZhSg4n)0g^WKB6#^+_GD664NnBhMSO0o-)^fx0M#L$6MzH(>cD(3 z>X)<8;Y3y%r)9(q1*OC~3~Tqz@vIF{rPI>VXlQ9UE&t#YD`m+6Vhy~9$ZXW!JYlS1 zSgBsUSm*cX0x>f)^YfzvQI6kLI0+sSp&G^_t@HLh_)bhr%Re5jJfkxE;0s8Us;s;0yfIcNNY1i7!f@rUi|yVF`|kh@koa`Vayz3X_i+KrO^|SZ#DCK4`|$6wWCvrH>&K zmIKxgcv5xelN_+&0D7vm-3b^t`iSq<)og%0-UG~LApl>iya85bx!oHA*i95TXuyz~ z0p62Yrv^e&6-XP0Z_nqR>wmo-F1G*qv&0dg`1@-W&@C6qgYZ}CZTkK}BNGz}05VXp zu#EF`)w(}DKXV1Vc;T@bDOg$20_;HO{pDJF-5TiHw{H-G(ZoZ*n%AtJq7ZVzI5{~j zn(r5;#dUWCuD*1(^ks6v(a6XfKo1NIR2a6U)YsPwi0W$n6aB%#!E@GYx?xyoq5tsS zbSJL=Gu-{!|4okmi7!qRycAt+Pl`M{!UX|y)$pr z86D@+udrWf%*i*aqlqdt+ydly^3R_H9)Fht*Bzba*ggshW&m3}DdP+b9{rb90J;dw zY++$x+|QrG>dM0VdR9+2$NyZrYJn7o(}vL1_4WDz3rM#%7@(y;TU-y-R8*YTjdlUk zFAFfg*Za*c`+t(XyuDlAzCyGE5c1}1J!8IH+jZ5Ui38aDNQ>(8KtDGc%DBs)ms`&1 zOF(VI_u*Y8ocac{idM**bZ@=Ko2<32o6|(q=W-z1=XNIFc58~j44^|fZ#Q%+4R%A> zAYosFS#xvq$0u;LH;^K|&sq+FJdc2k&${<}h-|lE(P$U&pb&pIyK=OR{gVNDe08_# z;Oef4{&4J3P{#ydqLP7Rd_90~%>HG9B-`hN!O!1+omjpgPrKTP00oZK zs9nd=C`ZH};57!VZs7oz{b;|Wa*pdbn!=LCZVH8oi3xyPP5?XtTtyWp1n`M!YH9>r zRw$jFoj{KLQ6L=)kgnavn6eZ*nd>Ua5dGQQlhrz8$Z?S0@CcJd-@*FNF+2q;Wa5wK zv~<;R->gJ#PM0Nt(+eTz{|!q4{?znXR(7==N`7@H`kn^#MX$+m9GIfx zGBQsjkTSV|RTgkN>IUGiUBHr-Mn6DFyq}Is9{<)&LI6~hDkA>^1dRG$Xh%sE*gcjt z@&YvyAeo~8XpsgAU&t!4pa*k!c({b5Bqlbtx?^Wq8Spgtwsj@o;H1SHs6hQzb$}o3 z1?KV}sICTQl$SA}0lNSY1#$o!1riKU_@FPgg3xO{PW2RM)uXf504_QOzU}YtkITu4 z?c4rTKCjj4r@4B4b5r5rYhwel0nTXD)YX5lo*ub@xF_wZI}Xa|jeU+k09kkafFVK* z$Od7Nkxbfzi_#(b(|MObS^4zo69l^OP24JH5y(>@E4iv5f1hZk-Ok-zN|8x4Xd{U7 z)%Plg#dlw+TBzjSjPgg~e39By!V`c0*?0wl({8)jq-5 zeDGc}NtJP=xE~>>wS+hlfEYdq31#k&rnUtXE2OD8>f|x1s;UB6$9bz8a?FaWT&pr4 zC`bV4**QKA*DBu!C>j9XwW^H_cW-@seN#ci;+2lR^MHX=K3;8N`^UF0hseJGEHG2R z{f`4-rPiqM{hBy{U^fBi7vu#!8uPiV><>Tz!T~8DB0?4|wVS>ObabW3X%Yb542+Cs zmpcRhihOP^MU%TmgMoOur|^)oyi%OQTI(cFlnQ5i%~!BU6Sj@}E!PR?eckY^L_+e~ z0;LHP*3rz2>h<~FGh^YGIvt=e0RGCO*V5G`x;qs61$eB`^%z$s-`DSlIiL-m_kSI| z`@8%v%Qv*rdi=LA{#ui*J89HTGi>wtdN4*v=5s{36O^l{ zHZwbG1Dx?RjJ~#mF}_TG**ZTQ*I$1%GXUt_cRt>(u&^2vxSKPrg42Wj{dwy)OO{s; zY>3#HW^jbjIUtz;F>b4J-UA%(4&P5!Iwg?jB*oq#smdv$H~4yhA-XG@BwDg4xQ>LI z!FSdk?>>otl(`^}6W^47!T?$awk};|01^f$HWZ2GYN8BIU9W?HOcZ~TlUj}|AstC7J(vUSQNQmQW_f?jsXUtZ5a zC5g})@{s6t${O>K(8i#wIyx;PNYJZL{CST4Ce1tYQQ1lw__{D{-nQ~W-RQ%%UVJU3 z`jb;=U*L!ZWVYQVZM=sa5`go?Zq`*zCkvrl+qD8i@1qw_xSt`{CJH^$lv(^Z&G# z@^?x^L}W$|^=G@Z7j*r&qJe>z45}*M(Syu}GT&2vu|fbp NvXV*?RbnRJ{|}kGIne+B delta 16863 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
izr8%vnhc@W)YMpPbO`SBM^SKa zVCD>i&QyzP4j}(E+dxSMx+UYs%Pj`omIOf2g2%?jinzFNJgj?HopJ#C1JP)u+u~vf zG`v7NT4T@!@&7BT-2e@}hx{=@M@MG_RA9=_pR0k})WMRzCjspSAo4*sKx_8T;&cnC zfEWi_0*|d=oWsRxiZb;oGk}$}-Hh|k*;Vl+3T9_y5bjT8PtaGjiLEr)YE~Nsuk27M zWM~}lN1gJBJNlSOdiC`vd4Bd2`d?{%mF7AGxsNSCAKyQJK0g{j`cft?>QX=lErY zzh(yRh(Agyis_SzYGPz0qFT8|*M#uL=w$8}Kwy#!3TBdkUeU_tw9Z*YMMV*b_!0(4 zK!gA+^79h{TVG$-Y4fO7Q=GP{&zm{Ayarv9Q&SIc?rY`MxJpV$#Qpl!9RLZ-l0H_h zRUh79yV8Q>tn;%pOY!@6OsN>+&j7juv?kC`eg*=s6N|IVLEraI6;q;XVIeu1i2r&& z-F_Otu?uYgLaA}s5(CI6OkjXS1a>vhHv%*Qh{ea37w3<+hgLf`0iQ<)5S4sd(2&V? z?SxR-RQ&05!6)10x~=AeED9EuSYWealalt+^q2VF-rn$p{RDu}p<-u`2bfZp_jz-f zT^%qr5fL!Jos9u}v3TYdf{6E{v9a-_+G$!&dUL(g)^B6ga2yX3{rBg}fbDIg`AXfd zT3T9}*$niK*Sj)e;$mV}9On$;@S#2bkRK2mzJcC$pf^kMR=o{JW3{Hddq5u!RqD2~ z;3B#lP6iZZ`#qAX?ghXS8vrh9XQ-{DB%-53 zSW;3_X-ThMX#zyezdj-wC?b;4ghK$P8w9pRXC!gddpAzXJT48geD5`}-sr`uZIOG@&L*wY)% z25hR6(#;z*mg;PUCHl-{aFts-fuusu%F24WSPj{_wqC4n1F#ZcZ)myKfW4;9^7!F- zvv1hA0{A)^D{EX)me+9oC;)&oTU==KC8LZ0NV$7(&^o3K0$3S<+gJdORFIRi+0xz* z5T5vigx;5nzY_pq`A1&fcECI?+8++rTDgI+-)~s4GwzSX!>TMQ{Wni*RZF#pTIUUA zg%7Vd5cPZHkd31}cPis6|CRZ_OPMdx^B%tH&nhbix=T9}knpR$z2fhep~91uy8QQ` z)1{p>VgiDZ1)yI6+-yYu{Tc`8Xu7+DKY5;34|v?oss9tKU@s3B2Z`!>hQNy308*^e zdu%Vp~-0OR$7oT_f-we1UBPv(KH3I{m82nCFVps%n0&_8W)2%s<^LIA%` zN?#~aByr&*`d3~7UWE2#E2?>~hkpcmU z2^eeZa4LUycekk`|9?!Tyfx2J{Cs~ZCIVt7ak@rW`s2w>RSO-z)EzR`Iy6L2nUjj* z>+Kc?#4yS#z)1}2wT>opA^!n>R@N!oj?z+}$F0y;09R51bD6KuW(U3dc-@~40ala; zfNQPUm=U1n{?(~}G}in6G>xPI3yalxUoOk<*;44`lpPGn&0%>opnt0dFc@L})S*^K z>6v^gTQK0k*X!OFaj~&VTlf9ZL|=iLs;sQs+uNIvUR6p5Jgv*F5de95cI)Gr`~b1} zR~!K(3SgY|ljr@?(&6K|GCTnf7BC!UJxWSSsCGRRf4wSdO3L0l#S(GV5zgP93-MDq z2U+0lAf4QoH%0Hq_aec{Kkeos%#kqdl#vekWtA=MKy3j(T&ku1gv~%oO&#j*4+i$n zZvfJAG?fnvoKS3^w_d=IQc;Bfx#1U(@l8x90kRGz@VFURuG@+oKlDAHn%k%s?$%2X zh!w!$cN};ot?Cn*^ylsY7*Yl_;~*`3t%{`C+3%-r{CsN{V>bW;YoQy)(f2_EC~2c- zc-~~5#3!JV4y*RxDQ~H{SiAzT1r-&w^9zdLZiC#>My7&!!AY@2a|p+UmTso<%xFBnW0PEVN z#Rgjf;CzQcyJ3{m_hx@A5|_1G)fUX6UaQdoICm;8)iQc*pUw4e`o1-Hu5V!vVWD5vf^SM&h-v0iUsF{$^&>Mi8{W0o8@VY(RYQfqDlEBZf zFbfv@(w;4YN#1o}WWc7Pe9KLlE(&V!HvZ36FyEuY6Z#1N~S6fm*RFP>cX%4jdJM)h>+!9Q7YV z2dI#TmlptKczqsO%xY7C-eSR{9jJGpy?&*#6+Kr#f~q{^*x)ZFczc5S)8qb}PC=w8vZB|<*&cwBJ-y%WJ7p)_23B?v! zky~7Oo$_*Wzd;}Gb~6Cn3+mY-rKK&AqnD0)4Bn?Sw#&2*0yQd6_Cq60b`qp>v3RX_;co-9nbibJ51kW2t28<)!l7wCzNx`W^=J^%H> zK!GcD`{!$3tlH(Te{BEK+gzOE^sK!Z0fF@8b8_TQf^?__hlmjYee-h0_FHjB^+?4_8^>G z%vVY0pfi!XU`rkQx&!X$%eSp?uW}I6?i<>)J${VrfWuzUXg%=jY3~S0Pf*Y;Nr{7m zplZ|S?AZ7RDIH6a@-gb0UQT2kAhQ7a4LI40&1{LL2^W);gaJaq)oFUPrw1~AC`h5G zY$iP|g33puY|4Nw_44vE_N^rss#2}20BHPA*IJW--fJ)_>qHvh&o7|+vwYxkr8cY{ zEkLCH{uRby(jn#Gs9U#ZrNyU?=<5brkjsaMzsEu}$21N|Fp$8Z3P5%n?AByOMFZ;8 zh%WE${uMwdSXg~m5qv}#VD}yPGJ$jamSM#`c;#*j4s=vh|K#N4*LXXcfU+qI;0B4Z zIdn`+%1~lgL!RH8TU!Ci$qTBW?xI`o-J>Jgi@4&4|3>@jW90vt=Fm