From de0a01672c98c2868b59bc14480f322ebeded6f4 Mon Sep 17 00:00:00 2001
From: Nicolas Henin
+
@@ -42,13 +42,13 @@ This **CPD** undertakes a thorough examination of the *Randomness Generation Sub
The table below delineates the **$\rho$ values** at which each scenario transitions across feasibility categories, illustrating the computational and economic thresholds:
-| **Feasibility Category** | **🔵 Ant Glance** | **🟠 Ant Patrol** | **🟢 Owl Stare** | **🔴 Owl Survey** |
-|--------------------------------------------|-------------------|-------------------|------------------|-------------------|
-| **🟢 🌱 Trivial for Any Adversary** | $[0, 49)$ | $[0, 47)$ | $[0, 27)$ | $[0, 27)$ |
-| **🟡 💰 Feasible with Standard Resources** | $[49, 59)$ | $[47, 57)$ | $[27, 34)$ | $[27, 34)$ |
-| **🟠 🏭 Possible with Large-Scale Infrastructure** | $[59, 73)$ | $[57, 71)$ | $[34, 48)$ | $[34, 48)$ |
-| **🔴 🚫 Borderline Infeasible** | $[73, 87)$ | $[71, 85)$ | $[48, 62)$ | $[48, 62)$ |
-| **🔴 🚫 Infeasible** | $[87, 256)$ | $[85, 256)$ | $[62, 256)$ | $[62, 256)$ |
+| **Feasibility Category** | **🔵 Ant Glance** | **🟠 Ant Patrol** | **🟢 Owl Stare** | **🔴 Owl Survey** |
+|--------------------------------------------|---------------------|---------------------|--------------------|--------------------|
+| **🟢 🌱 Trivial for Any Adversary** | $0 \to 53.6$ | $0 \to 32.9$ | $0 \to 31.6$ | $0 \to 31.1$ |
+| **🟡 💰 Feasible with Standard Resources** | $53.6 \to 60$ | $32.9 \to 39.5$ | $31.6 \to 38.3$ | $31.1 \to 37.8$ |
+| **🟠 🏭 Large-Scale Infrastructure Required** | $60 \to 69.7$ | $39.5 \to 49.5$ | $38.2 \to 48.2$ | $37.8 \to 47.7$ |
+| **🔴 🚫 Borderline Infeasible** | $69.7 \to 79.4$ | $49.5 \to 59.5$ | $48.2 \to 58.2$ | $47.7 \to 57.7$ |
+| **🔴 🚫 Infeasible** | $79.4 \to 256$ | $59.5 \to 256$ | $58.2 \to 256$ | $57.7 \to 256$ |
✏️ **Note**: For a detailed explanation of these scenarios and their feasibility thresholds, refer to **[Section 3.5 - Scenarios](https://github.com/cardano-foundation/CIPs/pull/1009#35-scenarios)** within this CPD.
@@ -116,16 +116,15 @@ This document deliberately avoids advocating specific countermeasures, instead p
- [**4. References**](#4-references)
- [**5. Copyright**](#5-copyright)
-These entries can be integrated into your existing Table of Contents, replacing the unnumbered versions, to maintain consistency with the section headers in your document.
## 1. Preliminaries
-This section introduces the pertinent parts of the Cardano proof- of-stake consensus protocol. We focus on randomness generation and leader selection and omit irrelevant protocol details.
+This section introduces the pertinent parts of the Cardano proof-of-stake consensus protocol. We focus on the randomness generation and leader selection processes and omit irrelevant protocol details.
## 1.1 Fundamental Properties
-A protocol implements a robust transaction ledger if it maintains the ledger as a sequence of blocks, where each block is associated with a specific slot. Each slot can contain at most one ledger block, and this strict association ensures a well-defined and immutable ordering of transactions within the ledger.
+A consensus protocol implements a robust transaction ledger if it maintains the ledger as a sequence of blocks, where each block is associated with a specific slot. Each slot can contain at most one ledger block, and this strict association ensures a well-defined and immutable ordering of transactions within the ledger.
-The protocol must satisfy the following two critical properties (Persistence & Liveness), which ensure that blocks and transactions are securely committed and cannot be easily manipulated by adversaries. Persistence and liveness, can be derived to fundamental **chain properties** which are *used to explain how and why the leader election mechanism has been designed in this manner*.
+The protocol must satisfy the two critical properties of _**Persistence**_ and _**Liveness**_, which ensure that blocks and transactions are securely committed and cannot be easily manipulated by adversaries. These can be derived from fundamental **chain properties** which are *used to explain how and why the leader election mechanism has been designed in this manner*.
| **Chain Property** | **Description** |
|-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
@@ -178,7 +177,7 @@ For example, if $\tau = 0.5$ and $s = 10$, then at least $\tau s = 0.5 \cdot 10
The **Coin-Flipping Problem** is a fundamental challenge in distributed systems that require a **fair, unbiased, and unpredictable** source of randomness—without allowing any single participant to manipulate the outcome.
### **1.2.1 Defining the Problem**
-Consider a scenario where multiple untrusted parties must **flip a coin** to reach a decision. The challenge is ensuring that:
+Consider a scenario where multiple untrusted parties must **flip a coin** and use the outcome, the concatenation of heads or tails, to reach a decision. The challenge is ensuring that:
1. 🎲 The outcome remains **random and unpredictable**.
2. 🔒 No participant can **bias or influence** the result in their favor.
@@ -191,33 +190,54 @@ Various cryptographic techniques exist to address the **coin-flipping problem**
| **Approach** | **Pros** | **Cons** |
|---------------------------|---------|---------|
-| **PVSS-Based Beacons**
_(Ouroboros Classic, RandHound, Scrape, HydRand)_ | ✔ Strong randomness guarantees—output is indistinguishable from uniform.
✔ Resistant to last-mover bias—commitments prevent selective reveals. | ❌ High communication complexity—requires O(n²) messages.
❌ Vulnerable to adaptive adversaries — who may corrupt committee members. |
-| **Threshold Signature-Based Beacons**
_(DFINITY)_ | ✔ Fast and non-interactive—requires only one round of communication.
✔ Resistant to last-mover bias—output is deterministic. | ❌ Group setup complexity—requires distributed key generation (DKG).
❌ No random number output in case of threshold signature generation failure. |
-| **Byzantine Agreement-Based Beacons**
_(Algorand)_ | ✔ Finality guarantees—randomness is confirmed before the next epoch.
✔ Less entropy loss than Praos. | ❌ Requires multi-round communication—higher latency.
❌ Not designed for eventual consensus—better suited for BA-based protocols. |
-| **"VRF"-Based Beacons**
_(Ethereum’s RANDAO Post-Merge, Ouroboros Praos, Genesis, Snow White)_ | ✔ Simple and efficient—low computational overhead.
✔ Fully decentralized—any participant can contribute randomness. | ❌ Vulnerable to last-revealer bias—the last participant can manipulate the final output. |
+| **PVSS-Based Beacons**
_(Ouroboros Classic, RandHound, Scrape, HydRand)_ | ✔ Strong randomness guarantees — output is indistinguishable from uniform.
✔ Resistant to last-mover bias — commitments prevent selective reveals. | ❌ High communication complexity — requires O(n²) messages.
❌ Vulnerable to adaptive adversaries — who may corrupt committee members. |
+| **Threshold Signature-Based Beacons**
_(DFINITY)_ | ✔ Fast and non-interactive — requires only one round of communication.
✔ Resistant to last-mover bias — output is deterministic. | ❌ Group setup complexity — requires distributed key generation (DKG).
❌ No random number output in case of threshold signature generation failure. |
+| **Byzantine Agreement-Based Beacons**
_(Algorand)_ | ✔ Finality guarantees — randomness is confirmed before the next epoch.
✔ Less entropy loss than Praos. | ❌ Requires multi-round communication — higher latency.
❌ Not designed for eventual consensus — better suited for BA-based protocols. |
+| **"VRF"-Based Beacons**
_(Ethereum’s RANDAO Post-Merge, Ouroboros Praos, Genesis, Snow White)_ | ✔ Simple and efficient — low computational overhead.
✔ Fully decentralized — any participant can contribute randomness. | ❌ Vulnerable to last-revealer bias — the last participant can manipulate the final output. |
### **1.2.3 The Historical Evolution of Ouroboros Randomness Generation**
The **Ouroboros family of protocols** has evolved over time to optimize **randomness generation** while balancing **security, efficiency, and decentralization**. Initially, **Ouroboros Classic** used a **secure multi-party computation (MPC) protocol** with **Publicly Verifiable Secret Sharing (PVSS)** to ensure **unbiased randomness**. While providing **strong security guarantees**, PVSS required **quadratic message exchanges** between committee members, introducing **significant communication overhead**. This **scalability bottleneck** limited participation and hindered the decentralization of Cardano's consensus process.
-Recognizing these limitations, **Ouroboros Praos** moved to a **VRF-based randomness generation** mechanism where each individual randomness contribution is generated with VRFs. Here, each block includes a **VRF value** computed from a _determinitic_ message. The randomn nonce for an epoch is then derived from the **concatenation and hashing** of all these values from a **specific section of the previous epoch’s chain**. This significantly **reduces communication complexity to linear in the number of block producers**, making randomness generation **scalable and practical** while maintaining **adequate security properties**.
+Recognizing these limitations, **Ouroboros Praos** moved to a **VRF-based randomness generation** mechanism where each individual randomness contribution is generated with Verifiable Random Functions (VRFs). Here, each block includes a **VRF value**, that is a veriable random value that gas been _deterministically_ computed from a fixed message. The random nonce for an epoch is then derived from the **concatenation and hashing** of all these values from a **specific section of the previous epoch’s chain**. This significantly **reduces the communication complexity**, which now becomes **linear in the number of block producers**, making randomness generation **scalable and practical** while maintaining **adequate security properties**.
-However, this efficiency gain comes at a cost: it introduces a **limited avenue for randomness manipulation**. Adversaries can attempt **grinding attacks**, evaluating multiple **potential nonces** and selectively influencing randomness outcomes. While constrained, this trade-off necessitates further countermeasures to **limit adversarial influence** while maintaining protocol scalability.
+However, this efficiency gain comes at a cost: the random nonce is now _biasable_ as this protocol change introduces a **limited avenue for randomness manipulation**. Adversaries can attempt **grinding attacks**, evaluating multiple **potential nonces** and selectively influencing randomness outcomes. While constrained, this trade-off necessitates further countermeasures to **limit adversarial influence** while maintaining protocol scalability.
+
+
+📌📌 More Details on VRFs – Expand to view the content.
+
+
+**Verifiable Random Functions (VRFs)** are cryptographic primitives that produce a pseudorandom output along with a proof that the output was correctly generated from a given input and secret key.
+
+**BLS Signatures** (Boneh–Lynn–Shacham) can be used as Verifiable Random Functions (VRFs) because they satisfy the core properties — Determinism, Pseudorandom and efficiently Verifiable - required of a VRF.
+
+A BLS signature is indistinguishable from random without knowledge of the secret key, their signature is efficient and the signature generation is determistic and secure under standard cryptographic assumptions.
+
+📌📌 More Details on VDFs – Expand to view the content.
+
+
+VDFs are designed to provide **unpredictable, verifiable randomness** by requiring a **sequential computation delay** before revealing the output.
+
+This makes them **resistant to grinding attacks** since adversaries cannot efficiently evaluate multiple outcomes. However, they introduce **significant computational costs**, require specialized **hardware for efficient verification**, and demand **additional synchronization mechanisms**.
+
+
@@ -1294,17 +1350,22 @@ N_{\text{CPU}} > \left \lceil 5 \cdot 10^{-10} \cdot 2^{\rho-1} + \frac{5 \cdot
✏️ **Note**: The code to generate this graph is available at ➡️ [this link](./graph/scenario_cpu_graph.py).
-The maximal delta $\Delta \log_{10}(N_{\text{CPU}})$ (Owl Survey minus Ant Glance) is $\sim 6.3$, matching the graph’s constant gap. This suggests $T_{\text{eval}}$ and $w_T$ drive a pre-exponential frame of $10^{6.3}$ CPUs, scaled exponentially by $2^{\rho}$. Note that the green line (Owl Stare) is not visible on the graph, likely due to its close alignment with the blue line (Ant Glance), as both share the same $w_T = 3600$ s, and the difference in $T_{\text{eval}}$ (0 for Ant Glance vs. 1 for Owl Stare) becomes negligible on the logarithmic scale for large $\rho$.
-
+The maximal delta $\Delta \log_{10}(N_{\text{CPU}})$ (**Owl Survey** minus **Ant Glance**) is now approximately $6.8$, reflecting a dramatic difference in computational requirements between the simplest and most complex scenarios. This illustrates that $T_{\text{eval}}$ and $w_T$ together form a pre-exponential amplification of up to $10^{6.8}$ CPUs, which is then further scaled by the exponential factor $2^{\rho}$. The yellow line (**Ant Patrol**) sits between the blue (**Ant Glance**) and red (**Owl Survey**) lines, with a delta of approximately $6.2$ from **Ant Glance**, confirming that its high $w_T = 432{,}000$ s causes a **~120x CPU increase** relative to **Ant Glance**, despite both having $T_{\text{eval}} = 0$.
+
+The green line (**Owl Stare**), lies below the red line (Owl Survey), with a delta of approximately 0.16 in $\log_{10}(N_{\text{CPU}})$.
+
+At $\rho = 50$:
+
+- **Ant Glance** ($T_{\text{eval}} = 0$, $w_T = 0$): $N_{\text{CPU}} \approx 5.36 \cdot 10^{7}$, $\log_{10}(N_{\text{CPU}}) \approx 5.16$
+- **Ant Patrol** ($T_{\text{eval}} = 0$, $w_T = 432{,}000$): $N_{\text{CPU}} \approx 6.32 \cdot 10^{9}$, $\log_{10}(N_{\text{CPU}}) \approx 11.40$
+- **Owl Stare** ($T_{\text{eval}} = 1$, $w_T = 0$): $N_{\text{CPU}} \approx 1.65 \cdot 10^{10}$, $\log_{10}(N_{\text{CPU}}) \approx 11.77$
+- **Owl Survey** ($T_{\text{eval}} = 1$, $w_T = 432{,}000$): $N_{\text{CPU}} \approx 2.37 \cdot 10^{11}$, $\log_{10}(N_{\text{CPU}}) \approx 11.92$
+
### 3.6 Grinding Power Computational Feasibility
-Building on the analysis in previous [Section 3.5](##35-scenarios), we assessed the feasibility of grinding attacks by examining the computational resources ($N_{\text{CPU}}$) required across different grinding depths ($\rho$). The scenarios (Ant Glance, Ant Patrol, Owl Stare, Owl Survey) show a consistent $\Delta \log_{10}(N_{\text{CPU}}) \sim 6.3$, meaning the most demanding scenario (Owl Survey) requires $10^{6.3}$ times more CPUs than the least demanding (Ant Glance).
+Building on the analysis in previous [Section 3.5](##35-scenarios), we assessed the feasibility of grinding attacks by examining the computational resources ($N_{\text{CPU}}$) required across different grinding depths ($\rho$). The scenarios (Ant Glance, Ant Patrol, Owl Stare, Owl Survey) show a consistent $\Delta \log_{10}(N_{\text{CPU}}) \sim 2.6$, meaning the most demanding scenario (Owl Survey) requires $10^{2.6}$ times more CPUs than the least demanding (Ant Glance).
To help readers understand the practicality of these attacks, we define feasibility thresholds based on economic and computational viability, as shown in the table below:
@@ -1322,22 +1383,22 @@ Costs are estimated assuming a CPU rental price of $0.01$ per CPU-hour, based on
The table below summarizes the feasibility for `Owl Survey` ($T_{\text{eval}} = 1$, $w_T = 432,000 \, \text{s}$), the most resource-intensive scenario, at different $\rho$ values, using the $0.01$ estimate for initial assessment:
-| $\rho$ | CPUs Required (Log₁₀ Scale) | Estimated Cost (USD, $w_O$ run) | Feasibility |
+| $\rho$ | CPUs Required (Log₁₀ Scale) | Estimated Cost (USD) | Feasibility |
|----------|-----------------------------|----------------------------------|-------------|
-| **20** | $10^4$ CPUs ($\sim 10^4$) | 56.74 | Trivial for any adversary |
-| **38** | $10^9$ CPUs ($\sim 10^9$) | 2.86 million | Feasible for well-funded adversaries |
-| **50** | $10^{13}$ CPUs ($\sim 10^{13}$) | 3.10 billion | Possible with large-scale infrastructure |
-| **70** | $10^{18}$ CPUs ($\sim 10^{18}$) | $9.80 \times 10^{16}$ | Borderline infeasible, requires massive resources |
-| **110** | $10^{31}$ CPUs ($\sim 10^{31}$) | $5.97 \times 10^{28}$ | Infeasible, exceeds global computing capacity |
-| **215** | $10^{62}$ CPUs ($\sim 10^{62}$) | $2.38 \times 10^{59}$ | Impossible, beyond planetary energy limits |
+| **31** | $10^6$ CPUs | 8,394.76 | Trivial for any adversary |
+| **37** | $10^8$ CPUs | 539,954 | Feasible with standard resources |
+| **47** | $10^{11}$ CPUs | 553.79 million | Possible with large-scale infrastructure |
+| **48** | $10^{11}$ CPUs | 1.107 billion | Borderline Infeasible, requires massive resources |
+| **58** | $10^{14}$ CPUs | 1.137 trillion | Infeasible, exceeds global computing capacity |
- **CPUs Required**: Computed for Owl Survey at each $\rho$, rounded to the nearest order of magnitude for readability (exact values approximated).
- **Cost**: Assumes $0.01$ per CPU-hour, scaled for the runtime $w_O = 20 (2\rho - 1)$ seconds.
- **Feasibility**: Assessed based on computational and economic viability, considering global computing resources (e.g., $\sim 10^{12}$ CPUs in modern data centers, $\sim 10^{15}$ CPUs globally as of March 11, 2025).
-
+
@@ -1489,15 +1465,18 @@ This falls within $\log_{10} 9$ to 12, corresponding to **Borderline Infeasible*
✏️ **Note**: The code to generate this graph is available at ➡️ [this link](./graph/scenario_cost-graph.py).
-The cost difference between the most expensive scenario (Owl Survey) and the cheapest (Ant Glance) is significant, with a consistent $\Delta \log_{10}(\text{Cost (USD)}) \sim 6.3$, meaning Owl Survey costs approximately $10^{6.3}$ times more than Ant Glance, reflecting the substantial impact of $T_{\text{eval}}$ and $w_T$ on resource demands. The table below shows the $\rho$ values where each scenario transitions across feasibility categories:
+The cost difference between the most expensive scenario (Owl Survey) and the cheapest (Ant Glance) is significant, with a consistent $\Delta \log_{10}(\text{Cost (USD)}) \sim 6.8$, meaning Owl Survey costs approximately $10^{6.8}$ times more than Ant Glance, reflecting the substantial impact of $T_{\text{eval}}$ and $w_T$ on resource demands.
+
+The table below shows the $\rho$ values where each scenario transitions across feasibility categories:
-| **Feasibility Category** | **🔵 Ant Glance** | **🟠 Ant Patrol** | **🟢 Owl Stare** | **🔴 Owl Survey** |
-|--------------------------------------------|-------------------|-------------------|------------------|-------------------|
-| **🟢 🌱 Trivial for Any Adversary** | $[0, 49)$ | $[0, 47)$ | $[0, 27)$ | $[0, 27)$ |
-| **🟡 💰 Feasible with Standard Resources** | $[49, 59)$ | $[47, 57)$ | $[27, 34)$ | $[27, 34)$ |
-| **🟠 🏭 Possible with Large-Scale Infrastructure** | $[59, 73)$ | $[57, 71)$ | $[34, 48)$ | $[34, 48)$ |
-| **🔴 🚫 Borderline Infeasible** | $[73, 87)$ | $[71, 85)$ | $[48, 62)$ | $[48, 62)$ |
-| **🔴 🚫 Infeasible** | $[87, 256)$ | $[85, 256)$ | $[62, 256)$ | $[62, 256)$ |
+
+| **Feasibility Category** | **🔵 Ant Glance** | **🟠 Ant Patrol** | **🟢 Owl Stare** | **🔴 Owl Survey** |
+|--------------------------------------------|---------------------|---------------------|--------------------|--------------------|
+| **🟢 🌱 Trivial for Any Adversary** | $0 \to 53.6$ | $0 \to 32.9$ | $0 \to 31.6$ | $0 \to 31.1$ |
+| **🟡 💰 Feasible with Standard Resources** | $53.6 \to 60$ | $32.9 \to 39.5$ | $31.6 \to 38.3$ | $31.1 \to 37.8$ |
+| **🟠 🏭 Large-Scale Infrastructure Required** | $60 \to 69.7$ | $39.5 \to 49.5$ | $38.2 \to 48.2$ | $37.8 \to 47.7$ |
+| **🔴 🚫 Borderline Infeasible** | $69.7 \to 79.4$ | $49.5 \to 59.5$ | $48.2 \to 58.2$ | $47.7 \to 57.7$ |
+| **🔴 🚫 Infeasible** | $79.4 \to 256$ | $59.5 \to 256$ | $58.2 \to 256$ | $57.7 \to 256$ |
## 4. References
@@ -1510,7 +1489,13 @@ The cost difference between the most expensive scenario (Owl Survey) and the che
- [Forking the RANDAO: Manipulating Ethereum's Distributed Randomness Beacon](https://eprint.iacr.org/2025/037)
- [Security of Proof-of-Stake Blockchains](https://search.worldcat.org/title/1336590866)
+- [AWS EC2 Pricing Page Detailed Instance Pricing](https://aws.amazon.com/ec2/pricing/)
+- [Azure Virtual Machines Pricing Calculator Detailed VM Costs](https://azure.microsoft.com/en-us/pricing/calculator/)
+- [Google Compute Engine Pricing Detailed Compute Pricing](https://cloud.google.com/compute/pricing)
+- [iRender Pricing Information Competitive Cloud Rates](https://www.irender.com/pricing)
+
## 5. Copyright
This CIP is licensed under [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0).
+READ
\ No newline at end of file
diff --git a/CPS-0021/CPD/graph/scenario_cost-graph.py b/CPS-0021/CPD/graph/scenario_cost-graph.py
index cb5a6bf458..a4113c5f6b 100644
--- a/CPS-0021/CPD/graph/scenario_cost-graph.py
+++ b/CPS-0021/CPD/graph/scenario_cost-graph.py
@@ -10,93 +10,125 @@
cost_per_cpu_hour = 0.01 # $0.01 per CPU-hour
# Compute w_O in seconds for each rho
-w_O = 20 * (2 * rho - 1) # w_O = (2 * rho - 1) / f, f = 0.05
+w_O = 20 * (2 * rho - 1) # w_O = 20 * (2 * rho - 1)
w_O_hours = w_O / 3600 # Convert to hours for cost calculation
-# Define N_CPU functions for each scenario based on the developed formulas
-def ant_glance(rho):
- return 5e-10 * 2**(rho - 1) + 1.8e-11 * 2**(rho - 1)
+# Define N_CPU functions for Praos scenarios
+def ant_glance_praos(rho):
+ return 5e-10 * 2**(rho - 2)
-def ant_patrol(rho):
- return 5e-10 * 2**(rho - 1) + 2.16e-9 * 2**(rho - 1)
+def ant_patrol_praos(rho):
+ return 5e-10 * 2**(rho - 1) + 2.16e-2 * 2**(rho - 1) / rho
-def owl_stare(rho):
- return 5e-10 * 2**(rho - 1) + 1.8e-11 * 2**(rho - 1) + 5e-2 * 2**(rho - 1) / rho
+def owl_stare_praos(rho):
+ return 5e-10 * 2**(rho - 2) + 5e-2 * 2**(rho - 1) / rho
-def owl_survey(rho):
- return 5e-10 * 2**(rho - 1) + 2.16e-9 * 2**(rho - 1) + 5e-2 * 2**(rho - 1) / rho
+def owl_survey_praos(rho):
+ return 5e-10 * 2**(rho - 2) + 7.16e-2 * 2**(rho - 1) / rho
-# Compute N_CPU for each scenario
-n_cpu_ant_glance = ant_glance(rho)
-n_cpu_ant_patrol = ant_patrol(rho)
-n_cpu_owl_stare = owl_stare(rho)
-n_cpu_owl_survey = owl_survey(rho)
+# Compute N_CPU for all Praos scenarios
+n_cpu_ant_glance_praos = ant_glance_praos(rho)
+n_cpu_ant_patrol_praos = ant_patrol_praos(rho)
+n_cpu_owl_stare_praos = owl_stare_praos(rho)
+n_cpu_owl_survey_praos = owl_survey_praos(rho)
-# Compute cost in USD for each scenario
-cost_ant_glance = n_cpu_ant_glance * cost_per_cpu_hour * w_O_hours
-cost_ant_patrol = n_cpu_ant_patrol * cost_per_cpu_hour * w_O_hours
-cost_owl_stare = n_cpu_owl_stare * cost_per_cpu_hour * w_O_hours
-cost_owl_survey = n_cpu_owl_survey * cost_per_cpu_hour * w_O_hours
+# Compute cost in USD for all Praos scenarios
+cost_ant_glance_praos = n_cpu_ant_glance_praos * cost_per_cpu_hour * w_O_hours
+cost_ant_patrol_praos = n_cpu_ant_patrol_praos * cost_per_cpu_hour * w_O_hours
+cost_owl_stare_praos = n_cpu_owl_stare_praos * cost_per_cpu_hour * w_O_hours
+cost_owl_survey_praos = n_cpu_owl_survey_praos * cost_per_cpu_hour * w_O_hours
-# Calculate log10(Cost) for each scenario, adding a small epsilon to avoid log of zero
+# Calculate log10(Cost) for all scenarios, adding a small epsilon to avoid log of zero
epsilon = 1e-100 # Small positive value to prevent log(0)
-log_cost_ant_glance = np.log10(np.maximum(cost_ant_glance, epsilon))
-log_cost_ant_patrol = np.log10(np.maximum(cost_ant_patrol, epsilon))
-log_cost_owl_stare = np.log10(np.maximum(cost_owl_stare, epsilon))
-log_cost_owl_survey = np.log10(np.maximum(cost_owl_survey, epsilon))
+log_cost_ant_glance_praos = np.log10(np.maximum(cost_ant_glance_praos, epsilon))
+log_cost_ant_patrol_praos = np.log10(np.maximum(cost_ant_patrol_praos, epsilon))
+log_cost_owl_stare_praos = np.log10(np.maximum(cost_owl_stare_praos, epsilon))
+log_cost_owl_survey_praos = np.log10(np.maximum(cost_owl_survey_praos, epsilon))
# Create the plot with improved aesthetics
plt.figure(figsize=(12, 7))
-plt.plot(rho, log_cost_ant_glance, label='Ant Glance', color='blue', linewidth=2)
-plt.plot(rho, log_cost_ant_patrol, label='Ant Patrol', color='orange', linewidth=2)
-plt.plot(rho, log_cost_owl_stare, label='Owl Stare', color='green', linewidth=2)
-plt.plot(rho, log_cost_owl_survey, label='Owl Survey', color='red', linewidth=2)
+# Plot Praos scenarios with solid lines
+plt.plot(rho, log_cost_ant_glance_praos, label='Ant Glance Praos', color='blue', linewidth=2)
+plt.plot(rho, log_cost_ant_patrol_praos, label='Ant Patrol Praos', color='orange', linewidth=2)
+plt.plot(rho, log_cost_owl_stare_praos, label='Owl Stare Praos', color='green', linewidth=2)
+plt.plot(rho, log_cost_owl_survey_praos, label='Owl Survey Praos', color='red', linewidth=2)
# Add feasibility threshold layers as horizontal spans based on log10(Cost USD)
-plt.axhspan(-10, 2, color='green', alpha=0.1) # Trivial (< $100)
-plt.axhspan(2, 6, color='yellow', alpha=0.1) # Feasible ($10,000 to $1M)
-plt.axhspan(6, 9, color='#FFA07A', alpha=0.1) # Possible ($1M to $1B) - Light salmon
-plt.axhspan(9, 12, color='#FF6347', alpha=0.1) # Borderline Infeasible ($1B to $1T) - Tomato
-plt.axhspan(12, 90, color='red', alpha=0.1) # Infeasible (> $1T) - Red
+plt.axhspan(-10, 4, color='green', alpha=0.1, label='Trivial') # Trivial (< $10,000)
+plt.axhspan(4, 6, color='yellow', alpha=0.1, label='Feasible') # Feasible ($10,000 to $1M)
+plt.axhspan(6, 9, color='#FFA07A', alpha=0.1, label='Possible') # Possible ($1M to $1B) - Light salmon
+plt.axhspan(9, 12, color='#FF6347', alpha=0.1, label='Borderline Infeasible') # Borderline Infeasible ($1B to $1T) - Tomato
+plt.axhspan(12, 90, color='red', alpha=0.1, label='Infeasible') # Infeasible (> $1T) - Red
# Add labels and title with larger font
plt.xlabel('$\\rho$ (Grinding Depth)', fontsize=14)
plt.ylabel('$\\log_{10}(\\text{Cost (USD)})$', fontsize=14)
-plt.title('Cost of Grinding Attacks Across Scenarios with Feasibility Thresholds', fontsize=16)
+plt.title('Cost of Grinding Attacks Across Praos Scenarios with Feasibility Thresholds', fontsize=16)
plt.grid(True, linestyle='--', alpha=0.7)
# Set axis limits to ensure full range is visible
plt.xlim(0, 256) # X-axis from 0 to 256
-# Compute y_max by taking the maximum of valid log cost values
+# Compute y_max considering all Praos scenarios
valid_log_costs = np.concatenate([
- log_cost_ant_glance[np.isfinite(log_cost_ant_glance)],
- log_cost_ant_patrol[np.isfinite(log_cost_ant_patrol)],
- log_cost_owl_stare[np.isfinite(log_cost_owl_stare)],
- log_cost_owl_survey[np.isfinite(log_cost_owl_survey)]
+ log_cost_ant_glance_praos[np.isfinite(log_cost_ant_glance_praos)],
+ log_cost_ant_patrol_praos[np.isfinite(log_cost_ant_patrol_praos)],
+ log_cost_owl_stare_praos[np.isfinite(log_cost_owl_stare_praos)],
+ log_cost_owl_survey_praos[np.isfinite(log_cost_owl_survey_praos)]
])
-y_max = np.max(valid_log_costs) + 5 if valid_log_costs.size > 0 else 90 # Fallback to 90 if no valid values
-plt.ylim(-5, y_max) # Y-axis starts at -5 to match the range of data
-
-# Add annotation for the delta at rho = 50 (where curves are more separated)
-rho_idx = np.argmin(np.abs(rho - 50)) # Index closest to rho = 50
-delta_log_cost = log_cost_owl_survey[rho_idx] - log_cost_ant_glance[rho_idx]
-mid_y = log_cost_owl_survey[rho_idx] - (delta_log_cost / 2) + 0.5 # Position slightly above mid-point
+y_max = np.max(valid_log_costs) + 5 if valid_log_costs.size > 0 else 90
+plt.ylim(-5, y_max) # Y-axis starts at -5
+
+# Function to find crossing points and annotate
+def annotate_crossings(log_costs, color, threshold, position='above'):
+ # Find indices where the curve crosses the threshold
+ indices = np.where((log_costs[:-1] < threshold) & (log_costs[1:] >= threshold))[0]
+ if len(indices) > 0:
+ idx = indices[0]
+ rho_val = rho[idx]
+ plt.scatter(rho_val, threshold, color=color, marker='o', s=50, zorder=5)
+ # Position above or below based on the curve
+ if position == 'below':
+ plt.annotate(f'{rho_val:.1f}',
+ xy=(rho_val, threshold),
+ xytext=(rho_val + 1.1, threshold - 0.4),
+ fontsize=8, color=color)
+ elif position == 'green':
+ plt.annotate(f'{rho_val:.1f}',
+ xy=(rho_val, threshold),
+ xytext=(rho_val - 0.6, threshold - 0.9),
+ fontsize=8, color=color)
+ else:
+ plt.annotate(f'{rho_val:.1f}',
+ xy=(rho_val, threshold),
+ xytext=(rho_val - 1, threshold + 0.5),
+ fontsize=8, color=color)
+
+# Annotate crossings for Praos curves
+thresholds = [
+ (4, "Trivial to Feasible"),
+ (6, "Feasible to Possible"),
+ (9, "Possible to Borderline"),
+ (12, "Borderline to Infeasible")
+]
-# Draw a thinner double-headed arrow in purple with smaller arrowheads
-plt.annotate('', xy=(50, log_cost_owl_survey[rho_idx]), xytext=(50, log_cost_ant_glance[rho_idx]),
- arrowprops=dict(arrowstyle='<->', color='purple', lw=1, shrinkA=0, shrinkB=0))
+curves = [
+ (log_cost_ant_glance_praos, 'blue', 'above'),
+ (log_cost_ant_patrol_praos, 'orange', 'below'),
+ (log_cost_owl_stare_praos, 'green', 'green'),
+ (log_cost_owl_survey_praos, 'red', 'above')
+]
-# Add the delta label in purple, slightly offset to the right
-plt.text(53, mid_y-3.5, f'$\\Delta \\log_{{10}}(\\text{{Cost (USD)}}) \\approx {delta_log_cost:.1f}$',
- fontsize=12, color='purple', bbox=dict(facecolor='white', alpha=0.8, edgecolor='none'),
- verticalalignment='center')
+# Annotate crossings
+for threshold, threshold_name in thresholds:
+ for log_costs, color, position in curves:
+ annotate_crossings(log_costs, color, threshold, position)
-# Create a custom legend with all labels, placed at bottom right
+# Create a custom legend with Praos labels and feasibility thresholds
legend_elements = [
- plt.Line2D([0], [0], color='blue', lw=2, label='Ant Glance'),
- plt.Line2D([0], [0], color='orange', lw=2, label='Ant Patrol'),
- plt.Line2D([0], [0], color='green', lw=2, label='Owl Stare'),
- plt.Line2D([0], [0], color='red', lw=2, label='Owl Survey'),
+ plt.Line2D([0], [0], color='blue', lw=2, label='Ant Glance Praos'),
+ plt.Line2D([0], [0], color='orange', lw=2, label='Ant Patrol Praos'),
+ plt.Line2D([0], [0], color='green', lw=2, label='Owl Stare Praos'),
+ plt.Line2D([0], [0], color='red', lw=2, label='Owl Survey Praos'),
Patch(facecolor='green', alpha=0.1, label='Trivial'),
Patch(facecolor='yellow', alpha=0.1, label='Feasible'),
Patch(facecolor='#FFA07A', alpha=0.1, label='Possible'),
@@ -106,9 +138,9 @@ def owl_survey(rho):
plt.legend(handles=legend_elements, fontsize=10, loc='lower right',
bbox_to_anchor=(1, 0), ncol=2, handletextpad=0.5, columnspacing=1.5)
-# Adjust layout to prevent overlap, with manual padding
+# Adjust layout to prevent overlap
plt.subplots_adjust(left=0.1, right=0.95, top=0.9, bottom=0.2)
-# Save the plot as an image with higher resolution
-plt.savefig('grinding_depth_scenarios_cost_with_feasibility_layers_gradient.png', dpi=300, bbox_inches='tight')
+# Save the plot
+plt.savefig('grinding_depth_scenarios_cost_praos_annotated.png', dpi=300, bbox_inches='tight')
plt.show()
\ No newline at end of file
diff --git a/CPS-0021/CPD/graph/scenario_cpu_graph.py b/CPS-0021/CPD/graph/scenario_cpu_graph.py
index 0406e772d9..393dbdfc24 100644
--- a/CPS-0021/CPD/graph/scenario_cpu_graph.py
+++ b/CPS-0021/CPD/graph/scenario_cpu_graph.py
@@ -4,18 +4,18 @@
# Define the range for rho (Grinding Depth), starting at 0.1 to avoid division by zero
rho = np.linspace(0.1, 256, 1000) # 1000 points for smooth curve
-# Define N_CPU functions for each scenario based on the developed formulas
+# Define N_CPU functions for each scenario based on the updated formulas
def ant_glance(rho):
- return 5e-10 * 2**(rho - 1) + 1.8e-11 * 2**(rho - 1)
+ return 5e-10 * 2**(rho - 2)
def ant_patrol(rho):
- return 5e-10 * 2**(rho - 1) + 2.16e-9 * 2**(rho - 1)
+ return 5e-10 * 2**(rho - 2) + 2.16e-2 * 2**(rho - 1) / rho
def owl_stare(rho):
- return 5e-10 * 2**(rho - 1) + 1.8e-11 * 2**(rho - 1) + 5e-2 * 2**(rho - 1) / rho
+ return 5e-10 * 2**(rho - 2) + 5e-2 * 2**(rho - 1) / rho
def owl_survey(rho):
- return 5e-10 * 2**(rho - 1) + 2.16e-9 * 2**(rho - 1) + 5e-2 * 2**(rho - 1) / rho
+ return 5e-10 * 2**(rho - 2) + 7.16e-2 * 2**(rho - 1) / rho
# Calculate log10(N_CPU) for each scenario
log_ant_glance = np.log10(ant_glance(rho))
@@ -55,5 +55,5 @@ def owl_survey(rho):
plt.tight_layout()
# Save the plot as an image with higher resolution
-plt.savefig('grinding_depth_scenarios_with_delta.png', dpi=300)
+plt.savefig('grinding_depth_scenarios_with_delta_updated.png', dpi=300)
plt.show()
\ No newline at end of file
diff --git a/CPS-0021/CPD/image/grinding-depth-vs-NCPU.png b/CPS-0021/CPD/image/grinding-depth-vs-NCPU.png
index 8eefc5ea5e5add67e049e01f8aebb84c830a9191..2bcced23c8908a8fd47e1f7f033bb936db81ae94 100644
GIT binary patch
literal 1725286
zcmeFZcUTn7vnULRfJ#!bWJM9lA|P==P(Tn2B*__xD>*JJBA_6GqJWZ=oO6)42m&gS
zB*&EuOIXq_VcDHKE55Jq@0|PHbN=}5dCt98eU_Q&>8`4-uI{d`s;Q^9wAE;ipFU1P
zLPDdVu6hT&oF^fnETWoWh@Fd0$6)W4@mcXyAGsl8O7NTtfCfTmzeEg6D3D6N!1 z9o$|J9b@w%P%H}{+>139bfNV??Ldh241R({!?%TA zoX+G>%lbgec14f~Ct4QXzh|8 } zmF7wfC1djBx>VG=Eq7fpUwJ9sZ5kGwRv+M8;LZ34czv1-)blO+?;fm;#trUINOR n_&mJol+C8F3Yj-lprmU2iHI>nG70ZO2j!Aj+ZSGc4^WJGGD2~-P zqPkM(*0K)z%f3R+L3-e<1oDn1?c7C^fz)&93+Y5XXE3}HQ88Mg6d{2A04kf@2$%sd z2lr4}6DQW2fD5rHa1%8loeB76L)B_jEij)1suf*I$q3Ye-a@hWvz#saWJo(*zI&VZ z1%oNnfy 6pbz(bGq-97>uZ6N0~!Q6{+%o zZC!Q6576@^FYmu2GHT4)=#&tsCjLC6B9FSk>HG27*;h9|Hi`$oRz32IXDEV`f;C2S zhp3DF>|x1d)7c}+$q4_8eB6Ddk!v^7f)6`reyATp{MuRHbs>NCwvcoEv-+(CbjtBB z?c<75#eAoKan^JJ>cot}>3Dv#Tt2wB&`nee`$kElwaC2)E4eX&S`)E{pa=KLiM*?D zy}h7QrA6sQIEW7 9`(18a$ex;Jnw+!uH z@t=QaM8;W*ELy#dS?~kTgR-QLu7x$rrpt?y_Mckp!F#(z=Rvwv2F&}9(F $;y6S 8$(zMYal;&{w+F{rLeZ6I~wJxUZs zPQ}c2eEHetC-PgG?^JfiDi!hw@_)MWKOYsvQy3O*Eh7kJ^yh$~BbyYP$LMG>$*u1M zwkOtPP=!(0J%{d7(I!R--C5qD)+H2n_$DgPsq&_+-x9P-KkL$eXGUC8L|)av!+; OP7tfOQFz0>xy#PmLJYciJ^Ve25)U$q85+%x8j7kdc4s3kXu)!f z4UflbxMp}t`Ssj_&F07N<3_KLhj(V7=$0(Cg>T`C?L%^Tm0pG=&m<~7YO%YE3E$?a z#BAxTB2bV4xX=-28uI(6TDmrFa(}cee{oGL`&b^q|58ki@7arhz!5Ea$M%AhyK;2B zB_q0cUIlgM2_PS|P_5Pl8;6i2+6>DyE}gyNEHwa+;mW82mw?p&EL3Ow!ASwsp7P7E z&MYkV_mF~tJ wFkq_ zHYdM1Jjz3)P}_)1KKTm&O2Y7XRNNQ>zZT&i6q8|Do{I;2>*PhK8Nf@!!~{0ksA@u2 zzeU77tUt!uC&XCtm6Vc&io@Anzk=Km#!TuyD0GQDpX0%U;HHn>cGooDZJO_Khb#4K zmFLhK&OHn{K~7sGA!tOV2Pgg?7O5EKE#V_4XHj3Il`Bs>2QnM9B_RC9`tjYDz6UkN zYnLXb$LfMyj?U-1@$S%=R@ZRN`)g6wes@ruEU^vIh=xg>m^>qAYj78D57A7%*Ly1G zXMek0p)Zol@^cC0shM2`_m2?`gJ6~F>d)FE1G>OS_Z=ePhvvQVF=LzT6~{ba#Xgrv z;-MjNWL3EAuD9d>99!Q1hDkV>I5=PxEc1v!-CGm{cMk +5m{KgpiiA{zt?@8S__a4$ej?VGo2TDcD9t)bclT8lJUpnosB3*tq1n#FV9 z^-Q_W(yteX1nL6+CzmTS;@cq!e0qzw$O@^ayvIa@ZFKBEDf={Q2pZykoF6#6wfX8Iyk4WAy0E5I)Yy;`bu+)Ny(*av`_hO z&9*ClJ1ST{8{ I`y&B42xu6s*e1szYp zDJ&YayvnN(&AS-HxJSC|e8bQIjrZApHSC9&$K*-EXA%WJGu)n|f +#<*gz7y03W^ isyuz8+ z@Xl)k$fV$?73ar!1fe4eqAxkFJ{pC`Wy!+lQ`iT@(GBxZA~|J0u{xg|F;Px=a#79q ztnRWgg})h}%wuv;X}!A&)GwsTwh?aFg-lRkcojtWc$EjtiMwHb@bF2t>_V2ri{V}+ zmxwP&hoaOAi)(s3WhX79ubPe#xvNVMzU>8c28iTYo5JqN>^6}8TM)%Q?=Ct47;5JX zzG<+582V)Hfs;rcVV>IA#{R4>#-44_@5L mX{=N{SlPtqQyOk&`aiX7%NyXi8RBN}bz@;_F(q&1!+*t2ISl(dqfdPJi zVC)mQNIw9dH;dLj9%)ioc#%=%-d`TtNxCXIRiYboFPyFan9$mJr~Kosw+8XqYmi?j zWFv|yIUAy+O@VS?-sS~Pw&eP=soj?46o7u!sZDjY58{*2JzLlAeKSm3B5+@7Jtcy z#G;?QAhr%#Uqfs}Y2*}pR0!QXvKo8Sr3Gg#HgU`LRa@d68E!wPA`X{#KRIE!v#2;D z@)X}jPf9U)v7?uQ=%35Shp$R_UzZ*~R|z~o*x#Uv`Cx1-Gx|#rErGRlEr!))5Dg0X zq+{oVj*&5T6_$Yz4>jmvMQbqB&eSTSEm2?QnS#%6pbhD`XLWp7b`^3~-+Uo8cF@lb zs^r{N-NS4X590d?E%+1xUZrW**K_xe94g2kv21eb>}xNHdS?NJb9@OO)vYVlU)?K$ z4~-aBxM#_|G(JyXoQ4|BiDAcu{|1VEz9zBuau`Z|(&EQY;)tsMDEt?3cW`t&0a=ep zp4REbrPCZL?v!KpE6-d%Xc86n($giT%`bVBrpAdp$@}RokNm}x>yGsfuUm#asySSK zq`LvhvexErUO{X-;yG%Td2y;ql2sR)JT!~G&EHEs 4MQW7sAbdK7hV67d=I;1SJN za|$g1p`O%DuFHS9%T&5q?$e*{@XahyB6{S4VY)<*8`1t`E_@`YI7W`bqME4Sffg?} zWdHLiUtEN+>L3}>bi;zmIrQ n!E^2Fclx_Zf158<0r2` Q=S)}@sT2glh0%rT*4AY;f1pL7~R8zS?`r0yGrwy t^rg45Gn!dRZQo(|ChrVnsNdAR7~&S~^mSW+Hi zsoF0-m$eVgf3ByX2S!I2<9#l7Ro+{T=Ti;|B_c;5;u27ZL*ze$IsU7WM;8$SP!@EB zM;nKzw1dB_=5dYjT<(vPk(A15E2UnENF<9jCa&MwQm4}2AD&t+Lo3`olS^vt(`u5M z*!6JTn>9DaKX<5`9v&*eU=#0>-iz1chku;kn8ms&R4L!j`O8d@2RLsVdLwDH6LXf% zSMQ6um%U)68Tfk{bV?Xy@jvpqgNSxa4LeNn{{3IaLkAia+@p$=#dD{VKE<+IOHtA2 z{S}bn#5&4SG2rYT>+6nNC({3GAW@J+h3ju)u+Q#`@EUGh$NUSpWL4Z%Pi8ei*W+5Q z-2K+ Z-X7y6A_dK&4I+k1Z!Ncj(l 0alZg9%!NK%VQJE=tzN){Ry_GKq0dz=F0>W^7w9!ax@8)4v@r*#)Ae+_i)T9} zoz?HM+|b}ICO3c82ydU9E(;Kk;S4Te_t(Txf<=TriINvD_wlhH7Gem6y<&Pl5snuy zXDZzksB+ufjkrZPu?=51MxI>e^lQJkUrICZ%NQMy7O+Kg4c2PCcs*wglEP>Py7P%! z!o1mC;$;vojec4S7*Wh03EhuSLrGmtXc4IUNh`QfH)Ih}fxFlw!$czV0!nZa0c_Kq zuhFHv5a(t5VPabfNp0<%K7H3A$l7VYw{!oMA~f}U!ZyE>%j4+ex*t?S`>%mKM5E@s z=Ar${4VkcZ$qOjOU7vuD`Pt+>lZ6jQeJW22pfp^&q~PWaMl0~0vpDR9`F2!phg9_% zMEIB&z$ScGFmnw83wieK0@r)H{kSsC3HUhy(qFxCG;j&9-fhVAHD7Y!O90~;7MeZ! zF6krSgC@S$6XNuRy?_@P2{7lp>(%4-)in`0cF8rBW6Dno0^%AMdrL2g)euOGiU@{lvySftc5lN z<>Kv^^6=7*Sy-h1){5%)lp9_CO%ZFx#paH{y;{&=@HQ9!|2mqnX+pWq2xdRd9jn9P z(!k2VxiX>Hs&jfTM@lI@h4w+G(+36T? U2=P1PJSwjvIq7Da5h8O7kcwo2?Jt naz8<61XfV6xW|^TtU=YbSca(dSj9=V;QQLMo5Ls@M=D% zPwC;+%BKe&jbARF!V=Aq{I8XZBfK{p*(B35RYD^{HA7n^Ef2V_UvCqWI4?QQMO3IV zE-mWyikJzf+f{hxJh+YFo^Vjt#c+2<#8bQX)rXCx6PJEniiV4$t@*b7&*EsAKvg_l zj^-)&_uj@!W!JYu4+4nVQta1v2G{C*E1$jX{r
h!=R$LpHm$654% z-sCV<@Na?d7anOM!-)&MhHX!NnrXe!_0IcCx2DoiklMbO92Dd&lPKG47RbeRmu#S* zQT&T}6IRbWuTkGXZmd{?)noOs$^+(CZPM8aLPLZHRpznu@>1~KYUWIb#6GUd#sy_# zryKq6I#&*>84whV_2B7_^|JetOg9(@w6BocD?0>wjHYj*{c`Zg$oE6)7hk>Ll8~FC zPdb{p(dqEZA0!%Pb~g9cb^mX_0D<@p9Wo89{!tlM*}#(r1MSCqw@xFIusJ`SI~c1) z$(P4%GuprXM)K29H1r3_e<8bq-+2%$?r7CwmM*^$e|(Cg1SZobkZ&VFDN(Rg>CW`j z!3mGap5Zfnap4%KtQLbu_Mc(F#4QEX(lN&@rBAg-5H)Qlf;XQ);sr*q+TS+WUmExF zL5(8s%Jpf(+Y8-v1AAM#b<#U|&LdT0x^l%)YIEF(V#NS_a^v>4J03H1)~lm($gD0& z5mtMyq6^MFwS~+tYV@x`Efg7 fB7;}Q5VACc }3> zME(9P{6VnMSlOYgg?Oyd1@#6UJT4!3LQ4C%+bzRb(20dVkiZ|5i@aP_f2DV*kmm!g zJ5L!Pu-iMSMExckPvtX+fXjHb5ion7&WGTu1x{Bl$1 3X zo5x)Z0;khER|w%LuGfGay7R4la!D`v*DVbp`dsR9NbT>GI~aJ$AOw~R6I-fXR+ALM ze#~%MiH3=q-b9kkFgd$(ukFAwe6HzxI>pxg0B+J}Ym)}KPSdefTpQuwa;{LcG^%d% ztKe#g2C~oMJmld%&<5Rao68PDK`;Vdo!Ri^Y7t;VEy$*>LdOs=fMX2eMR8@KDs`o1 z9@%rrX#XL1Gn`uSo|_;RkiUG+-r7;W_}oTFFWgmg8L}YLeXnsD5@?Y3VsII`oh3bD zZ_an`HQ*K!oAjC86ptQX1JECq+UD}|Q=r^=2Q_mTsBegUN# 7c_QFvv2m@x_^ zeiskTevVo|zDVdKL!GPYG@R1ITkfnf#c#wljKV>q0kzc5ZQ@y{K};$?eZSbJXR$m2 zMPL{i7D|odIg27}DI GM$sZFMBG =ut4d) z$9-R_=BrxE osN!MFv)kE0 )jqJs=^cAwmh|F9Ki_}LAm}>vP6e+`7!mNt!OpfaAR|{WA=zD-IKHb(L`}A z$rdf8JKwOke-ct@;xi%H0TX7fVK<@ ;P$D(B`u_*F+1^D$9kpDwkjO^*^6`Lvd1qA*$VJH|6eU51`5DlN3{ZesRKD$ zeRj{9(O9sS_GUOZQoDQLa@yzLqiJ^Ok+pKciAdhVHAdckOTSs>GI`HOcPkQprItsX z%T)i_Rp*TiY^keS4jWw5Vrcm7-d?p<1#F1>C1)^uL1-9>?EiWw=6lxZABQFkg3Mu1 zFtI#(HBqHSg`U~U2qZ##`$6b`YCQh{`S&vZhbRAEJQ*&4iGel@@x3w0_q)pyPdg yVQOrrR&RgiXDDb9Rb>w5cmH0{#2xtG|Tjm&OO3-(IXgC9znz*6Q>7$+m&5*2esU z-Msp)DoM#!+H~FTr?N?E(=t&L2@k%&GbF=)w>N%28Qz12iHxumy^%Skc#>qLK4 G_=QmIJ1&2$5QKj{x9zSqQtI@vuZ5-lfsvGMnl;BsfrIb5@(gjzE{ z*~4TOCgks@*BHA$-TU7=dKW!HK~4PVfyGO$s~6yGLM6RxZECzJ`~BG>5PToR<#9Wq z=78Wuu=vh~yR1j(EV0XIC?k@T=)5rXTiDhLCYt|}g%`nnJ6lk#=I=wM0ju8|-&h3g zvOZ68_#%>Xj~x^np)gm&-=g7dZTi^cZ*em;UfD4}n4a@kX*sihJ0l!2eX@fgW&QEo z_ua_Gqj?8Bz*Bm(g;kWEB+p@X+o+UM- zhwtRUqi2Js-- 1|Kl0h3OxRSjy-pitBHj`WbdaWUD_uL)>XMzj2zC$0sNF~8+J zvQ?_!_fuV|$W@SEQuA!xzWbZ$ko|NsA=V4nM<+xKMQRt*=FkA4p#wL$L)YaiaA#m# z4Kgng7Y`^C9?aGhAlurkgNld~zU>E-`)_g$@~=1jo;y)<`k#M4nHHW7K3}uFeGbcu zlHMZt6ejCwrz%cdTNXH60!qh^*ZgKfzTVj%zx&bVE;#%9sYpNS;qQL1cNG4kk99_p zWPeG)NfKwFYGNP%S}hz0sQ$s}KM4OXVX5&jXwkpBZeg&6AsL}ve9BsCH #MRAG#@WMg(yFsc4g7Yt+9+p#M!zYmMSBBAMmLzg_1c+oTQ$tE zeDyZy5l IG 30#o`qgqdVsA3EQXqBq4ha_{&reR}Ki(<)oQoCiD*9DhrYfQv1W zrXGChsD_V8FavkqmkzZt*UiNl$N4lYqxYp953o>RaC5MF@`v%QBIHH^+AsxIzksFk z&g)yZu#HgyJ2ZCda*;w;BcPLPfBLh_r}wbVzOE2KZzY}nCz4}a_U1@0*`lZs)!xzW zzj6TtDa}FVdl|$*Mzn`R@!0SNXd}TtYZEjwl|rx${V5>|pnoG!(6y7W41I61zLwH~ z12Xs(9Q>wEz*Eu@^G=O+egr*HL+#`R-mU>t-x7|vpNwy_hWfTF$5TRfc~7z2KexAn zCLloDSR-2H;xjNPF^zkj0kXjm&+hu+J*=n{&M>BDfFE~nWztD`%!+glNcez4hm--0 zgk?k{yo7NNy~HWd*ca+!L_if29BbB_qob01l;;qrZtQg7A^;wjAQke<_qwh8Bp(Fe z=;sVz0|vt81Sa#+z*^YD&6J(`co!GsvNSN$*|7|4V>$%QHX`PHR>n6Va6Di-iC^>C z*@*W0W*rB)hI ec_-qEM*BNI 6oQ$MF#iIMjty~ih-SWf!u^C9{T%#4GHLRe02!2t3HVx++zY5Sd6qI(eg|}M z7O%#l5T(MSaV2VNT ^48j@4RMlEmvEf`SS-wnrXL6O|Q+;(jWt*$Iygxz>Ig70Q*YJGhV z7`57fTupeeHy3Sgwk?P77~Da?tiN^x2i>B`?VHGo`UM3vTj&hj;s9lU@b~+yG8)eO zVC`XMK?vOt8rY4}@GdSlrxsmhj~$(9sSKKZFWRA5XpR65l!5?100*(CnSU!?nlicD zCM`ne+jL}6Z34EwgA_ez78Nqb4*+e0n+=})IPX|6q0)&8{&j)W&D;(rvn@xJ1?*P) z7}9OVy*m>9X4?R % zf^z0vY^Q&>`Di$@ic5|uZnE3Y1cQM4;n9UqzYg~i+jwC(V1{GngK~BpS%V|y4B)Fn zaXNmVf%$V*8?jxf;K8^P+vy1OHM%Xe$L%11xH((V05+Y|HEp+EmoOM3fE*;e9}RK7 z+mC<@pyA**+ZbG`8(h8vFO9r5F;>%Z+Rt?XAbzh;3>I2u%OQA7cSF)|yv!xY1(_q> zyiQ*EIW%C{v%Opv_@y~9^kn%!#x=!@upg6*Xrqjk@4XUN0guMQZQME}sL82qV(!b5 z->aWezV}lOR# ^O*yt>+?MDa9BC8m{~>y;r(+#M>`&paUVGT)XEBJ$&ZkpK5% z`&b4zJI!_-m zM0Y^4&_rKwqVAMf3~AfWg`W~I%^rIYoza!#0H+seF4uYu3go3;smG^^+2b7le-H$P zBzOh%WK9d_+Hh#$t1-%uNlcN?TyRT^FDSR-M7dp@BJL+9qtdArYQ}&jQSA?_o+vTF z=j8_!m=c;5FL=Rm?-<*xO%0FVTu%g$P!aR(Q1eCDrzdhI4?b?X;+kgm7E-%6OryWJ zzq;!}O8v36r2jvVX~#$AyRGJigiZsv _(togx*qRR! zoSZu$;gn%f<`#(^fYDIfeS`Ld^BScC`IF$MSyn~QSMDsMfmofdn9tS`dIVv=1uUIi ziek4}3+G5Csu%?=e)QceA3r1!<9-L!?!n|ay=+~ryK4?#!Ip<^Qu_dOMnGpwhT&m2 zQ|fAGIU8o8FXwj!kMdch7mdaQd^Cs+HY?=~G)zbEk4RhA$3U@j(RG1)$w*l58d4*B z$N!ms60GBUBpmI7OK5|vSkjpnHSX&rZP|!z+NC{T+5EVMz#BU_t5l0}IXKOl)9mQs z?ylrGy!BqtsFQ8Gd@o|6Z4xdY(D>XRU;T6kXk$l~j?ZvmX;d0=bc9oPHFoYzZq8R% zOjiw?VO*KK`rXwQb_sC80{r79f-nSi!=njnXd{s;z@xbl12c!nT{|ak?ZEkJh= GYF1j6Zd2KDYGsagWdXn1qbmNc9} zz%&J0ku9uKMOUcUJV`09o$QkWQyG%%Skhc`dY@Ao9X5nCvxake=Msw1B9pM{r3NnD zh~!KHWbUq_?OxwdL(xL*>mF&?jI;=7Hi7io=N%YN<`W!&$}#&%@9pnqa#n!b8M4&U z8luJnYN$APG8jxVh!2 KHeCjnlJH^BZ=KV6rCx%R$%cXC>?P vVRP#0qdW*P9oS)r^8nl*Ob7N( z*lR%2AcLIvc0lVeni|YoCa3Dk@cr&-`4^0Zzw(QLfjUIz{nEeW7yEb{zYrmq;>@k( z-&kx35ri~?zLx#A3}3P`<|#|?P=zDReI*2w8%(ac`WR1cJoj0bIAwYR_KkT_^^(nK zw#?&q%l#@~7BQ6k%rghT%>3ESIM5b|*6637BP#?hf7ZPQt1DrC*uHjF4c~wcYz& z0A|P(k<_?-`G$YZY-7C8kSTm3d=-PlyZV^B?k6UGAix1A0P|})0`c=3R^c99E}7Wj z+Dhm)F~gR{?|Xcg&Jx^qH*DM#L^$qcniDcNras>77*fOtbaWHGb?1F9(YmVMQ;C9I zMgT94!&(JY7RKSw4^xF5u)?4&jxI5v*msUwI2HR@$C%3zy#T7}Z&Stw6%h*o2p>Oe zd8+UU*pKB78(1
-pkC=1++2hj7?DA_TU zNz<#36b&2v0l=>Tz(GqJo%jbHg3L$ZtEulx<$>X!%R6+|I*V g6N!EMY~x!=JY;bR7&UOJ^d>>+&KKFDsbwis8duY_m0$C3mm zxNkuwouBLLCc=OzkC6ewPF{Yo8R*ml0&A95rA6R7Yd*q04P&P90TWwh9oCSo(vH@h zdNuQ`&c~Q)`?+Tweyi0pGc_2uRdcP`-XOh$O~`)BoFse`HOGm)dD-W~3}<|udEmxo zf|`QAUr&fAgRR+?$q-Z%u>(V!61H{B5eFm7$dd8h=j`!2;90aIl*Q~r;6Xdm)~^ZA zT@pB&&fPG+LCca*mfJ4Ne&W8m8}};_FqPg@((+mydx&Jl6+1F_Z_TZE_+ETRhdE($ zZWRj0x%b^fgI3hOc442o-L;Mo(SV-K2e_(2ta<(Nj1+~Fy0|{ga)G03&0O3Z6MQ>j z&I`U@OZZqbZ|;oVG9WA$n~2nIwP!l6&UmgT7^*~AoATI?VTwnW@hSlgaF^m8PHADE z+C^>HM2AS-w?@+yORRgTj#b<9=GKgYz2%}h*P89`nra9Apo#}Zw=5TB(!Q=054}%T zD?*et%M%TlLg>9UoW`oL$NH7Z`lXvtqctCdW;{532pyH!LRnZ&Ls4}jCTxyDacYu& zZIn`RQMrTNrQ14@u&Z J!+ViBU?w~S874uS;>DDV@TREWCsjpA>e&r2JlP5 z0A0{$mAIkN>d^|oe}fL+&TW*kCxjc!$6j4=g9N~l+br &qQq1&*)_p37j hvJNhJtT@Ypgu =vxuyQJj@oAX)wXYP>TB0Et}$+Vi($;m4=R1n>OsD3`C*0j%r~rf~Rhu(sN8< zak>r(t3faIb*QYE`3%)f3eQg(Dyc-wye26e0-Tn2c51U>9f|Uz)t)eL_a&$m5Rjmu zViX4G#8r<`<^qF?_x%W~-RR1lFLZ%FHrI7vi|+PykYyF~a;t$WiraJ)jVL`3Yv4@k zP5=Qpf*YBv3z+EWx)cp7fXz%OTygHw-;rkSiLuhQ`SD=>+m-J6wzX1e5$-K<9}|(r z_STN{Rr$U(8DqLsLA#X;CbSOkcSi2bW4z=1@a&To3z^<=djWDCfd$F7ij6yfPIdXW zqccL~;zt+m{HVRqD=%LAIiuXZk^fA2>1Iynr8adZ=kJ7*{(vyku0V!u=7P&vzteX( z-jKV4i7YEHgzga(;h)Je1p$w$TEq)^8iD6pWHJF|6r*2(q{1~QpN>kz*;plT(g#;< zLhSQ#>|gp~ra$w=fN4126(0PTfT{aF3}@=&!Y(&-wwu*I{rGX8e56lf6(KQXdK=8w zNb=9@i(OA2#VAp-PDV S$sV71r19|ekcRC{-=v@&47cmH zwn$<)${S28_K(DmGf5Yyj(I+uYVeH>4#B(!6H&4*s4AvF5+SJIr4B9I gxXl*9ZK`-xHudH_AK#VXa57q=GaTl- z+rmB79pI1mjb3v>w^j!&S944fu!yzg=~EKCWb9}Ns<_kZ#^gdGsI0e0q!6Bkz?yi? zvI~GbgNEa=Z(47ZXxr+{X8C9{QXt`=IU7SjhO5a>PnFtr8`m$a`b~l^U&TO8c!TtF z4RJc>f@lt2z^r? +X ztu>L1W95s4WP{)}9d&w5p9&Tz-@h(i51vC7%P28B)R^u11;zNc)eWmI;bRkP*qMfn zo$XdcIM+ay!Wss#Ck#~#+>(Z@u4|-jYb+5$-eMNqzoMq=Thh7lOW_NOXuog-VR@Wk z6jd9 QIspO5{WmQwTwFL`C!n$sBaHmMKR9--L8hA!h?k*M pXS*3abt}a`l_9i?xbVJ={km!gsVh$_>~#)tH|{wgohyCJi=8@K7vB`d z8R__Mr*p%6C%1xrtQ#a&4yCmF #58UeXPVrj<#kbxE0koP${1o63zj>A{$pKIhx*FyyixuQ?BL<`Q z=1VDYKlT mw zEDRwB;RE>u*6)f9uqQg$@3|qVdORcM+}*2j#)L0xNQm{q>){>W 8SPZr?7va z=M6sp?a%)8k2KDIcKQDfiboUaDuSZz+$On7Y+HiFfrLO~%28Qb);^av@=QU&24F(7 zj9IY!f3WwSVNG@Ix+sc@ih>=L5)=dx6#=C~R8T+=q@$FefT&23-jbjwC`j*3P(VOR z1f)YEqI3v7QX@4$fIvbLl90?ZdB69)u6 QSv)9^te?R!a$e3e{Ip%ntQJ(w0 zM+ac7D`nIbAMDS?Rx4kUnX~r^g;86{r$o=)>2M9lHg{n`RrQ4EkyD5vytR&$k+G>s zkcc_ef+aJgMa}wV|JZ30By;r@*Xca}lJMRC9=!q-Z2wm&ipj=zOecU8zE{c*H!42S zU>&W?2QV~9r&Dl3!6*{cpU$|#yl=$%D?2bXi3E8ITbg>TnbubI)%74i2)t6{K0qtc zTjV!`vMQkU{M};Jcz_m$$Aahs)!&N8e?uy(pglhUcC NX6-9 zp#c+-%fndvF`jt7Fk)%rsvX{Z2H6l^3sN5n4cVj3EW8^8{XKU_%d?T7R^Oo3C1n=n zE%f>?O8-_h4oJukTAA7g3a7;I) _3gHY=m~1M3>jI{t%}NNpyd@MnrYumFl% zXCjyKH=4y|JI^J*ht7&1gM(Hoai6J=dBkAO$ibldz?x vR<3nW_DDr@LZJKG`{b3y$w%nAHmEQJ^Shj&w@ zU+*a490qs z5Jn=4{4xuyQk!tm&ycx# rz-~^?NC
P0{kl*;z)hMZ06>Ik!gSLT}3C751 {iPAdEZDlJ0G!P!d4r|YHUne z_oy1it953Wrjt2Uwo^{2o ##3+K96z1?=vGrNaOST8%beJD63v5-8uubusn1`7G6<{p55B9U0iK z7TAA4Qu-PDFN>Q)mgXj$AKA9J#|U#%c3x0d&sq^@{^p%`ai7wrDPR90l}dorO<{S} zW)vqr{PEDOM<#i@dP3^5zzYhbAQkdkUof=^#-ElrtzL(^_T^+9uLO)WK%=b$EH$`u zwT3wMDtqT&_hG|F|CN0dc`=K>okIkn8JgC%7aJvSH-RGR!aRwspSu3nkTm}SWHr*c z28+M+gkptbdcFrA6O`Aye)!g{dzkCH_LyqL?`_h$(mxyV 4 s%CEpGS z3i3JR_}0i<0#4k6v+;}^VvV_B8o$gNHK)Uq-|mn<)9)lo#n2l`?N)sA$FFUk{^F8o zW)VqgVa%j0YF^<;8A@1mw~_k~HbdF#hO;~Jz4LrV>>GQWOKU&V4W1|GD@yq97NHcr zr$SnPY17pG+gk8l38-^8i}Vj}t2g|ggNP@iq$JNz22o9S7oSFbCc?6y0rxSog*^u+ z&PC4 pgr zDhL{qzlo0V{^(Hfbm6l9d;Oh%=B!K84hITe*8E{T&}&0JdFFpi>e|q=CCAm62VBZx zyr0 )@~-Egd7SB)`kd?zZ~emQFrQHs73kGe-QPS~D< zawTI`#3<~eB>+HaB(R%D@0L8y`Z10Tf4@-xhyt=5vi=0MzPThAwZqGTTcZkH6DE*8y}I&BZsLpj?q zQZs_w88_=7Xl-Ecm2VCnL+?KqA=A4WC-!(6vQh#oR>y1E*8ZYNfuY1qy!fJ-hncqT zq<=E>yEY{nmB&dMao?zZkHdRJTmr{Oy+IsmbL)k^5{+1ju|;4nuFZUA2C#9qfh*HO zp3em^0=@T34;Wz0k)7_=El1fZ#Nr9;m^=3fVW8R86hgoRQmsNgoe>Kc4u^QM+6~u) zS3N~4ak0d2^J$CKX@gsR(TL*0=^Tui5^i?Z;rBiMU0#X! 93yMLIyIXY-RTv s;Y{s| z9^bc`^svS>G%a*BPMhy_vS;nH+siIB2ljd1)%0z*f4w*O-%0=OiT_4pLbd~<|LS=3 z%Y#C1PP&I|tixn4^1YlE>eo?_?p+Eri9nw}_cPd;jZ%%t=fCF6mH9RHxeG^E-h;bn z_)E#B+k-*|J=_bgBORRC$&Y9Em`|8l-HI$w&dA{D-6z;S%#`VFJ6K#-R26>O$Wuv~ zKl`XcTnQDH7At7!ZQ*kK+NXJU50UGV&&92Xn5$xnUzbWpFFe!go|;t)Hu$YmHH>_E z+tqH!rqXQiZCZ1?|6kRY0R8XBzkjKJR#b5KT39@VOXZ>1$O9nnRP9SM-yw4&v1fde zgdJW#ZkJbb^tKzi`k&d*v2Z5xJBKG%@i-$g3p|hGbNs^e<#6a8IgGRQPme3UT+)On zPP!kxd8?yoc2|>(z$(a$saJ^edo>1s!#T;DBr(+m*5zejUj-4zp&S@ }Q5) zIqkf0baCFIq;@7sb%Wk%rPSM2Mrpm97o)oT)qea5tJq1S2 wkcH}0zyI(NA7dRImKR-41M4w7M?RsAE5OSFp+iA^-RvjXr+- zcXq%#d#A$q@sB^2X4RE>AvLFEm8Ro%4v*UQYs$>rK-T zVlk0E;*_;~b}u2C`FO))*S1NRi%Om+*Zs>L-u*T7X@CbikkptDLpD+)sL0W$`3F_L zdM!4x$7}s%2B| c;$kXp%@!-^vR;q}uiz);*LcN_eFBY{R)3Ek~!(pvPWYG7a zx5%9=e&l8|`*Quoxa#JTeo}%++BL~9FPZ*)>=#5JV656pm~gGoIUt&_se&eH+;27Z zs%^Moh+BVH?pA_6joH^mBy!sf*Z@xI#8g|c5+s~!@t%L1A^uUN*JA&|n;uL($#xXx z*Y}1UHhTuGPV=j3c<4Taz=BJ~49uRBNmKXhp+!oFPWBhgl@)ot
7C z!otAo1NUGYpZ9E1ad MWWWWs`|)0`X#%MX}!sg|Z8)fHKnW}*`AzYVWI^wxFar;f5e*$7ab zvfx!+hZ%f^FPOrJ{&vU;s-AYb)A`$hfZ_~i4-dIV 0xmv}Dg=bqNT z6;uRqIrVB7Nz}b6@wl7ofOX0firbPx6;(jqaqlQIJzzRP?@9nq+Pf;wXIFbGq^wD3 zb_u3XlJ7)X=YsGP2{21tqzn6({;5}Bjt@$fPh8kfc^<81U()}^c3OHmNXtr*((I*W z{fCbL_!0~^Ukp#YyI8@vJDOsk+W9KH#qLGwpr8@8n>!$9c5Jpp2efZ7kK*|l!S^rZ zY2owuK#;_9)*OF+ZQU>^=nWgExTOZ7DGkdIAuILb7XDpxOk9}hGDP|I`1LP}K1gfV zPgMR)8DYP57%^GsG;5o3a!5`*iJsqakb~c1DjFkB%n%JB=Kh^llaB~*>@%d@-2d== zR*JCw6gYQ7pdph7w>IvHJzh=TictFfx`D(`Zx7M*5-ZJ^QN*m@jgYaowz>jQWCh?Q zC8?3RoA>xlA}6Sk1`CZe!}->A2;-|r9Wpc-Z&ULb zL~>q#1G4#t=a0BY12ARRdW`492KXgr51Q9^GL}?yfUel|TBygC_LtsrbWd623-qY; zyP@iq13lFpa ^;5X~aiFA$l%@ zhTu#xdT%o^EAby3IF>o20K$t|=x(7!ByEe5i5%R7+ye&4-y!o~Ix6Q@Bz^IDZZ}V7 zSR>cKcpVKycQR?I }7rkl~;%z+yv>PJE-M+22+=AlbtIycb(>Lzj5vrx%hMY*vrWWCm zOuJXr=sO~1r^ZG34dHXrK Z&%??Px-()9c>gH#OjSrJ`zbuF2u&KkiYKEoRPWN+%V&vpIK zx{sf?9knWvl%s=)pRcZsw+J5)=Z8fXA2lw0DO$c^==tmVWhN^G*Y}JZGuo;Vg_qkK z+{MN$8?!G_z6wdVZm#+cVH^)7J5JIm91Qr(1_YNzlfpt`>kMZi?=6G?A3nyPQbxip z*9Gy#h|YU^pMB~H;lE6bPQuHjAOma&9h!C=D~T+mYoNhr_|LMB`E{HQl6zr-rty7= zBzk(g+woFpt%KawkBXi3`6Rc&YEV~^$x`h<+52Ibh$sz060M3uTYq dZ5vg*!T-bNjUwrMgzD>F= z-#3gOba_scdE9Xb%t8Ixbkmt=sCvkg$K~Ot6{v|}P8INT+ZO=(|Is5`BRCks{)o+) zH!m(KWL50h^=|P)p4D#=C9Z~dR~G7`9Hg$U#k3{-JL%s&@qhf7ki84h{}Gu|b9gXs zeB+rSh1rdI5ijW~WR|`al3pZm+4?t<>I~E4xo&o#t~7_^$y%wV5 {ge2 zFAPJ5Vmz%knt4}NZWRFTwYACkDkF#3uVv{r)JUD>u)3J@91z|h+1km_n2wEpEd_BF zPPkO~T6Mv)?(xAVfZx3?77!aPl(kgLvz1^9ayMCo>6UpmeN5*5pr*!&7<*+-mrO=1 z_HJp@Hkt;J+R*oKOH7e<*)oQmClK+XLPoOk&m8-g089ucz=kd@ WzOup8;)_SZVLI$10d1}1XbvP6mQ zhA@Fd6+uPX*I#mrhVBh1CF&&I Hm*O2>M2gh;=^Ofn=vzUbqFt zt3yk)k?wXq7d)Bg7B8J^7VS8@)*|S(fJ>-;wYD{^NVym&iWStl?%~qv`Y`a%t|h8s zIu#jPYCod*9Iwm5_SHoV=-%$OldG96*IT)JTgk8lsKcQz3tc_24pSvKmuU==cC%K+ zhMz0uom4xr{zfML(dH-){frPytix)^eAQnv2S4ZD{+;1Xm!9(raqZAL>1CtMCh$OO zvSFUx*CHs|*zzt6RAItv0FfoI719t%uxGFMj=wz1uvUYw1to!7_MFDly^XzFDs&Oc z&u$VOFR#ZWT)a{J)n;9|8sCSi?@`fkdJbJ>V%G#o7e!k=8is+74O04$xE6ot@)SRb zv2vH8 Jm%ucM?S~5Q*8TFF9gjXFYeFWHf@n zXL8`J(uZ}N06tV;W@#Y9GFW@D02BKnDj>*DRg`@5!E@PJq3mYG@89JLVB6gS*6hVQ z#?2F~czBNuF81P^JtF^mCarcl#s8xP@PESl{`(#OZ$nuYnsRm8`Pi?=!VYnH1=u@Y zoAFX61 ?hZDIy9WIdqF;Wj1bD*# zV2lR!`m};v&{Eg_Jnak}*v?zU`A^Op4=ya@puw-xCC*4L&o6uBRE_KG6ETKdQMo<& z!7EG6&Mqsl0EqH!5Sv?1+vd9UkKT5V%R4`e)NqA |JO}P7<~>-;*X%Tn)iCVU!XZA(kdW&Uuw&}O)!nb1xn|dR zg558fmR8O`m~p#*`X`MIA}(;I&Yz& ts78|>L!wG=I)5&qCa2>C{# z5t=5y{pr6_kRWTpY;eN0ex+kW>M>a8<*gnKV&|`^KTKdj8+r%f4+nKJFy8oB=B*=3 zNDpCKv0bk<&)(i1Cy!ECm=|m!sveys?{vKG_E9!S8R;%p_TmJ5;T5 ~pHS;IeGypy6)i;ooyNVThOP5|1e)W6VE&9fsO`u*Gqrym5(TI&CHe|IP%iHqu zJ O^gDx;WPV#tm>=yi@z2aIeX65qUPLE-*Fg$P{^uS z?cmiQ;)q20^KrcVoUfm0x8u<~{w0qr2?5HOaEYnLi5oJ^R`!125|w2&dA=~K;K=tU zvJTT`i}d}^TIvi-bv&4hS#c^g!$%uSy3fA~0&SJg!4eW%5K?}oc}Lm97j`~M=kAA_ zLso7O7nosETp4l245RHY{e-O@*gHCm^g1iUs?%O8_&b%tzw++G Np+AKWoia~%1_;UjLSfGc eGtj?#+IO^jQEXt)u jN&eG%O5V}@X{v~afw9cbO?Wy>FiUcB$UxU9mJ=$c74hjg$8~~YD`fK2_LtP zQW|?6WMWdKX0FJq)hrF#Zh!Voh&k}vPstRA#_U^da-@#+cTk{91v%kV%&!wxKaZco zj&Hs`;fns6BG3G)!!FyrapbJ|Cjc2vMX}6_i+)$nKC$?O{t&NGtSl?r>S3pjl%|yg zX~0-tFhgz6bb+k(E+?|q-IaEZv=xjS!!$!m^DaSWQn4rJ^$xr?`{dDcv@DJg9dyw% z>HT1-o1Q9XbB3i24Tanz!-G*f?1O;f+TjOmZ78$vcn_vq5#LbrAq--RdDjy?7*(vM zCVNQs7X!MwPM#>jXVoF!ZS~X=0&boLOKTg?qEJ1lpYS{HBg_ z ~T`rvhn% z$f7?xME&0eco_dKj4CH7p0uIQVqQ_INhD?FT3*j?RN!hg{POI@&bdh4y45Kh6+7r1 zE!G*;a=f+v6*Hta;fzPRMrHE0^*w+uJqcYn mO49Ae8oOs3EH>ncF#3_}( z9~tEg(6Xw4Z){1o{jZnq<_ y(5Md#^bBQ09K| zY`ZLuG!5c!m#w<;ZQ#*rJ5mZA*j)r0pnAAbGZ0Z*g(gnLL0-~_{IKeDpX#ku-w8t` zZD6&5lp)DfAGxRjPA>x9`57K}s=>3$fa_GnK`YnB$}zv3$PK8FqcYAC9=W<&Pg*s< z?|8h^zWGiUfS)9fxyDB-zDvp1n3I~g1#aQ%xYcRzTzg(;h0#o~+LQhL>WjLDUxIW? zmPoaP4-+FWjjPGfc>-jZ<0iauHWL$iq}ADn zTyz8WkWV8c(rwkXentTUH`{RRO!D@e?|N74qdN$NPtqsp-l)I{XGiRzn|HvN72gCM zgM2BS7Neo`2_$7qOiZDmYMCaul?F;rrkeZQhv} rTdLfCf;J@zE$V7(*1#uJKP$U()0*-Oe38D F$}IFXFykQ1og?+k9@T9jd``SI0kFM+K!o{77P Ab9{buVv7;IlytFHg0=4~?v=%x=!fgG(@`k5DQij4 z5JXOYe_lCcK9Oi)bBZ`eMIqt7<1bqMbCn`(fFcySZtPLSCGZR7LNA~JHpy3Y^=l5% zNFbY33Us^Gb&J%d)-dU{9ovwuOts~G`5!YrA(X-!Q?zsedmM&jW#xZL8QRFP=tNh# zPyIOWVi(SIA4RZM9E1TK(-#S9Wp2v$VH{Nk--N@!T@{An*j{3k()8Qaww$PCb1U!4 zK2F%o{-sXA*1Ee2{wYDNm#dipB5oSf-4jOIB10v0qnhEvw+!~gA(xq9o%@% F-L)FKa_+O zFvB^4_P(f$guycS*-VT`X#@OAV1Jc8#wm0tVMGs!&A5bdGLEX~Q7MYAHh*>jcsmf@ z1E6_UiKUx!iQ6_dHsMXMnJ{Kts(4 ?G+jgnfW=o;tJ5 zYJGC(TlITCyeAQJQ1n^+6!y)CBm6<-Wn13a`t>yDq~FTVL?#RcE?U}!B4TmEjqTpif8O(kmr+aH@u#B_Ndn5HZ2zC9o2~Y!F9fOI>h$0r{DNiSk-W# ziiD@Jr3G)WI4&4y(CG!-E99*7CpHN~!ysn_ELiLz1hNW`|1BIAhj3LDzu5>j m;96!yX z-|+u4bzBBnJ9`{`FeY>>m-0f%Jh(?U@&g=?5fpoCWb@}76a>@3=4Rg-V5G0w{ouz@y7#{6_4 zXa8#O7qmRkgWnpUM^FAPCIH{L`L&{8Hr|O)t!(AlnG&6YhixV|dfC$iXmnhDrq8o# zfWwNwuWem=d4PAmGej3>%Ux+z?)O3wIrXD=M~~9XfxtsQ>xbI8&kFifj|W6J^iaD6 zzUb2DnPCmfc@yoD9~?>p*!0Oj(kca}q f6Oe7Wp#>)731GW483w`v7NhGkf%9{mkrYxP;y@!0K z_WB#+CcL*3K6mi22U@S(jjUZ^{uv#n4`-9^2N+iOjC;>L+z%r@V6X(Xvd12VVJ;FS zR!)%*MK>J0dllM3+H3pm32s@Mr*go+kc5`xul}t)9+eO#83o3jFa3;GuBR}h!R|y< zsZJN<)Wg_IUzTU{jBoWCtX7S=W@^M#uT+iI?bxj~s(DH3L~Ez67v~`x1$qJ6l|+qf zQ-FPtU*hQn{|K{cEw`xT=;WI>a;{5ASs1(hwh$=1CZ*Vqg?;_bcg8>cAP!&ij1vao zN}ORrYu3UhqR3y95bhn@*ps@F>d6NkhHy6Zw@(lg<_)d64hh)!9Rkpy-Vk;{&q!?a zCXqWcaJ4r1Bz13{Yh$hF+{ezbl{33@+_`AlJk&Ha$BO{8mICq)Zj3N+!WPPd466C3 ztX5e$2+xS+U$KGLG;ZXTyJdPAtIU)Jawq_rwRI{hxp S}DH>3@KOcwz6km+h)SnNQ=SmaL@3mAjUnLC$P4k!)vJyzNp5 z3SrH3@3WeHc+9M%B=$R 1o z*GdTa9;jZsCHC=yMbl$&Fu2C! Mvl?lSe(Q+qCoSmF?(j!l}B{|`zV4d;rp4xOWdGmc47a$ zQjU$xUV)aWkG3qN&wN87_d~gsQJ+-B&&~~K)Ptg@lW|ZICw?*|H;?m{zf?>-?}AkS z-Z<8>sK*WCq`0$@qP1AQvjXCdQvXi=-=I$n_wmOmN-T!xa_Ecu{5^XNXu~^suV2>b z_%Rr!vDLJii1JHhckW_|Rd2$ %C zwW;O%`(c=OfP5+99^U>=i_3_ZSfeuif&ce;BW3+ViL!UyI9NCDr8>n%#@&fAfVy() zKtjY^x3OX1=ztdW0 Oo?5&UTsWl{>1lJ7-K=9WT)(xh~yCsWRzVM_48-#QFK zj=jv)($DlFznjqG_dhi{(#;IQGfGzvy7@Jl#Wq)m`7JkzTuzF*fse}NmuT`wYwXJ5 zmx$c_9FxjBdxsnb-TJ8ZdY1p&6FGPUj)VjP7t4AC)gLiLZ~xKOAjhuGk=H~uP(i<> z>-dA#Lhh}gJE+6y&TjkzPuR(17_&ch@x}?UPx(5iCT3Eu1t@JZv9A?^`odTkQ>uzr zG*|Pk&-W5+zYE?-6@vb#i~mWUfdH1zp8C8y)RCPqlSJV3&x(z@t_E37t@$_T z7aOZt3>oBOHxFhrgmdU)eikBt{zCwLZzHIm(5aaj;bY^_dJHFi_A}2G*W8i&R+PCL z*HsrXG>#-3d%CN+cIP(Z#+TgAyb|jRuLtp^mlMMzcp$T{j`2he_yx^(gxpq~2(qu9 zKkcl13w rQh5N ~QVW)|fghY7w>@Yvb`730wSBt7lJ>8kG^k(hS2qzEwL&3k zcHa_>)p5{`y&W^|#A9+9zCJ)luBo#$SS^ZZ**5C$R`n_t1KFWjRUXRt?zj51H{M~D ztwVd2$oXR}Ds`{WWZh~{@ #$r}X z@;k;NV?!3z?fj ?hN0q!$;$eG9A&pr88eOn#!b~UGg+Qr{&39m@pQ-d}5xBLEI zdF~1fCChx;s<3`@FgIDKI3{nXxg%CR-to0u#Ja UvX+X_vn`1-7ev$ zEC~JVyk+oV;@+Y8EU)j(o89|Pg80>|C=cyX=8Wyna^5SCgg Vwu4Vuok8s<$`Z+33T<= z#d@yoMvec~D8Pb%-@zl4jl2_y^a1ZF4Ep^7eXXsv^n`zJK5|;YFh&Tx4tM}4cqHR? zb6wQ4n?r6nQk17*?Hde6q=YoqQ0Jx-AZ(qdKffpQb%{pt8SA#N^rB-l=cMw3eweJa z?f8LNacRx9uckwP`Tsc?!_U0l&*;2cX|3ySrk_%Q@k$zOV 8zml>VZeQ4FY)F)x-q?(o`SfQdN ?}XHOF5VjOp{=#b$$$P_r_ z|7{Y~+Y#53_2HcUPCyYHA$oUGx%a&F?CyH<#?)$eAdOw-fkvn|0ueqV=U8dd44wmr zMxyd5iGt~iL7pnwoh5WNrxVW=Fg~w}+N`CUyLQ}oCTeduNGE3-fz&_tf_C%O)1q!y zjsnVuDFxc<;af>`3tN9jYgk5vnzf^H>r&3|8$7}%m9MR4hwv?dfN_-+J*ju4nAK6v zag^V!Z91Nnx^LU@V;|9XGI1km1B(o`^?h~N5oFC*Jh)zEfqR2`9S|Q+_*J$Tu&$MG z$u79ySL;{5c8AMq*Oe9Y#S%u|V_O1AwbjWy_oh!)&Vy&_+#}b{bsaWp`c5L% mt<>Y9p z#Nx`9+s8B(-zlqX32lqAG&T(7ryv#hp8%~vRxXu8%tqRH1u#kH820cS^S`mtI6vu( z#Yi)wmCcdBlU2g~Rnq-ev0lpSzlTyUeBU0QheqV&M;{geQ~dDr!;qd^d1{ArS_x|) zn!iH%rDr8x!ASi3`=!9g(Qq)leH0f-M-EbE(kJLhjk>0%2Yc{ppZ8z+@O~#%5dxW! zG*EVod3Ba)4{G79foG+qFNq8~kDpEavTChg|FiYuw=X3gPM$}4l 7*m_+e@27^g-AW3tf2pH{r&?g}nGwuSumIcbR|o?$KlrcBjGScne&4}rJs1-p zFD{~g(_6hhv6kbeK3}37Jz=TbhX %RA9XVR}r_J>@p*%9y7a=^f|9s0tP_!_^p zzsGa0WNXg^xA{B4;n<_C(?>phkqyO>5deGfwr!z|+sWWQ@lT@QaXl%iF@`c2c9sV6 zgKRm(t;Pob&zSj9=K%j4LnOea8(qd`^I!dAX?EFG?UY8r;n!SqB9^r4n01NtV=u@) z@0w1v3&NQGl=)N$6WO#|AlGYV vEsN_gU zO1j*&<6vP|pwGyuvh*dNjKOm>>=hB K2GoQ zjcJZ&7Tfv-nxbF{eST_|*#Wm67AdW0m@5Dl+98n-3JMY5V>;O6WXy8)WPtOVjTii# zsihxj3djzo1!u{EeW9rMQEPT!e=>SA?^BXS%Ilc{>JO@?!R?U{Iwt6VBYQd1GdRSQ z_lkJKHczN^{ULkCuNL9%5fz?4hTM)yJ_sn?9rQdvX%{1uAJngmKCMj@0$CU8xcbmb2Y@=M~PX- !<@* ztM#ZL 3N k?2TXmhOv&bpSVRBk`_^2A`4>q@o;%n zUJth#X_D{DhGqDj6vjb;52pf<^m>9eihYvemKqP9h`)h0+(UF)kKz4snQS;6AARJ7 ze)@=8YS0INSco*vS|f#JPl(phaR@e@Br+%S*pT7wzV*O!R6Gt|g<59Hh+M4lhH?UT zra(EJwZrb2W@^IaByO&tNON9HN}~uZXjf zQ`Ap37j (2kbGylK?CF0*swdsh9e*Gocy~`@aLc6Lv+ubAb$&Q!ZNmq|P ze`qT_k`&i-UF%!$_Y+xvCn$vcXutMp_bvsie*Ld+{JkBl?x=7d?%TQ3D(LTou><=h zac@r?`u$v2zUjpLP^^p8;sGr!-o4M)|4EQPpJ6Tb;JRJKxxeep%auQL_|m@{^6wt` z|29Sp#Fiz@>d*AMiA+c}%IXdzq}K3R2_dK6%ltg}-KV*Dc8gYxQ7;IZekVDXZurZo zdcsFK=xjys_xaer$M<~U3zK~Otn$?CF?%guE{(4NMW&3F+}Yhu??x9v&ZXpngbBQ} zBTg52wCk8-$naJE3HRoO*!gvy;2MKtM@d~6+BH;#(gw`!3JRJv7j{G3cYQcLqr2bZ z__^gK@!F{qik$|dRyH1RRAmEn@#oP93VyYHU?K%3@^J82HvhE+#td_%u1M{V1K(6) zwB`A6t|*F(JSyWv>h4`ty}7A&on+3>_}QQm8Fc7l4|I@eO{@r^UI(kF;mB@p*F_e+ z>XBziVr1V%UwUP6`Y+pUY(SP 8|BZg_=L2G`!wWb1ZlI;v2tx)^8o}vmcy%wqA!;-e23y zhdkBFZc%J(qMRd8dRS4Js2(dD8F@x_bpTsZz|i16My=db>0Q4 Xnh}?c{ zzdZU%BbZ=R{Lj9DhY76;#oo;a6=_+lai^7okH+q-?&~hW84W``hzyxg$5^%Hy7x!c z{BO&a$)i@E=d2~Z{>v#z-2G{0k*8Ra$H;F5e!$mkl5@OP7nP?1!0Q?}=D$cqNrDcs zbgB6h3r#gxa*mwvfrt7f8JQ%c#zieWU7At(r~sMl7;FvEMNG^cjLH9Sq}2q6Q-pm& zKA`U-KkhpBYi!(j7tie~G#;F{+_z@;BY4)S#u-p+$?$in{!}0MOSOUsji>Oj0nhTC zBi^|T6y7r}wCMF?ajPRIKDvc9uM;`;7>n>b1JZS?P*yFLic0VXiF;LvwddRd?|AYO zK6&(gvSB)wDR{!MJ*^7xMp@_W9*+9QBikSUOgIaAWM190eN|UbQP0!S!zq9H`Breq z@luxBs>=2ccy4#c8}YxL_Fb5B*J;r6r`!MI`7Pfp)^2 {~(Y|lA5|J1xu*;2gSIAw{y8y9Jo@*x78$u5ciQ#12{{qT0 ma+d%-D3IC%D^X#`|Mnd yma}R(9QNdp*e*{O&K$VzD^LxV7~9hPug(tG z%){1O#A_G(@F_o? s!%+{&~=Vc%oE(#%ZbPHe+@=GSCz1)FV_l zrx-vSGeb~`MV(Po*R_|RYu~xSokP#ZbpKYs8PI8>0u%z&P%)JiIqzItb{p9$?3-&( zeLLZ6$S;x0fdnqAh7#m{JQ0TX-o!%O9;9SsyeFT2Wv?>xUVeJ3l0Z@TeSORB+>^mU zHgq;dGh7Xe Wru^0J!3XxpeBMcUCH?CJ;{Wu zzkajEV{xEJe^3ybdgkJX1fKYxJitPTu1*oUqA<(ZUBZc!T>Wst3bV;13f4}Goe_G& zgo5 Uedtv5;mlsD&jAltfp1LdClAR zKJoZPK!S(;RLIsJ9v<-O7y#6YPJw)yz4_o=ODRV6i|m Dk_cCL;@=VPt@=rc#Xk62pF8wsH{9{P^xDcvDvc@K|F vN#jr9`7R^Xn8W@6JpX6#M0!PUw>c}&xuIT&7&dsr@Z%Le_ zTILcgT^hHuDPtJ<=cOZK#iJkDEvu}Y%0IZXgEOYw$1xGH7_J$%WOplA9m3gqUY=4H zZYo40kXAP9CbdnW6pxQmhm2p}f1A9J-q7#AM1lq(>t$|nrCr40DYYRe7XL^cxJL!p z=ZDq#uHTF?FI+4|DwSqy7)R@tI?~LcqhHuh*w~5|!v5})*W*pFK*qzjF=sD=CeMUq z>i+lh1b{OE|2ioi`lka=Y0+TPwJUE(Knh|UNV^3Xv-prUh;M70pyHa0nh{s|km22; z%X+KW?5q-C8^>g^e4+TjFt4CJtdm$&0$t=9-Er!5+9(H)1{PRoIPi^>MPr);6@8Wa zEi-bG_3ZgK*Ejo5AzT3Ajf%f9p=IEYmNL)Z!_O(CRRK?UdimN!M>(n~hAw~$iv$F- z=^(gf$pD0hZt5+9A)@h2Ad@mTN)G)xO_fnx^zjh;yyq7I#8p&`IioPVHcg OoF2r`w{dU1d(8T7?aVL347DWD4am=bNBvu-CB_{M?YJ_e9U z3IgGU*Hep uN{wqg^L~Thi)#0&n-*u?j(LbYivz)zHrwFK{FKr_ zqHL>|wy?hg`FQ?P9UrPf;xx _RC+Yc78g5t7_~A;taE5TLK*r<;}6*}_(tEnAm&A8-D)e8 z@j}w=g?p o`p`U-$N?Wp<5!Hbtoi}L zLB-b6`h_ro(GPEDhMbFuT#yYtdd7CBH~TI}YrY?pht+CQ#+=H&87Is*+t C$D93aUB6vhWbCB(X5sehfrpI^ydt(lGW8c$Fip;mvme=X(UpRe->x$$@q&%en}e z+TT$|GQWBvd=`6HJ^tr~J=_}}8U^o+vGK+B=S`GG_^e#68}ux~T_#)o0b#xt=MVdH zRL_(Rah!ur@8LWbDkLd84#tN!@4r$2e7&o @9s9z|F6AeRx&!-1iv+ ZCOdPP2G9F`|sn zB~QGK&tl$$30UAP{L=B8*#$?*>EgmkWgdYq_0BkvNstYCzc;yF?#&pf2h@?uy;DFm zrkAvKkdCwMpy>&CX%L)z=ysI0MhGG*13KKeyKSwiTKFhSS}EC){q^7z$)t|agz6mc zWb0)NaU;fOM0fae5Kf HO^Qj)RZpdb0GsF^7WY<_CEXDtr@^+j;=-P@X!l zKSo~Q;XHqjzMV6%|G3=NZE_{E{2Fu8@|%Jb=&9HOc-$}Xrkx@0b>k6(Z(U8K$9O1( zC75lfj!E$a^F72jk?V~~xa8E2H$!18j^KafolaNZd~*O(1sq_G{0r!w|J%&+RIz|U z3;Kv)H*$g#pOx(KIxP1U>g}Ct)f?B%UUPjVc?4XI^xwS6_x!j~;fcrNZ(kOgLw&`> zywp2imYls%NrkD{sh@g!zyw_OxjG~egnPf6A5I+IK2~>OFJ3r#|D=8;TM~R=Oe6fE zUD4Y+m6kKN59n8N2(AvM-!$lPiygJbo?T$E!@zjt` cBU*`EZ_4Ij4Zt*a=%3g=-wBM<1IQl*CJe zeZ+AuY(QHl+pr7;#Cy}^ WCj^TK4%s-(B&kv_ H}vAr3l__O3Gf#R4~7g zw_@q5!VPZC!#=w?@>Lxd yx}K(KNWjF#S0~qw*atK z)wuO&5*n2Ow`|vp;u1P;ZN(&KZN*CBuj{*+Bj>|FRV%`xxC&9;?&XU~+bd?iO+nZ5 z8lXOwU6CU;B@eYiZ=`?(^ncso`nkdI0P%i~a`%F2mxry!<9E}g&FmG%Md3ElN>wOE z9e&Bb(FK|$7r4>3nUmecZ$5<-ak=wdYH{3YD~Q1(``G_1ubKLJq}FP2V0X^ufShJW zvvDAAdDIk$yqyZ6p_K>?#&Guofsc+H>b> Jx3lP!v*v2 z4(u*1cOB5Arx|YbxITp?Sb~LFIRyEGP`lx%_CV8}_2$DT-E&E?2s8qNIL8S;Ocvk& zdCkn9Z;G1XfPJ66K14Hz`J^jtzD!2AjM;l)XU;|zhP~pGOqfpd= (?wT)Ya* zi;sqYO!+{ bK^*R9fR zFd6Rd9;z7C!VQwyVfuS;)6}Z5FvS P% =OI(M%d-6wZl zt2=ML`l!Pa0a1p%3L=zcMTx7CpaDnerav<6pip9O$d%FKIA@!HUtSHXC! GfeF~S}8>hQl`D90aLBpxtRf8YSFK2W*IE3~qGbY*B8 z0j{iP)JuEB5gW3O X8yWoNEer$X%V$P&zjv_DSCi$T=_^ z7u$LTbdarSXn^TGd}p_E!S(*9$jSPvW9*+DA0DA$wXXBHxy41;sCKp8*3~B#N#8xB zd1=md@0a30x0Z5!xp2?cVqo}HY@*fo+B>aM2w7k=Ui{wV 0|95**Qj+ P(8Ho$1x=5nm3T?ET#o3{m*A zX-y9bkR%db(&saI8o$X*8rOIADs`ottxe1lnG2-6ptPwtJEBGnL1agsdq$w6n9+;H zCJXNmpQlfQiDDDBwM)6FTV9g^MlVtx1#s{xEZmwFHc~dvX2@?Qm;g+?-d4-eP-gdK z(Y#!n`IIP>_X6kaw}Zv?;NC9;dz-(ac|&wf?bg+6e`5hO5Wy_kNZHM)?9?ckHc&5Q z6}GoA1|j=by|x@n$~5}0Fxm{~LgSE4mDsLy@2)a;>}J+cTu(0O6Rz;ya&vcglYJOD z;ew*SGmW0w?4uvpfu3h%D7BX9yVGIB6wIj&JlYI}!e!(<&=X)9cNEOtQ3bxZ1S?#~ zDsS^(-MtMW5ck*zpy-yT8vDo)mzX62iol4ycJ8E&)-*0PdJ?^pA*PBMP }Z7S z`4u `DFEfGR-k>OQTgplLRqCOo zE=c!c(z^7cSBWr(5n45b_;hGbu-Ul7!Cd7hfg^HTk5W>>!&t+QOr51zaTC;0#y}B3 zFLTN9@Qo;$WqOY7*9#~uQVLvkwB*6u^J`#G>RdJyU!cw^1arn-waLbyX5NXv!`FbJ z4|(~qAC9x)ehG7RfK@|Fy4xgi2#>Z``yvLjZ>@7@-ut=7dpaJB6v|3P@3v3U@Vk=9 zxVwtS4J+a&KKS`cJZCI5iMg0++1VQ*j*Pe@Uo-mBnw$D;3>#oXk&u4jTw9) J&zvRHPBPJIDcJ?Bfi=Sl=}*6Wo;GOsOOS*6I<3mEiEuBG#7hy zNuE@*k@~IC?sD@xauS-&P8@fk<_p`oPZ?=CcP1dMr>d|Fir+;7DmpNt$j^tlk|u;Z zU%^PhG>rM?;PU-yim5pbYsXI|1RqN?_ t8>zlH->_1LBzjy1-BSCdPnhy3@r@QS5sXI&>xd(5{b;vIa48t1NbB*s!D7PBa z@T>+(MZJj(0DM} ycB7KTQ0bmgjxk!#=dmC7m3#8K`15U6hravcUpN`<*V0$1qS@ @r@j2B@j@NDXkKHt1+1MF}_ z9g(Bsx>-hlq|c1K?P5>~Fka9i7I-1A^h)&5#`kc^P7bL%{0m@0KS0F-8Laa^uXA5g zsS5QGYK ;0@l5t>MCCJ! z3hpxzKLIk4^OhxO1F03_(=vexLYj81@izzKXT8UzTzc+s8Im9<+GgO8A^&^FC52zQ zoC9gll8SSwGyV@Q$+m!)lGAKqM6b!TNAHNJ-3tn^f~P<>1&pFNyD^&*;qk5u5=XSK zOL#k!!S`Zhdiu&k81~_5Iel%FM%kfQup|~dFAqAoJWY#|-(-fWDqVyk3zqR4E_F+} zQh+ds4oEo`j%GvP^x{Gjaw$(}a4<7Yojy*e3CO|Y8UoWy^lm?CdJz{F7u?mKqYc95 zHhzKb{tBAZLn3Jv7)v-O26o^Y)oU*D&IfqvC{J9Cu#H&emo!1&!ho{M1oPGs_$@On zwByt7FOzXq6E4tgiK>wcex@I(c2~0smJwidPavC9lirrceB{HO2|t&EzOD0gUAf6Y z5K&aS)$%+89k^XVwe$XEpGYc>IlZCf&vrU1koTT-dB(9J)b9K6aGwIqX0gkBKv$Xv ztN2WUWL$vb9w0p)Sr$5AR^Y0BZFgT T4%xU$4Sr z#46eskA8_cQ_}!muDC2WeDPe-EM>_`aL_D8+%35Kdw>rZ{PBqaqW+#^PAUkz^EeWZ zZ!R!{u9X$EF^;wWNCT4#NvI9kg)0LtO-mZ7ev158fD8$ak?tyhM8^8Z(GpGUiyP$b zq@%{Egq7;<5%R#aoqP}xL#aY# !N6_@5UPr2y4H>R^I%%9AATQUBtVDr-v zh)%%vRB`>9IhfKHYTS k~4-s-*u*D>7@{|qNbOLn1*^w|TXlZ<9lx`-J`g?R_; zp|bBxN_s}?Wamw%&yv`}w#!P*!zyggkVjbWX7>wX_|J(e!u4YM&tJ+3?pb<>7>j%K zXC~V`>0V|Pu-^1EReddHPsV7V;O^%Ij%@M%IQ)!`n|fd&ySK*isGjqLNIl_Jsm6Ye zP|;^I!=U)kkXkxyfxPU*7(JB*ik>GFuE{2Nt>7VNJTl{EHV=p VS^fQy$ZR)h<>_Tk!!&HP%DtOxU}%ym4kgA1nUO+UUD` zeFJJ-8tmN O}i;$pi`?x21fiiOS?)w zYdr@Hv&9Hn^K_wvb=Em`mVM6%PNz?uN|Dq3qw&}vwUSbKEOvbJ%5$4pvkik+R(~9) zbC+h0>zS3Baqqh!5GH)%1hbm{s|V-i_?R<4>l@;FYZtg}dTO_);D&rbd{*b$Gi-XL zhEu5B6~kkA0H|=>=?q)*pxudeXDr>GzE|oV!GzYiHUI2Hnp@Cu3vN?KHIKGP`wL?B zalayXA{P69nx0Hia#lWhUm^9N{e;!6q>$m1pA&Ag$!|MHh2&=s3)WrxGW=#CiU)n` zL9g&PF1fRPIhmEh*SsdYg+IB=vh>z`dn?ISER$I~+bVrLq2i8fE1Smir%#Gmdidlr z!t&E}UrRe*`J{c*QTNGO&BlMdp~&aa@Z@>zlI{6ELV}2}!kDl4-gIBquhltj5TO7u zT*eX8o^%JFBs?FU?3j%ThkD+TKj~zza&|XIj&=gIW!m&ad^H1 e0Rsaz}YC ^s#<^OrpQS5XnnDd1@G?x@81Ey~z)s z*a#
)oxi*jrvGB8o3nY!>R1=5 zb>-Ack3Mx5aqfhQFpn+zIYGUn&9#L?Jjx|l2SQS0JsRFs>1(6UCw{e8wj=URVWWAc zAs!iUu$WT+qDx`v!?3?B8VfY-AQPQ`&{6J!C(uTe5j_{><~qS`5%{LaXf7HlvK5A+ zd$*&AO_b*st4#Ucs0P`rj@3ruVAHN8Bs#*UH934QM?QW_(B0-ls{~3}@^j2p`QjsR zc8v3AKl4!1xn;N90LNo}RW8rWp2djld|?=!L9LJZ+L*+jaT%oRFw9&U4Vz+I z;9>!^0Stvz(x4R3fURIOM6zLBt?>J8D~n(BOh(h}Pa%0r zyWI}Daw3}cshS=rQ2CU0rMM>nQS0uegL38*#wSi(k#@L{-mr 9KcTwh%?GV8D1HH01&ExUic9#C9&UACBc-rYdd63)IpH}GOhh(=laIgJ8IyQ zRcn$)8+_cty9?j9T{3zeM5l&6lffG_&9&f6RF+e=d)LD5{9KL<3hk_{o+}*V?67>C zq&g~@X4O?hMIa>oxN7gl%lZ gn1*&SIJKMd0^s!bT}usAQF;3-KH-$DK|{K>E+m1VdtK$sMwC znXiJ+G_5)5L7Ovfzrz!JHaS>Vy2Q7*(%c||rUxpm-W-Y;?^Oq@1l{ym+0?% zQttMm^lu?ICl=a`oaa9M#JpMcM9RTDqr1;xS}=AKxCG|hvRug%j4j8i=5x^i1zUOr zW6~;x+iBMLtiiX@pfjYZ*rZtwQt6Vs 7Twna;v$`9 zxt0oZv@Wuo)b&=I{OC6VoN1N{eF0HWQT<*hpC~Wu!>Em4$^SpfOgfUGaZ<# $2ZfX&H)c&9=3_o&TnnR;iIA{IyK%p``1wXi4BT;fqQ) z)h<5oen7GqoclFsU`~IcqxB->jn-l}%<+N4e%?as`ThTN`ag-LghASTs}TJY(m%`q z#Y`y;RVngk+4){=S>uflb}?yCZ#r56V@9nPyGU$Dy3mSS94(0{EdyW`p_YA2E7*W( zBdUo>!$a?eqRo?}BzPuX0qy7P2qW^lw+n<5(QxuiGn_u%q5`9esZRE%tJcneS^NDh zdm;NRwK!F{+gs&GX4r*BQleRS?qfAd|2b~s_kZ~9(pDFWDf6ZZXs;$>dS%YzaDr~5 z5p4y%*$_hn5=DAx^Gtxd8;BG)Tov9DDL46Gs_Q8S{2(3xF-!d2R@~gPw2DKkqUHV= z^3O?HqSem}=Yy68(X{4w{*v;Xl}WHb1@ukq_o)cDa_}GYXQN=w{e84ZO8*WR;Z-V6 zTNhNbbSjklxYT1X?lmX^ZbA^F!0pbKLKx|D3x$O5^4lQ*lY~GoC8Ig< O$$QX}+Gs}ENqXD&GhB<=Xk#db$4s?e8!#~VhJ!0J)z5d76@g^@+2 z_fR38nvn8ihYDM+ZK>EKd+L0ISNhl8abmHt$MhcGumacC=Ozu*dN8D&T)BZHgMLWv zB{k17moK+~1%f4*;>dp#XVz=cDnHe12Jsb7`Jy^$5>Tfs)v=uIw3XW)&;e5<=&^HM zT*D*fcjt*^U>-)Frlcix3^VLg#5a7mkc^KGj7Ok)Ige UXL4T|-}H)fjnlpF>o!})erjm_Q2cHv;+X-~Ka7~kej#E%6} zUF+I0iyy1EyJr)?AmRWvxn~x _W@e#c-Gho?b^9C(Uv1hrn zA)l(IMfEzvr|!_@GdL7&-Y(*4s)3$@=Z1&7bRSs51R+@hYG5rTlS+jS)yniIxS8cb zq$O>^g+4s9I~#4!<5d07nYrmf#`+v}*gwZbg_BG;wM0!=G|Ou~IOSKn3Tj6#*DlFpYusjMlxsJ3cII0ld~rJy z9(s5KN|SmCzU~Dhdt$}?*Q-t23r}aMAoxo&XWiP1yyKgMc#+$Cz(uU9U!vJ~ILv6@ zA+*=Z61ev*+tlUC+oo&B{K==2AXA$QauQ9jwy6}EO`#4#VZiW?zH-Y|4_g&56@S^X z)dKz;Lfj;xVg9?#fZs+XG9VI{uS-a11f3YCs>+jm7`5R+94a43DAKT*79of5E~P;4 z;Z3%dL?dyxIM#AkA$o=${-d5wN-BV}fy@pA 0lU-od zxw6bP-%0MqxvdzKe-(wR3$7TwoLn!g`l*J}ce&HDWhj4+q-zm97QBFQ%hr2;*`{a# zLoD+FG8GA{#3n5y7D@3LMHU?)=po|>Zq(D-qj%Tl6$yBs^vz@GsYr9$5*!#PpTalw zSe9FMPS9vW2s2tpw{GgrDy9D6uv+TQmPH&T|A=qT3-u}o=r@%;i8*P?d`NB-&be*#T4 zN-hba{+K9CVx3R=xUE)rtP~rP1Y^4zb$HvXHO%$o%04?r5wuM&3YsdBd0qkN ( Nq3;R&+bt z9|_YEj@F`Z0Moco7&!r!87OmJZs}+WfNCNH#G3#T;S;oLyxzZVG#i1XWp6aqto2@A zNP-aAHP88+qHbJw?sQw-dcGl$>Y#@Jd~l7=y^V@vGe-Fvi0MJf1+PWb{K7ip9)z?h zFGw{fHEmtw(Y)|g={-b&W7Cdy16!|r@s-=^%Fmk|e5#Bx6juhAufqnTY ^SR%$@Fn zG4zvN#A0~jLUi3NGXtJZu=4}EZK3wcvs}%SUXzC7GIya#k^15F^A(eo9`*t&%HyL= zYo44(kzne%X;ktpW@MkHXMq8Xj*IYi>1+DY7dS&F^bmlJ!1-1#Z3FB(&+4nZRU4%@ znzB{fBe{cJ2!nIL#%l~4utY*4icn~X+?Atw8Sbn&Y;GLC^0V4C?com9b30oM>`v1T z$6n;1Pt)eDylK!4@}6L2_UUJ!aCPsbV3fT3?wAVf2x|iXh6UNmD1*hU zT0YwGsvqKNG{?Andt^m(K>dpjo>KALGyCvpyycFfNwsCP0q-ag4TbNfW669`_RLy9 zbIOg3d$R2V`61wR*QT4O&x-FwZazdNOeev~Nw!5zb%AP&kIw$|3L8B9B+o_%DLuSn z#N;D(Hy^cRicQo-ZoTITb}nE|Veu04kU_zx8;%*k>68N@K^zMCMRD#Y&*odF2HMGQ zzHJWW2-t0I2J`WpW+9idJTU2A>>&D3M58n93nS!FP?4kJ?w0Qxv8*IGy%DSAzaq$A z$??ZG2NK;S4o~)hfSVoM$uC(AbI@Ts$#d>&5c_3 -H0dEfdQ z!|Jt<{6_@*xGqXDx-1u5Y$3!Vdv@4+{E4w8%f|z`x??i1K-!|>$_`>P6yCQ=-5uZ! z1UxM!Z%P#$Pz6L73$x7wU|!sGNj>2?Ymn(iq&t1Maj`eOzSD$EM>cgFnWHqy5znP( zNiO4Yb<<#OHKiP80?aKL#Poe;Bn6U_x*9ZpBB0h(>zkll$_eZ28gW0WwthCV2Wxby z&QKGUj9tEGv{QsS8up(f_WoZ=S66s6v{CA*izUfYIJVU c+zJ$2xg>YvG8kDIyIR2) z&^x=4r *@#uuPJ%f`Zy+B+Q(cA`J2J>XPwI+LlK&lOhQ$s;a8$Xrwu7=X1&md4nEKE1 z?3C2KSQ)Ez6o9?J`80qii7tEuJI3%wf%wXZbYDx;@xCM9j|=Qe0$hMK!m>gMXcVL@ zih91y90w(QMk!-bNYCI1g!yKvq9hzL?n@uu{J~kWu}P-mV7>?Zo>JypQ4_A0^p3pK zV~gc67=?4pg+#P;Su)ClC(bsb-{XcOk96A?0q)I4*mN?9e$! 2biz73HjpC{sSYP74SG+TDKLV3L^HOsxKrQIEz_Uf_Eyi=a6!1;C8}Y 8^>jD`i?)$W`6Fmkxys0XQCB^h&QOQ+%8X&7+%A*Wn?sG z5W!M_JrOD@2a zYp(?Mk5 zMBgdv_Yx>l`r~YTcl0v)v>YBWi|md|gL@bVVG!nUPp |@JD~Dl5oX|pH*J<5U9!)g!4PHJ9QSK~oESZ38o{9L^l$#ihT3w?wPxRN ze)!o5&+|m(Ot#8|Pa9t|gfRnQ-wX5TGB~6dRwLd#9qPgxNNa=pdxKFI($8Y@n3fy| zL`Av`4mX*Xo~zPPw!7|(9J65%;_{Sfk;;`{QNzV%aueRok(*m7lv^Pk1DFa h=28fdK1%5Ttiz>;T B(tVU{n*KQnN5D-UWhn=%o977oVathlZn$$&O! zWSDwv-Pa7It>}FFL2biDSkCMHk;%fx|8Qf`5N#O&2X4s5Vu?!gbjG(ux^M7I!t{tu zG*_?6&Y?{*%2yt&t5ax&CX-l><)!(GDNP9J;bI}n14xyh9M|tOY|qf4q)>z+4GoZ! zWT&!MLEt3v`Z$U{?#Bxczz{&Nh)~X^#o+eK!>R=XdQh91&CczE{1IV+G?i7XvJ+UB zPSx0yzNH6jt>?<23bv=~id luAJ}_jugbyP|nzNCYrs1P}Bc6x0*X@}*Nq&2n>h z#Kbq_zpSU^1Cg7z@=wl%-J8E?H@Y3^)J*ZjC!K?P11L%%iaVnulMdfF0^>cm854RX zX&=0(xMih>iXj1LU p^3Q^bV*!049Os y*JK^Y&a5#! z+M&2Eg(i(*w_1VXK{d}f$kI*32Vz-t;IrLu4o1tml#kYw;Z=rb&n4vj{YTPVXIPq# z*cN-Yh+9hW!YAA+h-+nCJ %hXH~Z{IoSAPMUDl`xIk6S-CFYI!+h2{bmb*pJbPthTkOAGk)hJC z+X6Y)L}k(Y5CDwn+zpULMZwcK;S3yLQ$wmUd*|*zD^BpC%6DYRfCVT3#Af!*)%u2q zCV(e|Snon NDzk zi? vZy<^`CTJJOvEW2}1~-iBcC8Wo^k fkYLxdgT{jIiHJn$}#zCk*LC+is54{bz`B}P4-g8Njww{{tZr{z_f&UBO* zW(!%yeHv3F+SBd)bvTZ5@dkge^`LdpQc5C@DFCIE?o*-|g#HI}xCcE!-PWCNw3$)Z z`%xCH+)2taw5hB4eq>MN!S>XjF^9f;B`DJOYqc*I7}%2YP7U7ipxlk@m^Sc&_|SXs z1iC+60x%z=E!!SIvZKn5-r{QNbvq`g6!JOr{N*2CG+u_RE-ot$-*{q^@5}sMO~>)z zlaZ*B5*xlZvi~&shc5s1nc+}Cmyt7{Bt29+)U0VUVY+JEg>P-V%tIawLJDn`JEy9= zHO&zRVL;tu^72mkJTp@{_^3~+`1r?1N_BNnp2x<{em?hl$a%cVX&0=ytzaHN8fs4W zno=mTsK3hVIVjbfbr(LkE?-;bsNUqy&rp56eKE{~cOr@QQ`V6$Q^|N!;1@4bW@P5F z0P_*IN;$0m?0SKo#np++2ts-_R+aY>Vzp0`@1k6_ii13Lr6T(b1G%r{BvYT=QA3U! z#&4fS{=qihH{@9q^t1II=~&Ujj6i8~|BaSrqdEGNBw;7!CObEX48J&it@f22aWpy+ z%82)hkX#K9;yt#g^Mpwt>i3iX&l4&=Ho(1)yDF=2d?Y*&_%w~B&!NOO*xZ9UBjud= z*yY#H%Xxi1qiZ!P_44?~q2(m{Dr7SJQCB4HB$Phxm4Tv zNgsx@X+3y469j;o8#2{gyt@h{^2lV+=JJ?LkG7rjm~f5jKJItJFu$+*2k-bn=I_H9 zDN_5dT_zuMjrwzLZ-PGzzjcp?7@JGVi7^InP?+<*I%0`ZC>XWtI^zAKb$Xh^Z^U)M z#J)YUw1(@B;;)9%Uh8)tVY?ds00r409w@GL>iMj0kn&K8WzyPN_5>gQAF*}LD(>D} zqxMOuI-M+^SS~9azOw(z7?{$IUav)4sQ7QBK-jA%K&el1@dtshZp!gq<@H+Ga3^+} zG~c`%@OEPE%#oL>MYv@F<5iU$0-6nD?xAZEwAQ$DE*8nf9_zTs;vO`>)xUFdUPESL zL}7 9r*MV!G5m+wm$F{*qXpp{Db4M<@M>y3Ixe##pHhE^7K$5Igre1D!}o zOuafYuGyNiiPwc7V#{_ExcsUoeetds3oi~Te<|R)`zVwHw7O3>C)>A=jDMs?q?{5_ z_7!1%u {LA|I|1ft*wL{y8*jmv;kW2oXHH~KL<=-Xe1S|V zwtbVd@htp9@o&Z|(<9xgaZ=j8ib(RE6v#1=<`tBiQCZ#^2=zEeJv%zCoG SlDGR7Znr_g3t}$$ej2