From 16651d57d9ba7e0b6fb80558e3363f689f3ab5ca Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Fri, 10 Mar 2017 00:36:11 +0000 Subject: [PATCH 01/44] Fix typo in Study Guide section (#10) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce5149fc..809e7bec 100644 --- a/README.md +++ b/README.md @@ -183,8 +183,8 @@ More experienced candidates are generally expected to know more about system des Start broad and go deeper in a few areas. It helps to know a little about various key system design topics. Adjust the following guide based on your experience, what positions you are interviewing for, and which companies you are interviewing with. * **Short** - Aim for **breadth** with system design topics. Practice by solving **some** interview questions. -* **Medium** - Aim for **breadth** and **some depth** with system design topics. Practice by solving a **many** interview questions. -* **Long** - Aim for **breadth** and **more depth** with system design topics. Practice by solving a **most** interview questions. +* **Medium** - Aim for **breadth** and **some depth** with system design topics. Practice by solving **many** interview questions. +* **Long** - Aim for **breadth** and **more depth** with system design topics. Practice by solving **most** interview questions. | | Short | Medium | Long | |---|---|---|---| From aaecc59f6a22915ae3b4ce6918e682f9467d5ffb Mon Sep 17 00:00:00 2001 From: James Hewitt Date: Fri, 10 Mar 2017 00:37:39 +0000 Subject: [PATCH 02/44] Fix typo - lobsided -> lopsided (#11) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 809e7bec..0a84fe95 100644 --- a/README.md +++ b/README.md @@ -844,7 +844,7 @@ Common ways to shard a table of users is either through the user's last name ini ##### Disadvantage(s): sharding * You'll need to update your application logic to work with shards, which could result in complex SQL queries. -* Data distribution can become lobsided in a shard. For example, a set of power users on a shard could result in increased load to that shard compared to others. +* Data distribution can become lopsided in a shard. For example, a set of power users on a shard could result in increased load to that shard compared to others. * Rebalancing adds additional complexity. A sharding function based on [consistent hashing](http://www.paperplanes.de/2011/12/9/the-magic-of-consistent-hashing.html) can reduce the amount of transferred data. * Joining data from multiple shards is more complex. * Sharding adds more hardware and additional complexity. From b34e167233e83a1441e3bce7c323f6366e28b669 Mon Sep 17 00:00:00 2001 From: Tay Yang Shun Date: Fri, 10 Mar 2017 08:40:12 +0800 Subject: [PATCH 03/44] Add more disadvantages of REST (#9) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0a84fe95..14b6cfe3 100644 --- a/README.md +++ b/README.md @@ -1458,6 +1458,8 @@ REST is focused on exposing data. It minimizes the coupling between client/serv * With REST being focused on exposing data, it might not be a good fit if resources are not naturally organized or accessed in a simple hierarchy. For example, returning all updated records from the past hour matching a particular set of events is not easily expressed as a path. With REST, it is likely to be implemented with a combination of URI path, query parameters, and possibly the request body. * REST typically relies on a few verbs (GET, POST, PUT, DELETE, and PATCH) which sometimes doesn't fit your use case. For example, moving expired documents to the archive folder might not cleanly fit within these verbs. +* Fetching complicated resources with nested hierarchies requires multiple round trips between the client and server to render single views, e.g. fetching content of a blog entry and the comments on that entry. For mobile applications operating in variable network conditions, these multiple roundtrips are highly undesirable. +* Over time, more fields might be added to an API response and older clients will receive all new data fields, even those that they do not need, as a result, it bloats the payload size and leads to larger latencies. ### RPC and REST calls comparison From 65c056f6a649a9b665d4c1d1cd9fb182477efb0d Mon Sep 17 00:00:00 2001 From: Mostafa Gaafar Date: Sat, 11 Mar 2017 06:06:34 +0400 Subject: [PATCH 04/44] Fix multiple typos (#14) --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 14b6cfe3..ac1e4138 100644 --- a/README.md +++ b/README.md @@ -485,7 +485,7 @@ There are two main patterns to support high availability: **fail-over** and **re With active-passive fail-over, heartbeats are sent between the active and the passive server on standby. If the heartbeat is interrupted, the passive server takes over the active's IP address and resumes service. -The length of downtime is determined by whether the passive server is already running in 'hot' standy or whether it needs to start up from 'cold' standby. Only the active server handles traffic. +The length of downtime is determined by whether the passive server is already running in 'hot' standby or whether it needs to start up from 'cold' standby. Only the active server handles traffic. Active-passive failover can also be referred to as master-slave failover. @@ -618,7 +618,7 @@ Load balancers can route traffic based on various metrics, including: * Random * Least loaded -* Seesion/cookies +* Session/cookies * [Round robin or weighted round robin](http://g33kinfo.com/info/archives/2657) * [Layer 4](#layer-4-load-balancing) * [Layer 7](#layer-7-load-balancing) @@ -719,7 +719,7 @@ Workers in the application layer also help enable [asynchronism](#asynchronism). ### Microservices -Related to this discussion are [microservices](https://en.wikipedia.org/wiki/Microservices), which can be described as a suite of independently deployable, small, modular services. Each service runs a unique process and communicates through a well-definied, lightweight mechanism to serve a business goal. 1 +Related to this discussion are [microservices](https://en.wikipedia.org/wiki/Microservices), which can be described as a suite of independently deployable, small, modular services. Each service runs a unique process and communicates through a well-defined, lightweight mechanism to serve a business goal. 1 Pinterest, for example, could have the following microservices: user profile, follower, feed, search, photo upload, etc. @@ -755,8 +755,8 @@ A relational database like SQL is a collection of data items organized in tables **ACID** is a set of properties of relational database [transactions](https://en.wikipedia.org/wiki/Database_transaction). * **Atomicity** - Each transaction is all or nothing -* **Consistency** - Any tranaction will bring the database from one valid state to another -* **Isolation** - Excuting transactions concurrently has the same results as if the transactions were executed serially +* **Consistency** - Any transaction will bring the database from one valid state to another +* **Isolation** - Executing transactions concurrently has the same results as if the transactions were executed serially * **Durability** - Once a transaction has been committed, it will remain so There are many techniques to scale a relational database: **master-slave replication**, **master-master replication**, **federation**, **sharding**, **denormalization**, and **SQL tuning**. @@ -857,7 +857,7 @@ Common ways to shard a table of users is either through the user's last name ini #### Denormalization -Denormalization attemps to improve read performance at the expense of some write performance. Redundant copies of the data are written in multiple tables to avoid expensive joins. Some RDBMS such as [PostgreSQL](https://en.wikipedia.org/wiki/PostgreSQL) and Oracle support [materialized views](https://en.wikipedia.org/wiki/Materialized_view) which handle the work of storing redudant information and keeping redundant copies consistent. +Denormalization attempts to improve read performance at the expense of some write performance. Redundant copies of the data are written in multiple tables to avoid expensive joins. Some RDBMS such as [PostgreSQL](https://en.wikipedia.org/wiki/PostgreSQL) and Oracle support [materialized views](https://en.wikipedia.org/wiki/Materialized_view) which handle the work of storing redundant information and keeping redundant copies consistent. Once data becomes distributed with techniques such as [federation](#federation) and [sharding](#sharding), managing joins across data centers further increases complexity. Denormalization might circumvent the need for such complex joins. @@ -1108,7 +1108,7 @@ There are multiple levels you can cache that fall into two general categories: * * Fully-formed serializable objects * Fully-rendered HTML -Generaly, you should try to avoid file-based caching, as it makes cloning and auto-scaling more difficult. +Generally, you should try to avoid file-based caching, as it makes cloning and auto-scaling more difficult. ### Caching at the database query level @@ -1351,7 +1351,7 @@ TCP is useful for applications that require high reliability but are less time c Use TCP over UDP when: -* You need all of the data to arrive in tact +* You need all of the data to arrive intact * You want to automatically make a best estimate use of the network throughput ### User datagram protocol (UDP) From 69d4e5a70b45cfe1867c1ccbe2a504cef3d4b90d Mon Sep 17 00:00:00 2001 From: "Sudarshan (Sid)" Date: Fri, 10 Mar 2017 20:07:50 -0600 Subject: [PATCH 05/44] Add Dyn DDoS attack link (#13) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ac1e4138..8ad82818 100644 --- a/README.md +++ b/README.md @@ -541,7 +541,7 @@ Services such as [CloudFlare](https://www.cloudflare.com/dns/) and [Route 53](ht * Accessing a DNS server introduces a slight delay, although mitigated by caching described above. * DNS server management could be complex, although they are generally managed by [governments, ISPs, and large companies](http://superuser.com/questions/472695/who-controls-the-dns-servers/472729). -* DNS services have recently come under DDoS attack, preventing users from accessing websites such as Twitter without knowing Twitter's IP address(es). +* DNS services have recently come under [DDoS attack](http://dyn.com/blog/dyn-analysis-summary-of-friday-october-21-attack/), preventing users from accessing websites such as Twitter without knowing Twitter's IP address(es). ### Source(s) and further reading From eb2a6cb43c620fdb7fa610b1bab6beec89c6d2b3 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Sat, 11 Mar 2017 16:59:58 +0000 Subject: [PATCH 06/44] Fix typo in RPC section (#17) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ad82818..dc2e1e65 100644 --- a/README.md +++ b/README.md @@ -1428,7 +1428,7 @@ HTTP APIs following **REST** tend to be used more often for public APIs. #### Disadvantage(s): RPC * RPC clients become tightly coupled to the service implementation. -* A new API must be definied for every new operation or use case. +* A new API must be defined for every new operation or use case. * It can be difficult to debug RPC. * You might not be able to leverage existing technologies out of the box. For example, it might require additional effort to ensure [RPC calls are properly cached](http://etherealbits.com/2012/12/debunking-the-myths-of-rpc-rest/) on caching servers such as [Squid](http://www.squid-cache.org/). From e5df3f5adaa77d021be25f852d43b760d63a76f4 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 12 Mar 2017 17:17:29 -0400 Subject: [PATCH 07/44] Update Motivation section (#19) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dc2e1e65..c55a06bb 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ System design is a broad topic. There is a **vast amount of resources scattered This repo is an **organized collection** of resources to help you learn how to build systems at scale. -#### Learn from the open source community +### Learn from the open source community -This is an **early draft** of a **continually updated, open source** project. +This is an early draft of a continually updated, open source project. [Contributions](#contributing) are welcome! @@ -29,7 +29,7 @@ This is an **early draft** of a **continually updated, open source** project. In addition to coding interviews, system design is a **required component** of the **technical interview process** at many tech companies. -**Practice common system design interview questions** and **compare** your results with sample **discussions, code, and diagrams**. +**Practice common system design interview questions** and **compare** your results with **sample solutions**: discussions, code, and diagrams. Additional topics for interview prep: From a071e4abc75d8b7fdb972a72bc564af0101f3783 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Mon, 13 Mar 2017 06:40:02 -0400 Subject: [PATCH 08/44] Update Study guide section (#20) --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c55a06bb..ed0d4aaf 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ Review the [Contributing Guidelines](https://github.com/donnemartin/system-desig > Suggested topics to review based on your interview timeline (short, medium, long). -![Imgur](http://i.imgur.com/ciJelTB.png) +![Imgur](http://i.imgur.com/OfVllex.png) **Q: For interviews, do I need to know everything here?** @@ -180,11 +180,11 @@ What you are asked in an interview depends on variables such as: More experienced candidates are generally expected to know more about system design. Architects or team leads might be expected to know more than individual contributors. Top tech companies are likely to have one or more design interview rounds. -Start broad and go deeper in a few areas. It helps to know a little about various key system design topics. Adjust the following guide based on your experience, what positions you are interviewing for, and which companies you are interviewing with. +Start broad and go deeper in a few areas. It helps to know a little about various key system design topics. Adjust the following guide based on your timeline, experience, what positions you are interviewing for, and which companies you are interviewing with. -* **Short** - Aim for **breadth** with system design topics. Practice by solving **some** interview questions. -* **Medium** - Aim for **breadth** and **some depth** with system design topics. Practice by solving **many** interview questions. -* **Long** - Aim for **breadth** and **more depth** with system design topics. Practice by solving **most** interview questions. +* **Short timeline** - Aim for **breadth** with system design topics. Practice by solving **some** interview questions. +* **Medium timeline** - Aim for **breadth** and **some depth** with system design topics. Practice by solving **many** interview questions. +* **Long timeline** - Aim for **breadth** and **more depth** with system design topics. Practice by solving **most** interview questions. | | Short | Medium | Long | |---|---|---|---| @@ -192,9 +192,9 @@ Start broad and go deeper in a few areas. It helps to know a little about vario | Read through a few articles in the [Company engineering blogs](#company-engineering-blogs) for the companies you are interviewing with | :+1: | :+1: | :+1: | | Read through a few [Real world architectures](#real-world-architectures) | :+1: | :+1: | :+1: | | Review [How to approach a system design interview question](#how-to-approach-a-system-design-interview-question) | :+1: | :+1: | :+1: | -| Work through [System design interview questions with solutions](#system-design-interview-questions-with-solutions) | Few | Some | Many | -| Work through [Object-oriented design interview questions with solutions](#object-oriented-design-interview-questions-with-solutions) | Few | Some | Many | -| Review [Additional system design interview questions](#additional-system-design-interview-questions) | Few | Some | Many | +| Work through [System design interview questions with solutions](#system-design-interview-questions-with-solutions) | Some | Many | Most | +| Work through [Object-oriented design interview questions with solutions](#object-oriented-design-interview-questions-with-solutions) | Some | Many | Most | +| Review [Additional system design interview questions](#additional-system-design-interview-questions) | Some | Many | Most | ## How to approach a system design interview question From 390d0d5b66865ddb64958f55ea1914f852160e78 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Mon, 13 Mar 2017 06:42:35 -0400 Subject: [PATCH 09/44] Update OO exercises index (#21) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ed0d4aaf..ed0965b5 100644 --- a/README.md +++ b/README.md @@ -340,10 +340,10 @@ Check out the following links to get a better idea of what to expect: | Question | | |---|---| -| Design a deck of cards to be used for blackjack | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/deck_of_cards/deck_of_cards.ipynb) | -| Design a call center | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/call_center/call_center.ipynb) | | Design a hash map | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/hash_table/hash_map.ipynb) | | Design a least recently used cache | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/lru_cache/lru_cache.ipynb) | +| Design a call center | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/call_center/call_center.ipynb) | +| Design a deck of cards | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/deck_of_cards/deck_of_cards.ipynb) | | Design a parking lot | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/parking_lot/parking_lot.ipynb) | | Design a chat server | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/online_chat/online_chat.ipynb) | | Design a circular array | [Contribute](#contributing) | From 5fa4136b58d359f17eb8fda32d586f2a90ef5534 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Wed, 15 Mar 2017 06:59:28 -0400 Subject: [PATCH 10/44] Add high scalability to credits (#22) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ed0965b5..f685dc94 100644 --- a/README.md +++ b/README.md @@ -1740,6 +1740,7 @@ Special thanks to: * [Hired in tech](http://www.hiredintech.com/system-design/the-system-design-process/) * [Cracking the coding interview](https://www.amazon.com/dp/0984782850/) +* [High scalability](http://highscalability.com/) * [checkcheckzz/system-design-interview](https://github.com/checkcheckzz/system-design-interview) * [shashank88/system_design](https://github.com/shashank88/system_design) * [mmcgrana/services-engineering](https://github.com/mmcgrana/services-engineering) From eaed5dd016ebc0d2184207760e7f744e8a7f6320 Mon Sep 17 00:00:00 2001 From: Balki Kodarapu Date: Sat, 18 Mar 2017 08:37:16 -0700 Subject: [PATCH 11/44] Delete duplicate does in 3 design examples (#24) Delete duplicate word "does" in design exercises --- solutions/system_design/pastebin/README.md | 2 +- solutions/system_design/social_graph/README.md | 2 +- solutions/system_design/web_crawler/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/system_design/pastebin/README.md b/solutions/system_design/pastebin/README.md index 7f95ab94..3cc242ce 100644 --- a/solutions/system_design/pastebin/README.md +++ b/solutions/system_design/pastebin/README.md @@ -95,7 +95,7 @@ An alternative to a relational database acting as a large hash table, we could u * The **Client** sends a create paste request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server) * The **Web Server** forwards the request to the **Write API** server -* The **Write API** server does does the following: +* The **Write API** server does the following: * Generates a unique url * Checks if the url is unique by looking at the **SQL Database** for a duplicate * If the url is not unique, it generates another url diff --git a/solutions/system_design/social_graph/README.md b/solutions/system_design/social_graph/README.md index fac4b3fd..947956f0 100644 --- a/solutions/system_design/social_graph/README.md +++ b/solutions/system_design/social_graph/README.md @@ -104,7 +104,7 @@ We won't be able to fit all users on the same machine, we'll need to [shard](htt * The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server) * The **Web Server** forwards the request to the **Search API** server * The **Search API** server forwards the request to the **User Graph Service** -* The **User Graph Service** does does the following: +* The **User Graph Service** does the following: * Uses the **Lookup Service** to find the **Person Server** where the current user's info is stored * Finds the appropriate **Person Server** to retrieve the current user's list of `friend_ids` * Runs a BFS search using the current user as the `source` and the current user's `friend_ids` as the ids for each `adjacent_node` diff --git a/solutions/system_design/web_crawler/README.md b/solutions/system_design/web_crawler/README.md index b84f07ee..7876b943 100644 --- a/solutions/system_design/web_crawler/README.md +++ b/solutions/system_design/web_crawler/README.md @@ -213,7 +213,7 @@ We might also choose to support a `Robots.txt` file that gives webmasters contro * The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server) * The **Web Server** forwards the request to the **Query API** server -* The **Query API** server does does the following: +* The **Query API** server does the following: * Parses the query * Removes markup * Breaks up the text into terms From e417324830eb56cbe9c07b44399a0efcb6e95d63 Mon Sep 17 00:00:00 2001 From: Federico Baldassarre Date: Sun, 19 Mar 2017 20:23:03 +0100 Subject: [PATCH 12/44] Fix #6: Migrate links from exercises/solutions to use internal links (#23) --- README.md | 56 +++++++++---------- solutions/system_design/mint/README.md | 2 +- solutions/system_design/pastebin/README.md | 2 +- solutions/system_design/query_cache/README.md | 2 +- solutions/system_design/sales_rank/README.md | 2 +- .../system_design/social_graph/README.md | 2 +- solutions/system_design/twitter/README.md | 2 +- solutions/system_design/web_crawler/README.md | 2 +- 8 files changed, 35 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index f685dc94..d59d60eb 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,9 @@ Additional topics for interview prep: The provided [Anki flashcard decks](https://apps.ankiweb.net/) use spaced repetition to help you retain key system design concepts. -* [System design deck](https://github.com/donnemartin/system-design-primer/blob/master/resources/flash_cards/System%20Design.apkg) -* [System design exercises deck](https://github.com/donnemartin/system-design-primer/blob/master/resources/flash_cards/System%20Design%20Exercises.apkg) -* [Object oriented design exercises deck](https://github.com/donnemartin/system-design-primer/blob/master/resources/flash_cards/OO%20Design.apkg) +* [System design deck](resources/flash_cards/System%20Design.apkg) +* [System design exercises deck](resources/flash_cards/System%20Design%20Exercises.apkg) +* [Object oriented design exercises deck](resources/flash_cards/OO%20Design.apkg) Great for use while on-the-go. @@ -66,7 +66,7 @@ Feel free to submit pull requests to help: Content that needs some polishing is placed [under development](#under-development). -Review the [Contributing Guidelines](https://github.com/donnemartin/system-design-primer/blob/master/CONTRIBUTING.md). +Review the [Contributing Guidelines](CONTRIBUTING.md). ## Index of system design topics @@ -226,10 +226,10 @@ Outline a high level design with all important components. ### Step 3: Design core components -Dive into details for each core component. For example, if you were asked to [design a url shortening service](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/pastebin/README.md), discuss: +Dive into details for each core component. For example, if you were asked to [design a url shortening service](solutions/system_design/pastebin/README.md), discuss: * Generating and storing a hash of the full url - * [MD5](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/pastebin/README.md) and [Base62](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/pastebin/README.md) + * [MD5](solutions/system_design/pastebin/README.md) and [Base62](solutions/system_design/pastebin/README.md) * Hash collisions * SQL or NoSQL * Database schema @@ -272,61 +272,61 @@ Check out the following links to get a better idea of what to expect: | Question | | |---|---| -| Design Pastebin.com (or Bit.ly) | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/pastebin/README.md) | -| Design the Twitter timeline (or Facebook feed)
Design Twitter search (or Facebook search) | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/twitter/README.md) | -| Design a web crawler | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/web_crawler/README.md) | -| Design Mint.com | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/mint/README.md) | -| Design the data structures for a social network | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/social_graph/README.md) | -| Design a key-value store for a search engine | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/query_cache/README.md) | -| Design Amazon's sales ranking by category feature | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/sales_rank/README.md) | -| Design a system that scales to millions of users on AWS | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) | +| Design Pastebin.com (or Bit.ly) | [Solution](solutions/system_design/pastebin/README.md) | +| Design the Twitter timeline (or Facebook feed)
Design Twitter search (or Facebook search) | [Solution](solutions/system_design/twitter/README.md) | +| Design a web crawler | [Solution](solutions/system_design/web_crawler/README.md) | +| Design Mint.com | [Solution](solutions/system_design/mint/README.md) | +| Design the data structures for a social network | [Solution](solutions/system_design/social_graph/README.md) | +| Design a key-value store for a search engine | [Solution](solutions/system_design/query_cache/README.md) | +| Design Amazon's sales ranking by category feature | [Solution](solutions/system_design/sales_rank/README.md) | +| Design a system that scales to millions of users on AWS | [Solution](solutions/system_design/scaling_aws/README.md) | | Add a system design question | [Contribute](#contributing) | ### Design Pastebin.com (or Bit.ly) -[View exercise and solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/pastebin/README.md) +[View exercise and solution](solutions/system_design/pastebin/README.md) ![Imgur](http://i.imgur.com/4edXG0T.png) ### Design the Twitter timeline and search (or Facebook feed and search) -[View exercise and solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/twitter/README.md) +[View exercise and solution](solutions/system_design/twitter/README.md) ![Imgur](http://i.imgur.com/jrUBAF7.png) ### Design a web crawler -[View exercise and solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/web_crawler/README.md) +[View exercise and solution](solutions/system_design/web_crawler/README.md) ![Imgur](http://i.imgur.com/bWxPtQA.png) ### Design Mint.com -[View exercise and solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/mint/README.md) +[View exercise and solution](solutions/system_design/mint/README.md) ![Imgur](http://i.imgur.com/V5q57vU.png) ### Design the data structures for a social network -[View exercise and solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/social_graph/README.md) +[View exercise and solution](solutions/system_design/social_graph/README.md) ![Imgur](http://i.imgur.com/cdCv5g7.png) ### Design a key-value store for a search engine -[View exercise and solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/query_cache/README.md) +[View exercise and solution](solutions/system_design/query_cache/README.md) ![Imgur](http://i.imgur.com/4j99mhe.png) ### Design Amazon's sales ranking by category feature -[View exercise and solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/sales_rank/README.md) +[View exercise and solution](solutions/system_design/sales_rank/README.md) ![Imgur](http://i.imgur.com/MzExP06.png) ### Design a system that scales to millions of users on AWS -[View exercise and solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) +[View exercise and solution](solutions/system_design/scaling_aws/README.md) ![Imgur](http://i.imgur.com/jj3A5N8.png) @@ -340,12 +340,12 @@ Check out the following links to get a better idea of what to expect: | Question | | |---|---| -| Design a hash map | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/hash_table/hash_map.ipynb) | -| Design a least recently used cache | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/lru_cache/lru_cache.ipynb) | -| Design a call center | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/call_center/call_center.ipynb) | -| Design a deck of cards | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/deck_of_cards/deck_of_cards.ipynb) | -| Design a parking lot | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/parking_lot/parking_lot.ipynb) | -| Design a chat server | [Solution](https://github.com/donnemartin/system-design-primer/blob/master/solutions/object_oriented_design/online_chat/online_chat.ipynb) | +| Design a hash map | [Solution](solutions/object_oriented_design/hash_table/hash_map.ipynb) | +| Design a least recently used cache | [Solution](solutions/object_oriented_design/lru_cache/lru_cache.ipynb) | +| Design a call center | [Solution](solutions/object_oriented_design/call_center/call_center.ipynb) | +| Design a deck of cards | [Solution](solutions/object_oriented_design/deck_of_cards/deck_of_cards.ipynb) | +| Design a parking lot | [Solution](solutions/object_oriented_design/parking_lot/parking_lot.ipynb) | +| Design a chat server | [Solution](solutions/object_oriented_design/online_chat/online_chat.ipynb) | | Design a circular array | [Contribute](#contributing) | | Add an object-oriented design question | [Contribute](#contributing) | diff --git a/solutions/system_design/mint/README.md b/solutions/system_design/mint/README.md index 70cb5dea..654e8262 100644 --- a/solutions/system_design/mint/README.md +++ b/solutions/system_design/mint/README.md @@ -331,7 +331,7 @@ class SpendingByCategory(MRJob): **Important: Do not simply jump right into the final design from the initial design!** -State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design. +State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](../scaling_aws/README.md) as a sample on how to iteratively scale the initial design. It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each? diff --git a/solutions/system_design/pastebin/README.md b/solutions/system_design/pastebin/README.md index 3cc242ce..19a3587e 100644 --- a/solutions/system_design/pastebin/README.md +++ b/solutions/system_design/pastebin/README.md @@ -239,7 +239,7 @@ To delete expired pastes, we could just scan the **SQL Database** for all entrie **Important: Do not simply jump right into the final design from the initial design!** -State you would do this iteratively: 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design. +State you would do this iteratively: 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](../scaling_aws/README.md) as a sample on how to iteratively scale the initial design. It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each? diff --git a/solutions/system_design/query_cache/README.md b/solutions/system_design/query_cache/README.md index 273b330e..7e815abe 100644 --- a/solutions/system_design/query_cache/README.md +++ b/solutions/system_design/query_cache/README.md @@ -216,7 +216,7 @@ Refer to [When to update the cache](https://github.com/donnemartin/system-design **Important: Do not simply jump right into the final design from the initial design!** -State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design. +State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](../scaling_aws/README.md) as a sample on how to iteratively scale the initial design. It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each? diff --git a/solutions/system_design/sales_rank/README.md b/solutions/system_design/sales_rank/README.md index 0b4bf96f..3ee50985 100644 --- a/solutions/system_design/sales_rank/README.md +++ b/solutions/system_design/sales_rank/README.md @@ -243,7 +243,7 @@ For internal communications, we could use [Remote Procedure Calls](https://githu **Important: Do not simply jump right into the final design from the initial design!** -State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design. +State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](../scaling_aws/README.md) as a sample on how to iteratively scale the initial design. It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each? diff --git a/solutions/system_design/social_graph/README.md b/solutions/system_design/social_graph/README.md index 947956f0..b6607a04 100644 --- a/solutions/system_design/social_graph/README.md +++ b/solutions/system_design/social_graph/README.md @@ -254,7 +254,7 @@ For internal communications, we could use [Remote Procedure Calls](https://githu **Important: Do not simply jump right into the final design from the initial design!** -State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design. +State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](../scaling_aws/README.md) as a sample on how to iteratively scale the initial design. It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each? diff --git a/solutions/system_design/twitter/README.md b/solutions/system_design/twitter/README.md index 6ee014cc..415e6467 100644 --- a/solutions/system_design/twitter/README.md +++ b/solutions/system_design/twitter/README.md @@ -226,7 +226,7 @@ The response would be similar to that of the home timeline, except for tweets ma **Important: Do not simply jump right into the final design from the initial design!** -State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design. +State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](../scaling_aws/README.md) as a sample on how to iteratively scale the initial design. It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each? diff --git a/solutions/system_design/web_crawler/README.md b/solutions/system_design/web_crawler/README.md index 7876b943..358cb913 100644 --- a/solutions/system_design/web_crawler/README.md +++ b/solutions/system_design/web_crawler/README.md @@ -260,7 +260,7 @@ For internal communications, we could use [Remote Procedure Calls](https://githu **Important: Do not simply jump right into the final design from the initial design!** -State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design. +State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](../scaling_aws/README.md) as a sample on how to iteratively scale the initial design. It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each? From f1ae855ad0611c160373de5d0c055e76ad2b5575 Mon Sep 17 00:00:00 2001 From: Jakub Janarek Date: Sun, 19 Mar 2017 20:24:13 +0100 Subject: [PATCH 13/44] Fix typo JSS -> JS (#25) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d59d60eb..0428e309 100644 --- a/README.md +++ b/README.md @@ -557,7 +557,7 @@ Services such as [CloudFlare](https://www.cloudflare.com/dns/) and [Route 53](ht Source: Why use a CDN

-A content delivery network (CDN) is a globally distributed network of proxy servers, serving content from locations closer to the user. Generally, static files such as HTML/CSS/JSS, photos, and videos are served from CDN, although some CDNs such as Amazon's CloudFront support dynamic content. The site's DNS resolution will tell clients which server to contact. +A content delivery network (CDN) is a globally distributed network of proxy servers, serving content from locations closer to the user. Generally, static files such as HTML/CSS/JS, photos, and videos are served from CDN, although some CDNs such as Amazon's CloudFront support dynamic content. The site's DNS resolution will tell clients which server to contact. Serving content from CDNs can significantly improve performance in two ways: From 40b5be2d9ce33e7beebacfbd330bfae977dbfcaa Mon Sep 17 00:00:00 2001 From: Roxas Shadow Date: Tue, 21 Mar 2017 12:39:10 +0100 Subject: [PATCH 14/44] Declare variable key in the get_user example (#26) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0428e309..866972af 100644 --- a/README.md +++ b/README.md @@ -1156,6 +1156,7 @@ def get_user(self, user_id): if user is None: user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id) if user is not None: + key = "user.{0}".format(user_id) cache.set(key, json.dumps(user)) return user ``` From ae13db3b6cdc6d84d53ea37e014831e4eb27c240 Mon Sep 17 00:00:00 2001 From: Yadong Wen Date: Wed, 22 Mar 2017 22:53:15 -0400 Subject: [PATCH 15/44] Fix typo (#29) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 866972af..312af7a0 100644 --- a/README.md +++ b/README.md @@ -943,7 +943,7 @@ A key-value store generally allows for O(1) reads and writes and is often backed Key-value stores provide high performance and are often used for simple data models or for rapidly-changing data, such as an in-memory cache layer. Since they offer only a limited set of operations, complexity is shifted to the application layer if additional operations are needed. -A key-value store is the basis for more complex system systems such as a document store, and in some cases, a graph database. +A key-value store is the basis for more complex systems such as a document store, and in some cases, a graph database. ##### Source(s) and further reading: key-value store From 0c8be40660b7ed7262ad1073e2ea794d9d1cbb6d Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Wed, 22 Mar 2017 23:20:57 -0400 Subject: [PATCH 16/44] Add call for translations link (#30) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 312af7a0..89071e5a 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,10 @@ Content that needs some polishing is placed [under development](#under-developme Review the [Contributing Guidelines](CONTRIBUTING.md). +### Translations + +Interested in **translating**? Please see the following [ticket](https://github.com/donnemartin/system-design-primer/issues/28). + ## Index of system design topics > Summaries of various system design topics, including pros and cons. **Everything is a trade-off**. From 3021a3aed39ffbd083253739c126f3fb2917f078 Mon Sep 17 00:00:00 2001 From: Yadong Wen Date: Thu, 23 Mar 2017 22:42:02 -0400 Subject: [PATCH 17/44] Fix typos (#33) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 89071e5a..0cf09ddd 100644 --- a/README.md +++ b/README.md @@ -1218,7 +1218,7 @@ Write-through is a slow overall operation due to the write operation, but subseq Source: Scalability, availability, stability, patterns

-In write-behind, tha application does the following: +In write-behind, the application does the following: * Add/update entry in cache * Asynchronously write entry to the data store, improving write performance @@ -1348,7 +1348,7 @@ TCP is a connection-oriented protocol over an [IP network](https://en.wikipedia. * Sequence numbers and [checksum fields](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Checksum_computation) for each packet * [Acknowledgement](https://en.wikipedia.org/wiki/Acknowledgement_(data_networks)) packets and automatic retransmission -If the sender does not receive a correct response, it will resend the packets. If there are multiple timeouts, the connection is dropped. TCP also implements [flow control](https://en.wikipedia.org/wiki/Flow_control_(data)) and [congestion control](https://en.wikipedia.org/wiki/Network_congestion#Congestion_control). These guarantees cause delays and generally results in less efficient transmission than UDP. +If the sender does not receive a correct response, it will resend the packets. If there are multiple timeouts, the connection is dropped. TCP also implements [flow control](https://en.wikipedia.org/wiki/Flow_control_(data)) and [congestion control](https://en.wikipedia.org/wiki/Network_congestion#Congestion_control). These guarantees cause delays and generally result in less efficient transmission than UDP. To ensure high throughput, web servers can keep a large number of TCP connections open, resulting in high memory usage. It can be expensive to have a large number of open connections between web server threads and say, a [memcached](#memcached) server. [Connection pooling](https://en.wikipedia.org/wiki/Connection_pool) can help in addition to switching to UDP where applicable. From 619b5c97c106f4fd757be853ae82b2c3b665ce53 Mon Sep 17 00:00:00 2001 From: Alexander Brandstedt Date: Fri, 24 Mar 2017 12:30:09 +0100 Subject: [PATCH 18/44] Change service discovery example to use consul/etcd --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cf09ddd..cc32fcad 100644 --- a/README.md +++ b/README.md @@ -729,7 +729,10 @@ Pinterest, for example, could have the following microservices: user profile, fo ### Service Discovery -Systems such as [Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) can help services find each other by keeping track of registered names, addresses, ports, etc. +Systems such as [Consul](https://www.consul.io/docs/index.html) and [Etcd](https://coreos.com/etcd/docs/latest) are among the newer commonly used pull based service discovery solutions today. They solve service registration/de registration of what name, address and port the service is available at. Health checks are often done using a http endpoint. Both Consul and Etcd also have a built in key/value store that can be useful for storing config values or other shared key/values for running a service + +Systems such as [Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) is a possible older system that can be used as a service discovery service. Zookeeper has commonly been used for master election since it isn't a AP + ### Disadvantage(s): application layer From ea461bf23a07f3f5a601fd36ddb63c7160d56661 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 26 Mar 2017 12:50:23 -0400 Subject: [PATCH 19/44] Polish service discovery changes --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index cc32fcad..bb19f047 100644 --- a/README.md +++ b/README.md @@ -729,10 +729,7 @@ Pinterest, for example, could have the following microservices: user profile, fo ### Service Discovery -Systems such as [Consul](https://www.consul.io/docs/index.html) and [Etcd](https://coreos.com/etcd/docs/latest) are among the newer commonly used pull based service discovery solutions today. They solve service registration/de registration of what name, address and port the service is available at. Health checks are often done using a http endpoint. Both Consul and Etcd also have a built in key/value store that can be useful for storing config values or other shared key/values for running a service - -Systems such as [Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) is a possible older system that can be used as a service discovery service. Zookeeper has commonly been used for master election since it isn't a AP - +Systems such as [Consul](https://www.consul.io/docs/index.html), [Etcd](https://coreos.com/etcd/docs/latest), and [Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) can help services find each other by keeping track of registered names, addresses, and ports. [Health checks](https://www.consul.io/intro/getting-started/checks.html) help verify service integrity and are often done using an [HTTP](#hypertext-transfer-protocol-http) endpoint. Both Consul and Etcd have a built in [key-value store](#key-value-store) that can be useful for storing config values and other shared data. ### Disadvantage(s): application layer From 53896a0fdde34c082b14a07219b50a4f948bbad3 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Mon, 27 Mar 2017 07:21:07 -0400 Subject: [PATCH 20/44] Add translations to contributing guidelines (#37) --- CONTRIBUTING.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0affbd88..aba00538 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,3 +39,32 @@ The preferred way to contribute is to fork the ### GitHub Pull Requests Docs If you are not familiar with pull requests, review the [pull request docs](https://help.github.com/articles/using-pull-requests/). + +## Translations + +Thanks to [The Art of Command Line](https://github.com/jlevy/the-art-of-command-line) for the following translation template. + +We'd like for the guide to be available in many languages. Here is the process for maintaining translations: + +* This original version and content of the guide is maintained in English. +* Translations follow the content of the original. Unfortunately, contributors must speak at least some English, so that translations do not diverge. +* Each translation has a maintainer to update the translation as the original evolves and to review others' changes. This doesn't require a lot of time, but review by the maintainer is important to maintain quality. +* See the [AUTHORS.md](AUTHORS.md) file for current maintainers. + +### Changes to translations + +* Changes to content should be made to the English version first, and then translated to each other language. +* Changes that improve translations should be made directly on the file for that language. PRs should only modify one language at a time. +* Submit a PR with changes to the file in that language. Each language has a maintainer, who reviews changes in that language. Then the primary maintainer @jlevy merges it in. +* Prefix PRs and issues with language codes if they are for that translation only, e.g. "es: Improve grammar", so maintainers can find them easily. + +### Adding translations to new languages + +Translations to new languages are always welcome, especially if you can maintain the translation! + +* Check existing issues to see if a translation is in progress or stalled. If so, offer to help. +* If it is not in progress, file an issue for your language so people know you are working on it and we can arrange. Confirm you are native level in the language and are willing to maintain the translation, so it's not orphaned. +* To get it started, fork the repo, then submit a PR with the single file README-xx.md added, where xx is the language code. Use standard [IETF language tags](https://www.w3.org/International/articles/language-tags/), i.e. the same as is used by Wikipedia, *not* the code for a single country. These are usually just the two-letter lowercase code, for example, `fr` for French and `uk` for Ukrainian (not `ua`, which is for the country). For languages that have variations, use the shortest tag, such as `zh-Hant`. +* Invite friends to review if possible. If desired, feel free to invite friends to help your original translation by letting them fork your repo, then merging their PRs. +* Add links to your translation at the top of every README*.md file. (For consistency, the link should be added in alphabetical order by ISO code, and the anchor text should be in the native language.) +* When done, indicate on the PR that it's ready to be merged into the main repo. From 4d30304ef2967909bb4c6da141739fd6609452b5 Mon Sep 17 00:00:00 2001 From: JP Date: Wed, 29 Mar 2017 23:19:14 +1300 Subject: [PATCH 21/44] Explain difference between PUT & PATCH (#35) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bb19f047..e7d8cd96 100644 --- a/README.md +++ b/README.md @@ -1330,6 +1330,8 @@ A basic HTTP request consists of a verb (method) and a resource (endpoint). Bel *Can be called many times without different outcomes. +The difference between `PUT` and `PATCH` is explained by example [here](https://laracasts.com/discuss/channels/general-discussion/whats-the-differences-between-put-and-patch?page=1). + HTTP is an application layer protocol relying on lower-level protocols such as **TCP** and **UDP**. * [HTTP](https://www.nginx.com/resources/glossary/http/) From d40ba34d64e9ced0ab76dcf8fcccfa1473adade9 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 2 Apr 2017 08:00:20 -0400 Subject: [PATCH 22/44] Add sources and further reading to HTTP section --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e7d8cd96..7dafd652 100644 --- a/README.md +++ b/README.md @@ -1330,12 +1330,13 @@ A basic HTTP request consists of a verb (method) and a resource (endpoint). Bel *Can be called many times without different outcomes. -The difference between `PUT` and `PATCH` is explained by example [here](https://laracasts.com/discuss/channels/general-discussion/whats-the-differences-between-put-and-patch?page=1). - HTTP is an application layer protocol relying on lower-level protocols such as **TCP** and **UDP**. -* [HTTP](https://www.nginx.com/resources/glossary/http/) -* [README](https://www.quora.com/What-is-the-difference-between-HTTP-protocol-and-TCP-protocol) +#### Source(s) and further reading: HTTP + +* [What is HTTP?](https://www.nginx.com/resources/glossary/http/) +* [Difference between HTTP and TCP](https://www.quora.com/What-is-the-difference-between-HTTP-protocol-and-TCP-protocol) +* [Difference between PUT and PATCH](https://laracasts.com/discuss/channels/general-discussion/whats-the-differences-between-put-and-patch?page=1) ### Transmission control protocol (TCP) From 8fc20e606d643124187b9ff165aacb32b3e58cc6 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 2 Apr 2017 08:02:03 -0400 Subject: [PATCH 23/44] Fix caps and punctuation in RPC section --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7dafd652..feddd97b 100644 --- a/README.md +++ b/README.md @@ -1424,12 +1424,12 @@ POST /anotheroperation RPC is focused on exposing behaviors. RPCs are often used for performance reasons with internal communications, as you can hand-craft native calls to better fit your use cases. -Choose a Native Library aka SDK when: +Choose a native library (aka SDK) when: * You know your target platform. -* You want to control how your "logic" is accessed -* You want to control how error control happens off your library -* Performance and end user experience is your primary concern +* You want to control how your "logic" is accessed. +* You want to control how error control happens off your library. +* Performance and end user experience is your primary concern. HTTP APIs following **REST** tend to be used more often for public APIs. From 591fa4f6a2f9e4651239e2f737f5db3eee3a62db Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 2 Apr 2017 08:04:58 -0400 Subject: [PATCH 24/44] Change large scale -> large-scale --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index feddd97b..82e71962 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,11 @@ ## Motivation -> Learn how to design large scale systems. +> Learn how to design large-scale systems. > > Prep for the system design interview. -### Learn how to design large scale systems +### Learn how to design large-scale systems Learning how to design scalable systems will help you become a better engineer. From 9a8a2fb47aac82960c9735b4e1c069c402c6a601 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 2 Apr 2017 08:21:37 -0400 Subject: [PATCH 25/44] Add OmniGraffle base template --- .../system_design/template/template.graffle | Bin 0 -> 4922 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/template/template.graffle diff --git a/solutions/system_design/template/template.graffle b/solutions/system_design/template/template.graffle new file mode 100644 index 0000000000000000000000000000000000000000..6908231eee318cb474b6b630a31e0531db7d5479 GIT binary patch literal 4922 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 PEmhT77h{13KHh%-y&HmU literal 0 HcmV?d00001 From 408a3f4aa5c1b197eb6e7581fd394724802ae19a Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 2 Apr 2017 08:22:42 -0400 Subject: [PATCH 26/44] Add study guide OmniGraffle diagram and image --- resources/study_guide.graffle | Bin 0 -> 4329 bytes resources/study_guide.png | Bin 0 -> 171187 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/study_guide.graffle create mode 100644 resources/study_guide.png diff --git a/resources/study_guide.graffle b/resources/study_guide.graffle new file mode 100644 index 0000000000000000000000000000000000000000..39f81b0164154aa7dfa3ff2b4a05a31790f8ec51 GIT binary patch literal 4329 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

>HTQ?iFCIS!Bs02_4N;OY*&B}B!H^# z`m{7vGdnMb;gQdrP@mz5DROu(-m`!)qkLtpTIC#AM5-5C4OzzN#sRR z-%+csAO=OIA-!%p@yun*-QkA=lF=0kvH_pq<5>5;34)k3#I~+k^OvNPEMl$)8g^to=+=LRCYOM=U;!YU>Rg zS4>?yCAk|yQF&T@zIs-4PbL9OoAAiUt=y+lZ@e+n&zDg;o*>lwDr)6f;Rdsj*I6Wt zhka#SZipi7{m=uL{>Y1z4W8PgZ`0}aPzs{Zp~?9AgY`F7s$JYqv}CjM!zX1;hU-Z= zvB{jmV7Z6`iqvyyJ*)1g9YGX=lLa+UJbu}28Rd-0(e6l8@=w+x zndTF_3jb$V9q_0}yL@p*3%6Z^t?(ne7 zuFnHs@Qj}s^v-aT$5_s{OJCL486xf1j(nYub)^ zATpgZd%Wl*wmL;pu#WDe;XZCUE{Y)rnCG6mO_$J(q#e!j7K-9pufVk``Q_U=$#>F+ zz11|3sp@|eieKmzt1LeXOcS7uj08208Rczj+s=EJYc++X28=RHGkXO$@K#7+-ecKr zF^7`_q!lq(>tNIr;j)xU`-_vAl7T3A&NHvgBU?xj8Ps{rZN0)Q4JP92DMHCv(JY() z^GqNDAfk}jH`@CEL=@Bbfb(C887y%PVxhNA;DT*-kbN(K6cVVb9bg`Nz>2)Hj~-be zZYFH>KYZe!j}iXdiSn--yE*~La7?04gsX$(dFPwrB-Ox=cqF@ik@4RT5 zUd_&7Si#o~dz_mCE$?QPJ@{sH`a5UjMuG}tCGv`bdx0}IB)y95REy^{T{D3w%I$h0 zGU5k9?Yhrbw^TE7_8D@P9G-Xi3C_@J=^;*`K>)XFBDtXJjkZ6a;d}^8JzN zJ+oOouucc-hiktyG9dxTa%5kgy1D>~mOxD6kEuHVd=Bozk==BYG_U~0N!?g0&-7`_BA_kVadk*>tDBBcQ##=ySXx6x33Nv_rASN zp|SFY_behb1Ac(Lo<&NgBtJ@u%#ZBPw3nqeT`V-4Go&k zpBWlkP}-iwzxY`$Nv$FRa?X=Y!l!sZ&iOf70E_AQ?Hq=R3oadIuU&TSV-0_z~70A+5E;u#K(d6Wc@Qv26Yz5)uHE`!{Hm%l}zPxI*g>dsf;Q*g4BShY>Ne989GBAQ$RB>l@UzG70?!w%G5Y#nCyT~u7 z$kV~2v6lrZ7aZ0ALL`w1Sjz9OCb&lP#sFwHzRj29Z5k#D-xCE_-HxYTY*rF#}Ct+>Co zq33rRn7)G@i|}fc+Yi+q2^qTF_8HxE4W>todl+vT0m)`WB{R$sZf|=joEZA%aNM+& z$7>V^idfgW_`bf=nc(O|-p0a(d#-DIFb*|)OgqmM*~pcn~HsvK4>AZBN1m2rEJwYtx-RWK*KB8|%PX&0_U~Zt25C z9heD`WlJ=f?f$`$Kp52%8qbBmnthvTOFcInwcQP%ie>5d3W3CiNN%SZqXTZw*wpL} zQja9i3Ux3^;whSp>kP+V_lc)iJ+_d|FI%g@;>G9zvpgi{R5PD%ey7{aZ+}?7(sLyE zR%O(p+AmbYZJq~gD71bx;&EKGZg?V)5%Z{7Mblgjyi?TYR?@(|so0=rrb2min{l#x+#aZJ!xc@sZ6m6dZg)|gQ}mYFwlStG zcXs!Dhh>(T`qs=iR~&Q%lCUSZNeyv8!h$YcMp@peE+l;{Gx2!y{dypx5*$$5bLaK2 zc&JyE2@3xXDyMVF(+M>BX(;E}4OU*ybQaog^HkE=&{&`7r%y z{My;lr8CIF+B$eB9XvK#R9Sf<^m1~2+lw;rQq8qvDlZ}8`{FU)!U_+J%)ownDN6Z? zdQo#Wt^H(ly|&5N+@;-`bhy*mFl-<@XO@uv^z_WuGq7>?SCCfT0jB1uCwL%h+JaZf z^JG4@m-biOWd#(Y94O4K(NQr$96se3Z95@;*#}cG#zw?R9D2b~yq2+)*dE(b+h5eq zgRBy(_^gU|7i{@FLR>A(9rhH77DkOAR=N%Gx!w!=WRdk6?$)Ia3`w-`7+xI$`{B>< z1>@UfgMz#9Af3>%|BRMi*hupU+L~7zDZUm}>Gz+d^}YAdU#254@OLpzo8}W4NIOkT z8!1^!MB)%L>?)ooCp67o8H1DeJjtUxxUoEUhBsBit-Y-k_D3;v!>Q<01@_&vmd9Wt zZ$59dUm|9S7*F^Tq1%-z0uUZkorL`tNtKy1%OC~WyU_TFy;0}q1~Z*mS36%>Gg?W> z@2t=Dh&>yC1Bzx{mPMz_cxtEm03xt{Usz{04xu3caL4r()ob*&vxHYx0l?e8`_3k%zb+tEz+ zavw7u$fk|GsXhSiLd>8YB&jrYOQ{T;3u9c?o)b-wFDXL=1x-J%pj1$8gzJvq*MPRR zrb|qW><1?%herw4&13KAwWLXNzSg6Eu{N&G@ju0$#kBTmcr8*BAJEEI`!ejkPwPzB zXsE!Qb*eBuEvOlQ88C>|h3W{9e zH6-k;J7FNghjpOe=R(Ae(#w0>F=m9_>09}J&xN)=!Z9{Dnb#s^rKuKSoX%^1(*acC zCAPgD)D^yd;4;-~@mytOBV;F@V}2^m(yO}C&*ZqJFbo#4)n7Dt+1gBz6}52u!RU5a zfxe;|0fo8AVRI=aU?ReMxr%p(bRt7D6eh%Jp6$}ENSru zg)_mv#$hi#yZooAU$M!X%!93DmD8kXf4&WZ07$k+0L{e$*_CjI^e zl8M&6Ziz);K63lR#(`tNFjuO3<}Um9_sD4*1`{QhSYP5+Q~h-Cp;7>Lf_qi*kpVbZ z5ZxDp!JiDH=UhonnAIM}4eZvP>N1~$y`ufCr`0db37N7GwQlXp>v%%QHtjRAy1*tolNq=^`JwP^} zTz>;XMLNHmXvyU5Lk0l=L|f*qv5DL`RIoSJ)yMxp==132P><`mBi}+0CEJwsvgU%$@Wa$F{baIkzfBbtgsmI(kt9_#P*B*Piraf2&86| z9Wz0g$knyclJAmQ+a?rcK2~8bpL`IHze4Pzpp$UO4-&29snAVR^h|&BYfV#Y07EC7 zogr3fP<)bUE*<~H<`^S6%fFB{=ox?^-R3T<2q9;qW zKT|5pUEzMiGrL*_Tg)%$g9h~5GPe3D#~Ifo^U|(@fG$23)7>8W&||P?9qt4J#V<7x z`h;F86_xf++*ZK|SS@2O9zO<1AL|T3pNC&iEHw$*CK1ye!4ekw%de`Px~(Fmj#}?a zTA62W5d1_TK%YV{&?q#-s}qg%DDt#F&D8G+Z6>O`#MFR zx-DdwnVIcbh~yt-Z%QUe8)*H?BA{ZHi>3BJH8x2YkQxI7FV8*=Y3J|X&LQjxbhUeH z8A&70;q!h zIqr+nW-PjOt-&tsQn?MiC`g#GkH?b-@%O}NN~zZ-5BtDYilw*ge}iUf`P+aMGSW-O z2V~2KjR><$i(6?Wb%zYpE2Hx0i!h`rm_o8@L{`0&8lOnKO)623R#1AvjHpc|g@;3% znG|Zao+hD+@jI{fN{AF$%|YYKL!KDuKQgI>O)L;I^t5irB=R5xf|2AlLo2*X(h9N} zG+;!;l@#@p^~%{%i32@IQFOn{`*}#iCG-lyyf5DE3L zsPQN4I8j&?uPtC)YP5zWc9#oVtg+yTI2LJK}=v98OW9R*>8V7iX;NLpgB_6KllsHV<((+(5Xe~ z^~Dk}cp}o*bmk z&;K--A9w*?JrV1^gesnqCZmW!}t4(vc9)(YZa!x zt>Rj}QS<1DL~qX0IhQMj>_V0V#3FB4aKa21?JlGc&i0mtLsoUh1CLAhSY)S?-8Kjt zqcm9m4{Jw4Fh`mnRQv)9Y3@YP7ji#Z99l4IS^3 z9S)RoQ2XPfKo-nsnbc1b85%Vlu@u2IsAPzy0&x*J`pWNLP-zXZ^@pKSS0Hx}J z++`EtQPBjq-e*g$(&YSkBjDdGki0HB-&?Btw_-=$c?lMK>(qN zF5>R?AGcYA7_q*Oew0PaKzdytY)qGm1!}Vo`)vwL~I?XGU{#GqAX9 zb!nzascvZm?*d0J_YjBQ7b1Bamn&5 zxw(Z}x37tssXWbVYBA==$ZY6Ok=3KP;=4#PZfk_Vue@Cex=E z+0aR*5sk!u{jO-MZ>{1$5DyLVcc7!jmbZ~GtmKUeVWK2Z5SM>|Nzw3Um*Fv@kFOsHrZjQU7w@cmW@_HVw4rwXaueSPv7^VHK7O95-2KbiD;S5kT zA@LPsfv{8U7%CiVQ#bP{lRon-vzV~iRi%Oo)L^wR6@O_>r=$B$CDM!0iea4X{Y->x zbaHIBM}d;mx^$Dpc(~*Q+sIM5J;Rsj%Jv;gGvoUZa}RMFn@6`Tq{jc0GiJ2;BE76# zi64Q4&qspqow$(CpDij$Ri?-pZoT)&4rJvq=3BjmOAaw}>s)j7r8=z)n)6VcxbI`= zbS5!MH|owZC3I?Kx9N5j!xmXzn|=HCsY-BV-Jo&S1-2|%;N7nIqZ{Ee;ffGr-zekP z3tp{GZa3HeDY*QDX_*31SbpD_A^QGhY_}7w=n*E7hMW^@+0PHQ-SKgczvdPT!BcJe z;li5mX)A#`gyvv#EfDRN=*VqvU*_xA zW(zUp^WwMWH|GC16c)d=m0=zJo4+$MpPCHyepn}YO*E(b$DcIryehiiACKLd(1obSnRd_in?#WSW_Z;XN z5Pg6p7&qJ#hn_~_;oN=Tx~}M^EK>&Qk0lN7qK6c1pkV5akl}xHenD20j5SK*kg!Ri zAimDDU-Lvj>yCxgC-~#SN_z3%2l+KOFRGknLnH$b^*AxI6y#yCm`8srH*Oy$8+7Oh ziw>jYWZSD;RJDk;tG7(Ar>DQCKl#F)W;RWAsetYu0r(v)AOQ!6+NT(;xtE+pi+e8P z{e`%(P4(j5OG#c0$*hzja1%5qdC!ttJZs`>HilS_^f0g3t~ujxv-AtT0uzCJl=mHq zq}0VEct`HlV)b9+qV3c{ES__cvukKgmXS(Ltm-Z3oYlmaJtvO{gBOTEv!UQ)dlH zwVHfLf`R`q1HV?pH`PG%;;+=@*6H*iOyZvW5TYx0_hWF3b8^>1S}Ph7mMB?wZsr`6 zpV|I@ecL~D>yi2dwRh8zgvgfeFvfV>VHgcMYK7UFELKT5 zB^{GYKuIQlg@R${4_I62_tC5pUTXonhv18_buEPhVZWYyZ)$i3aGLfpIe-<+F zKalwdJh6y>{Vy0^BKQszKHi7D7kKCNu0AU_nkw^V>>f*H@OYcV0#WPZ7$@KTkn+a; zS4y4rzKFYK606|Vy~x>z|6Hj2&EX&7<@1`>rZM>|i*mNqr1Jb~i+TJ55J}PEPSD+| z6YogX)Bo7WPk~HL!%WJ_DcSox8R}Fx7^OTU3}>@qlZl$zq9@FkyN(J7#bDFa>z{uM z;1B-%_?UV`R2&6=+94aRK4_9~m;aLO zAoh=Z$UhDUdA@!N%;STRQ7I?uv5t}$C7k>$;GJn{Yz&Oq)an$Rzpmpb_p;c{CD9Pk zL2O2ptD<6o5qj3}ZV~al!TQ~ezl-_@O*E0=vN}2l=ghm2D08#v`BdAh3(9TD#@WqC znEYSW;{yZ@CtnOt(n-IbzL0r%qP9yIj!@G~czBZREamk4Zhr$|H+#l?kJq7ct}6VFsHR^P*TBJ-5FwfuH_`qKyxx9 zCn@#!^Q>^7X|D8cOF60VJ!GYE%sKG)YwN2jH8hFdzRD{P`s<%+@UdnruG-?!E{$4X zFnjZDdPEVITo7Ti%F*E&M|VQ4_gA%apztYLleMRZFkaGCi1X|5ucq$ovC&O4*W6Rg zvZDX%JKvH%g*yh$-8qry*&eyP^;B?zU3qc})%;SU!!w?FllJeFV?eK$T-NUh!z@ZZ zN%%ITf`?1axx%7NeVt1TOz>AZ7^Zuq7J4C7dQJbe5_|r$wN_zTx)NAgUw@9GorK39 zfypnI;Pa74O+|+9!T8P`HUASt`6%LgY(huVM%)eowGD0rBdB`gZe zFb>lSI{r<#Q+2S8Wn}gMJataKd8xp!!4EO*w%|AOUG!?aU&!`%%4wqs+&m`lz`fp- zyZS6Qxp0OGWL%ZB@4wi1dNbv}@Q9c`0(glwW-P-r_f&ENz?no84+5%Qo>(TZ{}*zb zp^bljH7aW|Vq0IuV;WLiv`@jjf8xOS8%qD-l|G^4MjDGdQBKhwWPi5wD-)UCdg4^? zwzg@ob#^6DKQHme{qvvRU#N`GbinUQYwcDbYV2v4TLvK0r8)a0io46)fj5qMB#WbF;^^8mcB;MxcyAate>yGkb zI(YXt<3=9xsl_dMoeqNPvE0p0p8}NU3kfJem$(}dyvn7(;S2+Np8n0T3i;vRDMYxa z?|$*lD=+%SG{S_N@ZHlTII0SKQqv}$|5s8pBz@9byK?9ty3EN`&U#+@+`j*~PF==L zXSZxTtupp+CZQh(>!wl)d!+9*cwZ3ST0q~xi`dV5j!GY^mfYQkX6Xe}s`z0HwrqcM z5k50dU;2Yjs~0;iq*s}8UlhKe0?nVD`rMz_N?0ekcl$Bs&t%e1HwLiagD%<(?w*ff zd#lCZ4Fy_FRp1XH#Mo6C2979@$p^33=4-Z`d!9c9tGLOZ=6+M3)Fx?hKJ{J508gSU zLFkI#OV%^H4y#X`uIp3f>Vivrt5tPTI|cEmnL&JlwCzAse;xe;O8{ZR+CpwI`X2SaVvd?h0i|s)P&;Zi_)1=)>4n zmhoouSlZr666+gF4S92iSFBd7tPINLBFa0^$jLI=Er(q7MiYK>nV$T_Zb$uPw#%wT zha&yFZ}pG6thyuX6U=4IQvVn4gsu_r$o4%J*+sW0h<1F;l$+MmXQga@l&fzFKbEFV zT&exm`4%<4G>dIp_4TA~lai0qpyy1;>`HWnVl;kl*3N^Jk362GR^0FdJGYhM-R{}p z@5Jau$za~7+ofGp*Shk2Cp~$UHVmtSI=MfaSIg?B@%#kG|Db-KQ|jXKTH9daB%GPY z^W0aU!~jImVomG|dI-41;wyUxXqQ5JmbQ?Nin)Q+wX2JpezeT~3ya!e1m9bBuD4#| zt6OkWW~<2+{iH>E-$wQd@yekrdwTCCcFB)*0nruOF^@#;E-4082vx{XAe zJsY{zsyS5m3#l9EFH#J1-cn`2GXdP$Ic{6|F1lhVX72F9(|A)%GLGRw6+7SI`2(*s zhls_-?)Pm{p8wldt-bjqu+~)<$>_N)g(2Q!Zv0YNUxx}_n=Z)%RWr2euAFxox3@M~q|pC69#2Jvj>M~;KHs?4;bzj#_9#u_>fda%nX z(+Rb#L&`(S%MJJ9zIVdvvM{pb=n!Y}`ms$?yLVikPRRc+_>d}#d3-bSQQ8sumQx3= zuQ8W>@q-czrH9bfhVYD`zf`?`@rwFED0(443D#(7WEFW>lTb zc$(}F@v1a**Q{j?TVjCsmH{{G=n5NBQyzOWyQXiuIg4B0V+nuNv>hK=Q%Dm(U!hRU zNo+fDL&BF=klM9?XL>>%`yBd$&w_=ic}XC8BYLmq`K9xjOvfsP)Fgu~WbHYFEh045 zS48Z^PdDlFoaU46F!@sAA}^3QGNvoey*t6e*T~>%=aOEY2$E=dKwDgqH_icWY(-oP|oY6M$;%msbxD!p5oIS|=%R4Ego5@t|% zZ&vx6<_GZOBe?tER-~%(xcc`H;$-0$1ypEGVK*Z;T*^3m4fHryA9c*CkGZ|SwC1-K zh_sHebjoa?Y@fJyZ3Yd&;gkcC-{mQ$?F|zON1c?cp}tJY?rX?&Rxta0o#Y>EA1(Tl zHO5V`_JjE9aCD{GyZv4|*V0{_jwn;P58e-+)Vlh*<9qAv6eUcuGLfF+5 zBz>bO`tH>cHQ)bU6?_~{Zjkk8r;?Uo5t?4z6kbJN)OcLGSpPYzU^)jKK^5J}1CrQt zsg#N4OSX~|FKR96^>$h6ri$D)Y40Cb5X54UnKLwsAN?FjW$ff~GEw{N)RjO1U{_M{881=&8{TtX_dP#=<(aLv(G=>o~bkPhM== z5@grYrY&|<@H7gb%?zZIOWkxiDJ52EWFps$6AvF9hDTnd)Rr#}EdAF7<+|#=`wu9if-Q8PFqu^~eOjkk4F_4m%v5{Z|CdO(@J{I#}+I4{XqVCu2+&YNX%1KQ8=4s-;%; zWnCtgT(_U%jz=rMy3YNMy)g}@w@n}VH~j1$O4mZ=CpI#rogSyqRbg!uoCr;*p4KnA zt-h_H;*Lo;TT;F^DFv0(6ql30kW`~Vy#lW86~$(z4T1-gBUJ|rSY+O{^pPSa&!L0M zwl5juHmy6tNQ+*rc5iFwR2b|z8@N)Q)M3Lvu)u|S{xePk&{8o`Ta<{LLczSk1n!V% z9C6MNe_99FVen-2_@dTkay^Hr>;Dn=R&jA<%NuBLYXS*w0fGg0Z6rW~TOhaxcW>M+ zI5ZBy65J)YHBE30!6CQ=cW>Z!X6Bs#nK|d-KHdAouj$R&wX14tyveL*gTK7Jn1F5DV3(5k0vY&B zxKg;1qEmTro|sNxY~gX@(oSFCXNx8&)m&RC6we^#x{FTy`UjM6g!g94H7$AnM9m#m)+CuTg#647DIF#Cw>XrJa^n(Pn{BuY2B zz^Qy2c8{GmG_iql=R?N1q16>_cOtp63=Vja=+VuqZBnyT6R1jYHi#+qC1=|a!zL#{ zTRV#vXwvrKr43C|wH4She3%IA!8a?1(V28hO9EtM*$VjT!l3Xg@$(HtDf57?Y96EE z^GloXD5lT{{)-Y*B?Ahu8zEzfl^v4E&02cVmHY0IyP(xa*R-!mNxc4zonR?C5@u%C zxs(kd3Xk%NY$chsheHw6>ER8#5*v+i(_F{@8-@S9^OB@jI+^&Cg%nTU9N(#OD0^gq zyum93FAYkn!#7;__*Jim>Z?RJ{~dZ{3)k)U?03X>@E8?3^r!vv8h-r3u#zl!VMpM$ z`*h&G-abJisX7(|*_lOVC|jsj)3l*L=mWE4QuM#;zkihgUOUjPY+h%d zdrn0+qRoEiFc4BW-NmhPc6u12&4iz`0`{L>zqf02Bd`ta(e zf`91+uY~ghi7NaIvHT{AHy7px2z*$#PS5+rhS#+sr-ylriSWu~;W~)v)qP2!4=Rt{`x2%*_td3> z@qp1d`5A{~S(2{?iD9xv;?v{~2DiS_1m{tl8kcVi_g+wqNkxZL#LhB;t8}Iq>!O{m zhD5%E4mw}$U52R%)H0_>Z-+6EYN5YDiqKwhd&|Z@bZ99FQF^X?zVAv*^D{%wJ9&t7 zLTbRxaU3StEGoUa4Q|@=o^X|P7I|+xefTbD$S!{H_}h@xeE~b&2`fG-nqpHC*lThB zH5cWTd&fDNRa%I;5`?8f_3|<4*;rnfIrC-9t7&oNBn4uNI2kg^;v}AJ)c%CT_FJhw zg5=dx1eK;hNlNki3L<)^X+IUM@v+t+%oh;O@uPW&&0w)aVlxrWAcbQQZloAZ(MOSV}83kO0mmYIAWIGwg?T5-NgYMOy z70qGXWN$vZB`+#*dP_vq6@(V-3$SZ+OnjYEKcOD*#kxPktX{I8*+GB_ zKXgzSFronUpZOmdoSc5%@bPB=y~@1Pop`5OO+Wx&?r8Y2awZ{Y?grHA+QB34oNn|$ zvfUtpO715mL>qBbe!Mq9GeK1FfloD}a{FZSj)m^ON;4`!0Ssq`iA$-%=^4~nES?gv z>Nx=D7Tg~Tq1y9AtjFdd{u=DeIM`NhRA2bvw0sjMs0m{xCL*f^rUIZWM)NwGG2(S5jH z1U}+bnt!)DVjiBEL-(sMl08d!91D{{{vo?iK3vxPxOBr6Xtk68bMO$f`plzv8@_S* z@Dim}?OD|%rV=sGQX`=gK@;s6({sXAEddV|z^w z@1*^$x~+p@TTsm4V*K1Ae66g(9Ip%^5YqDgM=KLe5=I_F6Po<8{HA`M2Z!>kLwsB0 zP~vWt9G^0{{lkZ614{gjS9Swirv^@SZTR$Spz(4BeOeL5W*8J~my3UU7O`ePU=rSc zRq)j=FKTWAe_(Sg5w=x#=y+XGad++MYsh_9v0G8v_{(nhrAX{O$lFWWcTjXjcJ9 z^^}^|#l*YFVSGW(bM;E}b?sc>TEwl@1SM^iW%UobG=|YfFx1yS!PJ9bIF0r&8GBS2 z$X%&85fp5$;(Xw|Ez{s$Aiu7)8s2xp2p)Q&nx=kM=GW34M+=PbdDNuiKCrtabDO>I zRG62^puO?(WfZVfQWc&}h!j{}pfv;^CI#KJ0`*U49n)uM7h=IxWASaL1Mr4y5JmpS z9}`bA*cq&pmfz2dHZQ3e&)@!nnoK_B_9yyzQK#7WZ<<+*64+61nZySl{VQZxiP#5C z&`&hdDhmjgloeoWtQ$+{?}`E$ORek$xW_#Lu|n$EvBq?7r%>IYs23x=*#Exa8B(Eu1z}y+Er>tWU8G zsys-m`AO$#o8HI@e5yBUGHJ5O^k23PgS;v5IE|miSx721fTHtmdW*(eO$^=tz{~Y@ zJrF$rGip}IH4K8H;8qRBq5Q9hlD#Zld67IFcPbV~RA2dc|ev zrKh7^Yx2Qv090qn5KV#CC|~KFY3j0&ZM4w#yw_9GHzBPr{6~=57k}piPW<86H2Lng z6k(vq2ZdTS=opu*kk&5t*3qJGhe9o$X(^9Rtq3)oy6T9rNZ1K*vEs91gf99CYi)<=icuF`is_+~-R{9?AqZnF17x7=|}fU!Pg;Q-T?O88Dtjer?^r zSP;M{V@EXpv|nyNr|pvBYCrMTfvjeZ5pSR7Ei7yPrn-1z3R5h>woK+nenr7lK~aGs zZB=RYm!9>mGN!gtdYe@PNiYB?xR357+H4@6M?r-L-tz(spYm8q?uZYRskA*Gc)XOB zyRhA|1M1zruSKFQ&wlsS2ylJ-&c7daPyR}u;efgz=j@ICGRs^;!v4m|7+ES%bx;Qc z5Li|c)FnnM+hp7GBB#}-{X2H;#z10r;~D54n9tH^I|`uXH|)d4rwJo_`}GVpJDm#Q zokISaJ7lymo~oOEo*xXb&uC$;R$&_;u@qRUvvO%oHqFWrl*z1&XD=G1 z^IV)CSa(_=8y-b<$#{9wY%W(McX4~PYO|Y3(RWy;*_A)CoO-6AKzAFb0}^g-b8DSc zo)>Ng&8tuBPPoE5j|Ud2j%~ihO`SiC?ikm+uELN*7Z|Ma9%NfC$G)%rv)r7kh73zJ zQx;;Ag)*zvD{I2^tgHs`2vQd$bPP}Pf3fbof|rn9KMb91f;G3unNiMYXA@~11p9?7 zpQ>jpJWyeXeL0S&wMQG7foDeSa>=s~r94WfBITWOL$X?9c<9Tr-Xhux>7YW^L`Ku1 zg$8gIwzjS=MyC8uw^qB^4!V`+z?Rqjy4ImdJYuT0ob&xx*1RZ6*|Ngt?&^zIzedcZ zp#-YeFAP+C?u2}E6(_6KX@Q0l=6wp6cg}uM8z-EDM2rjiCkLuCJDh79J#@?6Plf!C zx`Yj4Q!bxkVCs*G<>;aPBYPRALj-Ar45W8c%F8pbdev?bpvTF>EpH5FpskWqYE0as z7{H@mSf*`sO5}NaD}$L>0wlNs1+0WLzdcdUw<%}_@683S-+4m`KJoc$EP8U&KE4Hh zEwT)6D3ohboN3GkHzZWwQsZ`H-tN3}xim!+xs+GE7G+cSk^LvOJb}ObjH@vk5|J(m z)Q6?I0gZe_l;<^TD`*5q%CuoKwtYkiwvBSzG7nMbzTmSqRkM#g(zV?Ex&)u#O6S;N z*`Wmghy@4v%04U7c9%tCI7z?+a#b}6XlAfBKj07eZ$6EseOn_07iL{(M@h}yBp~}i zdO~4fdFXCJGyel~(*NLOycjU47*8%x`qu;=+0%>L2|QUCZD?2Q`)@a*b>03>ooaFm z7H*sx&Ll&2hiTv7X^b6`Qe!avtazjV>p|{~GkEJR@4WBpJ z4TmtuYPNyRv8}XsNOlAVE?Zm;$cKE(lfPBHyUufc<9q;#{X|x=3M$jE$u8uXb4qnO$uJhwP);|}x`&T|%gG!wS*1&2_VL~F|~!b#3TsGS7cM?)JJWsgHDU;I)M46vlS$y4tB z99=2OWy)6>(s;Dh=fT^&%#1mczy?l6+ zPuTxP!ibWY{pKkE1GC+_E9GJCDyUMVxn1IPH(Q^saWh#kn?*=OIO?+&JIzY67O2|O zdH?8Z=U3a8C}!z>Q52!c8Jdx^ek{$DAemY7?I0!pQ5oxKbxY~btOAzKn(ga9VznO^ zMBbftZi^Ib(^i>lzb{Q0k>lO)|FMu?NpUeo_^43Jnu0a>aPF>cZ%Be>W>P@)_xgn* zVz$Rz4Hy*Gi8`(3*4Cce@0z`B`Gg~AV@dp>D9-lb30=m#+=F|{FiCKd!YnN)V{Co zW#Ku@ocMLn#@=0iT!BfxI9Su4oC(F{wiT>d??G;U;4SA!*@j&bcb;upv<#lO1yck& z$V$udDc>^4q{=qRKc=Ll2Hh;#9|hCGqM?%D>rqUR-k(H|tvjsdXahaqEMh-CZZ6G7 zyHKHqowaBZoB_NgVR8LiS$~ z-Zcy&!32|JRB#m0?ofpnliPD%r`g`g3Jdz{I?uC#8Rmv$x<=oB^CXf1O)S#SRVE6v zwS}^My&~)BOlW!W`Pv+ug^44hMyI?~2daI(7{+jJFtUCPuRY#s77T#1c#dQaa~80# zVBu>92+ql-eIxY~dILA0B@gw{NYy{t(?~o_xI@~33s`=b0zDJ^a{W|Q(=L|OF*Apj zG=+zl+(QlQlS-1d(VlA`V#J~oM) z7O0}vXLi6dFyEN8!grZGD!bPCo|yj5V8>Yx-0>0mAPZ9qH4p@apO=~zLA58uXdB)C zAV?v8^PY~5&LUj+zs&L)DPrWayT;tIOwrT}%)^rxn&~m(lt^#&oev1Ox=zf{vNum( zu=4?L_S?9Xi*(lu3g{L{p07h_|Jg4;z&#FuWloqfDpa2qUfnmBi+lH0@wLI6W>q|N2!8e90TC4b;G}-{Y{7 zcy1`Unjq^VAIdK4F4wS<>nZ9^at|-yq2-M&8LVIaCk486xzZrZk9|}*EhQ40fx{a; z=!4s|PjAdZ^?Khb&4kK8S@vSbShlCG^ODX4o9rTUqHUZky9|6j^-@?Vi1R5T#=j@{ zndrwG*E0S%T3O{0SvXHb>h#-U84XO+N%<=%wISg!rMj1%Ln3Zl_EHj@^>PVZTlqDM zM@C2M)O2C%#JKK9FP__iz)r6~O6KCD^vQ~VQ!T@pysUw~Q}($9qYa2H| zY{1QKMy6x?ndo93QP?zCz{9}2o{)TP-L~@pY&qFBO167lYj0LdV}=cHU*c_V2v%rxFh1b( zzi9q@Dfr6|W{brr@N=E{5tNPEg}M?~qG**PMK~8U=M_$A$!wk?!jDibI42rViuI;l zPy$mt0X2Al?RC{Ns1(74@_Y^z7>`wYQYSWQGrss&#Alaw+C-X8ATXFK@$E+N&I4&2VHvcVjK%&6AL3_j!mYb?($Lcps@6u zEQf~|LbWToB;`S%{@D)Jxf-+Wii0dY+{Q`J^b=B_PEy%rG=33gaySKYr`eVvB3&8?H;)wbwu#)7X z;%N)pFt-rWXaG0I0Dz;g#;8@+NW3HEm_4xPj4=0Imjb*53&u}z&TK)@Vk^zMPdSR*COc!eqOycLD;wv$k6Jp5FGQ0w(!H&j+T ztqr|z)=)s(qunS-bkpwDI4WLj6pO0ML?<`5m>Kon^ry*{Bu})ZF3Z~1W2wNI$!UC! zjvD4&UWsH5w&7GdHnuC|E)aPZT_?#P;fSk7{196vLx^u^FtR|A1MwBHy~K$hZtbey zpHKGJ1OEO&tc|J_K=JB$5CMzbu`Hk_j3@Q`2gq$ey_dG9R){Wa`q0E=Ci z9+aNgJ_Wadpx?Vbpqe?HW0_Y+*FzYqPCmHlbDPpL&^|wE#Q8{F@K=|OzWCQa$NQ*` z+Z+>LlPN6G;_MJ>1xwWNA@54AZ|eCdanO*pru$Ks zvxPvPmf)cG(uLLLpjY84%<7*J8WTjtwe-htog19zK7G+LjWD~~XbASLD9%95_xwkIdP(S^LOE{uR1t1t`UOTJ`b`dW7CyT*y zOM}=(Uk?UcB#0Mw8}yKD@F|%8ym@s^5_ExL5P16;VxtgD3zu!j)>HqVvQe7{9Ep*$ z4?owkJbC{K$K#NyNdQS5F#EZU>F2t1c;Lb0qzlR(-jB`4a@+^R6!?w)ZrwjWaiU(Q z?J)+m7ecDmVR9>yIdFNHQEfSwu$7s;BMj6&Wc!x?&X3XB7^{-1CB$6ENr9x>2u zjE0Y1;(i_7H7P4=fUiRV7dfB{eFs-!kBSVhW+UGXgc~v1<0!}fB}Ft35=@vw%+9;s zD5|h%<5AfdrK^YJR}#XWbk>&3{dePloVgCE>JH~d*b%{^3e9u9ziSo#$>=L_n&F6u zLX&p&+vimjJ_cG6j!vj8W{_L8#v74kOAZK{$1)2{tyno}^K|^UI)qcENL2UsEMo%P10-+Z{7ZlMwJ_;V=eiyRpAg6yA z87@w)AQCh4jTo}u+a5x3mXAx+3V3>-0u4Bg?#nbcJq5pXJqgS34J||7lT_}1G&8n> zKQ0^>|K=*60t3wha=wYatIioTUv(*|PK5;Z!?nVT)X;S3)@-o!i=#R`!z;nacgO1H zQQjjRuJ->j4+O#iDU%Dw^e3_n>{d2=RPsoMUlz@PG`-z>Mr?3t$x)q{;n`s1yX$$= z$xzM&_n`mslJQ1Bd1c1Qp8TqfLfk8#r0Pic5(>yj4QbgQO>Q`)f&(iiht)!x5$|mZ zkMWEp|L3!G7#nF$ZCpWZy9oPy`c{pM#o?Ew$)J|wC~a`wYr*$zp*4M#?dY>#7R0tn zM4s^*Jv4wd>8?Q3Aa2#d$e8y830e_!(b>1T zeWz>RL^hXdY*J1MG8KUm3K718($gQo|%=bM$7{IoQKKo@z z>(jA!9_$E`u~B~m`agwwhw7ndCAK<-*s1U#Y7wi}N$=Z)ItWZ?VsAFBjDGd04fziEdO1hL{fK2noYv(UkH8w|(E9r23J z8Sf^Nm5ajm&`$JeO()O$2oL{zS=#?{-R@C{lJ&|MGCcEvt}x#CQ`!Drq#F`&abRp2 z)o9#AVzjL=wWn^--|Juup>*_@TBXF)MgN!d-W#GAX!(19i{A4+lNt-unTXh8wGwr*{QA%`~v=VrkV57#Zn(a!{o6w#i~Kx zcBV%7Jv2A#Jm6Qse^CKn6n>kf^HRM({!IJ-i$8m?Q*BeJ<~US`8be=(UaR!MRIQi_ zH8=T2%D=&7J-W%{HWF5E9&y1TdW2W3_lbep9^uuw{{qzUKEUyAFHvY;=rX~swwp=a zwHxMbPcB@Ah5iA;Ggz>BM5tP2K`4BwID2kR_#WE3{oi#G$8KV*N8a{07L)z|@@3{j z*eN+H2O5`%=(+s^lO~g50o;82Bjs=4))Mh|K`r&DyWVOJ&wSjmhFMpjAG`huuz>@{ zMs5^*FzuB(%qcB(<7j?2r)z9X$sr`9AcK{K7`^G1?{pv zQ_jt(K^Zol zrQ95CfbzmZU-2gW>b*dUG$PD!^eD`~0gvnO6RFrv3tEYa5 zL!Zi$F=7}Itce+`uI`xHS@6;hDv2nSA&m@T_0gunLCvV(eiU?0s6x*_VE5ra!;`8i z6{c&BeuZ?-aQoc}nuzF&!jbS$c8p*w_(!fWZvmzE;GW3-*EfS5R=P`r0@b{S)nllnN{`a*^%n`nPJuTmMt;qj0-*$2W1F8Zrxm_ z#j5)e7I&D}n15U_JO-V2?VuMsHA4^qEu__iANvLE5Duw;=0FXzgyx*n*Fe2HM=s(iyv5(^bu7)1% zR+EE%Yvnuzp>@c{=3(4;#vl?`rDT5#V=`k-<4U6-1BJ9j zm|iX$z51qhOKW%66W^ULP%}hjhE6t)JP*C=gz7Q~vqIaTYs|l}eFdOEh?Keu5&onj zJF6)mn?|=!PtI`sBuZd{5U#+$0n?Sr{S_NUb2`}UAGupJ5mL8xt}$ZZD(xqkY9Q)5 zrgI{PT2o-aHvk*)hqNTBjZUVEsq@R!N7K~{ZStqEcWkwmBPFSB*-)SNvjXPdmrC2p z(cMww0}0eE=$k&dcLbjM8hfv5uWCXK5EBgz+*)N;cH;h>pTRY9{CdZA^+}-MkTLWI z(S>pA^>D%qf>@$U{4FB5gc0Teo&+CUZgu(}|EQ+G)y#^tS8C4U*VQ1-IySm?O~7DE zVcb2LN_*A+)}PgQd-zeanOKvBa%UU;3_}bTy-q%;qSFPLo)f)_E8%h(nHGqVbn*00 zOHv`Voq|FjHw8G3O9;JU^tEW1QGcWu95ryq5~z{B_#%kZJpf^{o-RV^n6j85WNVf1 zXK9m4qlafZcs&6Z-4R0Blzo5F8>47I+dDW9WFb!q7T>ZH7dSu6h43STMyOh`h^=wy zDTuYF8R9X*vc|B6%vNUxHZK@VtyW(d%OgIENG5uBRxD~}WH%KRu}c8e>!QbC@AuC* zW<&Ur^;=sCFOWd`N(R`l{@;79Iy>V6Wi=;A-=b-sSX5(H-O(flj^3K^TsCG;yv_07 zu1+jIjQf1%Sj)o5hh$cv$Nz1UQnf6?VIAVpW}RAZ<9sBXL*yzGSMPmQE?u93XJp{O zn5oh#OnxlT$m%KSWL$^{vOl&QZPWQDggpll_E{{~KNCsIkpLWMg`jiH5*Or$7)Zre zvq`>M^y83p{!QVqpG1?Sy!dZ+@(T}jKjR>A*Ms*{V4g()8i^s1{j>esZeNM(^yyja-1WRo4x!D?v4#)=lSDJxugXCub$8v)IO2E^QQGGs(VC2X3 zQ{Nn~-i3-`_(=BNk{(tdF4N5$R6F1ez!P8rBqT_H{t%Lidevucj!8gy)%1PlF@IO3 zyq+ItBBjA~b#=!7Z7%rL(14%gX!$J$BckR{B(W$R9%|u~4c31|9?FiFCUa_V{|ci` zfuMoFkHN=KOUki332r7CR9FXRe9;KA$OfRiuc|jxu6r5AlSDvkr(`v zA46WC3)|DRscGpr8oY%HL|m*pF)c;8p$dI~^y)<8q++$*o}nUiUl+$B2_t)?I@TUX z8_lpB-b3R;d_&%%{0Fi8MT5Fu_)}W_wDepMiLAsg=edVmAD{J}WYZO<7;YLlJ8g7r zwZIAy-^waI^~Mfi=nXp8@}d(>j0|xwgq!>Y?QCTQaKliKcoQWfL(Kkzujk^^6%-(n z9ajKC*j`S}rCitT*81tf^`HR9U~Mkxmlyzu11`!!<}8{pJc;ETGFcG3kAI4PvM%RV)H1t}x3zcq&a z3K#ka=8UKhbXnng0C2=|Ot);1R6C{A5DHVV5EPd)iFG=EyBH&u@2u}&KI+H3%I3!; zwre0DmQ=J)L<=6t3B?K}3Nels7d+xCoWDP4fB7f^JwTNDx`W8|>Y!w5`cFU`mj=wf zUXWI2Qtv^%+mvI(BZ8OMJy&r9E1H4mKn!%<6i!6qoI+)t?}pKJj^8VohR&rJv-oI? zGv|CEHZK)GC%PGJCE~_mi$x(tDBLV*PwkTpWiMQM^W$ZuipdK5U^Puzf<0UVeaP7@ z4Z32d_--anJthQaxaLHP@RYRy-@|Kwjh1_&e{TX6$#KxrQ1!YL5@ezlC~D)JC5(e* z4&zD{9S3Y!aM}u;zk{J~53EVfxH{TV%Xm$3Mo5=V43MQvDa7#r{j`dzqd#{ROE=AN zM&6FeQEKOIP2Nz;=-(>dmMD$vN_0v&b`6ClhVX_QVdUWTFP8)8;zA%eCPKYs?C6yE zX~2-vHpFwAZvvT?jiB=ZpkLi3lzRQumB)*3E6^g08Ic*GE6>B5D4}7^enR;B4Dqy?1C7ujmeW%JkKsA0qgky>M6F(0`)DBjkH*lzu3Jq*5%OgS; zPBvx0Zspc;ZGO*fgvA}r?Sr*5Z>_Ej&z@rge@uO@!q|Um;$+@S?I|rcd(lMJkGOQlq5Y`@XtgRK!CKW@jcI43y0JMi#3{C z7zGJVL5evb-*%}3IfHsoXOM{FB2pqLNNb#smZI79h%AioiH*L0O$=~4l?^=kFxd+r zL$W;#fP-fAb2vq*fm5RUxISV>9jW4FL+KI=Pu;A*XT}h0o)KjpEVWG26Z?Z{=oaFM zSAK2w9&)_??~1fDHZfd-3jn>dl#6a zhBcJ=veT*M9q9`!VpeCiF-bdPnOw?o4cqi}MZ?oHm2(4UM51EKVy@N&&aXft)sWAR znSoLUse}Ls^(W4TQ{Qw4%p;-{dh6C$D7Q?21m9Ek6 zP#vgOP#nU`F0*2iCYg#>o!rN>+`hZEzsfkdc&I)r<>o{5T0W-E#>VdgaVA;mS?E47 zPMYP3u_UqF6`B=%EygGOL8M7EFP`YKUR_kvHfpe;8G^F#27EUQNh=VbJ3zqrC zzwX?j@IfT=-rF$~EzwhR`-QVe(LNB1*y{QT4QggOViil%Hqz$`-U-%Y!kvFOjnGR4vz4t)lanwjJj)<-kT&Jg!V z&d#=eMeBU}yggzcvOQ9^qa$ShOVgr1T;06xT#vLR;j~2aUVurA$o`$*JN}BCSaC8| z)@`ZSoHCPfQ5zc_!jmMD{Fy!SX-;ObDJ+l5J*Lhn26sK?FDicTW@0Hv%DBSba10+~ z3H!7qb9RgBu^!2wyPyHMSBV3@Tfbd3&11uQcx?hPuJ=T83BPRR#Ka0<>I&1 zzxNw}2&p5u@aD#J#iEvg)W)O8C*eawx|#)j+|IJvZMe31$Nn-;#mqh>9$Thsy1Zas zS0PCE>z&g2t8YXOpJOJi4f#Dw<ZmSEi>1 z`JZhuUo<;z17-r1gCaNjx_gsj$Qm-kP;_HAwAIY%eh_76r#prF4_9|s+kX;`<6Vy- zad+JF^NNSQ?ba8Gn;41Ho%jJAiuNzGFdNH?N-jyEeEihxGEqCM>@nIVII!Pb_v7o_ z%#1OReRXdDO5xsixcPM(bzd}^4(Ir&fKc{X zSo)ZeJ0r#n5a*SaZivfA@Mr12Dh%(r;U#8kdzKzT_0{~S9u1`}#jMm0Cg{tw9(E}b zZs_~wMWZtN+C{B|V^kZbZWyuysaiE0$C zfA-}fO*}{ODk&^<66QXbSLG51AhIlYFjS-5?QGr?S*Mv<@x;1qqn7@N<^>JV9|Kju z(T2lK_i@}DQmEyWs?j$i^#V}B)E1VKQ&j_njUOWT7LZ zRlXdANrL0@%Dr@zaR`z#M5u-0(>Nv7f86Clz{^d$>1YlK^Va)gZA0H*-tvZo7#T_N z>lz-e6+a=p_F`lJYr|k;p{?N1NR+I`J$<1Hl&^hys!}m zdorNqyvTm>UZ~Vh$6=$u6iR+BZuV_RU-Y{pzWeVFw;u8841mn##Yj?@<$MbwA}fMj zNiuzMw9}amUf>-Q_NQB7qx>ddIsm`wh{N__GUm$iL-$_JUI3@D@W%PctI451$Vo0G zu_Kb=Ssi2qWwqo9fA%f~PnRE(y}^!Ylp*r>$8*V;TkZAtwH8r3*h&wRukd=OzQQds zPJv{VI&`bEmH&h0HVranlR0b3jNK<4RBoa3)P2F|NsyhBxrx+b^-wW5B95dtq!n*8 zz{}Q`rFs>iaVqUu)vG9Oq?s-cw(&LIG?*3{k|j{Hd4zJ1cip8l{hHWFp$WJOaOFnj zAY;R-S-lvmf6^;?Nf9T}uJ8w0yA2Gyt}Umuo~CrGjv(YG&orIG3-ZB6LQ>3lt>kPK znWE&^T~G-tF_s!w4HC@4ElP(w#W(^|&yF(g=sk-?!wRNhUl}Ex=yQB;H~pU?iX=wH z=82Pzi$?pF=%jhqY0qj`A5KiEh-oIekyjh~qCM_|4D|R%kqi2`v5i^m%*oOFf*c7| zY@AQrvk)(RmN-J%Kj&n;Z(|B})HQkiU~kUKjTCd?yO?XL<}&jq-_0dKIx*9(Bma`x zJ3{x#w5FVC*%4D-`!3=K55o^G=h<_GhuaNi7TF#1rUa0h>>2;m@i${*s%Zx2ZLxjH z>0cad=VdvCQe6`MF>PyaWJN`ZbFx}{IJ*ISFf9yB}tcPJ$hg zBezLMwdU=}9qUs&&(%4`uZcN6Q5bXS@E)4HUVJTCe&N0NuKki>J?V}U-cUCBNPLW< zb;t0-o=>4^cygj&U+-8Bm}Q%%;}-Q&lqEv=tr*7J$ZgBDbhA~)Aqnu*&0Vd{ETq0s@yfbO`<~n9`;(i4+C-|&%Q&YGM@qf?U@N8X z#|lAF60OxOF-Pgog2savSDaM#xvQ1t_dgex_=e^G=zSO=6MtkMlFD5*vHf7FQ9?k# z=F!YrLvB)A;J=d?ZI8|B7e%&SLfW-oBbs>8e2xeoJqHbPXX4oog`50Zy!un`ZpiMWz@i|WtxKN zh51i^t7yPik=Sy(6mX}J_<154dB(=~lgG(-_*L!t z>Pw_)!^o3^5E@S)Dfe36G3U#%sFOh57iN-hx$4f=OaeI9?730PJ9&PT$VF|~c>_MC zf3WTZSr=sJy1B-=|5*VkHp&$?E>=1JMUJ%Um#!nhS?FQ&@{{7!E%8F_O(2QoZcmGa0^sYCxEjmS=$AN>x8}l&)JP(5xr86k%Umvk zPG6BNh^x^K_65A8d2t91%#KAkaTpI_KLlwHHPmILSP>q^+HF(Pza^t9ou7=P88htB zV_mwj8CC8)&mnq0A|2X^wT<3Mm`#YPI*1n*Xxkg|J_Bo#ZK77NkX%i_j5=#Q6Tr`=i{QhHsHbp02%5fXCAW_Rdo90y5Pg z1RAMN)1A5Lr+XcC%)0v4IQJWo(a)?(E{DyuUivYOz7-ImWSLL4XbS+Yqj3lN%>tzP z^W8|Z*L6@~RwF7?QHR_J5gR~#u!P*w?2QAzLkUM5F$U@f-$L!~b}?R)qRg+bSMvSa z*gubddA6A4rv64M6L(&qY9sH3k0+{z=JAJBg}}F#@3caCLw+J146lwybQw_U(rb9& z5)F~{qLjXKfH%yfxls~ogpKubNiV|S-83FGT#_NY|JPrpggZEPvh5=4%q2~om^SF{7$Haa63uMrpV%LdLQO(iLu>j= z2Vv#M-?T7K+D0MBoRBI}!<5xN=d0(1SV%V+YJSjMji#@r0SoU>Gzk2kPuCW6GF{s_ zMkB|nfV^1l3l?2$XunAZ)lxf$yxJ32JHX`ScL3K|#E1x}EWFiHoF83@q#1f$#z~{3 zFoljc^Wsoz9l8j6rE8W;;-KUMAa)1~FM^qyKsNk?%{@FS?J>T5BY~1a>7YwcHHmlT zrq5;u--h=vo@QqJxLCeo-eztc{n_7NN!ft|Z?P%RBKc?Z2VdN3)%a4ji}q>_nG8Mu z#lU!`5qq+Ye(&1b#x_FI&rYE*}-doVhXwBk|=O5pYte@~XnG`I`?j|7ypq_TF zy|3Sy?+fS>$oyh31kYeNOxkA`-&vF`TvFym>!LSe-eGdCM}OV}B9A8f69gVP7=0Dg z;OLq?lV2rSMGm~7F#9m6Ey;0HFYJykk8y;*M1LGfP@C=;a~uFEqv=-;O;j_q%f6Pr zi5r3nEaMB%Z~mSzc%2EDMJ!jmkbUQ^AdPZQYqsQ5B`%glStVZt_;%+Y-0-7Tf0?*H z)0Ex>EoSPQJ{)G?Q!X5i+aoK9^}*&Zbr1ST4N%umNe`{flQ`Wy1c{eZjHzy}_Hikb z7WR2*yhDRI!}PhaFpdaqEn?aRG(#J)h_HwaKm_KPnOKyBxCS{wGAoM-L`b8tP#46# z7XVIXEF3IDqBI(NhBn!i*(h`e{HJ)+1o1JUMIm+Qf5_|&NW#WG*d%kSIJHN#aGtz- z^VrzAXhY^U%1*(Oo#{}gSGa9&gPL}{fz5NHviDrCn$BMPGkeVD+I@z^W*B297AP|qXg*c*W+ z<~JGrIuMXaFi$gxO8$cl?i!r>?pc8k7DgSG1nrvARy#t@_H0E*xdY!<;W-RCiP53a zS@@-a6RE`WHd)F3*Dx|3VoR;r;1fcSdw?+kD7(6Qv(b*{ct-&(cr+QB5Gwr5feNO0 z{TVV>N5Q(?-t&xwA|hg6+)p&Na9y+qs1U7nT(Vi{Tg z6!>5cIZU|MABw1=XxrGv9s&JM%}y-(<7VMWVmsH#?5G^*fD|bwwfkvOPNO)y5vcN0 zL%@Kl3Zs`qgYk%9iM~yJ1;~YtN*bci(~22Vge4=uZHk5sWqz-Wc|;gLgc8j~Y+}G( z&AbgVCJN-r!5#ic123d;SOJdXH>g%W%9e?vp;dA*yQ+NaFX8&mq%4uiDHxf^+A;HB zv5LP+o%hO}d2J}@Cu!u)i)<}a=z`;VKcNjgISUKB6Eddi3@#jeEgA7ez??X7rr#wI zWzh{aEDV86*#_I%JXhT0eP4jKHP8hu#k0+5bs`7wO_8%9I7}$c8s~8HCP=yRqXx7) zhbXi)Br{Yp#2+1q-d};Z9em_zPc6(;Er}+mX=HzTglK|Ki4i-%s!dy^bih*mB~0^E z+JPZ;o7~C*zXgW>Gd?_y*-!K;V(?m9Ey)V?Km?SZzV+n+d1tzIUKZ?2soEB6G|9!n zgvc%-V8k}XC$%~df=e+tMsVE#vHKQ&7@t0HvYq-=BOHcj80FSThDuCuN}pc6jI)<^ zqF?VNz4`@e7^>l1gP(S5N5@fbN;+2|To$c~McpVoWOD0K1n+D_vm=?0^YM!f68iTr z?ia1=Rz0xYYpKUIck71yL{5oiyYG8a7+gE6KjQ6@o_P}8wTN|f9E-38gpwk<>sP)4 zH5ui5s%XhU(9hHnJoQ#;&`;o)iWH5}OBBt~ug=TREY1crQ6l7kP!UajIzMW@_0EQr z_5=8=f*zev>C+LS(`3r}Xm~4RAILHY=$n~*{oyBmzWY9ISmwb@FTDxsVg2CH#itB? zIy4a+T7+);!N;!B(Qn?GbbY;cB}$p4ciSUa)fz_bm@??=t1>_7e=$sEd79^Jhvqw+ z`=EeVh3Ch#&m3YB5JV^b|4{XoQEjzN*l6)mv}k}LEnb}9UMNtCmjc0pI|L6dDO$8Z zaW4gmyK9l)Qrz90;C}MF-*?toC%^Yf*4~*t_sk_TGn=%CMJpJ-L4IyI5tI}VqtwPk zpfOk){9$KieiI@IG}>T>`2DoE3>OOby_ovDw~24&5==MW>f6y#VnrQZnL8Vp+a2k$ z`B~@IcF@4!rlumT!|r+s)oC%Rk;*x#XBVOQxBIxIfDM&C3LAKv5NwWd4EHB{Qtjvn ze7jA6+KErO>9@wY=7pNFXi4LaY+15>F%iTeSLe#Vw>OAAD+FTrOMlOdFnrTXP@egW zfvbR?Mb=DjJ2>u~L<}M3Uesr4QIN885{dPBD2Vp{*-?7<1*tC0gG>FdY515~Xe`d= z;)1u4YQ-2RW-(?8B^l|X?4Nx6yym7OwEZ9!rZ4-n^v#hO>~(y>j@E3UWLMNs_^w5s zitYF+69zgNh^aaPSpAuyi$PgBwNX??)D5Z&_MVBEng-ogSqGc{mJgf+W0Tn4!X z>0xY^cZQ(4OZjbm_poS-zyX+9ykcrWz+!tO@a@iM6GOFA?5MBgZrurKULOh}^5Lnf z1L7J+nO!CRqQ>-pBLxviE!_wb7T;vXJ=#tMi6`DXGOcyiYSmZuGl6%Ev+N!vtgf&T zruF`^WbT=ZzhF#?sf1Yfl86d!8AmicyGaHKqMC)`QWEzK+}WV1p*a3hAC}Dc*$*_p zL{`3o-dEZbRwLT;%CM(%Si8o_!@#KxOnEl)1Cx@mj>z?fLC^l~aRu)WT60kz30wqV zY;R8gec$QVRd)w}9yR;yoXiVQ^U0-lYiPZ|klhEC>mZcdXU&&-r}&;y>fvWYx}2Qv zS(P6C1$)r+zW5*g`3+W;lM^8=$E}!B&&_moX!rF~lc+6=qW9t9+R<7FJ05eLcR+(B zTE^I5T1AqXhltXjQ^Wk5(O2Y{du*0ZZd=Rmd~^YWf}BX)g>r3?GL z9}^EAb~((L8p!=K$hi*nI`}p0dA1`asfS{8J={6!T^XAkrm@~6$LsEtYg@!Ab`LR! zG^c6DNl=kj&H&%#yT8ju@Y#s79Wat{v>JJ#E!Y=Rg+s!NcK}ecvKXXeKZ~SY`|z1< zZC*_NW!8=!&GxIs1JT#b@DuHPNt`vIB?aNGGChGYkdns=l`7el`dY{Tt7@R*W5YGr zfLDIlD*Q?sPwZAq*$an$tvT!1jPIE$Lrr@Vn`fhPC#YYv{#?~Daa0>5iJh~U*D;N% zy8QPJHG)1KxHb2AR@&$c3hR&?G7WkRX2$4d@~$8B|8a`8){dUEKK>W5W;Z@F__)Nk zXx}3xgc{V^W>seWlX%;z8$X|`ouO1*L!5J*q^!UC)!8YM+Ej?aZhk3>Bl-#uAcMw+ zQ|SJx7`vP-lRVrx=$!yz9SO|<(F)tO+8UnD4M}4p5AACqQ}S2kgrA<%PfI$4T*E4m z4h~GN#AjgV3lDOD;zg_etX?4;D}K#KO@LcGMhyF} zJcy)2t4pW(o9{klrdN{a$<`aWJr0eD)FxwTf4#c(ZjE8h{hLC=*Pc%Z`!#i#>=bj5 z<9he69Zuud#xk&aYe^O{b~>@MCWTe(`O8ie)cDZh;4Ex0j0Me`ya4WCqwynrpobRN_l*XxZ$4pJe?A(m>2Sc|E1T;IZa23+AAAgT zbS8t}hM!`gbe)oRIt2epPm&d5asM~u&+==-t~CwLhNuG40wTgU_o4K&}*2 zXku|M{-@*;#Z=K&&pu(a(AvHKeEk7qaH8NxzXfrL^N56%3PEv&w%YV-1k#)j@(Aoe zALvdjs%PnB`ifMm83?dv9+MD~Nm%B!G2A9D4x*DOD9yJq)3N<`Rxw{D)!3txnF1V^ z>Ge61OV|i-%GrY4aX5SO0(p3c#g4CnU}J~LStIxd$*;lZhh87JyE7B-Z2TMGs(qbQ zgTCh5y`JyRU6!hEOwxPARivIkE^!50sj)k1x7TDQis*21Gk4?flQSMs;imKv$e#oq zE>?5@i!@*9C4PzdhRkIY!)dEW@yG5ml2|*w+TOBbW4u^ zB*pm^(jn8a39KkDdT|Gqu9jZWu8VmO0yn^uYpiu>HGLL~t1_Zb{~odcjH5}yL?t7D zmXK{v5a-il5Z5bqC}HMjdco=R3$6&xy5MRn>CPHmrKA1_-B;-h>v-~^4M;Ss3Wf>PW`VBYY%HGqA35|GCYpeOz08y* zD&{~-FppA&Nqh-NUu}2HqdhP24O>Za?Ms;fiOw?}0CS65SA=rdVLt^iQ#X_GVO%A~ zWGcg_<5J0dUw1XUpszbO_e6Skq|u@{MxF{i%rw@V)(+4acIoShDWefD`iyf>()g`6 z3Bd$DsP^I?8+2|AQ6LTW&&`BscCDIc2RLCIyLNvs%XM9=Vb;JJ@p1=W(cI~<#EBJn`h|7C#Aqp*i`Dc0W2$shNOhCApC}i@ z|C%WZX}&*C^cT?5o7Tm5VQ$9Q@O?OU4XA(VjjfHXBu_wkMMB7=e1$GzcDlr1VN&m* z$3FK{K!2!8NTxGbpCkVYhhv+osj^2$-STT!&y(K9Uz1X-G|?jVsM@7lnq&gJo#fY) z!XU9$T@Y*T*~i8fXh3!-3=?T8Gl7F}Igy}%cd$10reG!W&IJgL58a+c9dUJxNGG;b zJvag#j(tch5xzVDnf*l%bQYq?$mNF9?QgE*Zc-Qx)i_NY+we!t;+Lu|IByM7Mg5?V zw<@KuDoe-;l?WTgIbEprAcrZLxS+-1liQW_ebwlNGXO`Hb3nj5lUd}$F>) z2gH+D-1+bIlA6H{8r&?yp{R^pBPsglYFTwf9a1gZkI{LLu7_JXoz42_M)IxhqIc95 zhe_Z=l^B}^cAdvNE8@y24vjR<39KX`G~|o4=TR=e)a2fUZQF*mEweRFq0Yu6+T#h1&FeDzE;LPY5O_*#Ya+VAbvrfA)6ZHq;6 zqq=9Trj3e?SXB?-?KNqqORsbf6k(>b=!E$Scg&@;8GK7xARQ8mpZbr4NQD$i#vK6R za`ZLnFs`RIF%25V39D}WAaqAmAJLJ*vOEVa6Y7rS^)JGhXs;V&3Ue+8uuxeI@N6iO zc$5FH3=l$->6JPY;CID4R1XZFxO?~*5lF)C<+=)czil;j)lmYk?|-!3uE!ww0Bo53 z7Rqc;C-v?T`t-@}TdfO6@*>Bz#M;|6OcdjsuRkp`f*h-~h6MN5knic@sC-7j@q+3} zTG}84b4Y*l2Szw1W$N|FCn`yz?zvg1$#|U>3M=TB8#L6#$_)#DSfvHkU-YiwMlzO$ zs|&GBzYV1w%Em)PvjmRAk47N@8Xmv1npO|!X#9*TXlg&11+^Tw?-b1 z>2C!Z1YSon)-hPJOL3M7U)uU92MZ3acY0FD8R0B^vOCA{{^XkD%JRJM?fV{Rc8L@g$B>GYE)n)(WC$U*hEpm5Qhjf1s_AH{awlf$tzH9~CV$<5)*lZy` z#W91ufe(O$Guhi3R6Ev}j-p|X)<67}^P3TOk~8xkNNHa^2;dW%&r~uxKxi7>ab~aq zauUqkThFDAp&bV*z1aHChmp76DqD_sLopoxk4Tjl!crNV zlNA|tn!@lx=l>X<>~??=nI*9CsYoYB!0&*SaNJ@nGi++IajlsTVD#7Rdq*+m4mJ>j zOo-|g)BT`J6QN4C)|ce(AoXc=^!V!YU~&vHFu+c!E@9^@Y!4;A?EP&J5y-6aM^%Bf zW>YR1EiJYkwup^gq_+1kgBqJZNq)7Vmd2bXLVGPtw|b&|Wuz0pvrO5&;agsj;26?T ztf=>@FDa-M16LsJRT?(VOD54lmn6rSj%25H$5^E9ezO|E{@#uqbYcO6R-O8zZs6WU zk`4z|?uT~%LyeFoj_hZDf|7F6HAcQi6OiX7r$OY}&AQ7cjw#1ICJ-}fK?MIU~9%|G`e(UIK_?9k`oYNDNJ3Ij+ktYZ3 z|LR3yJlurK18}vW28-Iie!K?*ahbkU5!i}I14S0Ojr1#32kA8}3{af1#c-EM;|fLc z`&S^Q&7@bgCmun>vy>XWeJDygS){vLXN4(5`k!$tN{n2M!bi^+rZAKe`QIk+bawaR znszSvnPl4x2^l8%xE21&`huI!50BhIheuWaKf%K#Z(ud>#og<1hPn7dn{r@Av zh4~p})7rhVKU34suT8N2mOzuWx>4)W(9$2AmW0F}`*6GEQI%eDwwlsOst=zO>@BIc zFd&PbU1rQ=u7C#?+w$oP4Q2U8&f>ze1sqH4Ui6QLG&f6nrgTrqOnlw*@A~vDNB%FD zj`kn!gU_pyz3)uyQ3A#9`N-DpI2=09+U15sS54?7h>X03sOayDrvuffnEnVTaHN@q zot>Eyj^xf%ierXv$nq?LS-T1oXw8?TCJZf8e50AM1z)x!JqQc0uyBxn77~^>>AE+N zhzY%ep(y=WAr?|SgsyK%{ST;+`S0f?N{q6!Slca`X!j@Hd)KDJB4M*}tP(^Gd)f6F z`F7cBDY?~)dWo$y%RoXZpqKwoV|E@hPXD}nL94rSABQ3v-)hNXfx_BX-p-3s#K+k= zMOQ{9Ek&)WTHIVXO?;LC)mSQo)BRt0WFQO;>Kydl88D-O`(36^U(|99{L=0ubD4$3 zOn&wjO-2PEnliZBlJxW&a-IU<&wdP&kJlMJ-an;J|E{3sgt~CUnDZmK$c1FT0U1Xu zm@Sgf!5W@W9Ar#aQ}ZQOFVK5SSY{{TlHAi9CbHsO*PjUt1j&nY;E>po@8edjEYlcq z&47YD7gai$(SajsG=|g<86AQ2uHd1EmT-F~;1)A(Z$r>Oyp26PS>H}A72wQ(jdnY= z_`c1GgmgQg?v45YBql*5`B)cLEfs%ueELCFDSKf|b974>5 zkWHB=k85GHz)mDC*YSlq{PLN5c-9WzjH`7f-2yU9G?xutcjR(V?c zU5`E(fw+nfK>MS`D+1R6bu#b;$8&7;BKl;PvIJ> zpDv}DU?{+zO#axPES5n!3IIUhqTs`jjT{mDPwq%;ekx)R z?>CR1Q5gkSWp1?gE%;0Z$o3w-~1-@_Scf`a4$ldGKR0*i<$J;Z^B zL;Kd-h3(NaGq1`(rfJ$ktD~7I{?HT{h}OEG zbr>EAMKt5%enY%mP()Kce7FOwwsM)#P0M#)y!W@m4f79Vg47khpV{b*K%sKs9y0F;90c;Z-xVHX&Ui6=Q(wvn85t9${aTUk3!M?RN-r&{I%Pt)NBl* zwOXA?MAI7A*8F>K;-y%AD(rM9JE8t~XPAE~FNn2=sEZFd-r|Ut@G7^+DQ7PE-?5WE z0p@_H6&w++;c=X9Xql~t+37dg4C0bg)^Wc)*FWOzm_sX30=RQya51p6Z<^h; zc=l(6rwFY0^w;!|67-8N-!wm9{<<}}sA(d!ECc|Jco2tKkuC9Z?$ME7%zA%+;*AW%jJR z*FP-zcnvB+r$LueD3b47l@u$;@#hyh|!78&4Un_hZm!p`v7{IZV2*`! zxtI=wcjsP!tX7DYX$l$WQcNm;xq}4^qwj%k=37dbS1U}QW-deOUT@Rf5t)<`+ z_6l_mi9oGn38H^8;{|G5_m{Amew9Jw$hBNn$SEz7Uv)IdNeE05JbH2vM7>ADRm=g= zR(jxsirfrhQo{X`kp82`g10@a96R~@4}8wG1sZuPD!0bqYXV6$0RfO=X$+_(m}6;4 z3m4$By=}QTL{TKC-2e$afx33;hTP>yPC7mB@*0Ux0V*U+&d8Wr@2L2!f>X8TJsQx? zZP^V3p3XSWd#aqsj+CY+EJst3OJ6@km=4QqV-%Zdbc26LZ%mO$fjBYWe5QXxY>)2b zgt?CU$Km%9TKx;6aXx1YU)+dQk|nkR8(&^?-M##N--Ha~J zZX+CRF^v{MqbDiYGWoCB%5`+vd_|vm#A94Akm^TAxGv5^7YdHF8kf%KGtp0rN8NForQA$WN|M{nR*IgBDbKRdv^Tv zy4nqHVXKoyY4sZx%fw%Xo@x=qv!O((weoU9^Q*!>bK5a%p+|QGuaRl!yyfzkRnpxQ z*LWFB?~vZ?SBy1=2|UGmKVG9?%OQ9C-8bzU?x9u7VbsG4M50+1d;W?0YJ#qwO}Kmz z?ySNnm;QNP84f^sHEm`0Eicg)n(H$>=Q82-_d&uXfgqoDZ+NT}rd zla+5Q$h>=mVo&qTc==a*nph97n3xEzE3ZW)KAWjEYvi{3*jEax&fKpC_5c4%YADf6 z@{?2N;9jYXxm`NXH6+I=mM^Y$QAa>~CBqrwsw?dO_&%~Wob%G-o#X29%@lk`Y)0~a z0GTK4#CLmg1z;ovpd4sh)6%!i%I`W}aFj}nFX_(n#cwNYd=|9|qmyTL*3DnEZc~Z= zN4$iHD`D=z*L>R(|4E2eTOU5YCM_jjNlX;_wP)tbBT|1Vj&?C#;jdF(+h%PnD(%U~ z(wkh?yu^zXhs?66KvjnFE>0JN<%`1!+>rRAYnN1kshnUhU|8(7lJ5#f1$vZ*qpCUM zrTJjxd{BDKh;|f-l9%VF3p<6#1znGWGn1|ct6m57O6E9)R40luv-|K20k##=8ZO+J zCx*7a7n(i|DHoI6MYz@QhM&>UKrnZS)9))BNbaPU)X<1O7ZM9*NiNsVLT|FPvhe9dO4vc()x=8`BfKck>TBMqlZ= z0;q;GOmZDa2JIC$B$91 &(KL0r1t9G^s@fOh1@32}mVx*oO#YBqK_lzLSqB=uyq z#1`?9(_BiP2_XU&H5%Ky`yIb{QfLj3O2$a<8{YQDx1p5{+)Ids*a&MHC}t{h1kK9R8gwv7{Lw!EMhx#SMFChxmLS?Yj}{Wf5T zsE5R{HAG42f~ma9c;Ddu_JyYsp-ams?`wyq{<@F?C~3Vrig|&M(P_0Y_EY*5LDJI{+L#DF9M_c_5&|=M zRwxD9WUTKDr^U?&9Xzs6l+J$WY6$EH%;54}+{2O{e&7v zgl7xr$QNsu0LqvfdMN<(XlrH>zlIh~9;-k;$UA)_t4!cND&-ev_EwZxHfe*TH_W8r zzR5%7KU5VN!xDmTKeHr$nWk(_e%Pf1j**o6;&f@ArE-PH$EZ4-dGM&Uc-fN?UiCJ> z;533ksT-P#T=o2D=~!e%ZxQrZqE=Pa=H>jurc_awZ}hl;snuyHg_dwrxir2!fn7<_ z$A4z?4>$}s9F<=wMOB0KA0!PwlOenCP11YnME0s7L<-bj$Yp0p;kaQp(k#l}U6l;v zTFIliA6$_6>G*!ZFg|Yv#HHicsto@+O=sTr^m8NLlGc}d?xEwFIfC5)TsCvBH2cSE z$L8a>whgbU0mR1Ucg{*4rVP<$%tJVFE^%%wg(VW4C;fB``}y$Om@bW*HK9&V>uB{> z&7K6O8S`mAS$l#jU->ifL$=ItfO6GPt;FXQAPF{045sXaDNksq9?(d;xiJzQuP}A| z*O94QAoFz;@^I5iUKmN{d8(zHqz6Q7Z%Yy_9#Zj5o6sV~7Vga9C)lGOY)Sx^f`pE|o6YrP4y>gN~5%1={RD4i{$+)pNR~=v7<_OYVvc_Tm zVdt`2uu$YRpB0`F1J=GT=QTqnqvDWcI7EmO?I&Vu{D1ui&^#Tjl#= zu(f}oc0a^~>_dSK=0#PsrOq$N6N@@&j4S3Z+@Qw@KawkXUP221&OOAFk8a94=Mx}z zcCMpV99a8~gCsL6nbw{yFA?}OGpdzN9%DcJf9gfuqOGO5j`T}FSyDLT2tdXiYT8F4u4f*6?xOY5y!3ATQl_;R?XdrfD0 zWcuy4ZBDm8NHkuiuP_tnyEhhDVyTW((+Or=rkNecNKRc=LfW&>iiamo8hCUpX9S@J zT88F9Orl&lS)WyEgBWzqw)A#J9Rin`hWmf+M~iJIr6n#4eYC^EBZ$@M2lQnmjBQq+ z#r@3U!~K+ZpPjl^CD7iNXPf*u()4-v3v%Oy>K}P#d$N3_)vx1Df%{M1BYfSM<;{RJ zd?5EjTUKb(@kt^IuzwOkyxw%hldC5oz5=4CsLYw*p`WC+r49l5_o?~0a!^_!1wSJ+ z+$^R0uDD?**_EKQ!c*z4&onYvRvTSxRNXYu()xu^(J41xGv^vw}EY^1i0Vd(Ruu z%j#Nw5!KX(Pl?O-CseJXkdNJ3d5TGrN76d^;qJm4ZxsWa}7_Cqy zPeu~%8NT+d2}>S1xQ)EwqF^kT=q|5kgTT<_eGI1Y`$hx!h}1^3oQ{~w1&`@ri5E7~ zBaq0Gd!HMvJMyrr>(kTU8=!tb@Hn-s()$A0IqQ9}1AUR0lJV^e$SC_X^=VwcvQmS| z;F}}UtP#oAyJ5m(P@1oXqyEcG$_=_y?RTF2rpDQOpS~#ak!E-tpzXb;%16?j zR!j6HlQp;e9jqtmI#KRx;iBwdue0FIHL5a|>Q=k1VV825v;Cu+3b>tl5ZS z_4rKHwjP~iz_R~vPk(N`etFC}B(KLRmTeH z2oSP`RNwu4h5PQ$!La3%K$t?@p8G>FxQtQkybrCvOYn(9$9kf4!eRN8a#mWAJwqvF z9;8y2Yr2(kKaMlXtWEuVWY&g3{<;0pv^+uF^W+E{WRp-EXFfgOF`0W@vXi9<_PP6R z_MKEaB7Xud?{F(WKtbyx02^)UFoka+Z$ODm*Llw?&a-MW#Dp~`=L6A74*va2&Fy); zdZ85f578Z~Np{}kJPb12t=Z-z>ommu@wrMNv9X(CjG(6}zR@`KUOob4LHR>_j^rx* zPD9h@&mej@Z^=q5*4xM*a_#2m6+WW_S>$rF20`*jA3POqDT!=jP5+B@iis%pbeD*& zHxx=#^(@E(Men~VjhhT}*F^xDZ0kFDXYRIAtU{rffeCczlYOH9dwUrigA(ZJ7g|4! z?4sco-+u%)%rQ+m`Wx~Xtz=v4vL4_FGrqI^a*ffx&u9KL?3M|D1}00c3cgODWu!Xxl%jm~FMEwXS8Gl{-A}MtLLJMB}nfomNV6UKwnTleL+$uM zKS#4xOxxoMdE|@em$ASR^kLtI0{V0tx)EPM+ax&E^W!|)5S%*UjmTVxTcK%_M+|jc zGqw;xJ7Pu^wB~&7zxsn6Rla+i(rPo1Kc6JUdzTAw>9`eV#H0BklFasN9AW7ewhx8w znQ~v3EDO{iHh=zRSd2y<=#m-FUj`YUBK?CFViG^6_8K=fk$ZB4aL$?-D-6vDvc8du z{&Hh>DSR!`L1x|1ghEKVc9E*<|F9<72mLdpz<{L* zve=cpa1>KKcSd72qH~fve)+f_a!`bO% z|B@}$uYRKV8!!A8*-Y_1<7=`ThPEOV!4+>Lv@6ur-rphPUC<+h>6>mxfIde4WEw7BYa*9NjnQN{?)`d{EElP^Diw^x|mLoLKS zR1xFnwFP0?PZtaQBF#M1Qy=;MObCSf3moMpGHbqkGFtuf7}+qHKRg5V{r2wjvVVrB z38lPVo$w*BpK;~c1TlLg$N8mxH0EdPYZcm4brHyKb<;TLz;*h{N0GFeVX zebq}9ADpDmWG%nb-|V1lA?E0g_y%n;vg;HId}~*Ywwy)t{Pt*^XJZIKWtS*cwj}0m z2vu>Oi;4aWy&tL{-yb51@xM83+Z+8x3|qq(LFVzq&H0r#@pjj3&q>J5(}F=Nk2g<+ zPVh+82b&4+r>{V%VQjFImzKTo$pNimrhocQqk?n0pYy|Aynp)UD3#p*I}70H0ZOU< zVCq{$vl8}F#af(nbP`c6q*=I)z_T$T#N{J?&MA4A`;F$9t7AB;3Hkz3wCdAr8krd{ zjp)~Osv_l_9afd(Yj2Edn`4>r9g%wGu1G7AZf{qvpgC-A{M!d8%lA`c1)jA2>Dr51HHA2n?-pCF9v@5!n z+mR7gxX}8xZ%~CSJ|gDHe?Gy<5V1QvyKjTIHl&Sj^W!^Dq1YRBAZ}jRiBS<)KA`R| zUpaff2Tsy|tUh6C_Pa~#zw>TkY+RQ&RGgjbWD^5O9yjlI>VCMpACkGAestG&mD{%@ zA4xp9u@aZq#&*X&OC=sx@ij5mSvJX{bC>1=p8=Ks-GkCQ-P!c&2e_)YFgIkDBxkIanjf& z^D_hgxSikX{lQiq&4JAAtk0)Mwj+}V?7R8N8+^(%r>#N2H$n~0BpXbjGo`Z>s|?mz zUb$r{iz1vQ>Y$|qTwGeThslk2)R{o#hItB`(3tPXy508MrJZcfb6lgrV%$Zzvm{+i z46@{4>5MVjeX`5Wnq=BXkPmw_Th@lkl!>C`e5_c;v80{YySx$x;g72lo-IgM|>R;gc3lZ#bt&eO&m_#62}$sV1M?+tr~{dB%1h$*T++phN4 zzE0bzb9w&3d1xu-Q7_AQaMb3|d2OcU)l*l9^keHir{tdzPXVmBf1S<`Q7#;12ALy1 z|C{jI3USC^MC`;@iFxOlPvOLPbe^f-Z41ONy(R{cg~1}-(pu-JpJ_IBUV@5Ex;iGbC)p|Fp+zpZq;=vT z-g^G8*~%tN5tke1;PQ8^yQgUtVq3IN=&H_aLXbL+(%gd|XH8UyNzf9WDVt=-ssmY4 zW*2EZ*^d~%n};wEWok;?EZvK?EBISbqYZD&$4)FIIB0|({?OsB3dF=Xu9abhWEV=5 z))rbFF;$mOuESIIA2N}{KSj`5USK}GeZ$HuAekx1hVkFBb><+mu=& zNgf4EZ;HaO*sp)(|9a>r!^v30nRFTjvjf!~nKxPnObBgeaMntp>Zng?|ARV?>IKs(XR;IfU)Y#VbD--JFi@*{BXH{gdBZhOXpS8fNh3 zs#V{8#L-|VXL}34*Gi1FPHk(g9v`e%xZxabEuy8}^IiMiYliz5Joh7SW;Gc1tVZp~ zV2wPphFn%;Vs8D2Rs~#0Ko@Fq#1r@`gw8wI8ZL94@1~=KnN*+UsD3xGYU#h%+K*T8 zq_1sV>MeFXD|5L{)0$G~AIDxhFR~XJMXvAD@7fzn(X_qiEtO-}umkHy96(b2)RJ$Q zPa63j|G4yd|5-UrYO>fkQ;|_vss2815?15wkS%@###BQ}fuU8xXO5Gz=bF=($q#r! ziw1u+wLey06!ER6TvXA$z_C~r3+^;qy~S-Q8Hgy+G}mqYg!R%1IbT>`v`GuX?hnx3 zsu!sf(Mn!HeC>H16XZn(Hpskw>Bv6ejvzIbdr^i__FY}qwXo43;!>4Ll~Yrp{J4p4 zbQc#FAMK#9Xa_rz^uiyWrcO9-a~_g4INEk)j}E>C$#Z*t%!G@gkm4G)?cne)h z7D4*6ZDT9ZoRV9eVnac_Cqu2t?vEmY!{kD=KZW0$2Bgjt>y$C)DXG0Z7yvmRIYcYR zKu=Ge64_hfUV9LH;23+Ly0mzQM0WFUKZ8E6?g&-!*zL623k~bV$-;@asf$$HaxUYr z%B6P^w!K5^Y$Zho{7DB11raqyS(1;QC%2b_(mpR|25hIzB3U2q2v@YN>m@X|#2tqj zt%)#`u*zEX%h8sy4Q0MiF%Veqj5;|ivMgyLjy1{@H*UJl$aTDKFJ>)PSJSwSmlpo% zm`6~@FG=1n>9_5e^tJMX^aE>~7o7!=PN({`zUY-u4h}=uJ`#POsl~x(MHI zFONS2atNg<_rP~w-25Z|4X!c$2|~9KWYyG>BjePQW0R zBfsi*LNk$maT>}3C+*6oiXhl1dO*%wn5^`O0M-K>j9ntUx{1jnv|TmcIy8@$aqgIF z8Y>%@4w>_|e8d#S_6D4g9g{%Fk4cleYvZ5?Qo?~HinQ{MC|qfN>H#u0CML4??5(@+ z`|~i+94$KWjM3IQ*uUBCz56S~G%o~?0nH9nIwFbIh&^LnTWXWN(8(3koE<6 z*Jfcj&PM5>#a*JsZD*6N?$N)mN7YC9%l)LMNpka)7!vU8zBLY{Uf&iB=2^Z|7eoHz@xa%EWD$`}X0qLKQ z?%P%Z?VI@l?Nw)y#9aFFoaM&plny zY&k%(Y?&F)-sEH7D0-e!5NAo_%gz5(ktRp_>HO4kio-C0y?HvsdbaIECcE=b-2T?{ zm?UB;{=zF#EY{FTI@l?nSeQej%&kwwS)~F}fS0zquROmdMU9sNs64qKnTPk3Oe6jEes3jDoLR8~4}?ah_}5{a*+;$8pbpHczA%v|N2ucpI% z8Q;(xtcL*&GYaYm3+x^!&*OWl8>cwAfbP#JP?uz-Dcw`8iULykl;nyqb4-(x9aNY4c;v?t2mdua-ib@h?ksA&5aM!-;qXq$|E z5@>xDfr63M2ovk>f082q>Jj0dCR=G`c`3HOyor!YhLj!;W zr>=Qh&LfM^zm~yn=rm3t*BKTwtzSbw?}`p(OyhP81hf&oI%m0?@TE9Tz{w={Voaw+ z9((}RbkUB+^_FBKf{(Tw07rl&?FFZUNbPvVds+Rg3#}5 zH;+8Cn96FtRF%Vh-D{WMtqjMy}%f@F&MbWL4mEwx=Fmoq$zZ58zEmd^t{2P^%5p5^h_akVcGa(Fkf zg}%U~Z!?@|<5rsG{xV34|7N1*p5 zk`&1++0D`@tl3rD$aU?ysBJ|UqiQ27Hysk|-o%CZ`f2ES}I>v{i}j#j`T2Vq(1?j{8@1^N@baF3c4M>W82Fg((GIwi%Q zztNxcm{iE{!mUFXgXw5_MrmaU+la1dB5!abq*?fIqw*T;X57lRP+2vv)%@EDNYkJg z66rl5i`?Gm{;1vFSk|6S_TZBX#})QDO*G(dcz8!tzFjea9*B+^271@}OB2;`jG^)_@$OeKn@PQ2sFKiCw7OqBcB*cjBw>yF*UdgH? zT89WZURYr%KS=ok2Bj8G#<{CiRFv%zW`gO$Mey6sE7Vrv2~NFy(979jZ0bQ~2Zc@v zawe^wT#W=R(iL{q>Ke#E@c?l|OpoT2Wl7UThG;NQC?IHtMt~Ijmivo6-E4QPDB8}E z7EBhC9?(oBZK_`)Q7L2|ky-9HfyWFMK;%HSWYRC4TgJO*_$Z(|N6;a^I~-3{F_vN%efRXr1B1?s@eeXi(xR3Z_9=qT1!%6$y%Eiv8 zwpWk9o_jDv=+bfzE0!m*^1wpxQD4x6Rv6x{bmc|-q&F%|!K~xRlScXbufX$Hf(V~9 z=68{biT&`Ru=!P4S-l0zVGx99zYDL2No~<6*=o)tA#LKavo}aHSQMR1|2LXzBhTDN z&E=-AOMgtxDurH!_w=sA73=pwn!WTig#+58D+gjfd#4fJ7@1FWI5>JQ%Sr0UlGWxR zY4wAnjhp(0DQmRO!u6j7FCmHLX^5tN;_1JbKz*i}?JtmqzKXUOy{Y2Psi8b;R!brwL8y%xq*@N5D5-$1~ww24X%~awi(Y1oI*I<-|{Z-Z9 zeouC{bp(T9i2I9&Ko>iA2;X2Yt>X34xIrSm*V_qItJ+kz&lmg9iUkO}|TMem+l z?4#9Y;d^Qq-N&6FYvvICNN~)Gr^e%(^6S*c@tGC@-}B}PXOa8(lV8TmrwK)L%g2R* zyqTDq4#(6@nEVcqg~C%4Vs)ms`mgmdB549L0Ed}tn6eJ9$SZD;k+%7DIiI+Ee;JhF z@C(6L>|HJLg8-RRm-jNJVds%K7VY@%bN%5P$1 z02Rvomz|&*S1Y_@n)FhBVPmTGD$N> zI@Z&L^!^~XQvVh?MU~W_IW?IP=cJ2vMd!3TvzdAPcs>EiQeZ2Q9P(|*Y>K;-q$_`>pZBT&;egcjs_6Ux0UEy4`B=do2~Kn}-u5nN(j;rK&Z* zC(hyK@oFQTXU6ELDyX8SW3jfbGim1($fc;YZ0GG;{V|>(YTU(QbOJ)ALNTs$oqjtM zxydE($Koj^_oKD#cJQK^t=4(n-!S>?qx0z2PX3Cbg5*>45Q0%QlF(mxzw54Skg5Ob z3gZ|IA5p= zVrZXs?UnWaY}l;p6Rg?!dvf%^^cw65YtwMCtm<#WVkY-Fn7}S4I-|}Id>$>_J21FX z1`PTf&qz*x+4&FNHRSJnS=Bc_s56~DSV{XYG=O%JOTk!5cW-N9x)Iou_U!WoS!@@kUL{=w4n353I%y9@6=Y>=H>s$C?|V$+W#8?LMbCU6^vo2Y9UK1Y zo_sqQu`_dc+wy#8;{4=KqshKM9KQPY#X0`=8$c+9OHuc+e1_X;(Kwu^?SxGz+TKBv zj~-<;q?@5Tk`G{M7b`0g&j$JE`YIp`yHL4lvoyjj((B{jiTBi(S|afoGy;X126qNY zY4g#YBNVeu)L@`0i;r=D_hyWO!lo!jsh2Q|Y&i}zng%R)n;p!{nnsC3j zHzpg6bcYBENOv<4knZjfX({O%(jnc_-Q77_0RidmknTo!rr+QH&GUYr!S4ISb*^*W z=XAX#?UD0DvFk-|rv8rC?9g+b?mAPr{bzvg#mj>ou4k!8KVhkWOyJAmCq^R?wow=C zuFLoUk>HG(A%{H<_{wP8y;sJZ&oAy#&P-6p#*q(O)K|w>`5CqavZ0eZLlGVA?W!6- z{ygp2Z5L3mYKX;A<&F*doWa?x!W)xiv&1By z#LQ!%=9f3RseBnM3i%}`jd{*;=vn+@fK@x2fKFCs)9raJz)YLrNtif2$m=6&$356f z<9Fc+|2F5RyN>O4^K@tkZKR+7mD#2N?Jx;nvt1zzuu$89%vwqY*hFhW!8W|an_(4&$pi7e+F&Q1mWpLd(SuQmsm0o)9 zvdyw6FNPjTkBII)KVskN#Zh01G7oXF(Ad1BY}1y_B6`wjx1JFiG!Rq%r2Fk6fqs=6 zCd2^u+j~cgJ)}Er-jlhLe$G+IVDr6)9w9#JfaiG5%NMaKW^yB+Ro^f#C;4+UcyGUH zF&F&(7&g)nJL;1)%9SG-k?c6JC8&5Lo_R_9*bA1kN%{G45Yl>AhE7eT) z+C@?xBr&6Dj$ZhXvEd$bVq}C@BaH!`H7*9}Vb?)Ok(h1TAg;Vd@!Y=MzT_wpr`L-? zCO$nc6bnE@E&k5nHNu`|hov2{pT{ZJN<*3EK74(z*kg6J%`#cB=Cl_{jo(D>q${Q4I`s(J*{T~cz_xX9GpzC;c0WiznYxbwiABzWGhMxmxT_5*rDM+pl>x+VphE!DL8U?g5Br^<*F~AIzJPa|+jR{v9kl zUldNbgt4klQy?d^WSCmz&Xg5x$Gy}0qNS&wJv<``)tqV+1PL+fIyb0|n5;`x`706k z;ZA$22JQE8JKfzrco9``KR&$0<0%X9|MIFB-HdJ~s%zx6HD}8~vWncmB$r%&{m9@` z-7uh2D6;-7r4_IsZV~0NfM+>qs8}@(EFlMpM55`2u~B0L;DQRgIawA&8LfV+5PzDN zzLQW1_QP!|x3t#j$(%^QtO%Dh!w|))DxX6NK>?u}!`q%vn%gQHgvkZIr|JiEwxH{9GxZ0@XFhl5*;u#T@-T|iSHy^TEN;|A!#1+09eFwt000= z|NYI+!HA(46X0>HAhvhRbR3bm$*99iHCxzs4l(bjlT|)?J4-ll;lFzcTh+8t@&yuBUz9l`~SlzkFM?cQvJ^ zUShy$?lF71q?>*&eQJ-U?s9LSeIE39y>hYJPCAsF0>#NqX79A*qqlf9mr}p15a;9& z==c2t%=+0$N+%UPNDY($xXJ%bW6unayzzhy4mHB=puOq}^l>2wmqh_trudaA-4MY7 z0SU~8NHd^=;t?PvXb@P}o#%aL13L`(`>_CC5OTCP4U<{VMP~Z0JQLiktQ5D%WNo&B z7+L&>bt+;MfiT%i2yfZsa(gLZ@uhEsfBg{9Nv2gz$Tp2#IbGO?R)a4=(lc>Xb4QUf zir^ELBR*qAySuEWT5w~9D(8wjlfr!4&SU*kiY$3jILWaVpDt_2FqF}ATK%PhiLR<^-)1)?gm9Qjk8M_xQ6uM|b9PC$}M;Ed@cvP{)$v zN^7;J6hZZv(uz=L%mm9{Nlm@vgpBXzk5)Dxit$o2wTPar!Gn=87rFx?d_ReK(QNiv zWQg(Sc2YY{CN?7J0BRBOmb#p+iV&Gj1gQpekak}B3lpkNHrllWQmW>}NyZFe5R^h# zK>*O0I)ZrheQiJVH4HH`6aL-O?Gd0g`UKAVJ>#6mN`pA)m@YU$D{+54ma08wYJJ@M zUC%L@4J7bIe9yP(qPBbl57g;Orrkcg6IrkWXqfnfseY$Ag$O{hDD>NE0?)2?a+W)L*TOG99 zI=hwY-WPw2>dfuGuq-Zm{>4SY*~>1k#L=6#-szN_KJryDQ}cO=M|-9kN$rQJ8MjB- zB$k2)k^?@y;p?<=dqx#u$&|B|-*5LSqcT;AMl-;ybLtxqNRjoC$E5Vx@UM3o9hwiN zJu-y6tUcX~di( zG^SRTbxi2dkL=P;IlE83l6$}4tGeuauL_QxVZ`^@K@2vvG73_ zk0O|SC{@mFnBS5AFB$~A0v*sh#;hQgh0H1+Dz??K7>fb#0 z+yf&`pb9dGqG2k-`cYN_)hw!P zR_)Po>NBIBP_nK&+1%MR{^1r)Q!r0u7g8VDBvs{dWdf(#G~1CV2=bfnqVo37d+wSY zXDe=eJe{nj90}bYseRDhO z;yE$Iblz7(Im%spe5&Gf1kRkekB4R^J?Oc-r0+14M;LN@9V**ZOAMU6eP&`ijknH= zG)BbD2FsRwJH2PBy^QnbsD$#bzPKiStMTr_sJC7Id|22WB50%h!};`pghEo5jIm~f zoIi`%u_!HDPsj<)LBaBA3!QML?p01%Dxch+t4WG^0n7bGORFKnIA=G&n!%a z{J(4z;5TUolS#4mi}Fi{ufTht%0`?gKxjT@)G^Qp*+i0>?|(iD0GsIkY+`BZc3$$% zaF&qEa-FbI(`;~7`1 zif&70n&?VCCbeE3DXUqH)$Cju*Qy6M7QfWAnvfeJercL$bC>*Naa!X>TzW~&pi~`{ z5hn45=%rf3P3(m-yX1>sN#&N3`-NYfa-4n{p}E%O1Y$G$Q9f9AGHNv^3ZRFlELCyk z=ykX$lgJiKvwCGGV-IS0o^B7%mJdqxO>@nPZ-7Kt4BN6cT*x@ob+?lF(h4NAzl5ov zTyI>|q#O%ZMEw-aZDJqzu~l&10ZOK~hz(yAFX$=EdC7+9#t>uq-K-l*%XvbDc8#Wl zPLD1GuHyc%HHAg|>}3A{X;nK5jrwnV`)m3_U_O=XGcz){0hjHs=94a-Rbg1eJ^`!{ z<_oj;%S-jX9=D zS4~8WBF(-;gj5~sml;)h^`3`h>h(Q`Z5Xw&CJQX~cUburU%~SpuSwA`&;~$B*u{nj8RMGxI07|<^#p@j9!V5C4fuy8%Bjz<6hz$~k2lvwW>Pw~p0r-4 zG1zR=y33=Un!fERoZX2_!*xfMOs&rBHd_u^B9v7V6D+l$dAYw02!bl3>!H8!_3bd zMu+&G=xLHwl(^%*cDNXf%DfXS9@`JKDG#^Z>ZUc#l$w`!F&@O}vq9Hy<3XsMvE}mT zM0{Hs^42b1`oS0!J=u}{`w1TwF*(bzq?NbKYdTzMXA(o?@2hyevW5;O|KN89s)kQLT;)3H-FlSD z1@nj*n?Csr6BQ~@^oaE#8ySCKGHXh%QXVXOxD}i#dXm+7;k?vSxqA`e92v(a1es=@ z2@Wisp8k}fvXwre7uU~hZX{g$P*_>?YkdD8*-29QLuA|#rV(c9W{bL19-abPDio!a zEJkbe25HCf9o;&n!InD8S}02nnO|nGohM=n7B^G(3)c zcszRup16;CuN{8xj#c>3dT#p=>w8}6;rg!nam%ie*hp9xJd3I1zKlW-5<;~H$e>O= z44s?Tho3!aj}})x{kVOg9FVs-6ns_$IcdKIeFucl5`nyG|H!oAtm}DuUGq3wiTbkS z*O;&`)>m1~3GMK{Ud|h6DQ0(V)Zkq9=|w%?`k`JIzjtw}<$TRrTF;HO@hkSjDR!9{ zbMd%e?QQu90+MOoS0}UNd+aPT`rC$f2YNd7>;-UKhigt&r++hcKFbnuc{(qsTD?_; z%n3`<0Rq3D9AREunvvEk*R7tu>Z|yaC&OKZ|6ZumVOzXB&FZX^*CeMk-jv-hk(JRj z0vVG?i)SLh`tyu^NGn z%Q!kY=Si5bx6FIEXvKgNxrQWuuH0bin@o{yQS)>v!Q;9R6Rmt6eYT$^xp<>;fsRPA zKQ?;4yz=ItqjLNqZqp?eY560XE&2{aPm<6=dICa^#08lhw?%ea#P~1bLy4vMK-wG4 zo33fBs6yZqPV4UXqD@kW)B?gt6DKKdB1c;Uop6fWGfsaYKgk0!z&LP!FjVi6SG?VL zuV}QAl+@cYZ08ekiShEM$CLEsJ*V(g>{@1jbN@lmru#Zgncm0tr+AHk;oINZ<@i4| z3u3KKFCYqPwLxeg#`+d*lJGcDgVvQ$)$_!TNKrf&>b=_yA@u?WU5bAFj3DQ7Jae*7 zhG?X<{lj4nhNXC(4c2DLg;4|iyPk|#C3T%sDLTDUy4CW|k==djs5U7SA<60Ah+R3S z&)0PL<5e!dz0o05mdj|Womi(5nI0rLlIyc=UUIy&y|&&bJUZ#UwDj?83BDtmh^5ci z+B(wEK5(`iPF(s}ZQj3Q@^d*)qtVCXkiu>!mUB25Sswo=W~3v^A@01PI8j5K;MJ5? zJQ+G@Z4@expN$S5#Yxcbn?puS1h6oQd860X4W;Ka@`xYr4?L^He{|m<`m^uX3i}3Q z0&HGPohGkoSlH6AZ`<#a)JHB=4LgVg2{8K*q)T|Tg!LQ2 z)agP8hgNffl)%{IK%gt6zA8~~U4T^&C3)OzwX#Gn&Sl=$WJQ5H&zApi$7Lq1A)ZRL zKGAsLaB%iCtd)nILWi87L{Ig6z_zmvcTnw+h%5JA#n?<*{Y=CA~fYlXQGZH3**U`_LBcV>t} zi&vLjS7^)|t%X-;XoVL5!e7JBYWaowNPg9PO200=EAS>86<>J|cZEBw;@e}vCk|BQ z`uR$!^8#6`{wo^aK)V20Xi8+Osi+GuT=)iD3<0=aDS`e6v&uP?AjmsJ-t%Wq;ISie zeQ9C99&*ylP(i<47`-|4%fFJ67}W38U-V_TdekO0MC4`BlI-?gT-{ZZ=Q!i#_intB z>zn+&?a|i)s@6pSwgnN-f?j0%R?L)bEyo9c2I;zzwX0Fd8lt**^6gnUCyoK`Y$&@U z{(eow!7r_^0V>8D5utnY_XbKIfrgCACZSPhMCHng?{n7+M-H*A=%(X|jx_Kn_wpJ~ zwxt;v>G`91zsP_a)p{p$=smArQXFj<2$?rb7p%~mH-XgW_HUTsv3e3RB{o|A!Q-31 zcnL-;Q@P|6DZbqvnF@IEFeUddFA&Nk@pufXOp$$>S$ki7$X9OMR8@szD&Hd!!Z0L> zJv~uik&W0NAgEjv!LCBEf0Aq(r|B!Gma>n#aaWxsE#;^-9MI+%gp7+UFXp2W`UV3* zKO|-+k0P1*S^Fva2?M4sM?q@aWk3TkBk(`QOV7V5Nq9u?h(-{8B(+DpFXjqb4E!Qi=F`pF6|* zh6<;KqG=%IlgwM3@!N^hs;uut3I|KsK`zDl2`^sh0=l^ zb5P<}lCttpG|gH!4wSZ&j)Hf8&mPgZshtSX5|->GWMUWX z(0hr%vJS*ru;}-Gu}~)?Hv8wRH8+(=HeZvF$eZGU;)q%wN*sa@o_)V=K6DDO-LusG zPRX|qAB9;TmfCKK$vbb#9+w`FAl3x=+U zOUS(%xu`3w#Rsk#k_kkg`Q+RXU4XQfYQVJ@iKCNd?}3%?cGy3%4u2)N0DO0GHCc#t zp#0?XrvZy)WxZc3j2xVb?2yZMeUA;l%`PA||balvt5L6(h5saf(#uhTG)L^_i;G^KB1wgy-&yB5?Z*> zyz(D7*^R;HG*gS9EbP8#qd_NF77g7rAVzTqYrSYd`UJXRc!_NkfR_FXt_9QJrRj!R zu^HVZjrZq+@7H`4SpfFDV?^|}M8W9sk7)KC_iC_#|C}T58A#f;r%11W1hP||%x&=) zu(DgZ#Qmv-aiYq(jN78AHY&eK8WN7#8~M@zl&;nKbPowXrd02*>E<`~RG?a}EH@9E zE;^QTKa1E9**2*cBplK3tlpOPb5y^)W6VgzUzGkm5#(O?<;#RO>Eh4h!0NySb*IMM zjn>A!J`d~9M_(5x-#wC)%Y|QOp$|CreDxlQ!w7gq;L?qaaH-~ z9H7x_|0ji%_xe|%78XmYUddZoifu~*(~2FMLG(^f!-P+>Xx3AUxdiIlX$!(p`Wa2p z_K2Nk>T6ccS%4ZQk41-uCqdcr$1O+#q6|?lU1%S{l8<;-n$`Y>utY$Z(lK5SV@E+# z=SM)W(Si5jpDNqx%v;U&X>^Xrpcn{6CJC1X>wwfHN9N0$`&+ zD+po=GS*2W7*ioQ_{MjlI~OBX7U2U@!r-POF~KZBd%S3hEc>OvP5`6z&E@TLMAm;6 z?w9BC$v;7{S@Ad9^T4t?$j$937&Z{k4CjSk!$lCa;B#<*U;IbvVq2{TwA5FX{>sb%i*TXh&<%<2lEqDKH(F50ZRueCG_BQkWj zF~eyy7dvI`Tt_JCRW!WbSX`Cs=ZM%z(wU9-@TOL~ui5nWt6M$u2ysSi80O)*I`sGD(gK7a%16UBT z4w6LwgEhuOFy*^mMp#39*N(^RF!kb!tEcad2_4C#|Iga;rEIr}wtQ6`zvq)V`GY@Y zdRl__cgY7LbvEwmX9h_WUJU8Bn3QY|EKbT*a||?)ReNAqi>17`+*0~?Fyd_X;2C=> zycoRS7-Ka-{%QNR7y+`Sso8L^{~etXCtN`vvI>Mb$L(&~!k(;+i0z;MFaL5A^QE2f z26pt9J7s4!nG{>8JU;$#3f5`7oKQ_Vi!TY`R_6OAOUr;^k4ah~QH!*Ye{5K*#@eQL ze+5}*Qb~*Vq`lD*N>bJu7zh_XAmz%*Iz6+NjYia^v?+dZQpQb~74*{tzd>Bjj%vG* zgZOP>r&oagIUOxX?^pEY*gL5Ey(HVo%miC7Jl!-n^lwx}crJ$$H8Jl%6K_Lo|M-|& zKwl_+L>aOd_9ywTy)C%c9eX6SES58}=-^8h9D#0;p5Y$9;|WKkVtqp@baz%fpW7 zgdMsytg(ukMLY(2zJ>9Rw)G470C=}J`_0_6kEAe*eIkwR`Lqt1Qy8QgX*g8PsX70g z{or8JmZ(H+D1MQzk7QLr%b=H&ts~eOcbrRJLnaG zpm`ZoNM>(^Pr#cAbpBr+#vKCO^Ol(w0IdNE=7YdtfB=vH76o98miU)Yq*O6}$1pvT z1V->K!vQwdJB_JGb~Vo!@j%< z@Fo9|%J#eqLy5t(?Bfmcy)WDsQ20(5g9(@jib6sL{s#n*jA0YWT6Q*orr&nDuzgcZ za0QYMh|6wU!RdcjM*udF`>3`4rW%_WcX30nQS>u?%jZP0OQY6|+~CQPKBw6D>WN_N zq9Gzx*NM#90jyG-C9=K4vZRO`F6ph%&G3oahAh;d5bjXXAOwjdm8HjmxOM4|u<$i+ ztTC%?D;V?Si>z1hU6fWogo+iY&5KU^mt2LCgBfXh7q|*u;}{^V26*U<{~zTF1DXos znbamfJn}S$CpnBb4P^HYK2$Cvur9u)VPj<$B1&h@eu(v2`r$2@&V{D_kw~kT45Uob z?(($chm&7~gZ#Cz5Ze9MRO*S@G&t)@nvriXjq*J?;g!p+uxp?XD$zgsK8uom^+HM^ z^MdE=?z;dg(0@VTIoJl=?TndJB$txD621S6Rs-vkUOua^vwfw2FU@6Yh}^7u*n*B~ z&Gyeq{ad0WpeP|%M$Ahw<(FurqnYZFfr!70Pn`9$xH@&sgIf{!aHmhaO61T`h7R;0 z7zO?N@$)9D9{8@W;2v3T-~t z<8qZ8DCq2V!}d<5ovpS7qq<_Zp=Co?6*_rWm0Jg%PmTyGmfLR3dT-@;S#?J-eJn8QE_aRV%bsFgwLlUcjQWA^3Y4>c6 z^^X;+-6B8f3|vCNsa4AS>yB{M-aYokg122}I!CYmd9)G6!Mi$ao5|n>$ZxEZA^uYw zHqskht$!^v=m!qC$WS?a0?OPPGO*_8O``C%&ZF%L)#0DXqo{(>W^cDYA8*ELg^vVO zBFpO`NQ7AmPeZ{3c54^sp{y0PP=T3Zr>d|N1kAQt8I&m5-8e2n`zhGJe)=FiWVQYK z>Z{dw?&PVdHl@~PoyVi9^Y-_*+-qwiR>v}XPYH}_TUL4Zt%Dhz(UF|H)t~lOg9u90 z{t%X2hJ&V96&FhyMz%aIWc2ym#S)qdib+?VzzN)nK2xTfqKt~tpU5qKAj)cuT2VKh z{LyITOVUOJ6P~E*{Z%5WQt$uz6xaL|zYHmZTU6SYl5EDh)e^w>(cL(!&s5foT8Vn@Q~tik1CtFWoE)dM;dtnHKFH&pk;lF`rS50? zANc=9OXFc!b!xWoZwmNln6A?`*ew!`l+nKCU$6Z+3C4$a?37?0q?bTO^DBVbWIR#^ zvN%5o_pjYj(-8B8s63~k#OSTbYW|=-mb?_jk|A7wvCG>zi?#^a0!FV^?`?<5BOoQEb`icLR1 zeBPaS!{{7&yj(CsDVpQs+fb-6V!x-Jp7Er5dF&&z#jO8U!fZINTrV+ly|IT_oBc@F z8-C6o9zU+Z{40s2E5-s08;`dQz$liD!uA3K%XT68qgN<<<+Jy&5tZZHgYpwCGVC5E@lUY`*&cEEyrDD zuK@M5Zr;Im{+)vm$!frZCX51Z4ka<7u*X&+T=le@i|cv$e|$APs2alxshxgmL&9vG zmtS@m|23m>#Mr!9S9BwOp%6)SJ$eG?w~v2vUWr1shQfS*GSI6smSp5^TU#fl>K|#e zCXJ{sY|Cq^^)8CoH0+&Ru~E2A3`>u2&!O8lw5#YoW#sV44cK_mzZK{Z6sz~TdzZj( z{z=%jxS!eEnVc~+$5vuI`=@nXcgX9#VOcf2* z;klD@%@z$<8=Y~Ub02hS+((Y*;}|>@)C(bfFULDHYiTXt4YmQWu+&@lPbfDmlbRKPn&5@nPEE1_X*Kw4E*$Tp>)O%F ziZIqLQ)(e@4$6lQ-|;#7cEhYON%6ie*bU58kPZ%{34ym`!bSSF}E>^Hg zC$U^9xh>UI3$!7~_!2~s!$`W{qSTaJS!n;0NGAOCiY9@s_8t~$(6ez){Ku%2mZoG~P{}Obl*DG~U$YByjhm2_7$NIfiE_rH}(LjEbh6CW`UT!D@ z!La0cQV0;G5ZQq_7=jdHowFHK$Xi9Ys(F|Qw}e~WuA=6Ql@z>CBCr74KYuT%q%$Y? ztO1D?FkOi4CO(b1=sppFH}>&`*UAJJCNh_&L5l{p;H( z7y-wmTW78Z73ohyj^Pe3QobK@Qp|@5g9ySL^Mf{fsG>aO6 zwCFED{#W3)c6Jo)4taJQS9aU z!};vvjU9l}IgnkrWP{9=4$c<)BO6P(+sZ5Q+&(SBa!;ix>@?k5Yechk4GDWB(cxlDy4u21u;wiP@n4% zmsM^X1D}QQ#92zzXRlFTlG=}|eftK5{*CY6I^mB>B1B1lg?(1v4`e#X7wmCa}DtoT954oUutz;uQ>3-NYV7L?N@72eq-4K zOc{rgr*Zw>#$!-k3j}Q_B2ef&;K8d)C*#)a&B%0(Xf(z1P&sh-*3yf6FJG~(CDi_j zXd+&BysSP90!B5*2yh9g5ox+m&duw4rb|;Xp1V{yk&ML9uctXvx<)lXUs6E_{E`)S zUqbV=_wWB`84FBOd6_myl@RkYfUYB+sjoU*)elXx7$e0pU{~Ku{~Nn3k9XJqIPlWH z4M7E}sPj~*Wfg)89c}|fnkpMpm$>SjKQ*^jKkY=VM9Zy)NjWf15~HAJaEd&7L_7I# zQ+eL7LfTXPZhm@RaVRx;SDqIZ&Lkj|_T-+j{h^P4{kkObj8qlrFEFbo(K0fJ z`4fey3+nomN@|q6!r~7!XRTTkAUJ*^4O!E$5g%~syXF%m(J~*{AUa@&D^R~kpo6Hp z1AJqDtVqxBbB3Hb`(k4HVi2P+~t9f+Fv-!l&SefI>Mi%|6a9y%LsDWolbIn4ZpWaNe9DZa3Y83bO7t z9e&C%5?g9;(N@{m23BEhxp(yw(Of>FGyW$~3cvs4;p1?(uv;BP2J-=XvV;WY?W1m)mfMRH0t$mTYFJT44!Epi64q zw{EFqw}iw7t6=K$+u4J6y}VJX$bfNO0EQQ+V7$~@j~ff zgQz~rK13(+UMQ=8->;+a2JD9!o_(xx`r*7R{5;DH4bm@sa853ciPQodem!9TuA=ln zIv%xq77X@*pS!;>79K0pU7_@t64vpTkTIcl+cuB$S>-{!~6YReQK=%izjHAS%y*8+wc zFcK7E!W7_W2%+Z6t|4qu9aKhXz3B04k51QFgQZtirhOJTLxpq)_#|!9{(C>=EI|>W zKXm>O;!LxDIR)6~m!ZDQAy9opN0c@6Z1%({)GBg938V}zxgQi}+sDf1C>SURm$=1b zW5UYqrh_$eOyk*p5wWJyC+_!rDYE$Lap#3-Rj5&vvG#b%xvzcVUdvXP^|O3e#?@Bt zw-KpSW#XKWtHh3&*#>t|v|C422;?xqSMb}+hW3#%T4y|LtF$j;mRmJ7vAf#jupMva z9yk~19*SejMkS@E%{KHs+!$*!9;djtqO=c0EB%df1mL2BEG73bjMaNV%q*mB9aw#v z@|cqQ-xl~MNua)87a&j-aEGL}qZ%rf|Kl4BN5h4j+#V)H7g;&T`f^0sL zq(A!eW(?^!rc(2Bt7EL1cxq$)E>~Z?lNUFt1v~Ou8ZudzIhE#vnj(Lu!bMj*)Q*L>Io8GjrT`f!Wa+l-77-Yc3R-+L6 z&`ANmHFZj;gZhzO;m_lNzLi#Ei-+}r5Z#ce@e1zUqM7botvN~O@huT2L1=Xo9)7vr z;=0Bd`Lam@bF`2WgE|sA4%rXgf*OshvB5n1dVyD34*IE5$;-V+?$ueFo-1N0sNE+eU&9_PhpRmjKzl4sU`}*fXoB=0i0D? z1Q z8@d)Y22vPE7TB>;R=N$4CdkdoUQd0{17<+JlSFAB=Yu|iUNNy>n&9b;-oY+aM2)ys zo~M|%_5v4HCQo^ z-{B$oG&P{RzF+@bh-HWAT&Bo(5moqF6m z4_(efb)wNiY$j`r>`M!1%(Ko_dDLar5t~dp<8D36m&R{R2m4$^L{b7!#J`9C5(@N^ zr1M9__ACgc8m&Ftm*fCSAl;ztYr$|n0-WV z&_zE&LCA4&R*4)Nk_)~pV>}sUF~Ym3drVywp07$Y&_sl#YXY#kDZzY2Pgri~H%P?K znh13G@KGJWHw&*fmrgI`&h&HhdRt91^a~XCIXhUrG#NpXVz*1|?s-EspOFnfH%F?| z09KGF$geFtgfN;(oT*@jgbgjr_T-$`3Q|RxBUerSM`X0&4{9+HRaK=s{t<7(%D1>N zk6(Ffw{q3XDYluPcP2>Hd&`NmU&mg%!;SA-m>P!cWlZ)Z_N@?N-oFGABVtwGF{jRM zjol@#gf$5o(X&riH-c7uH+JgvWS#>2!@4awR@W`pdo2c;ud8auCAG{xsBP&FVj6fY zy{jxiW42R)OtYvWXH_xi)i>0d@rRlb?#u3sl=Nd` zh2XL3c6`}Gh%Ac{{CfYOr>=MnZ&p4_Uhe~2ihksP{R<;r9**8{ zWXu8b0`Kq$vH5&9|BMjEczj9X5F_v~buBqUruD3|>g|n-#ncR(wWe zFhCTkOfyzjYe4zdDIvW|xmT{oK@dI}uDYgZ)h>lDa@_8nRz;V6nbSP-NA7mW9Q7V) z)T0_kp|BOvs_?o(%my=Mk0TLlu8xRp>gVI?rjW|UK(9Yrehi5B zE8j$jDPAipSeDFPQhw!o-NQ#siJr>FqP=yt&V=Pf8N((OgJ{G`%G|n0UF>hJ1Cl%OTch(*LsYbwgdYD!rG3j z0kEMFV+k>GJg*@#dgP5thgBKos6q1kQ`zbp}*%i>a@ z^;#vi)u2u#;prb<{Oc>x#3v?i@d)yCA%A!f4_O4Z9N!sJOJgwgPHn%DGS-wK(evSi zu4Zis!2H7qVI;l8PSD)8u41ij;B+luf*j)k6(326E{*~k7#MTj5Ip!o26^b$;0wcR zZqQCeh^!vq5j2fNuH_8y05Dyz0L+l>A#6B&V5OqfwLjXAn1DdE%=G!B3tw_C4%W?c zUD)+52HTS_Kpqe?W=8$uII_}we1_9TCOzIYcoZ*zczcNfD7wNf(%Ese|0c7`%N32< z*B{VP%k0+!HwCQxc>!ZJBUGUKMogJZO@NO-4Ut@Qm$E@vAJJn+0BG5H$EZ%8v**9UkN#Uq<9W_Lmw*L97`4jG0=sq0NzIgOL{=b|yFUELkMhL3kr@ zsTxtt9=(pkD0BeN?k<0Ff@3w~U=iL-c~e4%hz8A}U?V!{R(~l>*MeZ3khAK$Kit(1 z3^@LUL66}kBPa+@kGyT!uh6wPtid*-q(8b5dL%Q-@O>r#RKs$BzTFz0fxcONWrPN= zqt68J12jfPLHGru_Y-D(Z}yx3{L%`>lt(}rpdGMo#1iy?JPb}Yj2SaU9Mj0k_l`#M z@%X`Wl93OYQiH8Mv_*?-$5;eZ`vAt5w{ogN$A6E@&6V%Q7k?II5t}Wl%!v`nOZ00E z;WB>GR)t`)M+{nIHA3P6nz`+r4p+-sLa8cy_^PGp9_Qkcb>DcV$(qWwcuKPUCbPpw zm+@N5ZU!O=QhP;$D%oyvL|1{xst9vJNDvP&#EpX)v5j@f*=0yv=V)q_j*!9(i9?{^ zPm(D`)NKAQeI+*WL#<&Fa2!DzW&>g#A~uldef;t#4?HZac_6vHqc9d$w@{#AY%w1R zwoSESP0ax$0yzBVKy|*E@TqupHR}g6`2jc56^J~ZG&^TY1Li!%w~Azx$0@V`8;6T$ zJ%`VK!;9+#excj^jYH;s_-!QkUI3aOD|JG`Hd>E(TORE?u)vuTdyJ)Rg?_ShlLVo} zl{v;@{vm>-1yL$MiUJ+Sc`G~T{M7%cS0=Syn@Z%pH$B%Aw`op zOu(X|TVys&P#X=yFl(rUTp<7M8gN zfBM(dLSY5R&Ijd7BmX>IT9~ZUyf02iH!mILKQD3`h$`xy+AHE=_1$&qTAB1=8lj2u zOk`EM9n#Qnmq}DSJjgry^XH9)NQJ)sp{{MB?u7PI@Y5l%@kVPa<0^)na7PMNc+Uzok_tks5C8 zsjRH~u7#?^?}U+MQUIn#^lYEgoV_`FyTz8k!3ucz`d@n|WC$8i{X{dn7HTtQ)y81>^*Po#gIBf{y|WM+nL-_*uXbh)rG#lH9@#e^FGAaUgY9|j_6Ay8c@1(H2r z^etsM4kKU%^v3TSFy_Q;Rrtdn`BiKxiL6UC{nb}l`B8k?_-BJ^`EiMa)zkcwmn6UI zI{kD^O65qV&=I#nq*$M`8{%c()LQxe!kMtPpLv?M7Y!8FN$xI z)6El;G3C{S{ZpqSnF84pVNS}=AbC-(;i_tRgqrwVF?T~U%>jPBoMZhR7w?*0`+W>m zl&Sd44&Md81M2*`c*b{<|75;uNKFnt{$7BnbtNs8N!Qf+-DC_k;b=*slWio?*@Xa~ zy8Ta(`!(G8_RmLUIW&PBTY<}af7QUEOA{JYl~1N=cO~-L zOl)4FE;TJ>JvYb0G5%H`qWY~iDZWmgEbNt1eJbCf*O1FgzzasmEQwVAibF81w8d;Q z&RhAnnsyX*G&tWk+Ns4+9+o6N-URBL5OnUZ%6=!qE`DJ+&pi?&c&#h*{ zJr;BomZWc7M!FL((Llxa*~Aj>J2<#(`b(}`8;auYU5gRYT6IC9r~Dp1WSg_|_Q~Z0 z^h<|343eq;b@(pWpD6sMMyS;Gpd_)(hHq`OeH8w1+QUQ?pHf$R)n0lU5Y;|njx#w< zafj{y#4l5k9a!Lr>Mu!t{A|=Xn9SXJb*x(}{*&sV<%+0G4_#NmTrGlkMPu)zcMCmD zA_|MP%#*(K6_#qJuyb(3X7<$2#LidyCsnuR9y|@&NrlctQSDk|ZdajljK-=qh9m^Y zUs*rW>JdwQ!x%$@8ICIgegSO7=FpP6kRY#hfjYiI==M-$q*+W1$RLv1DJPb$2-aEA z@9gmbDN#2p06IW{N~+Wm2bt=beapl-z}*^DRZoF#&qj}c-Y2eH<9L+k6>J9z@I8l9 zsba6h+^1TiTOf45_!nSB5Y1D)6Q~U{fg5E7d$*Auk-~dzAx}72{L#eOVppcHV;awJ zU4W0uhmLCyjRVpA;r?40-D`kVUcGlR0q=uXb%KX>E zjpiZYi!i}sc;(=NAyb{rTv{LB7b?6!k>Nb($X!@SZtg32{WRMqgjdzOGfaAAMg=RJS&IiZd;z4w^TVoH z9Rb^q2!6dL3i7?Hgk(13Nin}kkR zeuyVkSo;k<}vWkWGk5uopjn6ShWs~ zZ}fEzO^GK>5Ha=!h@mUcyy@v+^amg(pa(mmGygD;apGP#g>j9^h#9GemauCL zbmJnTD)R?6^-+R;17Ta0wZiu$s}AX%#9;(n-yvV2Xb^Keo|bhJ6dq8OvFQk#hF@MB z*snikqeS4=FCrX_*YT2U%L@?$&;yYOJ3b|Xpg=UCG;1V~V}BKPLPQ!2@X=~UyVozZ zmQ}au8<$tsn%AWK;A>w|WD(R8k{SO`eqSi&P^v(7K<%M%ahx^bPLMa^HTge)#Ec~dfz8;Eza;*JHo4`E$Jqc`Oi;w zX-Qgat-aO#x;Ll$0a%&Z1MAA?KX+{;HMe@c%Wk3*;p$JyrfFC^hWm3NfZdct%ZS`K z-;YLead*bFXU42HI3M~mLVF_<(nASYw@_(`@nDPzEjP4_f_KCK zh_N659YLA~FzQy8Osich?_=$oSP1k74ZhK1Xx?}1tVrG8^nNb!S&#z*>)khiFX0`q z>9z=PNkoCz1Yifw!?xXKYr*eR1J{4Ow}DRqj;!6`USEOnD*4N&XHQlUZUHVX>IECU zNP+GcM~L87AjZKN&;rN|azgMHP32hy(qo?d!F%I=1b=wHN2v;%|jfUf479}^DR-2G~UlHOv9mZY8@pbQIJKxAX?=1nyy%^r9B;Xt#nFXkZv1?HqTUFnUQD;k~<#})>4fU z=-k91Uew>@y#TcI#H_k=nlPt~QZ!~I!g<)klc$MaYo*DWEsQ276tZ61yZp>JbCEacUqS zF9S!w%wV30S_~d|6i~`$S`i_pnB9#kzA#>Y|3O`ii+J6g)tY1p*kF843^45c?9v&k17(19=WOHw&q%cr z8?kKwZOB^);lL_H+d-Lv;P6g5-+t{5Jb1=Z__ot zmE`7CcpJ~mc7O%q&Fg!&1ATorlBm=dUc9rdq^iAfihW7Nb`gszc-9}L<}Kts=H@pe z8nfq(F~bq9jI!`IJ6;%Wmcphue3?*J>hr8=JuuyZAFdHc(BY=gW*vpHzSE zSy_IIxxsNpvmw@8WPOcb9FsPz?}O2yt$s;=`N+M>!TdeaJb3nO>(|@inx;a@F=nGB zqZ}epnnkr2+Z}$^QCut!=}#klftN!ne}u3eiiBA-h3I z0NFnl1ei}}Qo&siTicO#Ka3>*+`5`ATT-3?1$1qjiNO?5E5}_mijLV?WZy(%@{8?# zXU|`0UyXgk)0jt&yU;5=Zgaw-gk7VwKWAC#@4^bwalc@63<0apNm{R8%KqZ1hI0i=CKB_HZI9 zp8FLpr-#2c5rQ+jN>&UH3&OL^N7Q^EZ6^glKZ<$-J6T;CM#3O`D;4J9YC>*rIBHBhHX$4Wj zQc{D2IGw5Gggvl8l9t`H%@&`dUcrqMl_Q8e}@r`k~_b(05i%)jsF-@|qp+03-*@ zL@z^Z0aNSF(wy&=ljHE2A7DiWuqt^91eJEnlD>&AFU^`sYZTtNR0Va!#lBB8H`?qF z+rE>vGc0l=cwWN&W&3#WgIauq_BW?1A>v&@`&LI5c6es(sa;t5iD8oNpYFQ24F?{+ zZDGE4{>r5JUX_by?;`8N!sn}gkBVr!pV3~G$e3Qb@=et*<-HuV#V;MI ztXbZ;C`*R0umy}Y%MUp1v%1(fUz)S^gKHdmQegKHOx4W^OpcT@S`9rr9PEwCPc^%tT2xe zIulZDroLtinF7eb7KBb-;N}^u)fZpH8Hl;q zZ?L9$&4wEbDST?ph84S+twpuOZq|dmkuoG3i5(1l3d6041FOw}c5*xT2 zyLbN>%=kVzNI7qw*ru^72urnlPC~3r}ghmkwJOn z5C^{k5L3zKcmZ>NrV-1d%KT7Hrlj5Td7(h~ZCa=#^0wm|*pvp7N+lws=RE-NnKs)e zkO0zp3Ugv8w+l+T2;zy?Mm{^@34I+wGt8tE;C7eF2Vnf-=dEK7BJWkP(leZKG#lg- zBVxcga0qMxU|zg7I06W`JizIpXNdE%8BSTRhkjdS=gSPYhha;^y)K(fLYS~yJbr4gUJrjL7EdLRaW5d zJ0(GHqp%29O5hb?edXW3f38>Rt04?je^K<7R}0p2{!-h92!3SnuJ!!)B)UPx~bmwXvv3yb7CzhsA z$KMyavb(`IGf#ei!PGr)Nc3#@qktN8()H_pkAa zbR*V)xAyvzn-5w5e6GDj+e&`@a$-8nwtsmDvu+8^MUEz92UMHfMBD*XjRHfI@k!4C z1<&uXUZ#jt8N8dgWY%*ooCcrq!{cn+aC~2r-=w4#+n*d7hH^WE`yANCsbbZ--}vOn znB8Ahzba%iw=UiAtkHU*p$TiWCT@H!(8mETwM zIv}eDAHQr5n|!k@SpO1WH-_dT9;R^vm#Xrki0i{Su`M0k>w?t8u+zI^Sj*n9^RxP5 za2y}t)>Ia^!d(JZwlE@3U^6ad&~}Em;FGq5{HS>NXb>1gnCCroaaPY__}HFyV3$M*o?;1{*Hc4^w;HH9k*>e0inN#W+gV zaNY0d4jCf&*p_yKT^!t-;DUm8Six)_l+Fu=<0)5x$|j;u==J)alJX9OwUb# zMM3F6wbT~EwG;-7xlZs>I|Er%C^h)N&+ql_jZ^cdoDITBQ3=X5%)iY`kL#k#=ig49 zM`!|CiUZ01`DHw|us0(c+L@3iE5wYEbN5lM{?5qgI?=J4lEqG$i@rqIJaUUCLSWU2 zDN2}NxSpP0|8cUk_Pf=M?tK7lO9vOFe0M(ykG7m#4y-Ov~P5={>cg!%#qKW>W{C7xKU$-T}*`78zHgiO5;fcv-K zBot_Z=F&|1jO?1L*VO{U#;kDc$BU2n^75Z*tyK0?F6Rq!)f`BX#~R#n5QytMIeC)a zJr^i=n6%%HDJibcRlg&fj6#4RENLUTUQvg_{C9Vu1BozIz~)c&0jgO_LC1hQ2w~6> zjFVTFpcNq+2yzHOTe7hBLReaXvfb#B!At||%!8FjQX#~o2J`7cA@f2z+PK5PU1W<{ zBnCP?kw7~3#86-!nm~Ml?$8P4Y<_|L`}$l-14-~#v>E>y6cS1T9_*HAEt%29U%zDr zke{wNNe|AslnGO@Fs0J~W?;ksY~E4hEWr3T0}Ks8>EW_|2;YCL;g8#`zDu^7~2Zkj41Tf_#7-Z|KL z5E;c=F{mLK&;_|*4RD)M;3=~d<#FCgZ0LzQYalI@vC7h<@cx+cj99v<-9Dzq|ykw?`{)8^V9EAT1o1_uIbDP46A(M$_wD&Q< z6z)&P`EO-0lh%dIe^*~fVeN@+3vn3GpK-m9b8q(!1@eRCYP%7UZ-i}Gh()+3PRcgj zBg+u)_mn4oPKMdA>1?XHy+u98<{QMg%1w%o)_kUi$5YYuWl8JNbV1{0rf46flt~&Q zIm)J8Zgz|TW#aGP;(=K|J1|60>%g4w&8PzZ&G3T(mu?7g!OtJGpE3$G`=FMRMb3SR z^?YV^wOoY#gYN{*c=$#5%v@>86eOy+_H4NrXDu1?${jw&xBPVYq^mGLBW2}CPCm9H z=^kvq_cqjE*5EY32F+PzYN>xIyGCB1*7c}%bKa-ntoZnc;h4L2E;aeCu?Rx{&Rnxl z?)zPVQy(vadWI`pvaH$?_D2>uoDbd8di_ zp3c8^dN=)n{>Ij0tKv?%CvZ@vn;Zm+B}5E<736o3QpIqbNu^KTV4Dz>#&~um!L&wp zLUzJr`qtniJS^ijT#NK2*+?8H3vkfbhBTfum;!J7&!8+=TpJ@ahsx4Z@k5!&>4NSd z+>Rd%r`|9-|6s0DYX%rjgFU~@NG$X2&4Aw;oI)fUUNP!n4#k>>xE=r-i{R=IH#n8x zh2!E#eL3Qy4{v^nMOtrME2k@g+~517Phl%Ipp6Udu&uGWOdz7}0Flc&3gQbD>Yk+S zme4n+B1E})4h@gV0H?rrE2^yY(2dPLD?$YBWNT%W7ylb-SO_>hfNIVLphKssFJp}h z_TU&m++`cc1@4%ct5;X%~t$^z!g^|y}-Ll;!*j5Z#T0|xO-sY zJW2k_4Z{D#{IXtS0=gCIk~;~6x=?A;O_Qz@P{l=a6T;b)^crQ||1+83F}qtRW{$&e zROA#~0A}+BQM3`RUxYcT;zH~viC&?PxkAwbl7Ifu67W`DbeA}K9`~8UoqTxx(9gUl zqsE$eg!4F+$jmrNI*EmRhpuH3c9ys?jO&RnXCj$?H$eiWUz0XvcbP`W+noZ;Y7__e zon3MJ@cp1xvQZka=HRhSHhjW52|GlLF*umO<~6Eq>op1px<$DnBY$^1qzV%duzm~P zLw30%{?E`5G}b;N1H{F6#uOT*1bznFr0Pkrk5 zW!y@7Xp>p0drOlu_Ho{-D)pN%pCh({G49w7^j5uk=M%Pyo<1e8`d@r1P z{IO3CB<9M#{QAiWGzy7%CO{0(8ubX?Q(6sdz7V0&Pa@_6rG+J4=jW^ zWItSQ98&`>{AN_7updIDU_2DZCC|0cAtE*GMUV%A?tiGY8^Vu(vlvbckDkgg4`jBA zaSQJ^Ob>VD54*~z10mL1eZcJ*Xe#qO;Ya>0oHysLB0M)szZ1|=qgdk-C_;Nq zv2&%QlJ%~o@8x|40Y3L9H22mRb$B#Fuo&t|5255XS}NbCT+T6`wsnSraUXQ?8QT7T zbQm6Vc>*K2U-Yy?$)OHZykB`PE0+5%5Rr2*`Y=vCV51HG4{+$mnJ~vU(vEi5NC1**e1~_wF>prhuhl*$3Uo>L1@j0tazvpkW8XWdRSi z+MPmTU)x36rf5~h4u?u%!X4G4J^+`jgQhonM#CRV4<46oGpL05B8P<~G#;eg=c0rQ zd-B;5v&CKkl~qQonBmL8CBhY0dv{JEjxSqd%|-g^^{?Kulo9v@~~6{4Fgzc&>L1z%%aiTm7xQh*auTAGz-Bv}p$HBX=jmZ^sUoephi zZAf)s0n$C-0WkP^shL_VUkxLQFhw)L8X-Be?f(I9gJ6u91F024!%>Br_B59EC`ZmA zH)5Uk0G6C2?m+&`7HazM6w^L4`e1)?trLkO`wfIFb+6lA!{l)h_)QAM!Q>ZxCz-rs ze0O+awV^%%v7`g;Bm2_&nnhZDwW1M;5)Lz z`^BFxP)FWOe2w`(`~tFEOCV3wioj)dxDtpg;p$_wvw0ycE?#^hvZzp$zYa+Y2+wT7 zHI{D+6J%)j#v#d5q&?3{iF1xh9ly!gZ)+J$)rF-Tk#KYUBazcr7YIGIFD8l7XTQ|) zpLUO07W{7s+IpQ&g+q#Ah*`J3b)I__WctoFKV-hoQ)0ajkaH}KxQCLV#`oV&x?4hn z$aGPj4qdV&Ca4}(Kk$m#YECZOV(JYIqp_lbVctV(CSOm#rWx}2582}on@a!TG8GEU+3E2)=}M3w-QOA-1}jAF zG`1aM0#pb8C-3xYD5H&yWY3#-TJM_)Vtt2jQ~6`85uicMk!&<*q2%DMBhqkk$t1JC z7Z3W>CBcAq1_upyMbQ6In&6 z5ETp?rtzaP%n?Yt`HwF@9h{&eJHpKg9KqTpnV7n4LR+}|;2>8*m@d`i|E&v8yOp4E z3o0W2o^h7OErq}6UV`YPOM)U)9ez&2O}O`7LP=4HzgsrpGz@U;4rhb#?|gwL2o4)> zOb=#S=12Rcsr;{3hXTdX#@qggLV1#;*I?jTU*%80$D}>2m+M20fa7}PaV5^P|m zd49BIP36&lTre~UK-3I&9R)bB?t;RCwo+2;LJg>s`vIlmm}zCy2VXp?nE@>KJCIQjH}z9!5YH%V5DMNzpq|J;;D4@w0S?3BqBJe? zA+mvkWA?#LM8P?erPWBEJy{4<5SQsdJE2%=R3!2GJMsi(n*#BQ|@4qU@vFY0TFfnB%Kd$?PpxxPWwWTqsJ@_m9QaE={8Wq z28{a+2?D4}ix7Mu>HijKBm!`$5z5Tnme~KJ2#7jDO@C%GK)7NUz^tVb@%`{p(wp}t z$6$UVPP$XDA2yi^VogTj3>+!^nxmvc`9G@!4?=A7f_>Cm(*L6He>4l>SW5;v_4uQ4 zkn1?J&Bhn7!nM8kir~ZuTYP;CUfLD8^L1TebYH{&2ijmE1ouH~lY`$#w>EK0IFdg4P6nSwGRX&o!as1VN=kdY) zrPbBt(Q>=j@$$;D*ZI|(H-G%z%w^s!<9T&vHhUkCZkCV7!YM%D6!Ha;Op)0`!=HYE z{r>ccQd@f{hSPxVP14@+avnu}3uuk38o;8kg<_hS%0>5<;CkK|cRNNS@z6?u{`=6W znr5U>NJ;j7BvivQP*^F5IF zuIoJPp-IUAEo0cFGMuGd-{uZJ+@eKDKre@FZuV&~%_ z?+Mi64UcmD`|So?J$bj=^Z{mUkHVIb{E5*wUqbs`ml|%Hf5x#a=|`U9cAYM_lwmB2LVk>-a*R(&3SXEJ#|k9$CpG+|j32n;rzSsULwTuyIFFwo8k{{kpH;?>+A_kkdpfBs z*@_vMIWBcQIdnL&xa}tNW=`0z)cJsz-2jnJ0NN`Fazhy0tF*EWvm7R7NtF1TO-wgyffMv3{`r z=PQcT`TjbZLp^Q@5`tJnY^hI|e-sfyr$HC!iZfnKBXr$;LA6SL&(nenG2gzT5sz#Z z8B4tB_e+dEj4^s}?mYx0UY-=&asU~-FL7+A*6@fDpG-#;2f2LZ8sPB^h{Na(x}{<~ zLmc^;2tcL{2HDcpIH2h1Ne|FJ^;DcpEqSAJ(POqt~zpxX!&Gt8XtbU+-NHy{lR2@34rFB*17 z(cI}EK+Y8X8kzwe5#BQ4p_sOUP^peAulk{)--Tob(Fe~qNR~R;3M~^I%F6$p1>kvS z!|-H>fq1}53CFG4nZOACwI5;O?I_Vbkd8`b)1Vp(3Xc0Asj^R$Qob zF5@%sX<_!j0lpUv!JK_5+rg?SnDHE$hd1bgHe`lIL(beVs7d{AJZcz%gfMJbz6$g) z4ON)G3=>+N#URqhRW?OrnpeO+@QQ#0~2%r?xf%Yw@uyW!Bd*W zNW-5d+cfe5hi?;F_C}&r94qy;W=lt>8>_e*znj-4Ro*hNU3M<$*U!E)D*p0ip~|>@ zq1nmxQh>krrC0kGCp&qHpC(#bxO3lE+pRv@--iErsiQ-@^+%a%hJ z6{s8vsVx3beU{=$4WD#u)l(4|Lptr>XfN_LuYD#eTEQ{4xyyL-ruMYf%>+^ScKhwR zI6F^mypO1oW1&EPY%M_$7tTNNI?e%FCLwr^r!0@g5V@}|Ew-Y%OT;gfC{ckmewV^g zxnqD$eqqJ(z_E&}e23#$p09YmX|@hqT9h&%%r+hg#Ze^X1|TgRmaep+=U)hVH7rrg ze~2Drp)8#nS4n!$Eguaw_QaPKBWn+aIGHti`RGb7CX=E&N-stjPn4SG%gLaA=lF>! zu2|{bI>#w$E-4vO(Z68#Rp}ppfddICL7O*|Xtu^!74s{Q$!Lisb|M{ExD4PL>ON+! zcUUhCFdDR3T@?kF&L?t9!<35hET6Kf*?b)DC((!T_f>jy%TX#q<;mZvKf*Cxzip!4 zj%U5#{NAkO5xGEDe1Xc48Aa)5*kg_>jm8-i;WgZ8DFqmt^O<>D*@${{w;SJNB}-DU zfIZVBsfQ(5ti;3j9gCQ&m!CX_j_S_~NaR1u=2vQn7stw=P(!^yiD?b(_&Hpip|f+M z{9V;gtw|pLcPI(q`_swCGziPJxd1Us>OEFNWdAnZX9}?@B6`m%rC;X}R~83l-zms> z_)!giH8%5-SzaS2BGo&>N)Lylfdg%$E)d zsey+pIrC2udCgf~NW-hX6B8iFhEt$|Wj0CE9&IEc^n)=VvM1T4{hL^CX^!YVX50Mo z33fAdHfl#xL;u9y4eN2}vr($&w1u{PVFd=Z*mbepfu(k1+F+lf%ZZyY@z?#al&i*D z@$akQx6u}!wQ=suz9Ak0bKVZjEH_4ge*MKN`HIMEchTv*9jA4-c)p=`dRzF3mozhm z52yWBmDNojF$6FWTWf!!ytH}4lPDxiU(t|#vPdY5_nT(!n3Y*U;OEX^^iG(p->iv~ z)Rl2Mo~wH|)!ion>_F8{-6dWJm)NaZvx}c}$J@28)0i)3S3O_0Qc4u|%~EUmePc=P zEZzNMPj&%&@3PnO_uOxkKP=DUmBsZD_yeZd*~FGka)K*q0XHP8?Q%7hGW33znZFM% zW)s`&`-Z+n(5Od`;7I!R1K>AwD~n&!3UQ`7f}`iUA-XX^fXAAvDnq2BJ-H0PTg0Kja6x zrt%bMzFdqqMK0yGuKFl<#2M1}hWq-NA~mm0AGF3_V;mozz+0#f;mwh4wKqsI8HshW zgG?AuU^MjNcqV@tJ}OH=fE|uZM}+YHukSJv0MU@DjAd)a8`gX=EfS$sQ(pyTtD{9e+tdrZN&)F&Dy9K##8*P7KK7l@o6}a<^!xo=@m3YXkAZ>B}s}{e;S1pDe zuPwFBUuxgvefo3sIhk?0@8{3$a_(bAXdK=FK=OXCPO6s3 z7%l{{Ggi_)^7)C~INww(GeyBL#K@u~f>n}`*+%K4pnd>`;_0LTcj#XTkPzgtJZOSW zb=ckVe%2pkE#-ffaygySlf+DeO(W(-t^|g#`bFb%V%FMdtT2R1r1cXUbSqp>S6ejb zzQSZf)>ck#betj={YvjZ?s=V}#Okj1=Wh;s%>XG1G2`;w%XQxA^d@Yzz$6cW49kLsU>gsx+MV+!Cry7sG6Q(4I2jiHYOEDk+bpN2abnoDG>W|8BRKYGQAn{>CgD zp=N?FSi#1k!wn%qzA)B`Ly~~_wrKQOA%fzfkRLY15+Iw4ANFG(4XS9Jg zJ-uJu_HBAgdOj|=Et9804Q=9%;+yKA7fRBQ-5`t0Ov+v+9LP!9WjOh_VA%q0x9@uJ z_y)4C&O#OI7H&3Su)W7D+vq>Z`7Ss zBGw$)(-JiMT0UQ(fP@;SDY{$>8$Tl3w0?9%V=Q!pJ4A9s9U@M&%OngDXfi4-l6EL} zqFU&?Bgmnc^AZ#(QtuXlt($XTGgnyT4&_SNFlvRph(8P}UJ0^8YkH-JiJ}jA=D&v{1GzfVpXkb(4t0GNtUnklBNBxVviZBgP@n*| zHB(>feb0pdP>ih9D#wT17g39kT(XO|*I(!V{pQ%0wv^k(p?0m6|C4at4|uwQk|pFh zzM@nQCqvoTM&*$1ULzJH_QM90YJn9f;!tLJaNi)cm^o9krlb~%`a8=<;K=~`(+a89 zY9uqu3z9!ez~G-0@XT44dEeef*h0_`*-d_N1H*QPjdTd#Oei$b+=-% zr4r&_RA)sC@!}FQrT$Rd#mmuH$!RHf|1vQlw_EO#GTE!czhYBefjh((d!N|QAq&YW zr1CRm-`l?1ihf~wg!eAG+jX6L9wZY3pz0}+n>GQX`I zsO-QKdg(0K_`Lxr1<(FLn!8MyG41WTF)55rLO2}7w1}WM-NXz%;fboS_n%LX5y$7D zJ1f`IfF)}jhJ2$KV@JxCN3~eI+)C#3}bEC{eCQH+q z^~Kfp?=FgwD98t1VUQdHN-;T5Rnhem%V)W#AG2bJXvE?qg<}JoBzhoLz*Zm|a)Y=W z>U+F+x78!|GZLw;Uly%@&Bz_sB`?~(wwCOVLqqr(7@n}c+^D8WaC(&Y}d~MjB#cp-}{GtAQ2@CP85wG4CZME$oYB57rX`8A8W-} zGDJX$6F4Nr0zQY6&hH(H2Ynq_u^*SFEqSWe;6Byi2PL&{Dep!u&^<{<(P2D*`S!wl z`b6Yl!d^_G&W#OJV# zR!(u+R-#&>&=~ee&p&$A7F5mycU?vLaaGv}_UO?OYWzEP2x)g|4(FrY^r@q(Xgh1g9BNV54e*D9@*1 zm1jfJ_K(*x1N{g0@xzdrY|in@a+KetEKR$`4M1qua0g1z2Q_-)_)f}#Bgk_kdjfeM zqfSExWVoR%b3G!28nidSxIbVRVe|@YIT&O7Hzrl(0mnND!SrQxYOdSwe23**qno`w zDn(!!yu=tKu@A4svyh+BlOdq6T6>)K&uN_t?0c39R3aht!=Od3D&b0P570%tZQH5F z-FlQUKEaa$hLRx^4Wgg1zfYw%8%x_~+1Ynz!|~JPU1#!UidT`Q;y+_Zfi!(=izdWP zbnMrVO!ksChkM$l;00;S_Ry)tnhy@BN>EufYn!m4M{1fRoj*Q*P!t_Uf31&A+qeQr zSf*sMJ@p*RmePmro`QG%{AsW~OPX8}$;2LB788)!CJULT;c3aqlPIsOsKHPzr>4cR zF$XQ&dPs!&Hu}EurRFhI`-;qvpoNFa?Wi6X041EKpttws2U?gS)bU*Unqt-f4E*gK1{g{ zh#FpXB^&M~kC1N159B>>+ElGC%0uc7mZC@b!Sv@{1iK*`EWyCSjXqx- zVedP=wko`8NDvpz6U2N(1Zr?n+%_bBQCe!RII)m86O`86OmE!QPrM0uW6q7NmDD;g|oVqV6T;bn9LQ} zhsidc0`~=<%Jr%p%~wHEtCgOopcF9AiHu{T3v#*{<=r$3fMU1EG3p91+eFFc{!RiQ zYcmHW{GsCw>6;zN9}WtY(qU$P6zIvj74n1Nmg46UbJ`cNir{T+rm z9`@huvorPltfQ-}XRCpA9{ zAv;o`r(W4hQ?KV1;j7L^f`0byvu4@ZwX1h|`?9`LNHAZ)(WEDM;&X@IN$7r4_DsEH zwh(vTzv&AL^fwzqCf(PRf}7(|-ZQH&huO;#<}HJ7Wy5-4PolT+X@$)kWEwU&CitePt8*bQV>91IhVG!7P3@v63IS9M*Kix)07?PD65Q^QD*dc?jB zSY)M$zygE+dur({OUG4ECCiV~J*h`;fBa~CgmW2rLmjuE3n1bNz079{Qw?4wrmCL( z`8w|RY_!$*t8{qZFA`=`&i&N-{lUidp(t|ryqP!=ft^9V-YXyRtdCOaCC6)5eFW=z zetlnL4?il4dn?vV$#FgoT_IA|(Xoq!2}z1BNIPJDD7KIIMn6fK>H;rWi#{#%F}jBm zAwSK}?e;S&z~B5o#xUCtVH5Ae%>N`FzC1v9N{YmSLjW>i56dGczT=;M%neos-HP5i ztLs^g%vn=#D0k#pE`JvN!%!;y`Px!sHSV`Y8l^u@Z+wGkCSDqKwf+}@Z?G+zEd?h= z`{&i?E_VU9)-xS`>zF&O^+jMWy^gp0VQUo1K@6QKuE@jVp zUgCm2s}ML?-HwvK%(^=67(Mb#u3jop)W*D0_HohD84?okcKeTdYPfGwC@&#*Md zwS_z1^nS;ER;dx%EHU%^DuFmT9}$@+1`+_EYO;6Mvx|}at9=^~-RIs4&xjP7f(BMz zeW5GivmMoR1Gee~Pmb2x>4w&Pm!Feb;^N(YH(wEFTKcUPGbxu(bAHsR#ZwXCJ)>Om zZ+|}llEt^$IPe@qFF+4)C-6(US&$*^2z zh!lGMd<8Abg@HnQ+N+OFI+Ci~dhj`3cg=@amc|(;rNn{(DX*G7*v41J;C?avOD9h46h#1Gv?lFjcPe1}Bd?gUs3k&eAHNEJm#Q6h0rIAFUO z;=`p=82Rk6`kHiVNL=yf4Khqp+tFY2IcsnYR^OGtbm$`~F9ue*!Qm8E&jm;fQn{D; zmv!;vtI^UF+i%7ytHpy7Vq$@yp>3$Or0%jbLMNkr)n6k?$6qnUryyTdHa_?N{}GN zRxsH}F}a#QU|b^R$vEY@yPI_&&Oe#kk+&{QwchD>eiep*N6fHv^+oV{>}sAP*@T=T z)PH-7a84_=uH{&;R)rtY#J~2U$ExM5w3P4STl1}m!eBV~d90=ZDUlUV*C~ns+IhUOF84{*pe1+kV(uUp%nYI5`;q zrlmwpo?}NxLhQb0Lc!x3-Hn1$-Ru_lXHNXEL-hILC*FwVwQV!*jl5nQ7&5Dm4~Ks| zlGFlGJE}A`Y>NFP6*hJwBeyR)Ir!{qr^J@_O6P`jgO__uViw%B^0F#^~`s0WT+zH~;>PphyTpnLwD_Gp7ljsD0R5MEUGJ(YWpo zP6J>0jy-?Ffp~j53SDlD2|RW6Z9SR^d99wltXe%n5afDgIRE=R`p}q9e&x?6+vg3& z9!z-M&vQj_3CCot3abdUGEvoi3}exPrJ#A26Uj@NvH;;D z+hbRit6N*#YNH2JdbE*o6C-E7m0cvyChp*1($zxl$Uj3?ec4BWpI$kSkJ}{3tnS`O z8y2!8TdbGo4`SnmJh5RxNTJ~}6DGpb4QxbO+u8O`;L4Tvn)~&OO{~y~xZea?-D5^V zt9|+}8YWpy-V0?-s@fd`Tbn;y6?x8Z-?e&!$-Q4^`{PFKtv0vu?=7&iAua!6NH8cG z7B}j9JfMeJ7cD3uxX)-bd798WyRln2=gawOFWFuEu4*<~_R`OL_GSM0g;4>YT?}XT z^ye6YoKylQDX1f^UY+Jv0k=&pHz(C2{g}%n*Jj8GBwkg3&x5tG9PzpJ@yq>|BPTZ_ z8^;~>l4XG>U)rUpi+4g=oi!@wO;3VmY8qY>jAq!$tsXOZu5p^OJNw`sxYGv&MgM3z zO}mWpch?^Z;N?KIR{i|)YV49B$5|sU;oa>XqU>llvB^9Yxv!5!uCW0cnk>^qb}`># z@EVM)pd!kAI@H}#k?`c;lk&hy;7rYFE!6l$oV>rpcQHJDyB*CHZm$$C&9};;5a2KW z14kgL#3CD`>+q{|fJ2}0ZPk474MNZ&1?d6NoO^vUcbc13o^m(Zzf~85v=D5WKR9Jo zmfw8F6M0knyuWapB#ahjnvgQebA2n<+`-c_I-zP|+7b=c#cY;i6p0k9w7j+C&=wY_+ zlJ%sW(USB&^w-&rPcVxSROwq2l*_T*{lxP-U9v(<-@iOwn6=$wl*{{7b8>V*cQ*Xq zZXqOr#a$=KDm1NRx9A0GE!Zs#b(pV)yR)^jnCg?(Z?R6jF`1W~ ztU7CNCYOx}1wjD{z6=h{X@3G$n9N>H+Yb5JpF z4K>*25$1F5Fqv8|vK!*t$}ouH&s>-pcW_GpFGaA2Po8Zo#mm-6o%-4Rq>6!gxF~1%?*lD*lEU(v%w;MvI zVUtkWdB!I7;|plCy~NG z_J@^xOSi2Drln?8X+rZ58KuU^M()fRgVB`_9K^hHvxtZgyQyzZ(#Ngk{FJK5CF$)l zgB6Nvvub>}UmO$pW&-?hWGQ)1mGsATDF5z71=w7}&X$(XAS`4LUXRVz2BSrB3H4R9 zG!~-{=>2ZuV$kV9yEjon)%crgXlM(=xY?$G+EpYOaQG!85PjdoFSrb?9AsN!-%C zWW}tCIQ|qdOQoLAcwi!!LwRiIlbfm(J!eVXXLYp%&kl&5ID_smd0v`bj!Tc;&)XY& zA4(9WOEtbCPOyq&tjD;%O5Gx1QfSq(gN9oyo4XqLwRZW9#8C`mUu9ZcO$KbZ=J|Ub zMfjzX+fjssZ=6HbW4l0lf4f6i#GCM_aDH!s@4DC!-!VF+`MIuI{;51{yI3xpEgx~8 z;)}}H+8l1!w+Fwkw=_4*I&WycP4t8RDZ;yD4q45#NZIahw;zhqWmcWg=R2)Jv?}ZN z6SHYBP#dK7qaKgJerMF`*uGLy2vOr^`S6w**GY&rF7)CJ&O zYEIlOZ*zOUD-)Z6>?R_f=Kk-7f}ANPAp1+aA=@gyj1S~^h1jPzK^e@2;O~2hTPaAs zCW)YwU08&%)M%s171yv!tLR61)e-;wVn~0wtQd(^ukj?9(Y+%}Z1NtssZ#LfmjX~S zqLvvQ_=Yu`Rh{Fq2KJ?|#_g|tyHV&T{X5&-C{4%abL#5+zY%2>^zw5xgg2V|@2CB_ z43&OQWwMX+a=mX0{Q{v6?wZ>)!W1F@dR zsbAPHE&MeDCb`YP^Xr=RP!w!m$SrPn*-3 z!N)`;Chc*h?6L#)X-%MND%KDMQ5-=jkOCuI21rbk;3eCAtwZAlghiuxe`lr2G0JQi zM@0+6(NA(0hlu&i^v{VW@wGcY_HK1-RMuZLw%^61Hcsi``gH#(tDpuCbm*n-CU=65 zM2<%J&=PQr!lJzPvg*cEaayCIv(Fwka( zWQa-b*WP?my_!;=DH0rr{2jvc^rPL~#eC#%cFqhBpagOfxZZ0v#XC=OW)?$DHDNmH zq?+wuAi?g5+LR12yz>{lFJd@gCBj3ORa$jB#{gd@Q>3qO2O)ra6jV~SeVt32k5dBj zQc{hDt`>iMI+&kjx2c7BLv%4r#~_!YZYvbz=UeE~pT+BWUw`ya>z(VC5`eBcO5v7o z44-*1@0I(iMZQYta*n6`(>#!%>sHl_zP2=MIn@Vk?Rp(PxDI6IzcWisE}rU^S9O#b zLhr=)o#z+(4NroHb}VFjwie7J@FANd?Kd`%E_;jy(>(*a4zNO`we{ywjam%)n&$cT zOs{s?_mbyjrTPq78;(f@EZ%Pg)A4a4*$MTD>(*|6S>fPHAp$ub&CVRJi;Qwg^*!uP z+JkI@$SL;+aoViFqkRb{O-v z9FWD^#dN)>>r6qr0UGE4sFNpL%d^uEs-MCvwS<e4Jiz&-@$HrPWodqt|i`^})ew>TQTeni|yt20S zRr}I^`-9IwizFqF0Zod;MxO?mlH@t4R@dIIl?PcmgWtSd_ZNjy`^id3`sCwXsBW38 zgWhdJUehk4SM#T25d+to&|wXHgyE)b3ci;`Dh;S9K~>GOb=I>hpB61&LRLn+<^?8K z{h(7{Pc7ymqf;WUMBeteG&0cd8gl3`BLD~atJbT?_L6NCS;4n@Dh85cM<&8rt;1JwV%o~T=<5(x=$MHQN@OM!IS6794QQ- zPf3VJ)~PHRQ{D`3SyB$8#Z>m(0iph_Ys>se-PGynaeq|95#2Qsl!r;Fe(hRK42j^i z6}{Zwo&%N?Wr0%7eue>|%>YH`Dt6gEnKB1NML_>Plie|p1KiM;%F&T-nb~;2+htfI zhMI(F;yQee06EBFCPWjR7SFn0r*qytn@zVmYmdjn`n4#X)$>6U%6vAB39==A5W1?> zwmrSu`~8PQafar!*k`{1JioVDq!+@z)e^+Pg=ELqcYm-emipv-l81hi$teBBwkh9Z zV+jd*@ZA|YuW~=LbTvNNtzoX2M)~p6EyvQ#;gm>m6LQ%WVrq8~orfM%I_KIj&$aE>KU7KA`aV0eZ~wu9dY8Kvw^4YwKm4)VP}ErQ zf2pwt))?me7+RVDf)cqEpMq)z->3dRT!7$a=d;7_RrN9;Btw_Rn`^Pg_jDt!1KBKhJ+{UVBcAqw zB}pG!Vvl?~TcKI6>M!0|d|5|AF|W3zxm)qRUt2wl$RtxyVUomZ3$dm4oR zfj7Clopu4A1w}(34xV;`W5)R={HzH|K;3Ph__kuP_$ddn3p4PQ+a_Z<#(mLrL?({! z@t2>^FzbzPk`-M#k(5N;V@^ACknSbaKevS~96fDV?1H^h0bE0(&dh8{EEVne9I7b! zVaE!-@kv+l74aL%WE`kycM!5)JhEfGrEgSwBWV(E%=_pS`XG3W5nP#~vs(xZR4$o$Xuzf}O!<&pm7+cNbT7Vu^c z=^X1-LO{rnZMHaO~C7u)TMLF4LSGAu4?Z9PD>!PJkD? zql=wTPxS5J-SlqbU6utomU&ECq8eYYdZFsEvdH0ZzC)$^@{xLwkGC*&>| zeJ-t%&(LHp2&1)Xawqw1`ZwpeqkX#yd1lt3zwJ(ZIZ6Ntr_664P-YA4md8momKjRw zRSsn%2A7NH70nXBq0^46{Vr~2zf2-)eXJ1v^vMBA5Rzp^_dBH*x{|zNiJ0ja3Uo1A zyB|3m`!$>1Jp7t{ZrHwg__%74nFU@n^~KpXUsmmet7-$y7+H{ZI|p^|nnupaePTt0 zVRvLkbp^i#;%PU$WE#FhXuL}A?G6ruWBi?}F$o&`Zly1(hryDF<)={GB*e%&-!P?t zWoL6Gg9?}Qz0tt#Napv-e&^g}8M?q_!)HgMl<`uTAtIM@T zl!+C5a!7?_ltDc|78?)U2(}aehTIM^_|m z*56ow&kzfecC0lYg>jXM-LReck)w?-!AOFZpsPB#Q(JcVNZ;?~`zJ+n1TEIwNF~Dw zlCEe>Q9W|YeMS$n>;mRh1ZU?E)cvb+@M6Vx@E8){AeQHixoZP?5eO0cA|S*{OH9T@ zZYB$6Vnq`cqnV8;_=s!NySfzOXY__PLwu)w|C^~3qpJy$+z}cv>-hZP%my?^FN#Ze z<(>w#)hd5!X>GgnGM@xiC6ix-kpYie$M8I*GkXx)TgjPzHTUE7?e3YxD}$q{W`hB7 zs~Xj)qA%S=&CMz7k5=j_;ViraaXSTA1A<71}W2X3y6xDM2f5Z(XdCEnN*`i@Wt5yZqteaEbvtJP$wn-_D zr{{A|y25-ML=*88jg-1HsqKMzxT1v)-kYi4hkW<-1`A}NR)bPo)Q=32pvvGCb%K@kTT}6T2 z!Ha>Sp*f=>8TX8nxlOH5kmJZKU&N!X0m;JRyUh4cE@H588th2`F#=#N$G+fmIOF@s zqPTk!rR<{No8}^5EnMJ!{KZYzg!$y|(+I zJC>EVE5`?!>s!rH8AriT2a}P78%r;rKk*jB%_@)GOTxEIUVbC&1B)!+@h))`=N_p} zp5oU|CEevQELWXfEh@1@{2YqzlM56XUk=w!axBkYS zEj2Ct_b~SM(u#{DzwQU1yYTCSYtm$@ahJ`gurk+K5*sJumBSZLn*ldHKcxMqVB1gL zdo-PVa1Nq_NADoxLi?#5Hdl4NbBjn@nN?ynv+z%$%$9jqDC|Pd**JhH$&0V{dMag0 zz#&AYOmQ=;lCSxHDB4W~4G}&X)Bo&m^mI~-@quA8dhJu?acnf3Vt%$wz^O^E`2ijy z`BW0eVM3Gu$LIq=%-?B97GIDnP61geFNwN*7$d0VLAh)2J{htYo=tAI=G(8yEsW5m zCd3ehitGM4#w2g_>Js;G9w#r>dtx)gOlmhfGfbH+YID%4)HNp;+;!OcR&fPd7XDO! z2RV<+FESZfyy!EY`T1#HYAe~7_z%h9=t_WyHO7kVXctP`(d(^Jalt(Dl+Un1?cf|N zA?vaS=y$LCIZHDBgN4!C=uDA$!;|feRMQHP*(L+w0_B*l5=Cp}IHgz>688c@=i+>* z3L=?JX7uu^O@U#*mSO0Jn(&{`D-pd47q*p%eh1H_bzf=7?ON>&G}gNh@Pz4;insEtcUwFQfUc z$m=sxPy3xc`YXi*E*Csbo<{f_mT$d4uGc=gG~QR6vVV)Sw8Rw?WL>yPND92hiOw)L zkM4@}ZSkDhg-OqIB@sgls~TvEOPKL_P98ojY^-@gCHpQ$(7VhhG6K;Iwsts0N1cX& zW$FhGWojao!_FTCA#VmN-i5Y{3t2>vd=7j!cYy#LU5{+uu)D)TF*t{HoQM`8wWMTI zV{%;KAZCe~)l-hYOzVC!SXflgDxp>wToeg)a^zM=N`*NS)8(#LOCq)OF%GP*w2Us%g_V+QYS58hWkSnibR|;Qg3(i==bTn~3USsy z1g)!BMB;vi(u2KH4<{G2*SauezhFL{;+NS@oc6X`DO#7q>4leCd-T^fVkE`X2mgS? zZoB+GWJoO*BPVC;iCuqTM_5G5hTr{z@6c3y$r3n2fY%;F4#)5QPq#Z`xtp^mNHb*7 zPLPg|=bs>2SH3d7+Og0w-#!EFi@EaJ4 z!ZUutAJ`0Nri=e^GXegK6;0L$c1Oufq^oGLu!+q8U6wgv=_?h-2jc-l4nIL!AMxoL z^#0GgGAew5qcG`5vE-ENu;ycQURhRj>-a4q;B+|jK3>MwvL$idyN8Du^h*o)N#-jdaqwb1v5_nB^|G_^Z5yRNwz zD-YY6TZfB}mLD}Pn4*1+qgyc$7`vd)s5_F%(ll$T$Ryh1JOz|pthwz)Ns=$lb#BE3 zn(uPqe?veHYt@@$8}xaL3CEc#KnC|)+qimuEZ5(5zopYZIHj=g55zz{2nFdo??#p% zt%g5E2QftpN1u|lmg?oy`>N@mpLUMOK8{s}y9osJr+};?>Lo*KoyK8Z*mqpM=iO)t z2EExE+r6?Cj)wfPQ2Azz$LeX^b@u|U%$t_wZseI^s0Qz9={9+soh zb_YosDEnq2<8F_?Xf{c>#gN;%D7yW)_OTzF#TaYYen|}!GL^biVd*6f9mZO0-^0>B z#g}*!*XCy<9eFvlhI?Fabn@UD`Kq&;?Qg*S)lN=-M`-timQ@0pcM zNX#zL{31wa7!^}&IMg#2^;=hV9(gKC-Er-C>vM*d zkFJ0mmM^_P5AE7Ys{vBOHBY`jH5x6c94%6WF<0K;;nV{(2ww+R!Mj>Y;>*tgsbY3< z%VV!x8M!W-@4-4yhUg^|nTJDei06&kWT^oXbi?A7E?p}c+5i%3*$~vNot6qWQE90)5%pVbspuRM-TI-ImGod-U5KsZj3sx++bGCw zPX2eBP{HR7rq;RH*OTX}Qi z&x+2yazFabWd$;})?(*Bd*gW4JBvGfL=uW2_Dk;l&E1#2W{DtVP5@-tI(vFt{PF-kC#lsvwJt+`-|n3% z@^g1+o1FUzTl&Y`uPd+J&UE(pN)C3Z7aUP+i%~p2KvEKdinyh~+0;lJX);@w{qHAaQoFwDZfL=|HqOV=B z$0PSU%WIJQS_qvogV=qg;9+R=FrRFuNl>TrK%y%jfMk(>7@^=@{IvQ>PdMLVtJqLv zk7X5`wfS6lu;eYzpWseVIP+`d(4A*srH|r|r;gTt)YYgg#>P38e}d zp9jTHoR$19aW5yZsGQuQS)-q;bZU8~tTFBS#*9XAfG1;_zQoJ~f|13@ZJV?!2q zxPJ6Q=?h3C+-k+zlQxyFr zU(#YhxV&nj=eMM&0${P^9_qCH`%>WlWpNV7O>c>5U#X4l;A8~;POzY!Ya=LXF;|%M zN|$&hv4MdudxO2I`*61C{P698f!Fb40QdTia2D@jYk`)(kJuxKq`q~XN{?Ki$8a{l=s=RVG1jOVhW9%&wcPpS6<4-f9Y2}Vkcafz~!mf!rZXr z?wC>i8Vzw%pB**Z?dUqbeRVws_YmK&ny8l9yul4{vtuaG z`OG9U)I-~=@h@oAVvVJOJkbNU8s#}}^Xq5>>;6-KJVWOJXwP&yv|WWBoIDG`huZ}f5t`M90rTzS7ak8GalBg{D04}|lr&DnGk348!Vs2( z@b>F*zpvTMQM>Qjv`df@oG|O05hBQZufUqD<*LC~z|rdD3Ifn9`8ZwqA|anjjxmCu zLL|1}-sWN*%|=Ti;h=uR1hG^+o)%0raML%Zt!fhTSoOp&bKe9LM@MPX1HV;tieZ2| zx>&C)rn;h_e);r+D39;8GQ1IjaLX~C7I9~e9_NpmoYC-qf;HSOrJsIkeY{!@)hzasI0QM}!k+Sc*v$lp)9^%u(B zhyJ;}!zIy?d`-Tme-63f%%d`u)QxUk1zD>L_Ab|fs>bdMUeB&^} zx82UyOX{_)0ImwJf)wht+lK0%AM*Rks}s7-gtt`gvykUt>DJp?ePqUt>iyz)Wx3nn zXpL)f;0!lelhUuK@;@&CZ84xxMDnLpKAkJxBvpwa^yMbbFgc;29X}H}=w9?}Fq?z3 z>T#2L-_YpBmh%2*3{u+?G`f>Sc)@$aL6H@qkwJ|r!sdhE&0vAA@S&Bfz%OqvwCf)% zBh`bfwhL%yw-=qYpfqw3XR)%3`TH2$@;mR7D&6{tg`47ClmZ`C9-pM)faj@aP7+@r zF1)|YDbcYncOOUI!K{*Ic>$t--r{d*IAxj9m931XB)9_O;}!&qv3`Bq zdxnW;NMuz^JMl;#%IQ7f`Ilyw!4~@>0CoiJEk3m3?>cP$E)Lo`Sk-YeSO`k5d_1L} zW9azJc04|rq>lh?E7`!N<1u-F#T zd>K+Y3$RdTZx4aSe}$yYQ31z+=yM)C*y08d^@5-g3QG|&r&2f$fRyi^<^v3{9R|OO zrv(-XIVF4`noiVYB7(JoPB3}!byB{n7l1*1|9mu3);ynm)OI*+AI803ew$5#n-u@$ zz8iTdG}SVi`X}|~^6YBUa@SR&NqSWo^T2xk+}{-H*?M3X-6)e$e|OF=yUh1mm5~yP zvFtg&c2*QMX$ju&iRRv4ODLjIX|&(BZIWK&xA1m%UUz-mm7n|JcK<^*=wmfn`)?WH zaPVWDJmMe&Ysi9R64=h`e4bC=XLGWz`Zzqzaa4r%ZY7vJdAW_yr5lIKi#u^RYkq@p zMPBi%HU&e5e*KUNdn3rD|L6E`0Xx*8OpJ~#LoaXsi7uz|2frsw9jHb0gL;yhkI6Hs z`?7ugc&4K7iIjaagm$Gs!zGl1`Q=~Ghfam^&?XsB&^)Flc_27Vv|CcPCkf(e{S^eg z4fF3vmomDq9~n;ADo5ul$~^6dfZH=e`oXP0`8!0;csD4@tF8p_)~bu~9(JO(4`kW_ zLazWDM%0ezUed3veK*6T_?)fu$Sc8~o$^=c5%Hn)oqRpE)NhG+7fD^d1bpjOOz5?D z*GZ71&_M`q*=U)J=19u#WcZoIT`?>ph3VXG7OG+7yah5!W2zD}ecyO&IfTZ~+nj)D zvgl$saPXYJe;JBb8=*O1QcXjwgrhb3nDVE`v`qkh1Vmh8L4N%v|-1qBzQ9>)UP2h^s!8 z*VprcBQp&BaqHDNb`#jX>Z>Z~Ub!I9X)g7p)snf}z3|ifQ9?L9eM*8+q~Dl8^IGpM z$bNZ*)Z2pE?&4ruo0Vz>i3O*B_A{zf2S1M~wQf^Yf95 zES5NG3%~OA+TS;N|IW4wA+P7Y|7M`h0s@^+FQ=6AA{ok4Qoy=6)p@>r7x?qJ5#hIU z@|ek=7Tfut$&*Xc_lrChfm-1W=TX;tfrmz#nF(G%{?RfTMfa@c5P9xH+$%d;+kPI( zTeW5l#)-~8Br4*qdc7ZZtvfM#uzA~b`TES_k42B`ijtf)+f#^*s&w;P zi7e3NRQ`Qr9yT(Q<&u(lxE3{75m2*X@gIG4w$a&>j*>=Diluk~0Uq-kBW#KjDfhgn zpSmxT9-~u#dM#jfJ`+QJfj!0-y!$3+tKi41tR0AkTd_q*|fN>HduzJ zWTAq7rAD1}_*Qd3YYX)10VlIv#eXDvC27h-7Qqd!MJp-@ekjG%{LUCAd|l-4iE1Yl z+`Q7z5Ym5=Bib=az~ck2>`@L7k2sm}pra%(27HMS{&M3&7JDwFE)jpu(02;7BNBvQ zybt#Xs|#ROekT;!9ovw{aVE4E1qJ_Qn?dL7X`9nni2y-)w{f z=gb9h8n=47W2m}4$KzHh{25gMDY7NWD3#@D5Fkpsx9G!p7A#-})a`P+#v2P04AwiK zguGl$#AKW)_yfPxu#VpOD{e!4332Gvj8e-V1dFierxu6(Oo^2y(W{<;8jxTGc;2+M z43c~RrhBR)Z1>r`%3t<{QKOYnljg@-AC)xiV7=0yxAW8zAJeBn^sh6SL;NTE>QXi4 z5jWhgdDgOz((n`MQ+csO{;h&A8Orh;-S!qs1e1PREMl|12+C8^pagtXX3N1n$J%Fg z4xnk9S)EhQD4oclnf~KhS@*~SrNW79q+P@L+CXUK`tdY@2YIJK>bePAUo04%h~M}} z5dXg?52f_K`lKWAEFm~C)!a8TFK`xp^xe4W7G(uRuBdLYYD4 z{%=P{92P3^H?gPRU{Y?z3#oe0XXHXdZnC4ZdzFFzE`Z^PJc}0s@1Z6UpA*uZ2aHRC zNI+fI&ygI*J9bKBsKyToDw>ma+B}p*5fv>?2Uu6Vy|KCvjfXo$)2{Ql3%U4q@kEQ- zGSO|}1IYg-4cPT{eIPNe=&NkG7b2?t@n`*y$G?-P2r>anhSk8OeiIhf zQX(r-i96JLlaucl8H4E<5e zVSxB;0DqzarQJ7d$y_!W$!=oQ3{)M$h-h{DO?yD0xRlMg4?J=VJnX{Z4lkqn9~d;k z-QY3VT+rzwB)Q!YoOhChalABC94*e*F*vpcWo*e^ogOZ$*@@?qC^N}3= z!ZTB2bR)UfRk33o0rk~Y=lfMM`&$#+Lwhnc!;Z4qpH^Ci1KToR;loez)QNDb*;E(h znzB|9yIqRj6QlPl@g>*=S(-hv65DNspoq~o!z3vS+HOOdwfr;(=e49|IaUu5O&!KB|-L8TRxQ)$nuYMBjA$26>_}Z)LROp z-eJWaAY~lewPX5`!aK1zBPPMKS6Q7LK0}tQGDb|S-;SKm|4mFut7Z75taS5&Yv@Pj zU%}@X9XBZ^zH8VwZrUx*xfQGcren=>Xp%#Q^t?m=MD!i-4pt;~~N{g1K zMlUyYY0KocAeSQw+fw&aITeLCj$f|PuaHd3>W)V!yr@HC_it`M8zT;zOT<(E$fWGr z6wrf6(OZHoWBd}OFrcV&T?f?}~Aucr7c9dy96u!l%$EFbjr zn7=p#A^meS6n8@IYftV4EZX|yrGAld@LzNAfU7S8(zUssKJ9-|-qNl` z3NFQl%pQ5WwW5&sw|4~6Z}csnf&qIB4>6+|U>#BF!uR;ZC7|E=xYJOmV5_qXrU_wt zzcLk7%Befq59p3xjl4N&6DC6~G&e>v@HNxVyNV*Lz<(pY2va$MI9}PN%Ts;x6iV?p zId5PnTtO-GthEQuTu~S@z>yxvROq`KSh{QsUyBIaAEZ;TXUTTG$nATRDWd&I7vPC9 zm+fbkv)4$AQpLYcZHhfSS1%?*?au*Nx)f);rCzT3Z2%}6Z)AU>)9v2t&=LP-_WrKw`E?X7tqsmh( zt=$p_2i{!%;ioFM8+;s)EV6|A^PupM7>p#8wzAQ~@%y=L~H3nhdIR7T? zMoMxv+BGcI%?M4z4>FMvBaU(L#kA)Zb|!uH7T$u`B4vEM?L`PVaQ~in90d?Iui-JY z&4`?^?z}v>6WcU-dDy;$U9{t34D&Wad@R^3!o&}+XP78L%?BDei}>KGo7?&ForL;& zWXAXBGJpxz$}?^+O|!`L0u|zY@fKnYwN|G|znuO7Q2RLh#eZs6iOX-$<195t{bD3l zP1L|;QZsqDG!2mleE*nu*huQvo*7srE=d9s z3Z?@juf%j>#r6=9nshl~pw{)aLGzjzf0_L1S{l2ti)cu{FVZ=rzG%#%xVQME+Uuxv#lyLb8#=F|$ z{1wD!1#j&7ZRAh27b%mpXX~p`iOUKcH?;gSQPWV}f0REf@2QbL#j1%*Zk_vOyk9Ib z*GuJ9S8s1==r6Cyj5ApJjp@@yfqC9LKiPV{K&YRQHAF_@0ms0>!hlR2eCmc|h@DND zL9(het0H0}z;Dm<`e^yQ$3(qQeqPn!N?9h|Mk_Uuw@g|q6`#7yoL~Zw5FM09E87XD zxw0*$%;f1?(oAR-Xu32lPTmJ;#C9;!$3*Wn!HOmD$8`>Y)CFdjeGIKGLV}1HDEK>) zw1b*=Klhk_Jx(IDYPuM|ZqU6U%2}4cX7u}Ia0Tr-Uc)sgy^3jqVmH74&5Qk?IpY`H zt~)%LR;uGl6TidO#c1Lz2^x^=xMmK;pUcc{^qGXUjX6(uA09Pi8Cqp3+ub_txA^#c zB+`{k+6?3sv{*b?bt0XaKRDqIM@DjL>?UlY5Q2I0{H=Jc)PBWU$AiE3J*VY4>&V8o zfkr)9`19PAm!m4~pxYV}!U%hG%4%^u-j~E!(eFN>s_rYdx4goyCpjjV-Gf73aTt@V}9@5@?#G!9>!$(*Xw_055b-KdEjKjp^q!{I+b)n0jN@ia9e;wDMp+MIcGcIbkjCg zXH$`i+k}`lh7vY~YDU7W5P88@w+cJ?cKq-AO0afl5e~NrT&Lrt!RHVB9uRXgKv_Fb zU59VO(}fFPUMP!twOIJef!2nhtczWos|v5DuAv=;u+mQm{2MV z72uq%Fe9qiupct^xh_6HncD>k+03U)Y%n2m#VhcD<_ZvJQ9-~_GzVwl0t{i=XMbi3 z&Rd-&RzYrD97fRqy+Y)=Sd3@y)7}e1$|6fDP$X{xhMwXMinSi^ zb)WqwPig&E;3-P54o10D;o)e}qW-WX5qtNspE{gN@p*oBn_~0KW{bF$-q>lswP@v= zQaS4ysf}@^zP3USBqDehv^&e<-OU=Y*+E9}kfwFcY)B<`eT*i{b?lYQ<0oJvWG(CQ z$D0%GO;vRxPG}mjqyM@R0!xXiy%NY1zbfN_`@7~%cdfTXzgbGWKkNPwN%+D)ImoO}Dji=|fSO<{ zLG-2s;d|0>sWsDJGeL!3>T!R^;@n=czBgb{cNAOG1!N;A4E`|KqL)hOou0z#UEA`^c`@naKpDCK#nT9;GJZ zQZ+fM`)m^fvGw1{m(M*yn|x@vmpgkf=+yb*BTXCJl@5zHCtP<8$D?MiUi#m*Q*kT7 z4>H%;Ami~^KBH%8`0ry*CFJ6S4C2rot)`>dPqcinOg;wH| z!rACxccYen#Vt?p3q+Y$coKiIzO$m~kH_9CnNh?ZOB>>jN9%aw?T6IpIP;;0#yhWb z!7ShBxa+Paqu;ZDGvA;`p?-gX4U5pP2wZwnGTP)ZO~^MQmi!uk;BJ0xx6V^%3&046 zk=fkjetoY3kCyXeeu=Po&LY&^DAXAI6AxP(20u9&-U??jrEM%plXK3`0AAlKtc@;^ z58dwpt4mY5{C|daid{YorlhBC*ym8;Ff^=pK_>&=*lm#ItG52=mJ;DxyaEL&z;k5G zfO|#L%(Dh{Ea7H7DB!=P@Dcu#cs?A_gU)vmMBeOhMZACsL|@L2Zr_Fa?u^1Sq9dPD#e#2n%Li(ISkb7E=?Jq_*!qzOm;z6dg>!~!mYjoy`)AvUUc$3EMZeeT{mmB##kMcM6Z-_*vlz7-%5JGLzC=2QpG|)BlzycdX61gh zx4;`^xN)z~UvG20qxrz)+7n^U`-)?k4%j#*l+8fhlY`w1&kjz}XVDnu=5}~4(i!Ps z-K#!O1`}}~zNzM-Na_?pyF0|50sCC~mGc@|lrK!)Mzp0^fG8#KfFS}GH-yZJ&710s>~aj& zPA2$~L3dyJhWM3v+E(((vRMMTn0(>yBY&91QoJGfYJ3pvh}=&$e#xR7@J>vL|BqZ6 z-3fvsF=x_WBl|rn|0`xu%M-4b(r5r%{4SCOo-Fc_IABCF5#%|I@uscTmFLgs_oiLx zUMY#{@E=jsaMF3GME47qH9st|8PVxO%@kDHCKWq=P2ymMcu#h5bH8GgFg}eu{{Hr9 zaqd&z$q5V7+y)UEj;=}{uk-IMAETA{eZ^Twz@;V8o&qA=!?!@hD^5#DiU{0iG(=hE z(u@GVjvINr|57CxtdICSul&TB@&}3Tb%JY<@dRE~iF0kdZE$lfI_{TjR(QwF49mUw zZb#s=a+TmvX2roD_4o?K<}X%*JUn*#(@{{?;jn5ALpw2lkbA3&Y;1(j2$%CJ zg%QVMiD%>f%!TEX=T4W&tw(a;1KTIT{N0PBxFf3CR*rURI@$IW91kV41Y|_IceqNR zz3gM)Q!4{y4&{*S2s*nYso=&7l~V-s4|V_lFqC^?iuDjHXK^Aa4+rQq`Cdiu2*4j( ze;sjuLjmh37O}~9C>pPq;l)$Y#Q8DkC$Fu3Q-6Q70%(LS^d?7<^Cn?7JXTOScXFuS z7P&aE0WIi+tDj_U5(@;bE~ZG}Y5Kq#OcBP3@skfxty6I`X6GkoD2FjOXAR!pQ;QI$ zO>ewJJSXNIVEmg$h9UIwAx3&TACpZl8qu z_^a`k2%FQNLy@zpUb&}I#pppy%c+XFr-KO{`zvE@d`WLEaRMams*(Auw1T>M@T@pO z+gJnXEUbysviset7Lqi%f*M{12rsY<<_31-9xOz?)Wwib`gg=rA^~XqMrLFUk}qYT z8lu?PS}DY0E!wS~+2YU9%*j_BxS+Z``Vn-KyrY|y?Kl~Blf0WP93+#eHyg8V(e4+Y zLvIP0mGy;gnl^FyDlsBMDU!2VnoZH?xU#xl!G*nIEi|Ns-9$^^Z5qIQ^JkRrNL36f z70572+u{GSuV3vi^|2lPkMHN5kP5^4NeNk)@o3$4Yb0tzEBf?o#3P0zA0HxSZEg7g zm{+2EM%Xvm$VqIQaYgV$^LRq-86a2KJh+hVE}jwE+z7`_r{z5JH+l=oKoAak!-+en z*#M2XBlPyrtaOCf^a(oTAL=Yt7{+1^euMMWpC)G$?)hKjr+{fI8<*Wtvta~}F?_g0 z!{c{vG+hdC3}Ci6Cu3K(Li`0v73c)qhsSh%t+GxM(;6-jW4s2pSX6?xc? zT*?D#KnI+b*{XfUg1G&Fr|S5o67ZWJRXZ(xaoBX}fm4Bi{olZ!(&vyxdQH1=2!#v$ zWWX(`hy2K;4hgkoTTlDxln-G=z4--b)-$vAwG@RBGdUMZyxa;;__dRC!rQZdbW(Gapw7f%bNYHBz|6exu75-1w48@n6f_DK+JX|3f{8g!?_GiFM+j?}{;OG(|?v0GP zQPb^x>_@5|JnBf=L^?em?i+Kbsw%_Ob#tfDB*P*B;A)UJi98F2<9y>aq^&D0IJ~`g-c&UbLO+ou#kZ?!nr%R(LkABV-{*lW z_S8q@RE00QFFxMO*Op+uj~g1P{kvb9ap$y{-Gh-6xaSVE(S`D^q;nDiBCvDivBzNO z?*xtszbzv`W2r3_ND4UT(J!;&y%=q({giSqD;#Tc{&|j4s=$6e>K!9&$@?xLTKUaO z&>-E0H0Io!_Rb?9$h35cY=zTgXNe{Yue)m5lz zed9(xmLj|fMEyI7UQ)bSI>Unneyrn>@-+3UQxE=r6Bpde!?Lpft~?QUMBZs_E^(U0 zTq$~+y{p9sV`miEEXlROKKg%5T?JH>QPYNHfu&ixyOCZ>TInun38fpAZjhExx;q6y zT5{@6G_(oAOUIKAF z)qiL(IxxD(pDw6SRd1#O(?zlKHJw~U<2BU)$3Lirk2`wqgwHU{@IV3l=T8Dc0XP{x7%ApGOjEkHF&667 zku17Ko8b$z55JCT;-R32Q~RL-ZFU&(WLkfF+aI-Zbmmc+Ke6j{W27Lxws$rCreMEG z^!H4>6bk}aKM_CeILY)zvb;7bjxb`a{`jBgS_KUy{>J?a6CR(6CJ+VBn&Z&7nEh~XBmAu)w1_+34@Exy-U(Fe-c6?4jvR$+93smrRbjk% zHCBtbE`r3p?eR-dC&d35dh^gku)zfVYW5c2%J0GFM!SK|wpdBrV(dYryjOYIoM(12 z^#r*JD2ToS11u^QNr3AyQf2Ac-z9)z9D+L>u~LeQHH1h@nZADGG3)%f9ebOqkw*1u&;m+@}H+*mN)-S zlstwZR`}eceAZ*rxqsV1I;Wz*JFnl4Zcj6s=Z*iz{-<=10Y<2*Q0hogJi)g8$5`nT z(&eQY47#wW+W$`Wd3ecZ_@gdzxf2#%|9+CZDY?S+K782D?{iD<#9e{-ZF$N1m=F`@Lr%B@DLl1v4N3}5LaXA@D z;9f?^%YoCz>2gNC)+)YCE!?G>YEw6F2^VjedgcGj+yu-?OYjH`31xE9Cy5@$j;IR( zp7ydBMJh);?xdU?c;vP9$4lkN*eMIU_ai?9@{kmki5pQ{Z!-d_(bj zu#vHoN%-YenNNDBG1-ysGi2JaFgP#K0_6MuqloLFL zoCjmA{aTE-yq@1uOf z9d$SQHW_yM_c`Ey!=u9U!aI8D>G0o@n=ij+vjnLG+6<-#h#wz)v9OqSd|7(-g6^%% ziLe^}b*1z)(W9dWYBJ~S*K1aye*Y^h!TlV5`nQT=Md;%g-P1;W+B0t%l*mzSY((F? zM6FeLUOJ1qD(x2n`z}WH_|?EG`$rd7F9V)r>XfZpefw|NV@r`lExjI*X~P?n!b;*X zi`SsiV#Q?}wH7IXmgyQLelF-mjcR$4H$r(mDauk^_&2U3kRkdeCmMXyH~wc}_?#A| z(dU0+URQ5M{5G`=`sq(MuJgX=4Vtxgi4h=C|G1)X?mXNS$+RMHYDw#VC2ymsb*EDAA3FQ91XYf&mZjNaYPb5kD(eobT z4%}{(sM@O0`dSaKV@(IRR%*H^87F49`~lZgEXPOVBq77n)KyQukH z>Fvc5mHu6yzZ=U5KtY~#er&M|_nx#sDB`C+5xT2qJ;r=L-=effPQ*zH0Ol;KLvl^l z!O+l^c7jyaJO}fZpK631tj_-nLF)>V*SAOIly;9-JF3VdM5emSoXA|Y{^TO;=p)2} zUp^r@ugYmgT66@e{m7P0&-+4pelYodWYHBtR^#2h!n5D43SgQAA!tA_|=l#v9h0|^jiXu5FY&V56FB`wC#<$zcK>tRr{k}K~j%$%s@ zcI@&X(tsRoI$!}#Vo99kmvubEQaM58KdDrZQ z4P0h={0IwxH2~^h-NnSc=>fT0A~M1o|7NBzI^F{Rt~x6irobih_`EQi06A%382qmXcF_ip;avqj?a-m&Jj)JAy2tf%l`+`uF09MMHH zwVaORrf5Gb&IWf`{H4?gUgF`SnA7CLz9^dTEx&dNf0w)Q1a_6wl{t;saV^B>^?{8O zzo?#Uqj+%q`p`ZSP^wac{G^@SN`pY)5TUtHo^e=zg|wjd6PC!+dMEufbdz%3Ce=}8;+!JUM-9yRD5;VmXR zf>P_d;|`-q*}m)J5{dBCm5*s2KGA+dIP5#e@CMMw)kUL`be+qF9=$RINwh0}HbtRf zNyGq*&kPp6si+;Nt>W0b(C0>m>==@F#0I4YB*L9a5-cwOu<#9Y$sH7)HmaH|{PODK zfN#KjruBtM2n0duuX#K`JJIi5Og(AUx!*GCA@dcoPyS) zj>#_efip<#kIoVI1UPtvz3PU`sXc zXXh5Ip-KUxl5!-8og;%r#YjmRS}3v5KL_!_{fRNPh_Sd-;fHSIxOB6C^*R4>F>G*I zc11qSA!Ycxd>rigLvzsKC`9~4j^B1hKv-CqNknAc+{z;L3HPncHyOB+S0$?N*lK1Y zlNb+avewg_V{$m08FnL_5*XMX!G9Smp>ibGJfu~qNT{W!_uGu)l)*r}Ni{U8OLmaJ z6{|?Wkioy!(8zOux-x5F!N_~bu-^Xb%&W$n9O#-(h3%@$(X&!aEQUi-2TrPzva3n@ zSbH*`-MT5*>4Yx`6L~_OyT;{L2S-1_MtBi>%a+_#9rJBgYP}vV~PiS+gv z)FttZ%n@}0x9V?XNDYU2END|7jG2<*?_u6yD({lTMDTU|buDcmd`h5HQCw&zNt0k8 ztF$AC3hnH7M+E*bHs#ZlwD4ty76`RlLg=p;RJ1LnC7(xN%&u+7Vp!Qfxf`_y ze9kcqeS_s@!sCbK9T*}J8dQ=(S+r>1`pI&TaoTV9Hkx9M&g5fA@a{h24n;5=D1e?0+y`}g*1KkK@n4c5>|pMoq_7P5Cyz6fxrsf zUvV*Y>|Jy5oR|!I*rLF*x8mf z6!|LL;EutVwvcrLHGRBdsuvzXpwrKC#5jj4JDD4?^Z@6o+z!Le0ospILlPWL!;QG; z3uO*2b!Zgvc;W%NxQ8A?|E)7V;un{1@`=doFZT!{aseRgBeQQ^=+<#j&&b$~%xscb za%eq+$lRBAV%^^W@4YY_M(~wq)KTbR_`cyYT(vcRCm8emzh%$CTd&2Jm9ekZl0@Cs zNmj0cm9ccd(^aT)Gm#}HbcCY?Gsol8YyiS&NqnONqJt3Ay~6_8oqSVHp~)`*N%g-0 z4g_S0ThS`|XAfDFT`@m=lQlh?iIR&g}X$mVUi^09>d$NeI9nu$-DkP)|Zv+9-KQ6FMh(c}z-o_*j5 zz6kQkUgI7oJ97d5sEUo3k;H%LU7$^Np)DDYf}@aL0Zx|w%%^rHyE^Q>`Lk`*5?xf2&e90*GQ43MUOI*;Qj!vBlR4Y}u(Dv?w;U%Oo zIZ&?I%=IyqssjgOpnBS4NIn7=R0nM^6X?QIFToU()_-+j^Z>_~Gs zj}?kC;S7)w(h3i8COYGq1>Dekrxu_nS{SuU)Am}{%reeq_hV{kE5Ffp#Ihs+>~)=A z1<2dtYUrh`XRtBdDj$VnSpRHiO`xq=!stq0WI&hR@+F@0f=5I6qD^UB=y10$Y6?A{ z=hbfBN7q@#{O6W510ZL*OS(q<3sP>0lv~sr@;fdu+hIkt%sWQk$X|U|U9q#4_h;wa8$UprSZNj&6 zh?@RqM4Z4EC0BF@cCbxoX2)wNS8ydV7wW_MO0GXME%k1mq-VjpB(6B=^NSk^MAkvq zG+J4iMSlg;yCwbHAxVwz^WMWz>QGC2G`ql0h9)3jSB-}f1^mN*jYInWS^L}LpVSC< z>NV`|pV2=*QkZl;ENJ=+NYnOzHYYBVQ*uQ* zE?~AD&%oNlDEjJ#{^Q@$q5+KN=T12mND!m#U%vtJsn*eb=)jvL>@-b$!vFIL=x0c6 zvzJ?>%pIL@+%FZhVUCYaB>nX|qn1pJ4A*9fQb&f@gb%{0zwBbSiEBvO zO@CzokTsawhnA3J<)jc190#jJ>DWEs%A8uzq_otWXbNVLvnAujn*&Ev!XF6#s)c$y zfau4d)niT=4~z*m(~%E#_?O8OP!LPLU!b{(mq@KLH{S!nZly{Z(d9|Mgisu)whv`G z+21n^thhV8IE>`UBFOx*ToD^_|Lx+oM~r;ql!dKkh9?eDLA7k#C9mbvG!iY=Fip=` zPDIjNRnrF=!cp_?*OTe$K)h!#kF_-Hjj>r#*=t5_HCrzLg;+nW;$wnDlrd$e;YOMf z#q|;JAicol4*4UhqQ;+%81w){7(O7J;sVA~cG!9_>GybNz!M&MY5mBVFY20`Hdf{= z5~~sN5rh)?p4@gcY2Y@t_Dc=)M8+_V(1T-?5LLzmtW&sDmrY-6;b|hOG>Ni06w|4D z0o|m>xS;z%hJo8slJqPq1$ zp5W9K4Mde9QH53<85*L%r{P{CH|!}UuP+(T0M2R$IHv!~y1+?UQ`R*1rzr-I8tB3u zgi4wG6~*d5r@{_|dU3H!OX3?yIS=nxMi|>h9Wc?wf-02g`KSWrN8;LOe7myorlLF5 z!2_5f5YE2Ym4vT=v{&yII@KqH9>6^k5G5xX4)%kE1H`b3mKDUnz<wFS~pY^%>Ng2RKPz2+?GI#l*%0P zG3U=aDE7&N9$u7&4>zZm?^`*;_Ae;v0&~%PNRKfDVKF4p_6&~7)8Ad z(I9HblkRm)e>G|+G@-H7ZG$G4+(nIgZ`stm@a z(@Soud@uicp{a$yV-h~~0dYF$p>7WZ9i&X5!J45jIwq5Hr-xAg>#Kvo2z53duc#d+ zlz~n-cjz~`jbwk*h9Dpi=cuq+D!%iABjYCC^R#;pMzs-P96eOf;K3QHc|`+@cm+@? z+Udg+b%9u4?BO3(D@i|X4y3k!x)fgj5?sOnn(XvFddEa|zYEAh6h~0@=BpL?&s(Ys zgHwX$7x9%l#F)R#1hMunVLevKi8zQ~d`IN`?Qsc`7_j2V7u=K-Gkw&bR6H^yhh~Qk1)Q2%8cpS-ej{4$X z`TbB(uOS8*c0lMvDHlj@#4d=OP1BJ&A26o6FfK^m{F7s_CHpI(+lhvu!EbyH81>t; zeRc!gg4stme-zY!H*7rc7qt%V&E^nuf)q@#<)9(T}Y6n(CB1jBeGL|w^w%d?*vmX|vc_Tu-{MZ>p; z>?CAvZN8kTJhRHwmofTv0bN#O-ES6jdMbq0qCe{r=m!A8>XeAmhPS7?*XC>8>huM? zy_9|40Uh>l4rjeBe^vV|Mh2|5Fh@gcmTdO`6Fu%oo$Ae*5h0ZBM0WoW?^YVj~DF+?yJt zlTWOE$EO)=2?i1%UtSWGT~*BKyHBJga=wdGjJ@xK%-gtg-TcZC8NRUEJL+`sqO`vf zzbGm-ZfLu_4&xeb-lTjr(Uj#8xaE6#yRln?;|%1$y*cqcz^duWW!9q|`Y_g|eCmaz z99#2+|J#&Z3hC?6R5M*Fr|)~7cf;J8Hwm+tv`X`fa%q0CEw66?U;UYUt^9npX!)+2 zHR^Yj=kJ@sh8>wrR_eBIqhfh6{79|l&V}bFjxVkS{H{vehr4I8xu^b2^55PIPTCtZ z%(Zx4wS@*nB{lE9R;3y;Tg)Xj@v#my;e$?=EcIuIow#e&nBglZy6869+w-kjk0xkK z@`=`OOnyL<*Vd|um}8U48K>pObr(g3M{$`0Olr{of;b#k@&G<-tWaPvkO_fu|>JCx?_wfGXtRACRp{!e{YD zT@LE2*{yvWHsc>R9ffL#v74Xu^Rnb2BSj|=zP;m4pDyR6HX0vM_E|;a!|u$Ipn=fx zZ^>UaJYSOVuN)YtuxwZxx;mmi?ut5B`gDmO6yJbKWpC*#25`}5Vi%c5w`ub{k*#5j z-RPp2tDYT$<&vqVoc!l5fKW`EqfyfiC(e(y4jzO-7= zQ`-((Zg0Cyh?%W=ldAuxt6#S0B>RF4qQHwcbWSb2uJEr=NdzIbDTo7(`*)t2Mh**K zwLR|GhiwHf1|kvKY4$KTt_wLYu(+3a>K-f9xKt2u+B@}CaBq8biQ5Fx*+5-rF6^zG zvS6}r!{m<7Q0n4DhQO=v)0ufU@3(X5tMIGrTVHj>hl*MtlfwPS%k#4&`^Kg&)oJGm zWN);`k$G^w>PHk;zx#W(7j`a#d+Ld{Q^UeteuB-JZ%U(6M0fZVc=Pw00f1D|iSoDZ zZMR&IxgQ6Krw00 zMkfdB2Iw!xr{Edt`Dy8eX6CzA{aTTOV3pPD(IR%hRtyxa5ix6YlDGxn!E~0WgJt)M4Klq} z>h?ZKlyX}u&--GBg(|(6DD!qAFM^u)EcqL>-(0TmS`CL1Dn*-2u&}d}pII*^J#qO( z^zytrsT9R+9?VyfcAsoTZwcRS9j@nmx7if7Wz*#jM0a=jx+7^l_a1(S>RlUs$yBxT zg$yx!X+6gdRTH#*h8z?qmd^~sAn<@54f@!W?NXTRh(B?m_6cG=j)Dj;_lNVxLoHbV zSk5L+K}(2&fLP!@re(%|d3AMTkh)-~8^S$88_8pWN)3@zmyE{;742qjIOS2k z3#+Dm2R0CPO5)#ZK3hV@vq-wRY(5p-8=Y;cBje|vOn^_j;+|? zXvuEp!7^|^STRi$T5J22#)9Yi0bWp(gcWBi{JZ zm79b@Wjj~wcw1!Tm0-eaB)M@J1g+0w0+!8US3iG~=1bJ>Rqng!2~OWB%YmGELsqOu z!?DP0$IKI$qS38+3pfAx7SIF2^2ahrjth$FU>F@AqFOX?|FRm7&W(onXKEj@mkp|o zDuH~5FcgdWkQ?LfK(otG% zYcm-Zxwiu`;_y*>k*8tM+`fN;3UN9oX1@-pqZnSj@7on^iW{>BM8Yi9Ije6mI_*>kLyRjlSTR9tCAE zGS*yK?r`#o_2FcM!1uDtnu_n+(~fiF<%UiDj?J&u0tLlm@Kf9%6Q*3U)~7-3Js3S1 z;g;AT!t=XdCESFCi^V-tjc^=x?b}Dp1ZoHB1}4hn_F+2Zzn|HVV2|Z2chRbYtHux7 zR`~TznhxW}JY;CTfz(G1Xb*H@^`uiZH3cW%4y~SQ;qUG*8$lxcfEI4#Mij^l%K?FHpj{^_tOtD$q1J8kf6Y*am zsPw(0IN4kJ3-yCn2Z*M&epHVYZ{W$ZfX}z^!bdA+wumXtdSEE~pu%%GJf@1dW>CB0 z<;;%n7G+>@?RS^Wxr2mQ<3637sG+soUyQDmBFTx1sCRpBoz2uB%Ryeys~UzB`?27I%kBC8qP7hX(xsl1 zaYS&@QRHJ+2PX!-Xrak;r|kX+Z)>x$_mJBNGf@9i&cjP3LPWn;8>pcpP!(u)&^=O& z&!UXv!~WHz3JgF|DFRuCUm0&M*&FP;#`z*#rVGsFf5mBDy$m?R#22BOr0&dM$Es8F z>r#+|;0|#p{TgW;Oj^%AL#1%wBomvVxW`nH)@&}SaGyLA5OL${j-KOoO{=Tkl4!l* zju|b&6nW#Ny>FsvJUjk3B6M)_D{tZa13Vm zI<($dp8tq_QxmY#R)Q#%^cr8-T6U`iOiFUE!Oe<&58e#0KTy|MX@NQX`QJ+`G*t?+nM6Z zEw`f{+{Q`B3%jQV9GVAJ%_h9~OCIA{ceUFJ#GbN2Bb0|>%RI|({%BT4Iq`{>mYOQH z*);kxvpP1t+Qt)3V@WZ%JI@yIY8Jx@SN#$0Oo2uARRVvv=vM4=0MjmY?xG|*on+mC zE_6OX*cJy^9HK}$SNg9W&H-J3VQa}=7n3NyNXnVsj`L#JLlapE4~0M-F79PiBOG(g z<$NS`u;p)lSCJc6)Wa#pLHq*Ap&7Eh@av7n<&90I3xU9_8UezoFU-|HVROW={fBM0 z2UuL~rS;;D|1eS;NuObzPNt+$Jhn*s>ufTraCWwX{S$@72(1cQ$e=XavtXw9rt0(G z0K6AmI${rTm<(8!H%bpv>mc~?0dXJj{{gkU9Z)v+6ykW#*T~^PaiRQojW_`W<3J!} zk*N5C(VWgruwIRImiyT3Yhh)bC&O2^@7+64Dnz{Ql#d9AdUvcNWBN-L%gG?AlisJs z^-O?CDGIVFyl7J}Ry>>wn$CCIY%-eJT!PhECQ|V=iJSd)t9OCxRXneW;F% zWUbZDa44#$n&j#T*qUvo$ps%tnBR0Lsb%<##L1C=@GSdCTMG7$(m7E7bi`iEzZttq zU#lVLi^11qwAmGcx8+(r^(8))MS!%U9$mXi3Q$JWybpyDz9@zd?*;QecI^Qt*nre= z-->&Pdf;9F4jf^t9dG|eV*w!9x1Mh*Z3P5O`Vr$fXq@-Fil;dR){L|g4Z4|pKIrcm z-oh(i4ZoLPyDPMOsn_-

|e*Yh>aqcD`EUhAFyAP9UTm4j&OOMD}m(wVB;F`1+B zU*=m9+;0su?)`OW-Z^VZ^@11d!~IwZ4~9ZD37DCq006jmur7jBY%Bba1cLb zWUrERsSt4wl!XGXWT7-?8G;^WUnpBcJiahl%Nq$e2A1R zlruG7X!zlz0@e-@^Y2*# zqUM%FOfyB{b??^_?N=rGJnl(0^>5wzym#dJuIE28IdwgK9^8Z^k>zO1zhYK8kT0Xf zoTBnsm&{w)weHWrXQ2pw2fez5EXgSlv&a;Da!Uk%vEK_B5;RVQ)$2rt4L43Cb61Y>`hqaPg)SMH0Fmv|gE@#AWK5TwMG zUo=SXGjI1B&pLYwAClFuC46uXm{CrIHcGjtDLl`rK6CtX;o|yH?tQUhdi+!jE_~xl zb^TEI!2)M4c$;K1mETa>uzOZy z!#wC8FL$SvlIAwY?@7q~t!OH0V~#BS-9n)znw7_d!g!9t5k71CAD{Noqvr7Ga*#O! zfS{rs$q{*@4F(^5vi`q}M1Y7IsJ49IJK%fwD!xME2Ey`K7#O0$^HFr26#Xu4YE-cR zl9Vzn9i#Eli`w+{{)9gc^V1mu<}IZfm1f`Sa@bVG%ccsx={K0?mX1m8@FmZ$E53Aj zPLV5yF;XgfJL&Mc)agq~5G@&m)K}3_GS2{0Agvsvtpohh9qo@)B*Xry{OT^C3z;W~aQ(t1(lN5%x`e%^PT|9@PNkuQwor}D zu5FFIKv-ILM4xHA4p*AhU62a7V=moP7_K!;PHR}^^+u{?X7jwzo&M9ek+Us+nZ&By zHO@zBmWQr_CV1B;|o9CPCqK(wx z`IP-^_m#UlzgkkCoi7_(;v87Wj11_y;@>XqkH^PE(jS1|>e|TFx|01br;PFMEdr)E z$A2QkhMFwy6{}sDTTg2}iDqDR+2T2gmzPt0EhqXWvD{qe`?lLfahv=5eJSoEB9qEK zxBeSl->;VE*oQXVO>DD73MxF&&RdD*#0%i2;%7n@qwTZ*jG}@r&g}4sPJI!iu4D;F zDVt?~c}~{o`5)T$Va-{{5XoFxD14|=_Ep=Se=A$=!+D^r!(*Ym3?G%0^2F#JC4-qz z1+49Z(%DiKy}ur@B(FQVMCzU=4aW#zhL9EvJU8K?HgS*SrxEquVL6@=%=VCxXy4T2 zBL?758P*+~Qx8*T3zM;ICq1e5gp;oPz^9&}&k(3KRq!0hvnc9zDs2SrDr(N)5!H)Q z&iCG|&HImAdaOUX#y+!Prp>mcP_yEfOZO`-%d7qd(prdrXM^R?t?pcW$(u5rnmrsY zaTwaCBS8o5@0Kccu3VR^f}pIcbPmsSl?lq`RKI)Q8STn>=n(1ow+g%6_WP6tvbu7K zR3RY_mEm?|WS*mxl<-M=&n*MOxRRtV=p2P0a|!@4ET%VjK9IFw7E6@iaa+PO(*t&5 zd=5i4m%wcSD$`$!-c}(!Mww2q^#|)W)htzu$9AK7GKBKh)#d#~EE*~rHUqYn1yr*u z-6>NTn`sj57r20^enCxiDR~HqvPvS{-5t7)6i^p08fPz4YRa?y>+KiK zZ>MN(aQ`@u@=UXz@{PU=dpUeQ^2@G4RH2R0|84`#qpc%ah9BBpVlFx_Dz z#q86s58hX*T@Fuoy{K(CFD<{?1i3lseVx2H{w|bWtV6$t;%a@;nrs-Te*E$bQrvPC zJ?oeK+yM{*DVX-AvM%dz#8#L~#iXzgVZAB_VWoYtfBTfIK~B{Z{l-+Qt!_>dE`)+h zqW>%*NFaSd@gr*y{Qs#z9jF)vZD5&3x*_*KJ-~qlKe9dQcOW3dx*Usa(C~(rm}@88 zcCcNc$Ef4i%E>-;d)g+pol~fZZ=UDvnwUx(yY|O%g2zeem)+x{38dUMY#UMpv-lm@EkoJ+x^ zSbNI4ndj8|Rch7AmM(})afnWn&wq>H7!ERfsKN!TKGTk(=@w@nAoUYGwj8r(lJfM3=`bgC<@XX_jc({5U(@h$ zL*p8!tdZ-9FKxtXt^9m9^%eD%mryUGr)V8j=r{rc!fLT`Y2MB>vWYo378P{~A^d;T4*~r0CFl$M3a>?^Ht^7{ngg`q z5yHT=bC6HmNGKMWgiO6KtpH6F8t_JDaA_Z&eM^nIcKogqi)3cRR9cf9lvmwEglF7B z1Re;RE=n9>?D?=Ouia0(N=jC$buOn3+pt0xB`xs}JB}`Du56h2qm8FEqc>kXk>p3V}gu^^U#+?*YI2eq)PV&}999d@9X){{7Rnux4xv>!&hd-h!?IY|dNj)mCf z>4>z1UX(rE@&i$Xs1v5~Ac!Q$<4UlqrpdCyLER-Cv@%mL&?*=; z@E*w#i3+rc$r*X^?eaX2*E$UzQo3ny8FL15J0mhLo8I7xpmCZTMgFGicgsS-E#L8; z&Eydzpd34WkAWE?Jf_`j^On5M^OkJ;OTfn9({o_KjY>>FAVmxrFgceQLi%XyBs`Y2WHt?%t+REb;0!t9Beg zV#O07=@*Hb9k}o=3<11ycstl1zqu3!8tBaT8W?+r44T0o+FMudo?Y$uX7CN}W7r!< z3KX{9@HCx^ij+$ZWpI|2%`JZ*J?&ot8`Dxz{ZM_#JPe)v4-}nAT;>mbVFED1$IKHR z8^9j)mGsTcY;`q~lnGuG=<*g%*X0YmA4}j%L!aUO(KJns<)K8;j7&p{L3H|Te0%}F zt6{Cc1O4+}wJIAa9pdK@#YE};byk{%@A&(&=1|tBHQ=lL#5r!iKW~Qg1xPAj)p0&W3CQdJocUV=o&6@%w;qp^DuRm= zDQQ^g9$PYA(rFvt*PN_oT@GGkyfVJ$b4^bg1Ej$f?VhX<0Xg^yVnD{4%h(x;kn#N@ z*hV6VHDj44G%WBhnhJzG3&5!DS7tv9t@*&Yhu5d{mJP5T0hQPOG19+4UnOxN;%w&( z$&3hR?pTQQ@qCvT`p~%{4+P+)?y#wj8t(TEGDnt|)8X}KAC_JEr%GKnaKFxO8NRvN zduuuAusQ!7-gj6_Z{I4fM|31Akj?-|`zGOMWBGx~*3V-Zku{X#c}yo&^ci}DK=fpv z$6WcAGpT?92=TCOa6JOmF9vmaaDbFvpzoMMQ@*?OR%xl{-EqZ9Lyh;g@HviaZtw~+b z@%4~9A*QpQ7oTfkN8+AoIE#mW=%6n<1K9b zKm>0v3E7q5SEQ897`Dl&OEpIdlua$a0n*EFENRf4+OZd9H)5MyE)4>}-pt=2HfjgN26>DVM5|94Ca|^7ndQTI?5*9v`>95P_j4g**E0`&7t} zUYYxkZi?ioS;`c7mC5i6tY6oct}tXMs;DR$!W#w(CQB0G9ql-Xs&fY4k~d?|;Dw-L zitjDw!L_OCPH2E|-jBc1nHL>5`mnKHP!S*3_lGiE(w3GRXLuHM2#0AHY7+eI&r^yU zrk|CFqX^4N@I)(FL{~*1D62|z=`X=F#O+Ycnef4@+>o(qR zmb|l4j=sWbJ+ZCZ)|Y4yr1aUQA;AzIr+9N+Q=~X$D{wbDpUv~aZYq#Fp9~Y*#H=ZE z4J0S6K2^f8-ighTs_Mz}CrrwOwlsVBhg_zu+n#&T)|&;%iBq6ldNJBu!{()+l##l1 zkuPs|)@b*xs@#IePpZ=4H@;uIyKTqHFT6u9k^0_f!Kx-Sif4D#l}9Qxf@2Ed2q{t! zCJ=;0F+NV(?p;jAh#v;+(R>0UZu_PZB|nJg#Lizbz^Zn{Pq$89hNTURlnO8*vkc7C zc={=o%^3;084!!W=OcE}{upKC{ee{797f472ldY}?fws-R$c}8W~_V@Y880d#-xiZ zH-RTzi%4u?$Jz8DlrZp}Q~))pLZN=~S4>8Hqr>B12IRE;!1-VfN|E2fAl4szh63ai z)GE7J*70$<{cz<9D=Qrf?EX5mBIUH+UTP!lIQBpKAY`umoKgw!*&f;}jPV;i_KC3Nnp zFZqKy(|8`O+>Z&o*s?=UaoY3PhbXLW7MK1tz5|e@K)5o6$vFB%E@~iuAX4%v9S!@K z$9`?zUW5g_p*vmWw1YZeK8S88SX?-uV44%@UcHe5U+8!Uiu1=^{#J zX8JI87!J4ScvH3dpH=mQ0H%#%ZlaN0Uig89&mH7YQu>@gA9x3uyf<)e8JiREo$kq1 zC`-n2Y|_epc0NA;!|@TDXarVftluL=IydQa9dTNa7c{d1C(4}}5^K)Yr zeIfzeVL2!9WAGG1<+`s>5EnJ@8mw0LJ1^WTbR^&$sgjE=zvyB2&e3v{aBwP0c9FlL zdUQtz;L|+M?BH)4`9iiam`EK27qNX%>QNj-QL->Cu^l!jy1y5PDBa!sx)Fa@ zHCyEqVKe5cMlWY&1>*=?)NES8edQl|-nUyxN*@>DXL?8N^e*kep(Rb#Aa6v4vd)xG z#4u&LU0~b;cJGX_9$<+V4YX(B88`CRv3>p+tjV0!S21N(k1|~vs8+V7Hz+uiG}3X~ zh@kn>>(=KDbGtKm?6d$~o$yABCT>vQSp;iVl%vfuiQgH=# zHV9c*IPf;`htQ_cjCqXm!>q|6NAqYKsx`R&-S9B=l>VS<{zBUL)y)_ck{?T^livIn z_!{wm4vEp z50H%1_+Z@#>63+vx zkSeiEu2txT_4e|Dkkwz?b51-iF7%-rZ%l+%TM~a93}NHI%^4=0%c6~d^`M2^pQ@d) z+!ZN8O!S`SV)QA!hOgsuQv$Lf2h|(Aedb;sl}FKnIPjx2nWw}-A?yw&y;-swcW!>L z4c~e+__)>?1?h2@Uu{Ri;fkEx zFLb!lGzatjW$>dI!Rpe_^!4>0RA&$H?29+U_09X+Au~_1_AgVDwVmd7TZK-wF#$5x zqXeg_AiD)_X}G}k-)=i++!Bn(W|RhG47D%el#PU z;88_}Y+X#&4&S4K(g+Z{FbjU67tQfa6=tJW0@!=xV9pFG2(c*ck=ZI*p8^n=6>Ebb zBt8gwtezlcnHLg)-{R;eMugxiIE4$pS*8vdl}NR8x}U%rN6j>!h(gVN0qKS<#l`I1 zTfKr__}MKAlO@FC{25kLs-Mnidhe|d*c>c?HzRc1KT5FD`r`)zr!h-ycbkeFqXah6 z<(y9N+=V_Yxl-aGM!&z^i~Pnnyz@1G=xEmeA|J_*tcj!Fy$$F7bXUIS&E1aVQ=~}( zecspA`e!qcl&+6X$~?1dFQvg`5F&wR$u>F8K{?u9Ko(dN$&f;qAxsUbxE_U|=F!Nu zh6gD*6S&|%IH%nrBaA^Xf!zRlSNmqO6@sCt!NM?$g`6<&xisk(E>wvXffa^Eg79Hv z_GwNQi+3pbJ~$27SBV6H+Rp>d7<+>*=d)23QCld=wIKk4#w@fpA|I-YXU^Ryrf?3cYuz`&NkD>%;Y+NG9?h+SIGM~K07&1 z^(r8PP!TW{+wzn5FV%K@XtAKdMD(}oda2d|t=;xDXLwC9yXqdi2U*Sj_Wk=z(M(6t zey~&8AJ=Vfm-w(&TV#nA*>k=xkkzcV?`xf)LpZP5MdHGd?sOYj2dBxMN?SHL$eP>;N{*m52>ES=M3B1m(-q-z%-D zgH4dMgoyS(lYL4E2xzJ5NsJ(2Zn;Z#H+=sVnqfX5jbU8KOCvcn(5?R-wLFF|xD|Tb zK_M94pgD_660~yf`Z>p>)CU)~bBuX_#~rdd=Z^S{hhY`E)ju;Z+)TeP0aXj)bI|yH zz1}RHvYLIdmBc7Ywa!{KOT2(HbV(f1xo-=ry2@W&d6^9W6)AYV)7z68SHeqb%A42x zR5b~2ck0faHH@BH9;6^H`Pzb9{?;s@Dlwv63hz2u&NjF=xKq3I4@h#F^R7?%x;vHk zfp0qzO&+`gqfg}MLtKNHGi=67KkEzFm8J6Sz2&=`^;XW_rm7Ap1s`8#5~p%_{=f_A zB-LEJs)H*S25OSWQ(ZIq%gV!{D&=DqE6eb$jew6{6fvI6!Or#`J$RrBT;QZfiFf159tj<(*u*5(qrZ+V{dGLq=z-6-F zt{;AtRRKNzrPz2d9+8A0%Sw5sB2NG2q|qC^f{lQ0)#m&geWUy3&EZ1c5qETZa7&5T zPwXE=DaJ;g#=3t%-^nRAN60fbaPaZ}Tq_#AOF8_clR%zy7Gju`UDQ9c+MblK%)ida z^;3!LWqY;|i!kV2FdycSOHenrRZX`ND+S^i|D8a;h>V3Wg;`AVo#;(8Z{-K_EfU#d z_Kc^n$bFrQ7pFneIm9XRSuy5NMoK~Ch>GnuPY&hztwmXsRrv?s26yA9XNlBi+SJTQ zZB&VvaMz{RbDPy$6-7G(pF${n9(uz*@N_-)u`ywJ4(@m^Vin2W%34k*cU3qSxrA}* zSU*tRG%5O4T#XidBU~K}3|u4l*p%;%<1H8X+|vvB{QBxkKguFQQuIu>bwND5uQw^i zFhb(4XIQ8Kyq-;zE`k>;JxZsl)tZ-d>PS=Z=}G$*Y!15|E}QK^@RsXfVFb$^ns9G+ zr%x`ys~p!mxf*b9Gpp7-0>j{yCCwd`H0*i1GC|(2ym1C64Nr#Xb4kQc?{6LH{EU^p z5buU2CX3!ddO!Z&!ysD5TxBtZ_4;lQhw2Wr)|QlZOnMf#Ts2S=Bs>Os*PYhR zEniP_ytH0p+3FEGYc8{E^cc?b6lkr!2ixa4!${)47POCcQ*$uuWf&boa@g^?ii8OR zYo&7p416g(p6U@9k&2Ndt!jO$gxx&z!*6sHHdgxlg#>sZ4m;LN?k(`ADnYWhYTTL+169PVs4q_82p-F-u)CXjy#nUA!*RVoU`R| z@YS*s!zqwwN%VM5LF|x-9r8fBr*=WCAG*m@>=trsT;4bsKpDSa zu4&PAFZ1toe(yA9n;ofWiamhawX-h&&?XJ3cGH$tD6@Ip8Y{dx;=WhReK54T&y%zB7F9Fy62JZiXDWJ&%Q_GP3pJkP{9s(SH0+f{<6BS6WOo6H} z)+@C4rFWP{+wWk0dFNU5TBqA?x90&iIobxz`sGW^1{n4w)oZ!Eb@L#Y5v`a_YgR%4 zv(c=Y|Cdc`(ApXPYt(IM!~DZ^5(Q@aU3sth;-1T3f978^;)c`Bfj2&Gn(nZxO|R^K z;vBQh@rzWF@rCxv(t=b#lh|YOFS2H!$Y}6^i51mcL?8 zD>}^fN}RO2N|hX2S9H9jC*}s*Q94`_$0IkFj~s))i+|Osd<9sNcR~uSl4XtKcj@PA zpK=!3%Anc5HD=SMIcuMN_S2__L8dCYiN2wqs9^!GCs<7kLPBToH8WB7{=9V+{~W9M1#Y$X+!N8 zZe5!9Gv$~L<-0a$7}|Bfh4y-*Zad!!em=hbRA}MMF+I<@-pyTkodh*#Wbn!epj1GU z*kk0cQeHZI!(IZWSo2))L10UJ?9sve?|)Zf5>Xvo6I>0<_f$4qPA=#=%mU(fT<3?+ z$qdH;$Bka#OBv>sMK|k{e2in*U*2BH%OiQ|+7!2JY&cR!B%lBKk#wmulFw<6)M+o2 zF@GxZ_wPJs2Ri3@6%8ZX7R{VoksYCoGs&WHGV=1=f`Ya6a&pdCiGW`~GYjFb!7|BW z-)95-4MI>U0R)H{C#l4c z{gC6hg>k}+--3K}3#`lEpM>-Cw|McA?zre3wj5ojT&&CMN9v7DmvV{ZE9yEWsYh^d z+Qoa#&(Dw3&aKz3__(15WFArQ@B^6Rh73FvIbfzLqW<4MSGgyG9|U`IhrWHgn>+3} z4-5I45MIAp->)Ilg!izyt*l5kUADI24iOkw{qL{NZ?U zj4uuOuV0$-=~_mxrhtQfKK_azK1;cF^m7fnKJ!Mi{DfoY4%Mm^)^6F-w=X1EW!StS zm_tJqjR5B#0m@bzG#(xlpa@MK_8JWQK8Y<(`Gx|Rz7M`(c&ZYK>nlI;7;PSbO)Z#> zs~l57E9d>?WvSPqwe>gYw2PVd)7NG#?99|?&=>-sQC=Pjgh=a_{cD!aoMLU%oc{KY z_PFg8f6p+JhrXf$8sHPh1`P)(8R*0%oEbq}Fenv`0N-w8nPlYz`}-RG{xE_ulP!r0%NHHTyrrS&c9o`%bT1>% zsUq%!&n@hFVR14}$)t*9IkA#3{le^Qo8^+URC$$gBHCqki4(t6A&*7+ivPDxzdwwi_Za>0tivCc ze9>`?FAas&Uz&Q-xr{ug;5|@)vt^42rs(~?Z+#xF~UpgS-10xg80KGT$0B6=$E=|7p5S_PwdFilPne>%f?Jk6t&#bn3@%*fefe5^4n@ z&crvKfHurv8`ZE)CzA`iH;boEz}6_v|BUHz*45_EFFvqGYts(RKaESYTCm94*cK|cD*I(+%sf)S6*k|@PZSO@6OpL&v<|9(Cb7pSFBy61 z_+77tEnH}AhBTCuR|;sn#WJ$620IYq4_zyaq2C{7RZMh=UhmcBc_dZcN`ruO1Yh4^ z$B-@|LKrKUAt=5yDMD9-GZf6g&WVAYlR{?%2rL$mlN;sz6D?jzt_H7C2@w$d#0?hb zIHBW45EBh00fF)vH#Tny9SS&Ja2(-6Kt`P;+(X7yA!9&b!DI(u9Ro7%VQ>8#DxWcc zbB8#ms>r-S`guk#pvw9AIz~-Oe-ZyU9JAI_8#EDMd1}*1FOMRrf^_ zeZGTldCE*4_KN9p>_97=k)-{vebDT9!~nD4*Y8cU&byoDU3y|^=ZD`|TQ>V#cBiSg zZCfYJowrkyMyT^qr`hASrwo79)NIhibUoobBPTyeo{V$-FojGlBw00RGVaMI<%aw( z8oqp}k46mxx@3>I$KOzk1_n8;%di#FAd4)bZEm;Ag$ZY*H+r=eGvvAZ`<34>{GsMd0oDb~$G(T~1_~8pi2@q-Z6=aMAPKKhDG}fk z^Rrh?A#9N7xZ%N}o{}KI9>w1`$?tb!V*fG^$v;;3{Z6VoW+32>6aH~yb6()JCnaPc zkt;~Ny3Ui4F;vFXpn!(LbDcYAUnva&{@=adAFnR?h5CQ@e!rCCxMCT9Lgo%3+ZykP>3j4MSD;8voeAATzm5#pnb8FDmH7}KnC zcgxXf5*~HOg=X@HFPpk8+87FYme2mfCe?1zT(VfVbMDSk*cO@L$`9f*a7&m;me1!Q<~i-2WF~UIKkp#%VQMt3u%0v%}#t# zfit;Afb$EY8gT_DE zV(s1)yqxMO4gtYUT#h3F91A%{cw+{~4}^8xC=ORmFAD-*4}>S$U(C3%d1K(UC#~Q| z3-)bc)+#J{Dx)hH(3SC&E=OjMa)`N(0UjResQ?7nBQ3!b?Js5w;M}2r{WX?2I7mNd zt-`T6HKrmEkZ~qP8k3D<>tjfA$0U?B!s}pVttf5FQ|K~#>`237xZk_raC;whn{NjV znfCB!55x?K}w0WRG2!%$5-l1f#$g?Hmfw zb?%V)J)u1AP<~|S&C};XNPhQhm9#7*n?_YI0x{AUu|X5wjzl|CbZLF$(TGTx zHfU&z=C}7>f^p!9IL)b=>2~tPn4XswYpFTa+<1MUl=tZtD=grvGloJVV{)ZwgbHX9 zdvNS=GQpBB1mb!%*cX<~i9f!{Rskl!SzI8yf*4O8BmGtSGsD&|5nk1ac}iI_rzb1~9YzAQ{_SnJcgw;n-XnQ_%>-3TSwI zpsYbk-5RgAl)8q>RFFo6yPXs{-KjF&yEnktn=V<$v)`CwPmW|w9B+g&t~08DMjmbP zE+4*3uH-9NKzg^ub|7S9PWP)gCs_6aC8aWq_eeUZ6KO+|E=gWq^(X>91f-w1QGuWh zpwCGfJlULR+5U%)Wjmv!LW5>gpbN`ID4>zP&diYll0)5+AmGO@22bZ{A=;+kkGn9_ zaib&2hGsDP$qPmK@W&zxv^WWOj#*Kl3CeF1(fk!?Qy zb#^-0NUvBD@X1k)(Ap_6O-?cE%6+--+6%fq0eGKt&G-&*WX}qfiuAza_AP|bBwLv2( zu3H}C#=M2A&FXcVOx;@5%v|`}w5(@ZZd0c;_mOgCIQITDd4XxwtgczUYNJ`TW|QgF ztz`zP50?RY>0@OaH#Wx}vCT$NK*KADV1|D0itsBrcnBte1yc@F8Z_P& zO4KgRT;2!-#v5LYTb#npdc^Nr9V=^mMZtJey7 zB*tyZdW(-Lv!{Ik;ZKJyJTfAJcd zofE#d9zMn#dr+rDil=p+sk4@v?|=Qr)U933y#47kGvb?>W)r^hQb0B0=@U%XPTM5y z{w7RWWLB)+2m#o(sU!S}bT{99LNFu!$axbY9hg&rrpZ2n!g-fMoX8oB1l{~Th@IJ%1$N6*ib7n*jh8kh$4st4lz zfqWQ5ufpTnQ-p4P;%js7^Wy`pIdIQ5=JorJGEE!R3d9!|;6ii!FaMYw+BUK{6qi30 z(kYamGIOcfqf7I|g;H)W40J~HLFs#rCwAN@VvCbZmV#BL0zj$PhQN;}CtHG%ha%4* zSz|zXLvZ7xUzz9M`^8>n*ptVbzP;Ngbjj&|Ei<)i=9+CGTn(eJzFpe)aB0hhwW};~ zU;g;FIcVSzTg5$B^fot~yH{DND}C8Wck|Uz{20K@3D}_V)v4aCgn$g-p#mCj$s&!5 zJ95WOa7y};eO{?m-AaytbV3V5Aix;uF-V{{Cf$~TFfp*)b|Rf^)$~gx;!1j2yD}?C z>zmk$jSqAN?~8&Pi`SgjH2Rzgm-R7Z)4UKoOt*QwNH3es8}Cm(zGxnL{@b2#hWRKg zI{CU`W+lER+e<~)nS^j2gdj_};7dYXrLAKXgeARBebt#7;<+ftY+i$qVEd7c z3;AOQK>V>9G;s}nI#o*55jUhljYF$P%~lj;F?&qc45W?9%^5ObYN&_*}|~|6RJSY~vG}wh2aidkh$C z$3eaaEQPe!8!vcEWcRi_UxMRC91WV#fy8Ny{&f-H$Sc#&z=FwY&@dApigjF%^*hhY zdrod9d4B%q>OE9Rw6zuSNAe}X9scDE??O`{ER1PO$TeOW`n&1e?|IXy?{nt!akFE} zY}ypnw^2uN@8NjkM{(s6X>YRfti-%Us2K&wA=o4wCly7zA$9uuN?FE$A~a~iwj4ya zOv8yG&HFJ;1#AU_TqTc-cBL6cfip>MAbJ+(oOs>rgAFxcntbN9M3+ z8&-$ci0Bqb9gz&SPMb~QxA@gQW3CQ8N3?9p_abkJPGEB z=GYi1vv%EP^V&yK>=oLzs&6K}H_-g{;khOk8ZZ$1 zjK$YRES&ybzCJWPtW2VDr5RUV_~2J7kY>A|yy*}#W!QOU;Bj3UG{f-QAA_&eiC&-i zLNCpy?R4N{UC;^RsDi#i*{GRQDjd{9G8F_4;3y+iw zb z^84hqqTjWE~pb=rnWoHUs(*!v(U z>5d!vnLC(8LkS`PDW@SPgJPsHS)SIOTRl6WCC?KHO8=ni{)_2DZfSKCf%pipZ$;Sl zCAV)mWt=qr6|#Q(DF{C`E_5;?W#hQR5l>Ee^3MuVzOgCTz`)Ch27v>FpnY)$BAozp z%1hPPUm05jJ7uH)zB_7~7xmV|{mgKv7Yltceh$1v)mgf<6{|NGZkr%Y{fqCA($$lU za?Kk%TNoNQs9`3)cec6ej2_tD6xr4=d;W@~w6AXMs-9h+#tpdrBboP%>MWI@PB*Lc zBL@BCbVtO>#L9XQ;N;Mai(`XEwmA8#Q-AUh2s|q1Ir%C_s(q%uDDkqOJnumF3j}N~ z=Cu6vgn8C373(}Bv4U+0ngwUZ*Si51&-b91v}`gT$8;iATmqRJ)G)@0`Ko1AfEHN|5U|M~)93F>gO zmUax_6;(hZxTm}uGu~unWn(x;H2ML%f{^VNF@3`k$wc~}JWt}advY5ac+^e!^55L|!U+|00x7AYvlZ36_n)GXcbSK;L zhz**k8wuo!N<+}?gN}=U^l2}_D-y`*mHcb|Dw~6oJlaN?v%m>6^7lWTMZoH{n+ydx zV<*nHdHsKA!)4qr!FaxWC(l@7ra|};{KD^)Y}qtoTy(FlEzDI9d|}@I{11P%*8dai zSxlO?I3}J(e7O&sU(QIp);lAonZJE)k0}%b%$~o}ODFcz?S$2f3h~IZ zjY^Ve*Ok6uU1Vi+!o=6KM+o2r9mfWZUxTJZm+-1rPr?Xr`V&fVq9rerJ%&g6h8O8( z{C2`zDPj%hN~uG8wYBjqH|o3DULJbt)N+I{{4My2u3XeDrw8vL`(x>14W!!Cq* z=hI`&gV-X)-zn*VtNWP0MqOmyd#ryxO0;#)m8K z{{n)th!z6N6gO6hV26v(0C^n)vA({MjB#W0=FmA&sMIFVCJp!z2x`zof6bPhe2zs> z;4%B2bMzP>zxi0Vh{_X8;%}O^-~7ZmMN!0Ygzs0{jf+RJ4Jf*A7xf-4YWygw9Ook= z$Nps;!BVhAiM_vrWfQOINHn$6WTl`Qi5kHV=($4*lP80i(FG6@nSKu;4YG zd~<@CKl)N@l#^=7$6WrN`SJIKwvJtQXlh0bI?<+m`NQAl5ZG}cU2tMIbN^NQn?7g1 zX$2#^l{X$Z+MICcj^^v1=bB-o|Aev98s^%w_AoW7=h`ySe`K;#qgt+Q2h%y(654&I z<~F{lHc8&WLw_?D-8ITk*upRJZ#~q{9O)W6oWFRr>3GDmI9{^Q;&h{H*zeWhzZ)7z z+yG(Im8bVGcRlkRj2>167MIusW8aJ4g#hdyb9A2$=KaTxwU?r>?1?uf*a<4JO}4>R zJI2XP`CU%5gyB^U8b3Ih;rE6M*W(wEc7!lM`o_*3u!YAZE=+8^TP6?cq#Of2hIR^n z|L;HA-}dEUV`i8WuKp0e#VTg>i>H_#J2#gq%+qgAw7&z|w&7O8+b`MI{vIU5jK7y# zTUqn4RgmRJVI0~EnmT?eZd~!_rT@1-mw4NoXnRKPjcHx5MTrZqIsdG(cB!i5WZSm? z2BCGIJzATmZaxIzp%6|vV+9wCcVFJyTzb!E=Gk{9*;C-Y8hom!HCNRA(caBr7rbrn z`(uoA6qIv;dDVkon4d5P-hWje(|7;&Y?eo|03|NRU-_Yp=c4ZM8xOYII^vC=%*gTS zv>S$-4>3OOxl0RsA{XQN`1}|!t|Szo+jYEr3bZ+9@#kV_0z3T<-^Av zfdG%)7Wy0$Bq1KROW_QOM`V(&dt{6i&NOLA6@O#6_>eMO+}!loS7z7aUbJcaLt(^0 zd$lpU@6^nGd8Y*Q%$q;DMUZ;5&M8=zo^ z!Wk~&SbpFwBcwP4Eya&3US^+XwNJ~f)Am7oire{4h2iOT6y#DELV*oWYC7$PkF0Qp z?Y;ce?&i9)_p~)zW2Nx@^Y0ofaA9O3_s4v^e`+04GiU#^-!QMk_7BH18Api2nk%DaRZNX>P=vDbHuS zDW1ZVTr;KI=$`8~t|0u2w#N3*S~1Foqx#Fasyl(JDM-9 zMg!xyrP;dvv;ss$b8+d>`86DiVWwl^?^ocfG^Kl< z(h=lkWNX%-`=N$@zDLJl9uQ5>zCFo)jG?f22((k9DUrS{zfYEx_i!TPM_9Qb5SEg*Z&}Zb zd*cjmuJROqU)1m+mE`?>1%%X`t5D!N_lrx+;Cr084+YXwah$l2UxP;CQqhe!2C%Jh zK1fDS)N~Bk`VW?4PUHoJKvuT1#YxP_*(nH~6d#u3XFvok5EfuQOu-PT-silaWuiP7y(eQS0<;br^fTQ0~6ASY0y(ck}VZ6&b1FMsF=XlSp2TW}WQ z*jLs;nlx>ZXNzLqqBS<|=XcJ+g61f1s}3V&i|C)v6vjVm*B;$O1sZS=^rzgt*PsKF+ z3dLy9gcs7-q#|G^L`khNSXt9XjwakcQ9>Ag(Uq^d)FO$di%#0joPR<$FZ$ijrrAC$ z5h7^i=`HriZ6sU@HGT?xs7XSS-~5nI9Ssi(O**%aXwdPiHmRs_g<3DPYeT{Ff#C*oN2x0T=mPuOy{>blC!aNm5DEj{7BqE;pc8ohlNM8Ok8q(Q#ulj`a>9 z)u0IhB`Qir<(LIij@##=@~3=|TBkhCjdc1^JDaW@n_3MzhQIM?*fC5JE!ur|Z)J|h ze1uyK{gg=G4toz5HGW9_Vdc0*l63gK?d%ru-rcveVG3FP#JJ<9MBd-mU@P{1-CLQV zPaJPGi+}Wee33&HSf`9J{`ynFpXeCCw#qy)s@6x`JD!chPSmeMkC*+ppLuZQqkV z=yXYT%R-+9qVMMuScCiGGs5evY%}6kw#rR#Nb@Mp3(HF{PtSkx1$Y-sj&6f+h6@3z z7$1J&+ve$853^rcd2OEB!tF$y+|wv1zhcRv=Dg!~wO`j;VhaPmjB~rrOAy{r`{m`K zzk9076ow2qd?&kAA>RGSq=#FX_!a7|XU5vBrySWirU;Gkl5QBdm#0=t!=&H9uqnSR z^D8^a|E94KzCTrQ(gSJj`aHXJL9~5%ABXPU)}|%WrXAZhvU&Nni`x>eJ*y`$%JB>W z=jR6=x6S)2wr-KS?YNC~dAz6)>+ut{XU4$(j(oL0_5X(3WLeDm^OnU=tO6|+@T@BV z=L&H&XlTKeRRpSWO6cEoL!h;*S;8#`++x(q-TE^Hb|OSGtzL++P8z~)0f7qpD_@X* z%wBH77LqiM%XCr~j6vL%NZT(vLl7exc=9`G2SeN3CPi%(+I*3PN>SqqZQ(>OmMGNa zao?@&sYTAUxwXho6fg^g-QOiA?`Ezzt%qdsTy9D5QzG~0&;Kwq3^~Sf0ZJh_HFZex zJEwgxGEdJ6qvFOYE{cU(ZBy4!GeDk^#Fxh9$PoC!%TQrm2|$A>e2bGW3ElpE0 ztxN>G$ejfiOzEmYBYl{5R(iq~5;b=BfL*F@aTo!Gwj2kRKwwE*QxuBM#`Z!|D;V@A zaa%Osi9(6=?XdT7QR9cy9aipl_arrH&61ins%7nC@!dTa2Nw8kWF_+c=6FK>00$;q z|KBk<^uW;&WZes0OHCD+y zoNS2QiJ?$Se&PLJ7;V2CopnqX>*qxA-YfREetsD{{lKWNraZQoDPix_{}0#_r1 z*YA1qU^8ppN_$i$7c61KtrY$*X+vT7lESXLFYE1PFX|U48Z=x0y)$yUx9H@yE()PY ziL{9Zi+R!m>9!}oHM4L$x8JazY@xCl@P~^qYTJ-HxPlqyXkr^>Ho9M$`LZMZJY|tB zb1b$;^>qyoGhVhr(Vr{|nNPV@2a${;pxNYWN3eh|LA}XApuD#@$#0&mo$A_~qJJXn zF9`7jG(T~{)vi^2Yv8g`{TeoD5wz<>pyJOf+lScq9~u0ExdvPKSpM;w4u)o2ww>t7 z;-m$xLu2Oip#J~U+h>`R+@rpwzOZrSsxy1o6PYd=(9OL2-~MJEjBhXa@-l0nxJ8pX zo`LP?lVkp$z3TvwqFCBxL_j5ofFMb76iFfy1SCjQq97_}e2R*JXZ+1P6J`)ICJ?~@ zND@>q5F|*DEFd{3NhAsAUtiDEY|re>?%wU*-tJx3-R$)Abefu;?&|6a3zk{ZZD{jZ zXXckG)ESa}&kwxV6(<+o?>yS`As@y%0g)Vl(RHX!2psn80D0??bkW8t!6nic;{_!o zmUQnmQch;hv5Xr53>w#5n3=kBSss_jnl3?_PIwTnkT5=)b}H0mkE++0>y1rLwGRLA(p-!^xdEwzwtxL_vVAs05Ez1^64KF2Z!pp60at~L^8_miZ3{ooo}oWuAZ z#Wmh2FHU$@du7($p`z8G|pMkyLRCwEQmB` z-@ah?K|Tq9ma_Vw-G{i#sW^W(+nJ#|I&ob%QXUM0CcamM9^^m(htIj66#;le=)}f! z+pt%p*^4);9W2--XvZSE0PIpD9snkesNjsB{;Ol0wri`(RG2*_3H0NI5IiZt6AK6! zNP55xtqxvdN53a_E#4fnQ0*W!WpU;)ys#3$;!OvL{p%`4kbuF01ERvQKwg^(0|@~b z;1sx?rGf;awF&89>==6JtuHL6vVA^n71d!?F&GpDc%K=}AJJ=v#1TLYEhBvRu>aU` z6RVAgL1U!LDo})0SmEy202L>%1dXeohZSieGKv8gKJ~?YMhl81J!~Hd==P@;EVmdK zxF@!nBpnty;$j-2^-GW0sV76Z%#iF^VXxu@HW68b|nTu`1ck)&)nN1DI;J~)9uH$bv))`+Vd#t-s}-7JLFPB8*0 z3ZbuEZ=gFifI$PICw!97i!tG3VgN4%;>xH##y{wcR)2#!opl*xgNA!>hG8t{z>)Ic`e;+WwW-%YSLcBH zEB~D zCmsA2YI0v(?-pfGNH5-dF->CQxlp-+@m>IS(8VSMM13JqB5lEas9khxT^YfcK%`{$ z>^r19BOw#o&_wfG6|GIk1ATE2XkQNLPXBjvV?-%+G4bkxwtAtKz4(Rg9*A&@%U+}t zI~RJl0O58~gVKsw7PLV0))CirSexB_)JK9wR?O~%aW%qZj)VcVTM#KhocCI@+gLH^ zJKi?b4Q8_RReX=Smp7?S)Qa$30brBGj|pAB=2?4`Y$g4m^TUX}SV8DX`r-Mizvm&fM$YJh_(jB9?*+#}32ZlkD`B#b#;hKzeCPU_n z%~;M?cvo4BO=3ayrmeOF_s;@n@s6_qcGIh9?r1BQE$r-cBhB6H_7Xc`a1{v~FumGY zBDyI1ux1=G(xOtBA`N`$*8}JK?~nhE-2ybD0(xfC?ZOCIHxmfZeCz z?CKrvrU8&j5vdIoVgG!^cBc>Gwzi2|EC6+F)S@c=GmUN^%6Q*@4x_ckHb$>)au#8Nqj+0&dQ@rQ2@5_(=Z za@1eC4e9c+q!2)!HJ0bocf_&i6XWFiBF0;%K3=H`?H|Ea(D>PqZG8xU@jaELC=(5l z#*F|5jXrK9x;Z(qJlBFL9VKW)y$LS|61UsGyNxz|b1QxI=H>LvUCq@yQw&6#F@a}< zG#da?HuyGl`!k4-rEmMq!^jJWG=BKy6Di#p^ERmbvKa%_L}4n&I)DFcOC%zFLslpM zdiHP1c9v|GEn!b?(!S%;z$kR2F#yOC`b8lw^dmH}p&ddvNrjMmyg8BQIDSLm!?1l{ z`d1ygpdG1XTY)Q(0VhrMgv%4gQL)7et6_YlLSm+=P<@ z@G1ou^VJHvif!1`?eVTMx(k~YV(a3611?gG8S&_%myI?zVgg4NN+@fCW^51FItU{~ z;-I1=yXq1btxeeRlZD(Jyr{$uzcAeD+C-(kh+Sd3%xr3VeHhLXM#I=66&PMHdX0`-Hrc81zUwb=!n)@ps5LgZ>O*x8Mtz|+Da;x~>V|h=(*@Aw_D`wzz_HZNE+0$= zKm+#Z2EcdHjBQfDcsRb3d$qc8Khn5@`+iWqR3XP5IHZC~Up&MyE)MBD7~~Z=VtbUE z$@VgWK)!SN#*r@C^T|#;(!vvrxaZctb1=MgkY`=PQhV5a7l<}iVLX>{6b6(B4*piM zvgbGvWO1T06>xP>PYD4Gn#5G>sVfIxx@fO-WYCP}`5gcTCgx6EO}c&43M@fl8Qp)D zjb;mDqE~xMf)|Vs*ryRE1tscKf@ZtDh)R+jy zHK1S5I_iv{Sm$qD;-=RPjFag+NgVc8=k^^0Flzk;sa+%FxrQZP-~t-}I|{J>po30~ zjhL{E2H(?C83aX|8Z1?E{|y(=pf_jH$cf8THV`Vq*&~z?N!ZbsU40~gab8H#fGKib z)#9owNMVBbgXfv&*!U=1S<6nnD%AebJtsko`pri!(Qm78ENyy&jVrHUPcZPJ^1ruc zseCXrEN*zKvB?NqCGwE(hQYMh{eLTkyS*>yTCge`cNC1 z@ZGP}ja4*s29?y2h%=^vNZ`Yuar*|3l-b-%2nJ;Fl90jz3c+^-1H0EfG(j2dmSp!_ zbH4gs_tHi%^UOH+B!%#KJu>C=LljsH%!b zsaVD;Fy.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 Date: Sun, 2 Apr 2017 08:24:47 -0400 Subject: [PATCH 27/44] Add mint OmniGraffle diagrams --- solutions/system_design/mint/mint.graffle | Bin 0 -> 5902 bytes solutions/system_design/mint/mint_basic.graffle | Bin 0 -> 3551 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/mint/mint.graffle create mode 100644 solutions/system_design/mint/mint_basic.graffle diff --git a/solutions/system_design/mint/mint.graffle b/solutions/system_design/mint/mint.graffle new file mode 100644 index 0000000000000000000000000000000000000000..5ba2e5f8680c884c16dafea5bc6f5cf19a9b8c63 GIT binary patch literal 5902 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 literal 0 HcmV?d00001 diff --git a/solutions/system_design/mint/mint_basic.graffle b/solutions/system_design/mint/mint_basic.graffle new file mode 100644 index 0000000000000000000000000000000000000000..95c2e81e34b984f0dbf7b65bb529904d13edb9f6 GIT binary patch literal 3551 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 Z8c(K3wbdGVz}&Ca{twb4x8Bf{0008u?a2TD literal 0 HcmV?d00001 From 0c3a785a8d5ccf02135460ca48cbb7811495c715 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 2 Apr 2017 08:25:28 -0400 Subject: [PATCH 28/44] Add pastebin OmniGraffle diagrams --- .../system_design/pastebin/pastebin.graffle | Bin 0 -> 4996 bytes .../pastebin/pastebin_basic.graffle | Bin 0 -> 3163 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/pastebin/pastebin.graffle create mode 100644 solutions/system_design/pastebin/pastebin_basic.graffle diff --git a/solutions/system_design/pastebin/pastebin.graffle b/solutions/system_design/pastebin/pastebin.graffle new file mode 100644 index 0000000000000000000000000000000000000000..879a6275331d666d39ad857da0e4e80df457e3f6 GIT binary patch literal 4996 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 O&;B20g*~=CK>+|P>E4F` literal 0 HcmV?d00001 diff --git a/solutions/system_design/pastebin/pastebin_basic.graffle b/solutions/system_design/pastebin/pastebin_basic.graffle new file mode 100644 index 0000000000000000000000000000000000000000..fad80c2315052ee4343a5fc004d3c699766ddbf6 GIT binary patch literal 3163 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 BF9ZMp literal 0 HcmV?d00001 From 1f7d78ba3e3d4623d31588520e8a9231053b1e2b Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 2 Apr 2017 08:25:39 -0400 Subject: [PATCH 29/44] Add query cache OmniGraffle diagrams --- .../query_cache/query_cache.graffle | Bin 0 -> 4053 bytes .../query_cache/query_cache_basic.graffle | Bin 0 -> 3055 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/query_cache/query_cache.graffle create mode 100644 solutions/system_design/query_cache/query_cache_basic.graffle diff --git a/solutions/system_design/query_cache/query_cache.graffle b/solutions/system_design/query_cache/query_cache.graffle new file mode 100644 index 0000000000000000000000000000000000000000..bb122b4f057b4db82ee0c5c19c0fd1b37602e9f8 GIT binary patch literal 4053 zcmV;`4=V5bzL*c6*~ysJh+l z)9udj!T!l<2g>MncMe~4UR-9`=w-Kidwc8n+REw2*V-`c9w+fgCE48p6t)fy&LA7S zfNCbCmzo2g4uXF6>iM&cD|PouR~PjC46eVQm~C|R=Wy9i5?{Z0wvlEDwEq=U=fu}h zFihg{$T@;{uM_{`B2;3dJ2fd-W5FE(O(DV+m=!EGy0en=7HlOduYTLl)V%JgF+rHG zBX6B}9pt^l;wAGs|3L6lEN)&%oK*d{<0w*{H-3@@QPl<7KDykF`{QdBW!1h1QKp6} zd4=glclLhfHx33WJ&5~PYEZ53@TgWxZv8$;gY&S~y6&<-F+5O(3@~rWw>Qgkl}BbwoOtyu|V)V&);7 z6r@%f!#DAb(!;msM}tr;9f!j>Q_Dx~C<%r^w6ys#4B#fD<5jvufREvqY(Kh)=eE5TT}q>< z0xZ*cZ>VUqm;FB2`#Jpe14imUo8ia(y|~AI+5BbyWaqMXdGrps`254qVSl&&u@A_4 z68x^(icjRMd!g=rIA`ezClWVcLVV@7+(IVBXJs!{*2-`xVr%ZWi1Zv#~x})r^@}1`0+Q z6K3MK8<+XfJkHw6ILv!0yipm*lS1Aj>zjH$$wbAk!-TIweR zRvZ*FNuk{y;=sNxW?yQPz1U$R-WUcoz4Qn1ZF!W6MopO03_9hpY{E5DEjk5zNm6Of zyr$hC4Asn_T;+7(poV_`uHt;*hpFmT3}Jqr-i=hn)VL%mxSjez*wQ}K8i;y^>*D_4 zjH6=J8Hd|uTLDM;V$K_20iAu z0(*i(fgW6JLomi2N-(7Y%n9XK`@7gekcFV-A&6QCdME^;Rb&1D%;Mf(jakyc;Kc~! z8p4e6wGNfMO{ke*3M7_=DGO5;rXCNbR*(4u)`MI=5T;;pg%K>pJmLbzuORs(gPFlX2hee(Eiwg25^RukVp!bwfI9_9z`C(d{RGYz(osl zPYC9yT@XGx%+be$Iq~&jju7m4#UHWKJt*P|3pr00a)@Uk=dmG&$Oj+@f9QJ7a}akC zL#`CCBBNAq0=F&3DA4%p#Q4`hcYxwn!;!L9`y3pjtRM0u@GmYT3>cH*FACe;VO7l!fe zmOeh%*N3T=&bEeAGNpquSh$Ysap?*(kSx6~EFTmXF5NH`&V9*INy6 z?QBi?`nuVmjCoC{XO8g&z)3a6WwZHdoyA$@Cd-NGdDU!6oXDX93rRRfzyK81s=UOc zixP&7B>-6f{7XU!#+-W|X(%CSC;>Ovrz5|w>OQlxlF9JAJ}lKFn`JFTv<|DyN8z58 zAY-5pQud-@SohBx?x9)_O0EwZrx}Jjgd>+=L!TQ5sO-ubU6XrUv1oMtii30v5C+0; zr9f9pYEljjGiXyq%FixqwHZ%Zw^mt~5e-%DCQ9jZ=CwMrWL!`KQ)>WHL-X<&kb7cb zg4Q)Q5J4><)eC9`KkpI^o4KZ=aSwHT_zP<#~bMi|%K8N2WM$bQ=T>xoh z=i%7}I=hGhcMNvbl`DR9Q=Wf1-I3t0E{bOG~!o+WBPT=#4UA&c~z^Kh)-HMjcv znff$>II6+i9zH)C`N`lc`{Z&2|6@$@7cTV+AuNB9NWV~;n@}$|VJtV%!g=DYUpUT9 zxB!#i`nu>$A5K=$h2PKO1U-MA_b4T(bJo9r&Zz4+x$A8C{Yzz{3?0$;D$$FZ@Yt_r zzzj~SIbIR1<=-Aztw`*knp%;LYxN4_)an(hSFB#Kdd2FMub@}{VxHsmRXL%SoD3VN+^FaqQteLC03N! zt%9evRWN&C)Y!S-FE`rf~{_`y2a`it6QvYvAV_H&iMxSov5(;P9Rk5 z<3FrWu|mZP6)RM%P_aVg0sBtO`v&)&{?xzTMza32`21<@_V2f;w6e;|Dl4n3tg^Do z%Bt@|R{b(o$z7*+y#Hf9QcZt7S5>Td*h&>fJu6kLRIyUUN);BKP6TWK?uiGV$3|U@*`H2pd zJdLk%(c*<;dq+mg7yEEFD_^X9vGT>rmmhE|qWaw~Iq`8zdyLvgeOcPGv}bA0(%uiT zGePangx#5#YaHx)R^u>g4_iEn#*s`=nDvyq8Yu|(R@OK!L!RK2xi0k(Ol|x9bym_? zNn*nLF^AYn||m={U@{+fjPB%5n8a=2XYM=IG zSz(d9dLALK*w8?@- zQBX>0vmjVb4wUn;HI?K8Q^_a+?hyd(^xsbYhS^mk{(2m1q;F871|l)(hx3N}J;3yo zA_+XrJ(mk9Y6xQDk(swAT_&jjnd%9~1!6|;q`_NKf}vKAP!PI=a%uE7u}LeJm^7uC z?AxgRKB8}6pZiFDsj<12-pzw@FSVOT<6c_-dc)96=jL!$_^N@(OaGxX6KxwwyTZy*pXK zuKVLk0q{!Qr@`vNvijFyb+j6b3z%cDRA-EXo+Og5#Nx=ZwqWv(oY<%F+-C{DCl6-a6tz&Eiqa;S-;YcqLfKO7Qba=0}YE(i=m1ujZ` z&spp;zD;!(imh*$hs9uN3mpRVZ>+XxzWL$K=qzHikTJPY0W#eheR!XL=D-CV3gC+a`;) z%!69van_!Dy(qZ$Gi4aI>Rwc#$O^^I2dsJsGI!|*Nk4`Z-wx7ZKc~0tOH26NKFq7w ziH1RBYL*84*wC{4^8@fXP|>i2z_aN~rgzqeClR596z@G$bMh$BFyZU1IzwU-Lt^IR zcoZp}%mtUlP~}!{s3{8b1L!n@P0@E0JT5!l4O^cdqIt7)=PJ^s8F{WYK@}nC+ ztt4RX^)3p28>^zgZk>MbSDCBtgETk~)%!RY{9D~sdr;W1nMZ$-!jmpt1Dxmax`xqs zJ%+VH+UsY*&Af|dj9EDAq|*nS+I&liJ_$;ycA_juN`twW?o*zRK%f*S*L-SC1o=2g zpwaoL%)8z&*i(s71dqkq&XsJf1AM4ga~OybmMq8>&V1hcAafS; zpujIBs%e{kOH^01DS_3zj>3eQ&!HT2kj zOQ=3mCxO=V$J@Kjh9LPs>h-|9Xft247e~Ed|I649gY2&8GU+;6sIG$fN$`8Qv5Sb* zz-1cq;v_G_46Lu!ZkzxQnp%u%ExydI!#rG?2bXgRqJB6Ys7=3rHB9u4oaxP#<}gk@ z4&x|i7HIfH)HHkOMb}Oqo#opF7zsR^&*)m{NhR`-P&c4NmM0(*6m4){ptSh3OxX(&eG)qpZYhd zm+ppswhO6!G}7+Nd5%*xm&47&23BwK#3`E0xMXH=7-wcYnIY9icN79Wzk2?E59?9U HmfipWI@SR{ literal 0 HcmV?d00001 diff --git a/solutions/system_design/query_cache/query_cache_basic.graffle b/solutions/system_design/query_cache/query_cache_basic.graffle new file mode 100644 index 0000000000000000000000000000000000000000..27ebf47fb201c4414763ba705991be5c9c5800ef GIT binary patch literal 3055 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 literal 0 HcmV?d00001 From 3544e62d7b66eefa63a879ff933b983035e12e27 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 2 Apr 2017 08:25:47 -0400 Subject: [PATCH 30/44] Add sales rank OmniGraffle diagrams --- .../system_design/sales_rank/sales_rank.graffle | Bin 0 -> 4970 bytes .../sales_rank/sales_rank_basic.graffle | Bin 0 -> 3172 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/sales_rank/sales_rank.graffle create mode 100644 solutions/system_design/sales_rank/sales_rank_basic.graffle diff --git a/solutions/system_design/sales_rank/sales_rank.graffle b/solutions/system_design/sales_rank/sales_rank.graffle new file mode 100644 index 0000000000000000000000000000000000000000..0a491db54f8871c7b1a46d4bac77dd7f6be9e480 GIT binary patch literal 4970 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 Date: Sun, 2 Apr 2017 08:26:02 -0400 Subject: [PATCH 31/44] Add scaling aws OmniGraffle diagram --- .../scaling_aws/scaling_aws.graffle | Bin 0 -> 15601 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/scaling_aws/scaling_aws.graffle diff --git a/solutions/system_design/scaling_aws/scaling_aws.graffle b/solutions/system_design/scaling_aws/scaling_aws.graffle new file mode 100644 index 0000000000000000000000000000000000000000..460d1debfc040f479a58e90d9a65a4afd5e82b7f GIT binary patch literal 15601 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 Date: Sun, 2 Apr 2017 08:26:11 -0400 Subject: [PATCH 32/44] Add social graph OmniGraffle diagrams --- .../social_graph/social_graph.graffle | Bin 0 -> 4209 bytes .../social_graph/social_graph_basic.graffle | Bin 0 -> 2958 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/social_graph/social_graph.graffle create mode 100644 solutions/system_design/social_graph/social_graph_basic.graffle diff --git a/solutions/system_design/social_graph/social_graph.graffle b/solutions/system_design/social_graph/social_graph.graffle new file mode 100644 index 0000000000000000000000000000000000000000..a245d5a66c6cf1adee681f215f75695d42f0c3e5 GIT binary patch literal 4209 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 F?_Uj_T;Biy literal 0 HcmV?d00001 diff --git a/solutions/system_design/social_graph/social_graph_basic.graffle b/solutions/system_design/social_graph/social_graph_basic.graffle new file mode 100644 index 0000000000000000000000000000000000000000..a753b39c782fbbe976ae8348e047b086cc8475fa GIT binary patch literal 2958 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 Date: Sun, 2 Apr 2017 08:26:21 -0400 Subject: [PATCH 33/44] Add twitter OmniGraffle diagrams --- solutions/system_design/twitter/twitter.graffle | Bin 0 -> 6340 bytes .../system_design/twitter/twitter_basic.graffle | Bin 0 -> 4119 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/twitter/twitter.graffle create mode 100644 solutions/system_design/twitter/twitter_basic.graffle diff --git a/solutions/system_design/twitter/twitter.graffle b/solutions/system_design/twitter/twitter.graffle new file mode 100644 index 0000000000000000000000000000000000000000..f93f4eac7b46b024f9ae8cc441a15eba22a9a64d GIT binary patch literal 6340 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 literal 0 HcmV?d00001 diff --git a/solutions/system_design/twitter/twitter_basic.graffle b/solutions/system_design/twitter/twitter_basic.graffle new file mode 100644 index 0000000000000000000000000000000000000000..c754b9e8844cac5a8e2e04b177bfe4805236df65 GIT binary patch literal 4119 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 Date: Sun, 2 Apr 2017 08:26:33 -0400 Subject: [PATCH 34/44] Add web crawler OmniGraffle diagrams --- .../web_crawler/web_crawler.graffle | Bin 0 -> 5149 bytes .../web_crawler/web_crawler_basic.graffle | Bin 0 -> 3830 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/system_design/web_crawler/web_crawler.graffle create mode 100644 solutions/system_design/web_crawler/web_crawler_basic.graffle diff --git a/solutions/system_design/web_crawler/web_crawler.graffle b/solutions/system_design/web_crawler/web_crawler.graffle new file mode 100644 index 0000000000000000000000000000000000000000..831e02fd36379087b44c9f57a08b251816258c00 GIT binary patch literal 5149 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 Lu_!LQWmW+Ia>4u= literal 0 HcmV?d00001 diff --git a/solutions/system_design/web_crawler/web_crawler_basic.graffle b/solutions/system_design/web_crawler/web_crawler_basic.graffle new file mode 100644 index 0000000000000000000000000000000000000000..7d466eb227fa349717677771f29c2e28c859d5be GIT binary patch literal 3830 zcmVHjld?_f6eWhRGarOPC?x1d{CJaLyiK zH%5z)97%>SIr;BfE#F#FOW2SLn}`Q2TUC9juKKE~t1WN-{_!fbu4R%2arE00Y@;WZ zjQa5)h=#vCd2_P2;Xe8O+1lnmc8<1B{_5>oqcBJ_tM_K>V1L_sveD^uN25@7Iy)yj zR_|c{_{4%XI-T9aC)SgTEE_%TbZ%~LY+q5?{rE}|rk!3Ak7SbF9zbIoz+exu!4v3a z(t2Sy@aZ7vXV2Dt*}Rmu&s29o-_PLw+X>lbM|}>r{Uq_##V?y_mcaO*L3eh16$Qg2 z9*^uJxO$%W=jWjmo1H0%MvVox1q_7+&5+`N;oj8i5_0mtWAS$!K*hd#TaesUzqpUplAj;%WCeJY4 z?98rbeB)ps(}TEwDF@~L4v#9mS!v1IS8W5 zy4I_MdFc-$nXNFImwpQ4IKGg;Rn&{loCI|He5ye;ODHxF+d#y^esJ^#zrQ$p z@iy$j{q0@n2TZq@e@Zzhk#7R8*8qIHZbbt6-`h%k= zyuI7bO{kc+JhR}bgY9R*wLI`|WwIX)?>Nm24BWu5<@Ya@ zV~z&7V+;Bk-+V+>=XL877Q|h*Fys7lL35`qY=?eoYT)<+tYtBP z3g7;Y&NQ0?DNbi9-t2aPw#7+I2%z!!Ql}`8OlWoz|3)9@FXr{kZ*(*%Ew1&;iI`LQ zK8~-JT*hrby7tqF2hmt&^3KIw)YhCU4#!tfHw=c+vi;;7$0NTF4QV{!hr(wR^d-NT zlkWuSDD-cS`@SyYxuw|18fDgR*5sl(zUcy|D%{lA7uHx^t+K|#n3sNXhWhJs)0t+~*!Ga|X>KwH48=BLjHQ$H!XF_m;dKku7a{a~i zHLPx3+Y6&OO|o-*>PKmi|Lc#2m^kFLANONl-Et6{yh+Dr@ZQB}?bGQw__^#XJUvIJ z=TQK!{R0ej_Kl3d}0&Y&%wqf}~xHJFAm|=zZ0l_+IWQHuN99F4}iQO1o5y< ziD1-oF(ZsK*PAd=4?#=Rafl25Rt{p!-L`Sd_l{e>ZtziDUxUtT5x84UWA%)3>3paj z7HUDEn)g-!;Z8U(gMkqWiUOMHOY?wAKrxq^!z&9rp)cd!Le6D|>TqgSh=__7)gV$S z&79!^12}RWj0q8hxx(=Pj%XfNR-`#+!OW%(N3P(I`w*g_gu2}3oC?N}i!kGa)bkTh z*sixgK%7Gnsdi~l)Cvq$m&E`<1}A2KpQT-54e%IxsR5m3Ag2~^%5c*FHce2|1T?iU zQ^Jw5lB(wJXETJ-RgDHW8BL2*OURs|Rb|c|095Eg;t)6JVN*#U_SRK^yUjQd@W)RV6Q>A}0nc9<^P>DWe|17lEq=encw!UW7Ys*4M(-%BDlu z7foCm;i_7eTNLFCTe%aJUbjBE!uIq(m##tR=*0B5JB8VPdu+FR0*++*X_>VEkU%0DY2sk(O;v)4zX--1DoP@EQ1V)c0 z-0FqnoP?`d_lN%7Y!cx(Bi{qiV!oMl5I9~);3>&D; zxbidZxVE^`P-bXx)1N=>t#LU{*O{LtN2#!Ul1h5sVOH9ub@pXHvL!R9Q$k z4tJ?w4STKBWo`J=p09b>`5M;3)He@*9s*P3JHV7<3yNKbdV;EIQeLtqHl_qIz)c7E z`HC>r)~{QbdIXgnW1!Exy21|SKW1Ua0AX!m=YEA92-!GA6v8mfAy;+9N`)OjSK98}$sgzP-)fTTkA4^462Lp8Ou3eEOhvD}SK(X}&WR}k8Vy{u>|)km>?y$6Ff77PVzl+l6UgVQrU=19?zK} zMl0@~dedjSIqb)E?+*U~yt@*$X$`h-!vHitF^T`N>`D@@zU2+JgAsLIvg*kq>Nt+z z9#|)39$qOXfWXzE3<>q?Fv3GZv@t;&6SOfw8xwqwnBXuzes%D8!U5t`!U2a(q5%*6 zxb?=G2jRE5{>qLWt>(xDm>F{%#yCWx#N{hFa@0ER)^WFvyLH^(Waxpj!2 zqC_w#x=L*=C;lpk;zW^^fus@y_$FtKY-)1R6-%Dc4~K-97;ems3j)hff{Vi3Cpm3= zld37`qpz_;U08XIs^<@-=B?{WB{}h*QjSjIV^}3^ZhA#(QjPL&WuiB!x!sCTyP%k0 z7^UEp>L{8t4|f0a<&O-S%4hDb9+wu&w-JiMi7b-lN(iOmYE-!T^`eQpYaf4 z-GXpiC3Bd#4x}uoyuCZe;DWI)ly7>FWFXJ{g@4iTOTS+XV46leW%$pDf3_6;R3Bc; zp>9@-nQl0qjUDDuOgRL$9^*p&cB_quiv_}*Qo%UKN)X(0Y@yz{s!%8d^42ZRnJpj* z23FVM9C2X~()&2RT68^8M4REfF762AGVVAUCe3-?`ViMF6kl^F1>e$SZ%cGnp_%^` zuxj3;W-oIS$}u;-8YMDKj}+=&YQ|Sm;(k231eI}0s71H;1_UZ{C z;)6)93*_Q?HY?-crZsSFif%IDL#R<4U z(}+=J#249Bn2Srf!R1(js2`38a?9^u4imMJGu>LL7vq%UFphG^0t27KH1!-R=i1Gs zv;4RKBEik(7GDuPaf*@$g}R17WckK{d2kekxAj8?6^+BOaMUJO@Tq?-yXju&XM3R9MCo`nl?2JP2&d=8V2Z9>0?!uJ-0M!MCg8%>k literal 0 HcmV?d00001 From 8a263f99257922b8fc49dabc325748a01c00139d Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Mon, 3 Apr 2017 06:41:00 -0400 Subject: [PATCH 35/44] Add reference to interactive coding challenges repo (#49) --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 82e71962..c9164c71 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,19 @@ The provided [Anki flashcard decks](https://apps.ankiweb.net/) use spaced repeti Great for use while on-the-go. +### Coding Resource: Interactive Coding Challenges + +Looking for resources to help you prep for the [**Coding Interview**](https://github.com/donnemartin/interactive-coding-challenges)? + +

+ +
+

+ +Check out the sister repo [**Interactive Coding Challenges**](https://github.com/donnemartin/interactive-coding-challenges), which contains an additional Anki deck: + +* [Coding deck](anki_cards/https://github.com/donnemartin/interactive-coding-challenges/tree/master/anki_cards/Coding.apkg) + ## Contributing > Learn from the community. From 32a537b1ecb358cb4ca2ff997938c58f78afaffc Mon Sep 17 00:00:00 2001 From: zanemayo Date: Tue, 4 Apr 2017 10:56:38 +0100 Subject: [PATCH 36/44] Change AP wording for clarity (#50) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9164c71..f084fa85 100644 --- a/README.md +++ b/README.md @@ -456,7 +456,7 @@ Waiting for a response from the partitioned node might result in a timeout error #### AP - availability and partition tolerance -Responses return the most recent version of the data, which might not be the latest. Writes might take some time to propagate when the partition is resolved. +Responses return the most recent version of the data available on the a node, which might not be the latest. Writes might take some time to propagate when the partition is resolved. AP is a good choice if the business needs allow for [eventual consistency](#eventual-consistency) or when the system needs to continue working despite external errors. From 424c3465aded9d84b9518b6c98f523c1b40b577c Mon Sep 17 00:00:00 2001 From: Ben Gadbois Date: Fri, 7 Apr 2017 17:20:37 -0700 Subject: [PATCH 37/44] Change Pull CDN wording for clarity (#55) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f084fa85..0326880a 100644 --- a/README.md +++ b/README.md @@ -589,7 +589,7 @@ Sites with a small amount of traffic or sites with content that isn't often upda ### Pull CDNs -Pull CDNs grab new content from your server when the first user requests the content. You leave the content on your server and rewrite URLs to point to the CDN. This results in a slower request until the content is cached on the server. +Pull CDNs grab new content from your server when the first user requests the content. You leave the content on your server and rewrite URLs to point to the CDN. This results in a slower request until the content is cached on the CDN. A [time-to-live (TTL)](https://en.wikipedia.org/wiki/Time_to_live) determines how long content is cached. Pull CDNs minimize storage space on the CDN, but can create redundant traffic if files expire and are pulled before they have actually changed. From aecb070eb2bbc9ec4890de77cdbb6f9077b994df Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 9 Apr 2017 13:15:57 -0400 Subject: [PATCH 38/44] Update system design flashcards (#56) --- resources/flash_cards/System Design.apkg | Bin 46286 -> 46227 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/flash_cards/System Design.apkg b/resources/flash_cards/System Design.apkg index 22628ab808f003b916154cf9aa2952f313912f96..67f05d190cbaf67142d0cf634db38b95e696d7ce 100644 GIT binary patch delta 42495 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�ALWdA+Px|hi< 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 F{vQdd;0^!) From 99acefaa01e237aee7d00ef49d53e7b2936aabe8 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Mon, 10 Apr 2017 07:04:43 -0400 Subject: [PATCH 39/44] Update Translations section (#57) --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0326880a..fc623c35 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,14 @@

+## Translations + +Interested in [translating](https://github.com/donnemartin/system-design-primer/issues/28)? Translations in progress: + +* [Brazilian Portuguese translation](https://github.com/donnemartin/system-design-primer/issues/40) +* [Simplified Chinese translation](https://github.com/donnemartin/system-design-primer/issues/38) +* [Turkish translation](https://github.com/donnemartin/system-design-primer/issues/39) + ## Motivation > Learn how to design large-scale systems. @@ -81,10 +89,6 @@ Content that needs some polishing is placed [under development](#under-developme Review the [Contributing Guidelines](CONTRIBUTING.md). -### Translations - -Interested in **translating**? Please see the following [ticket](https://github.com/donnemartin/system-design-primer/issues/28). - ## Index of system design topics > Summaries of various system design topics, including pros and cons. **Everything is a trade-off**. From 2986f71025b046a1e66b4f4f2b8e5db549fab1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Thu, 13 Apr 2017 22:04:38 -0300 Subject: [PATCH 40/44] Fix Coding deck broken link (#59) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc623c35..d725ee0b 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Looking for resources to help you prep for the [**Coding Interview**](https://gi Check out the sister repo [**Interactive Coding Challenges**](https://github.com/donnemartin/interactive-coding-challenges), which contains an additional Anki deck: -* [Coding deck](anki_cards/https://github.com/donnemartin/interactive-coding-challenges/tree/master/anki_cards/Coding.apkg) +* [Coding deck](https://github.com/donnemartin/interactive-coding-challenges/tree/master/anki_cards/Coding.apkg) ## Contributing From 95b4d92667ec841721bb5122292e80c68b3365ef Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Fri, 14 Apr 2017 20:35:50 -0400 Subject: [PATCH 41/44] Update translations section in contributing guidelines (#61) Add credits section. Remove currently non-existent AUTHORS.md. Fix maintainer copy/paste error. --- CONTRIBUTING.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aba00538..7dfb1c96 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,20 +42,17 @@ If you are not familiar with pull requests, review the [pull request docs](https ## Translations -Thanks to [The Art of Command Line](https://github.com/jlevy/the-art-of-command-line) for the following translation template. - We'd like for the guide to be available in many languages. Here is the process for maintaining translations: * This original version and content of the guide is maintained in English. * Translations follow the content of the original. Unfortunately, contributors must speak at least some English, so that translations do not diverge. * Each translation has a maintainer to update the translation as the original evolves and to review others' changes. This doesn't require a lot of time, but review by the maintainer is important to maintain quality. -* See the [AUTHORS.md](AUTHORS.md) file for current maintainers. ### Changes to translations * Changes to content should be made to the English version first, and then translated to each other language. * Changes that improve translations should be made directly on the file for that language. PRs should only modify one language at a time. -* Submit a PR with changes to the file in that language. Each language has a maintainer, who reviews changes in that language. Then the primary maintainer @jlevy merges it in. +* Submit a PR with changes to the file in that language. Each language has a maintainer, who reviews changes in that language. Then the primary maintainer @donnemartin merges it in. * Prefix PRs and issues with language codes if they are for that translation only, e.g. "es: Improve grammar", so maintainers can find them easily. ### Adding translations to new languages @@ -68,3 +65,7 @@ Translations to new languages are always welcome, especially if you can maintain * Invite friends to review if possible. If desired, feel free to invite friends to help your original translation by letting them fork your repo, then merging their PRs. * Add links to your translation at the top of every README*.md file. (For consistency, the link should be added in alphabetical order by ISO code, and the anchor text should be in the native language.) * When done, indicate on the PR that it's ready to be merged into the main repo. + +### Translation template credits + +Thanks to [The Art of Command Line](https://github.com/jlevy/the-art-of-command-line) for the translation template. From 1ae841afba2ad7a3d34e98345d46044e72424f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A0=B9=E5=8F=B7=E4=B8=89?= Date: Sat, 15 Apr 2017 21:32:32 +0800 Subject: [PATCH 42/44] zh-cn: Add Simplified Chinese translation v1.0 (#62) --- README-zh-Hant.md | 1797 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1797 insertions(+) create mode 100644 README-zh-Hant.md diff --git a/README-zh-Hant.md b/README-zh-Hant.md new file mode 100644 index 00000000..e50f17ee --- /dev/null +++ b/README-zh-Hant.md @@ -0,0 +1,1797 @@ +> * 原文地址:[github.com/donnemartin/system-design-primer](https://github.com/donnemartin/system-design-primer) +> * 译文出自:[掘金翻译计划](https://github.com/xitu/gold-miner) +> * 译者:[XatMassacrE](https://github.com/XatMassacrE)、[L9m](https://github.com/L9m)、[Airmacho](https://github.com/Airmacho)、[xiaoyusilen](https://github.com/xiaoyusilen)、[jifaxu](https://github.com/jifaxu) +> * 这个 [链接](https://github.com/xitu/system-design-primer/compare/master...donnemartin:master) 用来查看本翻译与英文版是否有差别(如果你没有看到 README.md 发生变化,那就意味着这份翻译文档是最新的)。 + +# 系统设计入门 + +

+ +
+

+ +## 翻译 + +有兴趣参与[翻译](https://github.com/donnemartin/system-design-primer/issues/28)? 以下是正在进行中的翻译: + +* [巴西葡萄牙语](https://github.com/donnemartin/system-design-primer/issues/40) +* [简体中文](https://github.com/donnemartin/system-design-primer/issues/38) +* [土耳其语](https://github.com/donnemartin/system-design-primer/issues/39) + +## 目的 + +> 学习如何设计大型系统。 +> +> 为系统设计的面试做准备。 + +### 学习如何设计大型系统 + +学习如何设计可扩展的系统将会有助于你成为一个更好的工程师。 + +系统设计是一个很宽泛的话题。在互联网上,**关于系统设计原则的资源也是多如牛毛。** + +这个仓库就是这些资源的**组织收集**,它可以帮助你学习如何构建可扩展的系统。 + +### 从开源社区学习 + +这是一个不断更新的开源项目的初期的版本。 + +欢迎[贡献](#贡献)! + +### 为系统设计的面试做准备 + +在很多科技公司中,除了代码面试,系统设计也是**技术面试过程**中的一个**必要环节**。 + +**实践常见的系统设计面试题**并且把你的答案和**例子的解答**进行**对照**:讨论,代码和图表。 + +面试准备的其他主题: + +* [学习指引](#学习指引) +* [如何处理一个系统设计的面试题](#如何处理一个系统设计的面试题) +* [系统设计的面试题,**含解答**](#系统设计的面试题和解答) +* [面向对象设计的面试题,**含解答**](#面向对象设计的面试问题及解答) +* [其它的系统设计面试题](#其它的系统设计面试题) + +## 抽认卡 + +

+ +
+

+ +这里提供的[抽认卡堆](https://apps.ankiweb.net/)使用间隔重复的方法,帮助你记忆关键的系统设计概念。 + +* [系统设计的卡堆](resources/flash_cards/System%20Design.apkg) +* [系统设计的练习卡堆](resources/flash_cards/System%20Design%20Exercises.apkg) +* [面向对象设计的练习卡堆](resources/flash_cards/OO%20Design.apkg) + +随时随地都可使用。 + +### 代码资源:互动式编程挑战 + +你正在寻找资源以准备[**编程面试**](https://github.com/donnemartin/interactive-coding-challenges)吗? + +

+ +
+

+ +请查看我们的姐妹仓库[**互动式编程挑战**](https://github.com/donnemartin/interactive-coding-challenges),其中包含了一个额外的抽认卡堆: + +* [代码卡堆](https://github.com/donnemartin/interactive-coding-challenges/tree/master/anki_cards/Coding.apkg) + +## 贡献 + +> 从社区中学习。 + +欢迎提交 PR 提供帮助: + +* 修复错误 +* 完善章节 +* 添加章节 + +一些还需要完善的内容放在了[正在完善中](#正在完善中)。 + +请查看[贡献指南](CONTRIBUTING.md)。 + +## 系统设计主题的索引 + +> 各种系统设计主题的摘要,包括优点和缺点。**每一个主题都面临着取舍和权衡**。 +> +> 每个章节都包含着更的资源的链接。 + + +

+ +
+

+ +* [系统设计主题:从这里开始](#系统设计主题从这里开始) + * [第一步:回顾可扩展性的视频讲座](#第一步回顾可扩展性scalability的视频讲座) + * [第二步: 回顾可扩展性的文章](#第二步回顾可扩展性文章) + * [接下来的步骤](#接下来的步骤) +* [性能与拓展性](#性能与可扩展性) +* [延迟与吞吐量](#延迟与吞吐量) +* [可用性与一致性](#可用性与一致性) + * [CAP 理论](#cap-理论) + * [CP - 一致性和分区容错性](#cp--一致性和分区容错性) + * [AP - 可用性和分区容错性](#ap--可用性与分区容错性) +* [一致模式](#一致性模式) + * [弱一致性](#弱一致性) + * [最终一致性](#最终一致性) + * [强一致性](#强一致性) +* [可用模式](#可用性模式) + * [故障切换](#故障切换) + * [复制](#复制) +* [域名系统](#域名系统) +* [CDN](#内容分发网络cdn) + * [CDN 推送](#cdn-推送push) + * [CDN 拉取](#cdn-拉取pull) +* [负载均衡器](#负载均衡器) + * [工作到备用切换(Active-passive)](#工作到备用切换active-passive) + * [双工作切换(Active-active)](#双工作切换active-active) + * [四层负载均衡](#四层负载均衡) + * [七层负载均衡](#七层负载均衡器) + * [水平扩展](#水平扩展) +* [反向代理(web 服务器)](#反向代理web-服务器) + * [负载均衡与反向代理](#负载均衡器与反向代理) +* [应用层](#应用层) + * [微服务](#微服务) + * [服务发现](#服务发现) +* [数据库](#数据库) + * [关系型数据库管理系统(RDBMS)](#关系型数据库管理系统rdbms) + * [Master-slave 复制集](#主从复制) + * [Master-master 复制集](#主主复制) + * [联合](#联合) + * [分片](#分片) + * [非规范化](#非规范化) + * [SQL 调优](#sql-调优) + * [NoSQL](#nosql) + * [Key-value 存储](#键-值存储) + * [文档存储](#文档类型存储) + * [宽列存储](#列型存储) + * [图数据库](#图数据库) + * [SQL 还是 NoSQL](#sql-还是-nosql) +* [缓存](#缓存) + * [客户端缓存](#客户端缓存) + * [CDN 缓存](#cdn-缓存) + * [Web 服务器缓存](#web-服务器缓存) + * [数据库缓存](#数据库缓存) + * [应用缓存](#应用缓存) + * [数据库查询级别的缓存](#数据库查询级别的缓存) + * [对象级别的缓存](#对象级别的缓存) + * [何时更新缓存](#何时更新缓存) + * [缓存模式](#缓存模式) + * [直写模式](#直写模式) + * [回写模式](#回写模式) + * [刷新](#刷新) +* [异步](#异步) + * [消息队列](#消息队列) + * [任务队列](#任务队列) + * [背压机制](#背压) +* [通讯](#通讯) + * [传输控制协议(TCP)](#传输控制协议tcp) + * [用户数据报协议(UDP)](#用户数据报协议udp) + * [远程控制调用协议(RPC)](#远程过程调用协议rpc) + * [表述性状态转移(REST)](#表述性状态转移rest) +* [安全](#安全) +* [附录](#附录) + * [2 的次方表](#2-的次方表) + * [每个程序员都应该知道的延迟数](#每个程序员都应该知道的延迟数) + * [其它的系统设计面试题](#其它的系统设计面试题) + * [真实架构](#真实架构) + * [公司的系统架构](#公司的系统架构) + * [公司工程博客](#公司工程博客) +* [正在完善中](#正在完善中) +* [致谢](#致谢) +* [联系方式](#联系方式) +* [许可](#许可) + +## 学习指引 + +> 基于你面试的时间线(短、中、长)去复习那些推荐的主题。 + +![Imgur](http://i.imgur.com/OfVllex.png) + +**问:对于面试来说,我需要知道这里的所有知识点吗?** + +**答:不,如果只是为了准备面试的话,你并不需要知道所有的知识点。** + +在一场面试中你会被问到什么取决于下面这些因素: + +* 你的经验 +* 你的技术背景 +* 你面试的职位 +* 你面试的公司 +* 运气 + +那些有经验的候选人通常会被期望了解更多的系统设计的知识。架构师或者团队负责人则会被期望了解更多除了个人贡献之外的知识。顶级的科技公司通常也会有一次或者更多的系统设计面试。 + +面试会很宽泛的展开并在几个领域深入。这回帮助你了解一些关于系统设计的不同的主题。基于你的时间线,经验,面试的职位和面试的公司对下面的指导做出适当的调整。 + +* **短期** - 以系统设计主题的**广度**为目标。通过解决**一些**面试题来练习。 +* **中期** - 以系统设计主题的**广度**和**初级深度**为目标。通过解决**很多**面试题来练习。 +* **长期** - 以系统设计主题的**广度**和**高级深度**为目标。通过解决**大部分**面试题来联系。 + +| | 短期 | 中期 | 长期 | +| ---------------------------------------- | ---- | ---- | ---- | +| 阅读 [系统设计主题](#系统设计主题的索引) 以获得一个关于系统如何工作的宽泛的认识 | :+1: | :+1: | :+1: | +| 阅读一些你要面试的[公司工程博客](#公司工程博客)的文章 | :+1: | :+1: | :+1: | +| 阅读 [真实架构](#真实架构) | :+1: | :+1: | :+1: | +| 复习 [如何处理一个系统设计面试题](#如何处理一个系统设计面试题) | :+1: | :+1: | :+1: | +| 完成 [系统设计的面试题和解答](#系统设计的面试题和解答) | 一些 | 很多 | 大部分 | +| 完成 [面向对象设计的面试题和解答](#面向对象设计的面试问题及解答) | 一些 | 很多 | 大部分 | +| 复习 [其它的系统设计面试题](#其它的系统设计面试题) | 一些 | 很多 | 大部分 | + +## 如何处理一个系统设计的面试题 + +系统设计面试是一个**开放式的对话**。他们期望你去主导这个对话。 + +你可以使用下面的步骤来指引讨论。为了巩固这个过程,请使用下面的步骤完成[系统设计的面试题和解答](#系统设计的面试题和解答)这个章节。 + +### 第一步:描述使用场景,约束和假设 + +把所有需要的东西聚集在一起,审视问题。不停的提问,以至于我们可以明确使用场景和约束。讨论假设。 + +* 谁会使用它? +* 他们会怎样使用它? +* 有多少用户? +* 系统的作用是什么? +* 系统的输入输出分别是什么? +* 我们希望处理多少数据? +* 我们希望每秒钟处理多少请求? +* 我们希望的读写比率? + +### 第二步:创造一个高级的设计 + +使用所有重要的组件来描绘出一个高级的设计。 + +* 画出主要的组件和连接 +* 证明你的想法 + +### 第三步:设计核心组件 + +对每一个核心组件进行详细深入的分析。举例来说,如果你被问到[设计一个 url 缩写服务](solutions/system_design/pastebin/README.md),开始讨论: + +* 生成并储存一个完整 url 的 hash + * [MD5](solutions/system_design/pastebin/README.md) 和 [Base62](solutions/system_design/pastebin/README.md) + * Hash 碰撞 + * SQL 还是 NoSQL + * 数据库模型 +* 将一个 hashed url 翻译成完整的 url + * 数据库查找 +* API 和面向对象设计 + +### 第四步:度量设计 + +确认和处理瓶颈以及一些限制。举例来说就是你需要下面的这些来完成拓展性的议题吗? + +* 负载均衡 +* 水平拓展 +* 缓存 +* 数据库分片 + +论述可能的解决办法和代价。每件事情需要取舍。可以使用[可拓展系统的设计原则](#系统设计主题的索引)来处理瓶颈。 + +### 信封背面的计算 + +你或许会被要求通过手算进行一些估算。涉及到的[附录](#附录)涉及到的是下面的这些资源: + +* [使用信封的背面做计算](http://highscalability.com/blog/2011/1/26/google-pro-tip-use-back-of-the-envelope-calculations-to-choo.html) +* [2 的次方表](#2-的次方表) +* [每个程序员都应该知道的延迟数](#每个程序员都应该知道的延迟数) + +### 相关资源和延伸阅读 + +查看下面的链接以获得我们期望的更好的想法: + +* [怎样通过一个系统设计的面试](https://www.palantir.com/2011/10/how-to-rock-a-systems-design-interview/) +* [系统设计的面试](http://www.hiredintech.com/system-design) +* [系统架构与设计的面试简介](https://www.youtube.com/watch?v=ZgdS0EUmn70) + +## 系统设计的面试题和解答 + +> 普通的系统设计面试题和相关事例的论述,代码和图表。 +> + +> 与内容有关的解答在 `solutions/` 文件夹中。 + +| 问题 | | +| ---------------------------------------- | ---------------------------------------- | +| 设计 Pastebin.com (或者 Bit.ly) | [解答](solutions/system_design/pastebin/README.md) | +| 设计 Twitter 时间线和搜索 (或者 Facebook feed 和搜索) | [解答](solutions/system_design/twitter/README.md) | +| 设计一个网页爬虫 | [解答](solutions/system_design/web_crawler/README.md) | +| 设计 Mint.com | [解答](solutions/system_design/mint/README.md) | +| 为一个社交网络设计数据结构 | [解答](solutions/system_design/social_graph/README.md) | +| 为搜索引擎设计一个 key-value 储存 | [解答](solutions/system_design/query_cache/README.md) | +| 通过分类特性设计 Amazon 的销售排名 | [解答](solutions/system_design/sales_rank/README.md) | +| 在 AWS 上设计一个百万用户级别的系统 | [解答](solutions/system_design/scaling_aws/README.md) | +| 添加一个系统设计问题 | [贡献](#贡献) | + +### 设计 Pastebin.com (或者 Bit.ly) + +[查看实践与解答](solutions/system_design/pastebin/README.md) + +![Imgur](http://i.imgur.com/4edXG0T.png) + +### 设计 Twitter 时间线和搜索 (或者 Facebook feed 和搜索) + +[查看实践与解答](solutions/system_design/twitter/README.md) + +![Imgur](http://i.imgur.com/jrUBAF7.png) + +### 设计一个网页爬虫 + +[查看实践与解答](solutions/system_design/web_crawler/README.md) + +![Imgur](http://i.imgur.com/bWxPtQA.png) + +### 设计 Mint.com + +[查看实践与解答](solutions/system_design/mint/README.md) + +![Imgur](http://i.imgur.com/V5q57vU.png) + +### 为一个社交网络设计数据结构 + +[查看实践与解答](solutions/system_design/social_graph/README.md) + +![Imgur](http://i.imgur.com/cdCv5g7.png) + +### 为搜索引擎设计一个 key-value 储存 + +[查看实践与解答](solutions/system_design/query_cache/README.md) + +![Imgur](http://i.imgur.com/4j99mhe.png) + +### 设计按类别分类的 Amazon 销售排名 + +[查看实践与解答](solutions/system_design/sales_rank/README.md) + +![Imgur](http://i.imgur.com/MzExP06.png) + +### 在 AWS 上设计一个百万用户级别的系统 + +[查看实践与解答](solutions/system_design/scaling_aws/README.md) + +![Imgur](http://i.imgur.com/jj3A5N8.png) + +## 面向对象设计的面试问题及解答 + +> 常见面向对象设计面试问题及实例讨论,代码和图表演示。 +> +> 与内容相关的解决方案在 `solutions/` 文件夹中。 + +>**注:此节还在完善中** + +| 问题 | | +| ------------ | ---------------------------------------- | +| 设计 hash map | [解决方案](solutions/object_oriented_design/hash_table/hash_map.ipynb) | +| 设计 LRU 缓存 | [解决方案](solutions/object_oriented_design/lru_cache/lru_cache.ipynb) | +| 设计一个呼叫中心 | [解决方案](solutions/object_oriented_design/call_center/call_center.ipynb) | +| 设计一副牌 | [解决方案](solutions/object_oriented_design/deck_of_cards/deck_of_cards.ipynb) | +| 设计一个停车场 | [解决方案](solutions/object_oriented_design/parking_lot/parking_lot.ipynb) | +| 设计一个聊天服务 | [解决方案](solutions/object_oriented_design/online_chat/online_chat.ipynb) | +| 设计一个环形数组 | [待解决](#贡献) | +| 添加一个面向对象设计问题 | [待解决](#贡献) | + +## 系统设计主题:从这里开始 + +不熟悉系统设计? + +首先,你需要对一般性原则有一个基本的认识,知道它们是什么,怎样使用以及利弊。 + +### 第一步:回顾可扩展性(scalability)的视频讲座 + +[哈佛大学可扩展性讲座](https://www.youtube.com/watch?v=-W9F__D3oY4) + +* 主题涵盖 + * 垂直扩展(Vertical scaling) + * 水平扩展(Horizontal scaling) + * 缓存 + * 负载均衡 + * 数据库复制 + * 数据库分区 + +### 第二步:回顾可扩展性文章 + +[可扩展性](http://www.lecloud.net/tagged/scalability) + +* 主题涵盖: + * [Clones](http://www.lecloud.net/post/7295452622/scalability-for-dummies-part-1-clones) + * [数据库](http://www.lecloud.net/post/7994751381/scalability-for-dummies-part-2-database) + * [缓存](http://www.lecloud.net/post/9246290032/scalability-for-dummies-part-3-cache) + * [异步](http://www.lecloud.net/post/9699762917/scalability-for-dummies-part-4-asynchronism) + +### 接下来的步骤 + +接下来,我们将看看高阶的权衡和取舍: + +* **性能**与**可扩展性** +* **延迟**与**吞吐量** +* **可用性**与**一致性** + +记住**每个方面都面临取舍和权衡**。 + +然后,我们将深入更具体的主题,如 DNS、CDN 和负载均衡器。 + +## 性能与可扩展性 + +如果服务**性能**的增长与资源的增加是成比例的,服务就是可扩展的。通常,提高性能意味着服务于更多的工作单元,另一方面,当数据集增长时,同样也可以处理更大的工作单位。1 + +另一个角度来看待性能与可扩展性: + +* 如果你的系统有**性能**问题,对于单个用户来说是缓慢的。 +* 如果你的系统有**可扩展性**问题,单个用户较快但在高负载下会变慢。 + +### 来源及延伸阅读 + +* [简单谈谈可扩展性](http://www.allthingsdistributed.com/2006/03/a_word_on_scalability.html) +* [可扩展性,可用性,稳定性和模式](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) + +## 延迟与吞吐量 + +**延迟**是执行操作或运算结果所花费的时间。 + +**吞吐量**是单位时间内(执行)此类操作或运算的数量。 + +通常,你应该以**可接受级延迟**下**最大化吞吐量**为目标。 + +### 来源及延伸阅读 + +* [理解延迟与吞吐量](https://community.cadence.com/cadence_blogs_8/b/sd/archive/2010/09/13/understanding-latency-vs-throughput) + +## 可用性与一致性 + +### CAP 理论 + +

+ +
+ 来源:再看 CAP 理论 +

+ +在一个分布式计算系统中,只能同时满足下列的两点: + +* **一致性** ─ 每次访问都能获得最新数据但可能会收到错误响应 +* **可用性** ─ 每次访问都能收到非错响应,但不保证获取到最新数据 +* **分区容错性** ─ 在任意分区网络故障的情况下系统仍能继续运行 + +**网络并不可靠,所以你应要支持分区容错性,并需要在软件可用性和一致性间做出取舍。** + +#### CP ─ 一致性和分区容错性 + +等待分区节点的响应可能会导致延时错误。如果你的业务需求需要原子读写,CP 是一个不错的选择。 + +#### AP ─ 可用性与分区容错性 + +响应节点上可用数据的最近版本可能并不是最新的。当分区解析完后,写入(操作)可能需要一些时间来传播。 + +如果业务需求允许[最终一致性](#最终一致性),或当有外部故障时要求系统继续运行,AP 是一个不错的选择。 + +### 来源及延伸阅读 + +* [再看 CAP 理论](http://robertgreiner.com/2014/08/cap-theorem-revisited/) +* [通俗易懂地介绍 CAP 理论](http://ksat.me/a-plain-english-introduction-to-cap-theorem/) +* [CAP FAQ](https://github.com/henryr/cap-faq) + +## 一致性模式 + +有同一份数据的多份副本,我们面临着怎样同步它们的选择,以便让客户端有一致的显示数据。回想 [CAP 理论](#cap-理论)中的一致性定义 ─ 每次访问都能获得最新数据但可能会收到错误响应 + + +### 弱一致性 + +在写入之后,访问可能看到,也可能看不到(写入数据)。尽力优化之让其能访问最新数据。 + +这种方式可以 memcached 等系统中看到。弱一致性在 VoIP,视频聊天和实时多人游戏等真实用例中表现不错。打个比方,如果你在通话中丢失信号几秒钟时间,当重新连接时你是听不到这几秒钟所说的话的。 + +### 最终一致性 + +在写入后,访问最终能看到写入数据(通常在数毫秒内)。数据被异步复制。 + +DNS 和 email 等系统使用的是此种方式。最终一致性在高可用性系统中效果不错。 + +### 强一致性 + +在写入后,访问立即可见。数据被同步复制。 + +文件系统和关系型数据库(RDBMS)中使用的是此种方式。强一致性在需要记录的系统中运作良好。 + +### 来源及延伸阅读 + +* [Transactions across data centers](http://snarfed.org/transactions_across_datacenters_io.html) + +## 可用性模式 + +有两种支持高可用性的模式: **故障切换(fail-over)**和**复制(replication)**。 + +### 故障切换 + +#### 工作到备用切换(Active-passive) + +关于工作到备用的故障切换流程是,工作服务器发送周期信号给待机中的备用服务器。如果周期信号中断,备用服务器切换成工作服务器的 IP 地址并恢复服务。 + +宕机时间取决于备用服务器处于“热”待机状态还是需要从“冷”待机状态进行启动。只有工作服务器处理流量。 + +工作到备用的故障切换也被称为主从切换。 + +#### 双工作切换(Active-active) + +在双工作切换中,双方都在管控流量,在它们之间分散负载。 + +如果是外网服务器,DNS 将需要对两方都了解。如果是内网服务器,应用程序逻辑将需要对两方都了解。 + +双工作切换也可以称为主主切换。 + +### 缺陷:故障切换 + +* 故障切换需要添加额外硬件并增加复杂性。 +* 如果新写入数据在能被复制到备用系统之前,工作系统出现了故障,则有可能会丢失数据。 + +### 复制 + +#### 主─从复制和主─主复制 + +这个主题进一步探讨了[数据库](#数据库)部分: + +* [主─从复制](#主从复制) +* [主─主复制](#主主复制) + +## 域名系统 + +

+ +
+ 来源:DNS 安全介绍 +

+ +域名系统是把 www.example.com 等域名转换成 IP 地址。 + +域名系统是分层次的,一些 DNS 服务器位于顶层。当查询(域名) IP 时,路由或 ISP 提供连接 DNS 服务器的信息。较底层的 DNS 服务器缓存映射,它可能会因为 DNS 传播延时而失效。DNS 结果可以缓存在浏览器或操作系统中一段时间,时间长短取决于[存活时间 TTL](https://en.wikipedia.org/wiki/Time_to_live)。 + +* **NS 记录(域名服务)** ─ 指定解析域名或子域名的 DNS 服务器。 +* **MX 记录(邮件交换)** ─ 指定接收信息的邮件服务器。 +* **A 记录(地址)** ─ 指定域名对应的 IP 地址记录。 +* **CNAME(规范)** ─ 一个域名映射到另一个域名或 `CNAME` 记录( example.com 指向 www.example.com )或映射到一个 `A` 记录。 + +[CloudFlare](https://www.cloudflare.com/dns/) 和 [Route 53](https://aws.amazon.com/route53/) 等平台提供管理 DNS 的功能。某些 DNS 服务通过集中方式来路由流量: + +* [加权轮询调度](http://g33kinfo.com/info/archives/2657) + * 防止流量进入维护中的服务器 + * 在不同大小集群间负载均衡 + * A/B 测试 +* 基于延迟路由 +* 基于地理位置路由 + +### 缺陷:DNS + +* 虽说缓存可以减轻 DNS 延迟,但连接 DNS 服务器还是带来了轻微的延迟。 +* 虽然它们通常由[政府,网络服务提供商和大公司](http://superuser.com/questions/472695/who-controls-the-dns-servers/472729)管理,但 DNS 服务管理仍可能是复杂的。 +* DNS 服务最近遭受 [DDoS 攻击](http://dyn.com/blog/dyn-analysis-summary-of-friday-october-21-attack/),阻止不知道 Twtter IP 地址的用户访问 Twiiter。 + +### 来源及延伸阅读 + +* [DNS 架构](https://technet.microsoft.com/en-us/library/dd197427(v=ws.10).aspx) +* [Wikipedia](https://en.wikipedia.org/wiki/Domain_Name_System) +* [关于 DNS 的文章](https://support.dnsimple.com/categories/dns/) + +## 内容分发网络(CDN) + +

+ +
+ 来源:为什么使用 CDN +

+ +内容分发网络(CDN)是一个全球性的代理服务器分布式网络,它从靠近用户的位置提供内容。通常,HTML/CSS/JS,图片和视频等静态内容由 CDN 提供,虽然亚马逊 CloudFront 等也支持动态内容。CDN 的 DNS 解析会告知客户端连接哪台服务器。 + +将内容存储在 CDN 上可以从两个方面来提供性能: + +* 从靠近用户的数据中心提供资源 +* 通过 CDN 你的服务器不必真的处理请求 + +### CDN 推送(push) + +当你服务器上内容发生变动时,推送 CDN 接受新内容。直接推送给 CDN 并重写 URL 地址以指向你的内容的 CDN 地址。你可以配置内容到期时间及何时更新。内容只有在更改或新增是才推送,流量最小化,但储存最大化。 + +### CDN 拉取(pull) + +CDN 拉取是当第一个用户请求该资源时,从服务器上拉取资源。你将内容留在自己的服务器上并重写 URL 指向 CDN 地址。直到内容被缓存在 CDN 上为止,这样请求只会更慢, + +[存活时间(TTL)](https://en.wikipedia.org/wiki/Time_to_live)决定缓存多久时间。CDN 拉取方式最小化 CDN 上的储存空间,但如果过期文件并在实际更改之前被拉取,则会导致冗余的流量。 + +高流量站点使用 CDN 拉取效果不错,因为只有最近请求的内容保存在 CDN 中,流量才能更平衡地分散。 + +### 缺陷:CDN + +* CDN 成本可能因流量而异,可能在权衡之后你将不会使用 CDN。 +* 如果在 TTL 过期之前更新内容,CDN 缓存内容可能会过时。 +* CDN 需要更改静态内容的 URL 地址以指向 CDN。 + +### 来源及延伸阅读 + +* [全球性内容分发网络](http://repository.cmu.edu/cgi/viewcontent.cgi?article=2112&context=compsci) +* [CDN 拉取和 CDN 推送的区别](http://www.travelblogadvice.com/technical/the-differences-between-push-and-pull-cdns/) +* [Wikipedia](https://en.wikipedia.org/wiki/Content_delivery_network) + +## 负载均衡器 + +

+ +
+ 来源:可扩展的系统设计模式 +

+ +负载均衡器将传入的请求分发到应用服务器和数据库等计算资源。无论哪种情况,负载均衡器将从计算资源来的响应返回给恰当的客户端。负载均衡器的效用在于: + +* 防止请求进入不好的服务器 +* 防止资源过载 +* 帮助消除单一的故障点 + +负载均衡器可以通过硬件(昂贵)或 HAProxy 等软件来实现。 +增加的好处包括: + +* **SSL 终结** ─ 解密传入的请求并加密服务器响应,这样的话后端服务器就不必再执行这些潜在高消耗运算了。 + * 不需要再每台服务器上安装 [X.509 证书](https://en.wikipedia.org/wiki/X.509)。 +* **Session 留存** ─ 如果 Web 应用程序不追踪会话,发出 cookie 并将特定客户端的请求路由到同一实例。 + +通常会设置采用[工作─备用](#工作到备用切换active-passive) 或 [双工作](#双工作切换active-active) 模式的多个负载均衡器,以免发生故障。 + +负载均衡器能基于多种方式来路由流量: + +* 随机 +* 最少负载 +* Session/cookie +* [轮询调度或加权轮询调度算法](http://g33kinfo.com/info/archives/2657) +* [四层负载均衡](#四层负载均衡) +* [七层负载均衡](#七层负载均衡) + +### 四层负载均衡 + +四层负载均衡根据监看[传输层](#通讯)的信息来决定如何分发请求。通常,这会涉及来源,目标 IP 地址和请求头中的端口,但不包括数据包(报文)内容。四层负载均衡执行[网络地址转换(NAT)](https://www.nginx.com/resources/glossary/layer-4-load-balancing/)来向上游服务器转发网络数据包。 + +### 七层负载均衡器 + +七层负载均衡器根据监控[应用层](#通讯)来决定怎样分发请求。这会涉及请求头的内容,消息和 cookie。七层负载均衡器终结网络流量,读取消息,做出负载均衡判定,然后传送给特定服务器。比如,一个七层负载均衡器能直接将视频流量连接到托管视频的服务器,同时将更敏感的用户账单流量引导到安全性更强的服务器。 + +以损失灵活性为代价,四层负载均衡比七层负载均衡花费更少时间和计算资源,虽然这对现代商用硬件的性能影响甚微。 + +### 水平扩展 + +负载均衡器还能帮助水平扩展,提高性能和可用性。使用商业硬件的性价比更高,并且比在单台硬件上**垂直扩展**更贵的硬件具有更高的可用性。相比招聘特定企业系统人才,招聘商业硬件方面的人才更加容易。 + +#### 缺陷:水平扩展 + +* 水平扩展引入了复杂度并涉及服务器复制 + * 服务器应该是无状态的:它们也不该包含像 session 或资料图片等与用户关联的数据。 + * session 可以集中存储在数据库或持久化[缓存](#缓存)(Redis、Memcached)的数据存储区中。 +* 缓存和数据库等下游服务器需要随着上游服务器进行扩展,以处理更多的并发连接。 + +### 缺陷:负载均衡器 + +* 如果没有足够的资源配置或配置错误,负载均衡器会变成一个性能瓶颈。 +* 引入负载均衡器以帮助消除单点故障但导致了额外的复杂性。 +* 单个负载均衡器会导致单点故障,但配置多个负载均衡器会进一步增加复杂性。 + +### 来源及延伸阅读 + +* [NGINX 架构](https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/) +* [HAProxy 架构指南](http://www.haproxy.org/download/1.2/doc/architecture.txt) +* [可扩展性](http://www.lecloud.net/post/7295452622/scalability-for-dummies-part-1-clones) +* [Wikipedia](https://en.wikipedia.org/wiki/Load_balancing_(computing)) +* [四层负载平衡](https://www.nginx.com/resources/glossary/layer-4-load-balancing/) +* [七层负载平衡](https://www.nginx.com/resources/glossary/layer-7-load-balancing/) +* [ELB 监听器配置](http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-listener-config.html) + +## 反向代理(web 服务器) + +

+ +
+ 资料来源:维基百科 +
+

+ +反向代理是一种可以集中地调用内部服务,并提供统一接口给公共客户的 web 服务器。来自客户端的请求先被反向代理服务器转发到可响应请求的服务器,然后代理再把服务器的响应结果返回给客户端。 + +带来的好处包括: + +- **增加安全性** - 隐藏后端服务器的信息,屏蔽黑名单中的 IP,限制每个客户端的连接数。 +- **提高可扩展性和灵活性** - 客户端只能看到反向代理服务器的 IP,这使你可以增减服务器或者修改它们的配置。 +- **本地终结 SSL 会话** - 解密传入请求,加密服务器响应,这样后端服务器就不必完成这些潜在的高成本的操作。 + - 免除了在每个服务器上安装 [X.509](https://en.wikipedia.org/wiki/X.509) 证书的需要 +- **压缩** - 压缩服务器响应 +- **缓存** - 直接返回命中的缓存结果 +- **静态内容** - 直接提供静态内容 + - HTML/CSS/JS + - 图片 + - 视频 + - 等等 + +### 负载均衡器与反向代理 + +- 当你有多个服务器时,部署负载均衡器非常有用。通常,负载均衡器将流量路由给一组功能相同的服务器上。 +- 即使只有一台 web 服务器或者应用服务器时,反向代理也有用,可以参考上一节介绍的好处。 +- NGINX 和 HAProxy 等解决方案可以同时支持第七层反向代理和负载均衡。 + +### 不利之处:反向代理 + +- 引入反向代理会增加系统的复杂度。 +- 单独一个反向代理服务器仍可能发生单点故障,配置多台反向代理服务器(如[故障转移](https://en.wikipedia.org/wiki/Failover))会进一步增加复杂度。 + +### 来源及延伸阅读 + + +- [反向代理与负载均衡](https://www.nginx.com/resources/glossary/reverse-proxy-vs-load-balancer/) +- [NGINX 架构](https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/) +- [HAProxy 架构指南](http://www.haproxy.org/download/1.2/doc/architecture.txt) +- [Wikipedia](https://en.wikipedia.org/wiki/Reverse_proxy) + +## 应用层 + +

+ +
+ 资料来源:可缩放系统构架介绍 +

+ +将 Web 服务层与应用层(也被称作平台层)分离,可以独立缩放和配置这两层。添加新的 API 只需要添加应用服务器,而不必添加额外的 web 服务器。 + +**单一职责原则**提倡小型的,自治的服务共同合作。小团队通过提供小型的服务,可以更激进地计划增长。 + +应用层中的工作进程也有可以实现[异步化](#异步)。 + +### 微服务 + +与此讨论相关的话题是 [微服务](https://en.wikipedia.org/wiki/Microservices),可以被描述为一系列可以独立部署的小型的,模块化服务。每个服务运行在一个独立的线程中,通过明确定义的轻量级机制通讯,共同实现业务目标。1 + +例如,Pinterest 可能有这些微服务: 用户资料、关注者、Feed 流、搜索、照片上传等。 + +### 服务发现 + +像 [Consul](https://www.consul.io/docs/index.html),[Etcd](https://coreos.com/etcd/docs/latest) 和 [Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) 这样的系统可以通过追踪注册名、地址、端口等信息来帮助服务互相发现对方。[Health checks](https://www.consul.io/intro/getting-started/checks.html) 可以帮助确认服务的完整性和是否经常使用一个 [HTTP](#超文本传输协议http) 路径。Consul 和 Etcd 都有一个内建的 [key-value 存储](#键-值存储) 用来存储配置信息和其他的共享信息。 + +### 不利之处:应用层 + +- 添加由多个松耦合服务组成的应用层,从架构、运营、流程等层面来讲将非常不同(相对于单体系统)。 +- 微服务会增加部署和运营的复杂度。 + + +### 来源及延伸阅读 + +- [可缩放系统构架介绍](http://lethain.com/introduction-to-architecting-systems-for-scale) +- [破解系统设计面试](http://www.puncsky.com/blog/2016/02/14/crack-the-system-design-interview/) +- [面向服务架构](https://en.wikipedia.org/wiki/Service-oriented_architecture) +- [Zookeeper 介绍](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) +- [构建微服务,你所需要知道的一切](https://cloudncode.wordpress.com/2016/07/22/msa-getting-started/) + +## 数据库 + +

+ +
+ 资料来源:扩展你的用户数到第一个一千万 +

+ +### 关系型数据库管理系统(RDBMS) + +像 SQL 这样的关系型数据库是一系列以表的形式组织的数据项集合。 + +> 校对注:这里作者 SQL 可能指的是 MySQL + +**ACID** 用来描述关系型数据库[事务](https://en.wikipedia.org/wiki/Database_transaction)的特性。 + +- **原子性** - 每个事务内部所有操作要么全部完成,要么全部不完成。 +- **一致性** - 任何事务都使数据库从一个有效的状态转换到另一个有效状态。 +- **隔离性** - 并发执行事务的结果与顺序执行事务的结果相同。 +- **持久性** - 事务提交后,对系统的影响是永久的。 + +关系型数据库扩展包括许多技术:**主从复制**、**主主复制**、**联合**、**分片**、**非规范化**和 **SQL调优**。 + +

+ +
+ 资料来源:可扩展性、可用性、稳定性、模式 +

+ +#### 主从复制 + +主库同时负责读取和写入操作,并复制写入到一个或多个从库中,从库只负责读操作。树状形式的从库再将写入复制到更多的从库中去。如果主库离线,系统可以以只读模式运行,直到某个从库被提升为主库或有新的主库出现。 + +##### 不利之处:主从复制 + +- 将从库提升为主库需要额外的逻辑。 +- 参考[不利之处:复制](#不利之处复制)中,主从复制和主主复制**共同**的问题。 + +

+ +
+ 资料来源:可扩展性、可用性、稳定性、模式 +

+ +#### 主主复制 + +两个主库都负责读操作和写操作,写入操作时互相协调。如果其中一个主库挂机,系统可以继续读取和写入。 + +##### 不利之处: 主主复制 + +- 你需要添加负载均衡器或者在应用逻辑中做改动,来确定写入哪一个数据库。 +- 多数主-主系统要么不能保证一致性(违反 ACID),要么因为同步产生了写入延迟。 +- 随着更多写入节点的加入和延迟的提高,如何解决冲突显得越发重要。 +- 参考[不利之处:复制](#不利之处复制)中,主从复制和主主复制**共同**的问题。 + +##### 不利之处:复制 + + +- 如果主库在将新写入的数据复制到其他节点前挂掉,则有数据丢失的可能。 +- 写入会被重放到负责读取操作的副本。副本可能因为过多写操作阻塞住,导致读取功能异常。 +- 读取从库越多,需要复制的写入数据就越多,导致更严重的复制延迟。 +- 在某些数据库系统中,写入主库的操作可以用多个线程并行写入,但读取副本只支持单线程顺序地写入。 +- 复制意味着更多的硬件和额外的复杂度。 + + +##### 来源及延伸阅读 + + +- [扩展性,可用性,稳定性模式](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) +- [多主复制](https://en.wikipedia.org/wiki/Multi-master_replication) + +#### 联合 + +

+ +
+ 资料来源:扩展你的用户数到第一个一千万 +

+ +联合(或按功能划分)将数据库按对应功能分割。例如,你可以有三个数据库:**论坛**、**用户**和**产品**,而不仅是一个单体数据库,从而减少每个数据库的读取和写入流量,减少复制延迟。较小的数据库意味着更多适合放入内存的数据,进而意味着更高的缓存命中几率。没有只能串行写入的中心化主库,你可以并行写入,提高负载能力。 + +##### 不利之处:联合 + + +- 如果你的数据库模式需要大量的功能和数据表,联合的效率并不好。 +- 你需要更新应用程序的逻辑来确定要读取和写入哪个数据库。 +- 用 [server link](http://stackoverflow.com/questions/5145637/querying-data-by-joining-two-tables-in-two-database-on-different-servers) 从两个库联结数据更复杂。 +- 联合需要更多的硬件和额外的复杂度。 + +##### 来源及延伸阅读:联合 + +- [扩展你的用户数到第一个一千万](https://www.youtube.com/watch?v=vg5onp8TU6Q) + +#### 分片 + +

+ +
+ 资料来源:可扩展性、可用性、稳定性、模式 +

+ +分片将数据分配在不同的数据库上,使得每个数据库仅管理整个数据集的一个子集。以用户数据库为例,随着用户数量的增加,越来越多的分片会被添加到集群中。 + +类似[联合](#联合)的优点,分片可以减少读取和写入流量,减少复制并提高缓存命中率。也减少了索引,通常意味着查询更快,性能更好。如果一个分片出问题,其他的仍能运行,你可以使用某种形式的冗余来防止数据丢失。类似联合,没有只能串行写入的中心化主库,你可以并行写入,提高负载能力。 + +常见的做法是用户姓氏的首字母或者用户的地理位置来分隔用户表。 + +##### 不利之处:分片 + +- 你需要修改应用程序的逻辑来实现分片,这会带来复杂的 SQL 查询。 +- 分片不合理可能导致数据负载不均衡。例如,被频繁访问的用户数据会导致其所在分片的负载相对其他分片高。 + - 再平衡会引入额外的复杂度。基于[一致性哈希](http://www.paperplanes.de/2011/12/9/the-magic-of-consistent-hashing.html)的分片算法可以减少这种情况。 +- 联结多个分片的数据操作更复杂。 +- 分片需要更多的硬件和额外的复杂度。 + +#### 来源及延伸阅读:分片 + +- [分片时代来临](http://highscalability.com/blog/2009/8/6/an-unorthodox-approach-to-database-design-the-coming-of-the.html) +- [数据库分片架构](https://en.wikipedia.org/wiki/Shard_(database_architecture)) +- [一致性哈希](http://www.paperplanes.de/2011/12/9/the-magic-of-consistent-hashing.html) + +#### 非规范化 + +非规范化试图以写入性能为代价来换取读取性能。在多个表中冗余数据副本,以避免高成本的联结操作。一些关系型数据库,比如 [PostgreSQl](https://en.wikipedia.org/wiki/PostgreSQL) 和 Oracle 支持[物化视图](https://en.wikipedia.org/wiki/Materialized_view),可以处理冗余信息存储和保证冗余副本一致。 + +当数据使用诸如[联合](#联合)和[分片](#分片)等技术被分割,进一步提高了处理跨数据中心的联结操作复杂度。非规范化可以规避这种复杂的联结操作。 + +在多数系统中,读取操作的频率远高于写入操作,比例可达到 100:1,甚至 1000:1。需要复杂的数据库联结的读取操作成本非常高,在磁盘操作上消耗了大量时间。 + +##### 不利之处:非规范化 + +- 数据会冗余。 +- 约束可以帮助冗余的信息副本保持同步,但这样会增加数据库设计的复杂度。 +- 非规范化的数据库在高写入负载下性能可能比规范化的数据库差。 + +##### 来源及延伸阅读:非规范化 + +- [非规范化](https://en.wikipedia.org/wiki/Denormalization) + +#### SQL 调优 + +SQL 调优是一个范围很广的话题,有很多相关的[书](https://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=sql+tuning)可以作为参考。 + +利用**基准测试**和**性能分析**来模拟和发现系统瓶颈很重要。 + +- **基准测试** - 用 [ab](http://httpd.apache.org/docs/2.2/programs/ab.html) 等工具模拟高负载情况。 +- **性能分析** - 通过启用如[慢查询日志](http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html)等工具来辅助追踪性能问题。 + +基准测试和性能分析可能会指引你到以下优化方案。 + +##### 改进模式 + +- 为了实现快速访问,MySQL 在磁盘上用连续的块存储数据。 +- 使用 `CHAR` 类型存储固定长度的字段,不要用 `VARCHAR`。 + - `CHAR` 在快速、随机访问时效率很高。如果使用 `VARCHAR`,如果你想读取下一个字符串,不得不先读取到当前字符串的末尾。 +- 使用 `TEXT` 类型存储大块的文本,例如博客正文。`TEXT` 还允许布尔搜索。使用 `TEXT` 字段需要在磁盘上存储一个用于定位文本块的指针。 +- 使用 `INT` 类型存储高达 2^32 或 40 亿的较大数字。 +- 使用 `DECIMAL` 类型存储货币可以避免浮点数表示错误。 +- 避免使用 `BLOBS` 存储对象,存储存放对象的位置。 +- `VARCHAR(255)` 是以 8 位数字存储的最大字符数,在某些关系型数据库中,最大限度地利用字节。 +- 在适用场景中设置 `NOT NULL` 约束来[提高搜索性能](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a-database-search)。 + +##### 使用正确的索引 + +- 你正查询(`SELECT`、`GROUP BY`、`ORDER BY`、`JOIN`)的列如果用了索引会更快。 +- 索引通常表示为自平衡的 [B 树](https://en.wikipedia.org/wiki/B-tree),可以保持数据有序,并允许在对数时间内进行搜索,顺序访问,插入,删除操作。 +- 设置索引,会将数据存在内存中,占用了更多内存空间。 +- 写入操作会变慢,因为索引需要被更新。 +- 加载大量数据时,禁用索引再加载数据,然后重建索引,这样也许会更快。 + +##### 避免高成本的联结操作 + +- 有性能需要,可以进行非规范化。 + +##### 分割数据表 + +- 将热点数据拆分到单独的数据表中,可以有助于缓存。 + +##### 调优查询缓存 + +- 在某些情况下,[查询缓存](http://dev.mysql.com/doc/refman/5.7/en/query-cache)可能会导致[性能问题](https://www.percona.com/blog/2014/01/28/10-mysql-performance-tuning-settings-after-installation/)。 + +##### 来源及延伸阅读 + +- [MySQL 查询优化小贴士](http://20bits.com/article/10-tips-for-optimizing-mysql-queries-that-dont-suck) +- [为什么 VARCHAR(255) 很常见?](http://stackoverflow.com/questions/1217466/is-there-a-good-reason-i-see-varchar255-used-so-often-as-opposed-to-another-l) +- [Null 值是如何影响数据库性能的?](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a-database-search) +- [慢查询日志](http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html) + +### NoSQL + +NoSQL 是**键-值数据库**、**文档型数据库**、**列型数据库**或**图数据库**的统称。数据库是非规范化的,表联结大多在应用程序代码中完成。大多数 NoSQL 无法实现真正符合 ACID 的事务,支持[最终一致](#最终一致性)。 + +**BASE** 通常被用于描述 NoSQL 数据库的特性。相比 [CAP 理论](#cap-理论),BASE 强调可用性超过一致性。 + +- **基本可用** - 系统保证可用性。 +- **软状态** - 即使没有输入,系统状态也可能随着时间变化。 +- **最终一致性** - 经过一段时间之后,系统最终会变一致,因为系统在此期间没有收到任何输入。 + +除了在 [SQL 还是 NoSQL](#sql-还是-nosql) 之间做选择,了解哪种类型的 NoSQL 数据库最适合你的用例也是非常有帮助的。我们将在下一节中快速了解下 **键-值存储**、**文档型存储**、**列型存储**和**图存储**数据库。 + +#### 键-值存储 + +> 抽象模型:哈希表 + +键-值存储通常可以实现 O(1) 时间读写,用内存或 SSD 存储数据。数据存储可以按[字典顺序](https://en.wikipedia.org/wiki/Lexicographical_order)维护键,从而实现键的高效检索。键-值存储可以用于存储元数据。 + +键-值存储性能很高,通常用于存储简单数据模型或频繁修改的数据,如存放在内存中的缓存。键-值存储提供的操作有限,如果需要更多操作,复杂度将转嫁到应用程序层面。 + +键-值存储是如文档存储,在某些情况下,甚至是图存储等更复杂的存储系统的基础。 + +#### 来源及延伸阅读 + +- [键-值数据库](https://en.wikipedia.org/wiki/Key-value_database) +- [键-值存储的劣势](http://stackoverflow.com/questions/4056093/what-are-the-disadvantages-of-using-a-key-value-table-over-nullable-columns-or) +- [Redis 架构](http://qnimate.com/overview-of-redis-architecture/) +- [Memcached 架构](https://www.adayinthelifeof.nl/2011/02/06/memcache-internals/) + +#### 文档类型存储 + +> 抽象模型:将文档作为值的键-值存储 + +文档类型存储以文档(XML、JSON、二进制文件等)为中心,文档存储了指定对象的全部信息。文档存储根据文档自身的内部结构提供 API 或查询语句来实现查询。请注意,许多键-值存储数据库有用值存储元数据的特性,这也模糊了这两种存储类型的界限。 + +基于底层实现,文档可以根据集合、标签、元数据或者文件夹组织。尽管不同文档可以被组织在一起或者分成一组,但相互之间可能具有完全不同的字段。 + +MongoDB 和 CouchDB 等一些文档类型存储还提供了类似 SQL 语言的查询语句来实现复杂查询。DynamoDB 同时支持键-值存储和文档类型存储。 + +文档类型存储具备高度的灵活性,常用于处理偶尔变化的数据。 + +#### 来源及延伸阅读:文档类型存储 + +- [面向文档的数据库](https://en.wikipedia.org/wiki/Document-oriented_database) +- [MongoDB 架构](https://www.mongodb.com/mongodb-architecture) +- [CouchDB 架构](https://blog.couchdb.org/2016/08/01/couchdb-2-0-architecture/) +- [Elasticsearch 架构](https://www.elastic.co/blog/found-elasticsearch-from-the-bottom-up) + +#### 列型存储 + +

+ +
+ 资料来源: SQL 和 NoSQL,一个简短的历史 +

+ +> 抽象模型:嵌套的 `ColumnFamily>` 映射 + +类型存储的基本数据单元是列(名/值对)。列可以在列族(类似于 SQL 的数据表)中被分组。超级列族再分组普通列族。你可以使用行键独立访问每一列,具有相同行键值的列组成一行。每个值都包含版本的时间戳用于解决版本冲突。 + +Google 发布了第一个列型存储数据库 [Bigtable](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf),它影响了 Hadoop 生态系统中活跃的开源数据库 [HBase](https://www.mapr.com/blog/in-depth-look-hbase-architecture) 和 Facebook 的 [Cassandra](http://docs.datastax.com/en/archived/cassandra/2.0/cassandra/architecture/architectureIntro_c.html)。像 BigTable,HBase 和 Cassandra 这样的存储系统将键以字母顺序存储,可以高效地读取键列。 + +列型存储具备高可用性和高可扩展性。通常被用于大数据相关存储。 + +##### 来源及延伸阅读:列型存储 + +- [SQL 与 NoSQL 简史](http://blog.grio.com/2015/11/sql-nosql-a-brief-history.html) +- [BigTable 架构](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) +- [Hbase 架构](https://www.mapr.com/blog/in-depth-look-hbase-architecture) +- [Cassandra 架构](http://docs.datastax.com/en/archived/cassandra/2.0/cassandra/architecture/architectureIntro_c.html) + +#### 图数据库 + +

+ +
+ 资料来源:图数据库 +

+ +> 抽象模型: 图 + +在图数据库中,一个节点对应一条记录,一个弧对应两个节点之间的关系。图数据库被优化用于表示外键繁多的复杂关系或多对多关系。 + +图数据库为存储复杂关系的数据模型,如社交网络,提供了很高的性能。它们相对较新,尚未广泛应用,查找开发工具或者资源相对较难。许多图只能通过 [REST API](#表述性状态转移rest) 访问。 + +##### 相关资源和延伸阅读:图 +- [图数据库](https://en.wikipedia.org/wiki/Graph_database) +- [Neo4j](https://neo4j.com/) +- [FlockDB](https://blog.twitter.com/2010/introducing-flockdb) + +#### 来源及延伸阅读:NoSQL + +- [数据库术语解释](http://stackoverflow.com/questions/3342497/explanation-of-base-terminology) +- [NoSQL 数据库 - 调查及决策指南](https://medium.com/baqend-blog/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#.wskogqenq) +- [可扩展性](http://www.lecloud.net/post/7994751381/scalability-for-dummies-part-2-database) +- [NoSQL 介绍](https://www.youtube.com/watch?v=qI_g07C_Q5I) +- [NoSQL 模式](http://horicky.blogspot.com/2009/11/nosql-patterns.html) + +### SQL 还是 NoSQL + +

+ +
+ 资料来源:从 RDBMS 转换到 NoSQL +

+ +选取 **SQL** 的原因: + +- 结构化数据 +- 严格的模式 +- 关系型数据 +- 需要复杂的联结操作 +- 事务 +- 清晰的扩展模式 +- 既有资源更丰富:开发者、社区、代码库、工具等 +- 通过索引进行查询非常快 + +选取 **NoSQL** 的原因: + +- 半结构化数据 +- 动态或灵活的模式 +- 非关系型数据 +- 不需要复杂的联结操作 +- 存储 TB (甚至 PB)级别的数据 +- 高数据密集的工作负载 +- IOPS 高吞吐量 + +适合 NoSQL 的示例数据: + +- 埋点数据和日志数据 +- 排行榜或者得分数据 +- 临时数据,如购物车 +- 频繁访问的(“热”)表 +- 元数据/查找表 + +##### 来源及延伸阅读:SQL 或 NoSQL + +- [扩展你的用户数到第一个千万](https://www.youtube.com/watch?v=vg5onp8TU6Q) +- [SQL 和 NoSQL 的不同](https://www.sitepoint.com/sql-vs-nosql-differences/) +## 缓存 + +

+ +
+ 资料来源:可扩展的系统设计模式 +

+ +缓存可以提高页面加载速度,并可以减少服务器和数据库的负载。在这个模型中,分发器先查看请求之前是否被响应过,如果有则将之前的结果直接返回,来省掉真正的处理。 + +数据库分片均匀分布的读取是最好的。但是热门数据会让读取分布不均匀,这样就会造成瓶颈,如果在数据库前加个缓存,就会抹平不均匀的负载和突发流量对数据库的影响。 + +### 客户端缓存 + +缓存可以位于客户端(操作系统或者浏览器),[服务端](#反向代理web-服务器)或者不同的缓存层。 + +### CDN 缓存 + +[CDN](#内容分发网络cdn) 也被视为一种缓存。 + +### Web 服务器缓存 + +[反向代理](#反向代理web-服务器)和缓存(比如 [Varnish](https://www.varnish-cache.org/))可以直接提供静态和动态内容。Web 服务器同样也可以缓存请求,返回相应结果而不必连接应用服务器。 + +### 数据库缓存 + +数据库的默认配置中通常包含缓存级别,针对一般用例进行了优化。调整配置,在不同情况下使用不同的模式可以进一步提高性能。 + +### 应用缓存 + +基于内存的缓存比如 Memcached 和 Redis 是应用程序和数据存储之间的一种键值存储。由于数据保存在 RAM 中,它比存储在磁盘上的典型数据库要快多了。RAM 比磁盘限制更多,所以例如 [least recently used (LRU)](https://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used) 的[缓存无效算法](https://en.wikipedia.org/wiki/Cache_algorithms)可以将「热门数据」放在 RAM 中,而对一些比较「冷门」的数据不做处理。 + +Redis 有下列附加功能: + +- 持久性选项 +- 内置数据结构比如有序集合和列表 + +有多个缓存级别,分为两大类:**数据库查询**和**对象**: + +- 行级别 +- 查询级别 +- 完整的可序列化对象 +- 完全渲染的 HTML + +一般来说,你应该尽量避免基于文件的缓存,因为这使得复制和自动缩放很困难。 + +### 数据库查询级别的缓存 + +当你查询数据库的时候,将查询语句的哈希值与查询结果存储到缓存中。这种方法会遇到以下问题: + +- 很难用复杂的查询删除已缓存结果。 +- 如果一条数据比如表中某条数据的一项被改变,则需要删除所有可能包含已更改项的缓存结果。 + +### 对象级别的缓存 + +将您的数据视为对象,就像对待你的应用代码一样。让应用程序将数据从数据库中组合到类实例或数据结构中: + +- 如果对象的基础数据已经更改了,那么从缓存中删掉这个对象。 +- 允许异步处理:workers 通过使用最新的缓存对象来组装对象。 + +建议缓存的内容: + +- 用户会话 +- 完全渲染的 Web 页面 +- 活动流 +- 用户图数据 + +### 何时更新缓存 + +由于你只能在缓存中存储有限的数据,所以你需要选择一个适用于你用例的缓存更新策略。 + +#### 缓存模式 + +

+ +
+ 资料来源:从缓存到内存数据网格 +

+ +应用从存储器读写。缓存不和存储器直接交互,应用执行以下操作: + +- 在缓存中查找记录,如果所需数据不在缓存中 +- 从数据库中加载所需内容 +- 将查找到的结果存储到缓存中 +- 返回所需内容 + +``` +def get_user(self, user_id): + user = cache.get("user.{0}", user_id) + if user is None: + user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id) + if user is not None: + key = "user.{0}".format(user_id) + cache.set(key, json.dumps(user)) + return user +``` + +[Memcached](https://memcached.org/) 通常用这种方式使用。 + +添加到缓存中的数据读取速度很快。缓存模式也称为延迟加载。只缓存所请求的数据,这避免了没有被请求的数据占满了缓存空间。 + +##### 缓存的缺点: + +- 请求的数据如果不在缓存中就需要经过三个步骤来获取数据,这会导致明显的延迟。 +- 如果数据库中的数据更新了会导致缓存中的数据过时。这个问题需要通过设置 TTL 强制更新缓存或者直写模式来缓解这种情况。 +- 当一个节点出现故障的时候,它将会被一个新的节点替代,这增加了延迟的时间。 + +#### 直写模式 + +

+ +
+ 资料来源:可扩展性、可用性、稳定性、模式 +

+ +应用使用缓存作为主要的数据存储,将数据读写到缓存中,而缓存负责从数据库中读写数据。 + +- 应用向缓存中添加/更新数据 +- 缓存同步地写入数据存储 +- 返回所需内容 + +应用代码: + +``` +set_user(12345, {"foo":"bar"}) +``` + +缓存代码: + +``` +def set_user(user_id, values): + user = db.query("UPDATE Users WHERE id = {0}", user_id, values) + cache.set(user_id, user) +``` + +由于存写操作所以直写模式整体是一种很慢的操作,但是读取刚写入的数据很快。相比读取数据,用户通常比较能接受更新数据时速度较慢。缓存中的数据不会过时。 + +##### 直写模式的缺点: + +- 由于故障或者缩放而创建的新的节点,新的节点不会缓存,直到数据库更新为止。缓存应用直写模式可以缓解这个问题。 +- 写入的大多数数据可能永远都不会被读取,用 TTL 可以最小化这种情况的出现。 + +#### 回写模式 + +

+ +
+ 资料来源:可扩展性、可用性、稳定性、模式 +

+ +在回写模式中,应用执行以下操作: + +- 在缓存中增加或者更新条目 +- 异步写入数据,提高写入性能。 + +##### 回写模式的缺点: + +- 缓存可能在其内容成功存储之前丢失数据。 +- 执行直写模式比缓存或者回写模式更复杂。 + +#### 刷新 + +

+ +
+ 资料来源:从缓存到内存数据网格 +

+ +你可以将缓存配置成在到期之前自动刷新最近访问过的内容。 + +如果缓存可以准确预测将来可能请求哪些数据,那么刷新可能会导致延迟与读取时间的降低。 + +##### 刷新的缺点: + +- 不能准确预测到未来需要用到的数据可能会导致性能不如不使用刷新。 + +### 缓存的缺点: + +- 需要保持缓存和真实数据源之间的一致性,比如数据库根据[缓存无效](https://en.wikipedia.org/wiki/Cache_algorithms)。 +- 需要改变应用程序比如增加 Redis 或者 memcached。 +- 无效缓存是个难题,什么时候更新缓存是与之相关的复杂问题。 + +### 相关资源和延伸阅读 + +- [从缓存到内存数据](http://www.slideshare.net/tmatyashovsky/from-cache-to-in-memory-data-grid-introduction-to-hazelcast) +- [可扩展系统设计模式](http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html) +- [可缩放系统构架介绍](http://lethain.com/introduction-to-architecting-systems-for-scale/) +- [可扩展性,可用性,稳定性和模式](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) +- [可扩展性](http://www.lecloud.net/post/9246290032/scalability-for-dummies-part-3-cache) +- [AWS ElastiCache 策略](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Strategies.html) +- [维基百科](https://en.wikipedia.org/wiki/Cache_(computing)) + +## 异步 + +

+ +
+ 资料来源:可缩放系统构架介绍 +

+ +异步工作流有助于减少那些原本顺序执行的请求时间。它们可以通过提前进行一些耗时的工作来帮助减少请求时间,比如定期汇总数据。 + +### 消息队列 + +消息队列接收,保留和传递消息。如果按顺序执行操作太慢的话,你可以使用有以下工作流的消息队列: + +- 应用程序将作业发布到队列,然后通知用户作业状态 +- 一个 worker 从队列中取出该作业,对其进行处理,然后显示该作业完成 + +不去阻塞用户操作,作业在后台处理。在此期间,客户端可能会进行一些处理使得看上去像是任务已经完成了。例如,如果要发送一条推文,推文可能会马上出现在你的时间线上,但是可能需要一些时间才能将你的推文推送到你的所有关注者那里去。 + +**Redis** 是一个令人满意的简单的消息代理,但是消息有可能会丢失。 + +**RabbitMQ** 很受欢迎但是要求你适应「AMQP」协议并且管理你自己的节点。 + +**Amazon SQS** 是被托管的,但可能具有高延迟,并且消息可能会被传送两次。 + +### 任务队列 + +任务队列接收任务及其相关数据,运行它们,然后传递其结果。 它们可以支持调度,并可用于在后台运行计算密集型作业。 + +**Celery** 支持调度,主要是用 Python 开发的。 + +### 背压 + +如果队列开始明显增长,那么队列大小可能会超过内存大小,导致高速缓存未命中,磁盘读取,甚至性能更慢。[背压](http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html)可以通过限制队列大小来帮助我们,从而为队列中的作业保持高吞吐率和良好的响应时间。一旦队列填满,客户端将得到服务器忙活着 HTTP 503 状态码,以便稍后重试。客户端可以在稍后时间重试该请求,也许是[指数退避](https://en.wikipedia.org/wiki/Exponential_backoff)。 + +### 异步的缺点: + +- 简单的计算和实时工作流等用例可能更适用于同步操作,因为引入队列可能会增加延迟和复杂性。 + +### 相关资源和延伸阅读 + +- [这是一个数字游戏](https://www.youtube.com/watch?v=1KRYH75wgy4) +- [超载时应用背压](http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html) +- [利特尔法则](https://en.wikipedia.org/wiki/Little%27s_law) +- [消息队列与任务队列有什么区别?](https://www.quora.com/What-is-the-difference-between-a-message-queue-and-a-task-queue-Why-would-a-task-queue-require-a-message-broker-like-RabbitMQ-Redis-Celery-or-IronMQ-to-function) + +## 通讯 + +

+ +
+ 资料来源:OSI 7层模型 +

+ +### 超文本传输协议(HTTP) + +HTTP 是一种在客户端和服务器之间编码和传输数据的方法。它是一个请求/响应协议:客户端和服务端针对相关内容和完成状态信息的请求和响应。HTTP 是独立的,允许请求和响应流经许多执行负载均衡,缓存,加密和压缩的中间路由器和服务器。 + +一个基本的 HTTP 请求由一个动词(方法)和一个资源(端点)组成。 以下是常见的 HTTP 动词: + +| 动词 | 描述 | *幂等 | 安全性 | 可缓存 | +| ------ | -------------- | ---- | ---- | -------------- | +| GET | 读取资源 | Yes | Yes | Yes | +| POST | 创建资源或触发处理数据的进程 | No | No | Yes,如果回应包含刷新信息 | +| PUT | 创建或替换资源 | Yes | No | No | +| PATCH | 部分更新资源 | No | No | Yes,如果回应包含刷新信息 | +| DELETE | 删除资源 | Yes | No | No | + + + +**多次执行不会产生不同的结果**。 + +HTTP 是依赖于较低级协议(如 **TCP** 和 **UDP**)的应用层协议。 + +#### 来源及延伸阅读:HTTP + +* [README](https://www.quora.com/What-is-the-difference-between-HTTP-protocol-and-TCP-protocol) + +* [HTTP 是什么?](https://www.nginx.com/resources/glossary/http/) +* [HTTP 和 TCP 的区别](https://www.quora.com/What-is-the-difference-between-HTTP-protocol-and-TCP-protocol) +* [PUT 和 PATCH的区别](https://laracasts.com/discuss/channels/general-discussion/whats-the-differences-between-put-and-patch?page=1) + +### 传输控制协议(TCP) + +

+ +
+ 资料来源:如何制作多人游戏 +

+ +TCP 是通过 [IP 网络](https://en.wikipedia.org/wiki/Internet_Protocol)的面向连接的协议。 使用[握手](https://en.wikipedia.org/wiki/Handshaking)建立和断开连接。 发送的所有数据包保证以原始顺序到达目的地,用以下措施保证数据包不被损坏: + +- 每个数据包的序列号和[校验码](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Checksum_computation)。 +- [确认包](https://en.wikipedia.org/wiki/Acknowledgement_(data_networks))和自动重传 + +如果发送者没有收到正确的响应,它将重新发送数据包。如果多次超时,连接就会断开。TCP 实行[流量控制](https://en.wikipedia.org/wiki/Flow_control_(data))和[拥塞控制](https://en.wikipedia.org/wiki/Network_congestion#Congestion_control)。这些确保措施会导致延迟,而且通常导致传输效率比 UDP 低。 + +为了确保高吞吐量,Web 服务器可以保持大量的 TCP 连接,从而导致高内存使用。在 Web 服务器线程间拥有大量开放连接可能开销巨大,消耗资源过多,也就是说,一个 [memcached](#memcached) 服务器。[连接池](https://en.wikipedia.org/wiki/Connection_pool) 可以帮助除了在适用的情况下切换到 UDP。 + +TCP 对于需要高可靠性但时间紧迫的应用程序很有用。比如包括 Web 服务器,数据库信息,SMTP,FTP 和 SSH。 + +以下情况使用 TCP 代替 UDP: + +- 你需要数据完好无损。 +- 你想对网络吞吐量自动进行最佳评估。 + +### 用户数据报协议(UDP) + +

+ +
+ 资料来源:如何制作多人游戏 +

+ +UDP 是无连接的。数据报(类似于数据包)只在数据报级别有保证。数据报可能会无序的到达目的地,也有可能会遗失。UDP 不支持拥塞控制。虽然不如 TCP 那样有保证,但 UDP 通常效率更高。 + +UDP 可以通过广播将数据报发送至子网内的所有设备。这对 [DHCP](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol) 很有用,因为子网内的设备还没有分配 IP 地址,而 IP 对于 TCP 是必须的。 + +UDP 可靠性更低但适合用在网络电话、视频聊天,流媒体和实时多人游戏上。 + +以下情况使用 UDP 代替 TCP: + +* 你需要低延迟 +* 相对于数据丢失更糟的是数据延迟 +* 你想实现自己的错误校正方法 + +#### 来源及延伸阅读:TCP 与 UDP + +* [游戏编程的网络](http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/) +* [TCP 与 UDP 的关键区别](http://www.cyberciti.biz/faq/key-differences-between-tcp-and-udp-protocols/) +* [TCP 与 UDP 的不同](http://stackoverflow.com/questions/5970383/difference-between-tcp-and-udp) +* [传输控制协议](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) +* [用户数据报协议](https://en.wikipedia.org/wiki/User_Datagram_Protocol) +* [Memcache 在 Facebook 的扩展](http://www.cs.bu.edu/~jappavoo/jappavoo.github.com/451/papers/memcache-fb.pdf) + +### 远程过程调用协议(RPC) + +

+ +
+ Source: Crack the system design interview +

+ +在 RPC 中,客户端会去调用另一个地址空间(通常是一个远程服务器)里的方法。调用代码看起来就像是调用的是一个本地方法,客户端和服务器交互的具体过程被抽象。远程调用相对于本地调用一般较慢而且可靠性更差,因此区分两者是有帮助的。热门的 RPC 框架包括 [Protobuf](https://developers.google.com/protocol-buffers/)、[Thrift](https://thrift.apache.org/) 和 [Avro](https://avro.apache.org/docs/current/)。 + +RPC 是一个“请求-响应”协议: + +* **客户端程序** ── 调用客户端存根程序。就像调用本地方法一样,参数会被压入栈中。 +* **客户端 stub 程序** ── 将请求过程的 id 和参数打包进请求信息中。 +* **客户端通信模块** ── 将信息从客户端发送至服务端。 +* **服务端通信模块** ── 将接受的包传给服务端存根程序。 +* **服务端 stub 程序** ── 将结果解包,依据过程 id 调用服务端方法并将参数传递过去。 + +RPC 调用示例: + +``` +GET /someoperation?data=anId + +POST /anotheroperation +{ + "data":"anId"; + "anotherdata": "another value" +} +``` + +RPC 专注于暴露方法。RPC 通常用于处理内部通讯的性能问题,这样你可以手动处理本地调用以更好的适应你的情况。 + + +当以下情况时选择本地库(也就是 SDK): + +* 你知道你的目标平台。 +* 你想控制如何访问你的“逻辑”。 +* 你想对发生在你的库中的错误进行控制。 +* 性能和终端用户体验是你最关心的事。 + +遵循 **REST** 的 HTTP API 往往更适用于公共 API。 + +#### 缺点:RPC + +* RPC 客户端与服务实现捆绑地很紧密。 +* 一个新的 API 必须在每一个操作或者用例中定义。 +* RPC 很难调试。 +* 你可能没办法很方便的去修改现有的技术。举个例子,如果你希望在 [Squid](http://www.squid-cache.org/) 这样的缓存服务器上确保 [RPC 被正确缓存](http://etherealbits.com/2012/12/debunking-the-myths-of-rpc-rest/)的话可能需要一些额外的努力了。 + +### 表述性状态转移(REST) + +REST 是一种强制的客户端/服务端架构设计模型,客户端基于服务端管理的一系列资源操作。服务端提供修改或获取资源的接口。所有的通信必须是无状态和可缓存的。 + +RESTful 接口有四条规则: + +* **标志资源(HTTP 里的 URI)** ── 无论什么操作都使用同一个 URI。 +* **表示的改变(HTTP 的动作)** ── 使用动作, headers 和 body。 +* **可自我描述的错误信息(HTTP 中的 status code)** ── 使用状态码,不要重新造轮子。 +* **[HATEOAS](http://restcookbook.com/Basics/hateoas/)(HTTP 中的HTML 接口)** ── 你的 web 服务器应该能够通过浏览器访问。 + +REST 请求的例子: + +``` +GET /someresources/anId + +PUT /someresources/anId +{"anotherdata": "another value"} +``` + +REST 关注于暴露数据。它减少了客户端/服务端的耦合程度,经常用于公共 HTTP API 接口设计。REST 使用更通常与规范化的方法来通过 URI 暴露资源,[通过 header 来表述](https://github.com/for-GET/know-your-http-well/blob/master/headers.md)并通过 GET、POST、PUT、DELETE 和 PATCH 这些动作来进行操作。因为无状态的特性,REST 易于横向扩展和隔离。 + +#### 缺点:REST + +* 由于 REST 将重点放在暴露数据,所以当资源不是自然组织的或者结构复杂的时候它可能无法很好的适应。举个例子,返回过去一小时中与特定事件集匹配的更新记录这种操作就很难表示为路径。使用 REST,可能会使用 URI 路径,查询参数和可能的请求体来实现。 +* REST 一般依赖几个动作(GET、POST、PUT、DELETE 和 PATCH),但有时候仅仅这些没法满足你的需要。举个例子,将过期的文档移动到归档文件夹里去,这样的操作可能没法简单的用上面这几个 verbs 表达。 +* 为了渲染单个页面,获取被嵌套在层级结构中的复杂资源需要客户端,服务器之间多次往返通信。例如,获取博客内容及其关联评论。对于使用不确定网络环境的移动应用来说,这些多次往返通信是非常麻烦的。 +* 随着时间的推移,更多的字段可能会被添加到 API 响应中,较旧的客户端将会接收到所有新的数据字段,即使是那些它们不需要的字段,结果它会增加负载大小并引起更大的延迟。 + +### RPC 与 REST 比较 + +| 操作 | RPC | REST | +| ----------- | ---------------------------------------- | ---------------------------------------- | +| 注册 | **POST** /signup | **POST** /persons | +| 注销 | **POST** /resign
{
"personid": "1234"
} | **DELETE** /persons/1234 | +| 读取用户信息 | **GET** /readPerson?personid=1234 | **GET** /persons/1234 | +| 读取用户物品列表 | **GET** /readUsersItemsList?personid=1234 | **GET** /persons/1234/items | +| 向用户物品列表添加一项 | **POST** /addItemToUsersItemsList
{
"personid": "1234";
"itemid": "456"
} | **POST** /persons/1234/items
{
"itemid": "456"
} | +| 更新一个物品 | **POST** /modifyItem
{
"itemid": "456";
"key": "value"
} | **PUT** /items/456
{
"key": "value"
} | +| 删除一个物品 | **POST** /removeItem
{
"itemid": "456"
} | **DELETE** /items/456 | + +

+ 资料来源:你真的知道你为什么更喜欢 REST 而不是 RPC 吗 +

+ +#### 来源及延伸阅读:REST 与 RPC + +* [你真的知道你为什么更喜欢 REST 而不是 RPC 吗](https://apihandyman.io/do-you-really-know-why-you-prefer-rest-over-rpc/) +* [什么时候 RPC 比 REST 更合适?](http://programmers.stackexchange.com/a/181186) +* [REST vs JSON-RPC](http://stackoverflow.com/questions/15056878/rest-vs-json-rpc) +* [揭开 RPC 和 REST 的神秘面纱](http://etherealbits.com/2012/12/debunking-the-myths-of-rpc-rest/) +* [使用 REST 的缺点是什么](https://www.quora.com/What-are-the-drawbacks-of-using-RESTful-APIs) +* [破解系统设计面试](http://www.puncsky.com/blog/2016/02/14/crack-the-system-design-interview/) +* [Thrift](https://code.facebook.com/posts/1468950976659943/) +* [为什么在内部使用 REST 而不是 RPC](http://arstechnica.com/civis/viewtopic.php?t=1190508) + +## 安全 + +这一部分需要更多内容。[一起来吧](#贡献)! + +安全是一个宽泛的话题。除非你有相当的经验、安全方面背景或者正在申请的职位要求安全知识,你不需要了解安全基础知识以外的内容: + +* 在运输和等待过程中加密 +* 对所有的用户输入和从用户那里发来的参数进行处理以防止 [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) 和 [SQL 注入](https://en.wikipedia.org/wiki/SQL_injection)。 +* 使用参数化的查询来防止 SQL 注入。 +* 使用[最小权限原则](https://en.wikipedia.org/wiki/Principle_of_least_privilege)。 + +### 来源及延伸阅读 + +* [为开发者准备的安全引导](https://github.com/FallibleInc/security-guide-for-developers) +* [OWASP top ten](https://www.owasp.org/index.php/OWASP_Top_Ten_Cheat_Sheet) + +## 附录 + +一些时候你会被要求做出保守估计。比如,你可能需要估计从磁盘中生成 100 张图片的缩略图需要的时间或者一个数据结构需要多少的内存。**2 的次方表**和**每个开发者都需要知道的一些时间数据**(译注:OSChina 上有这篇文章的[译文](https://www.oschina.net/news/30009/every-programmer-should-know))都是一些很方便的参考资料。 + +### 2 的次方表 + +``` +Power Exact Value Approx Value Bytes +--------------------------------------------------------------- +7 128 +8 256 +10 1024 1 thousand 1 KB +16 65,536 64 KB +20 1,048,576 1 million 1 MB +30 1,073,741,824 1 billion 1 GB +32 4,294,967,296 4 GB +40 1,099,511,627,776 1 trillion 1 TB +``` + +#### 来源及延伸阅读 + +* [2 的次方](https://en.wikipedia.org/wiki/Power_of_two) + +### 每个程序员都应该知道的延迟数 + +``` +Latency Comparison Numbers +-------------------------- +L1 cache reference 0.5 ns +Branch mispredict 5 ns +L2 cache reference 7 ns 14x L1 cache +Mutex lock/unlock 100 ns +Main memory reference 100 ns 20x L2 cache, 200x L1 cache +Compress 1K bytes with Zippy 10,000 ns 10 us +Send 1 KB bytes over 1 Gbps network 10,000 ns 10 us +Read 4 KB randomly from SSD* 150,000 ns 150 us ~1GB/sec SSD +Read 1 MB sequentially from memory 250,000 ns 250 us +Round trip within same datacenter 500,000 ns 500 us +Read 1 MB sequentially from SSD* 1,000,000 ns 1,000 us 1 ms ~1GB/sec SSD, 4X memory +Disk seek 10,000,000 ns 10,000 us 10 ms 20x datacenter roundtrip +Read 1 MB sequentially from 1 Gbps 10,000,000 ns 10,000 us 10 ms 40x memory, 10X SSD +Read 1 MB sequentially from disk 30,000,000 ns 30,000 us 30 ms 120x memory, 30X SSD +Send packet CA->Netherlands->CA 150,000,000 ns 150,000 us 150 ms + +Notes +----- +1 ns = 10^-9 seconds +1 us = 10^-6 seconds = 1,000 ns +1 ms = 10^-3 seconds = 1,000 us = 1,000,000 ns +``` + +基于上述数字的指标: +* 从磁盘以 30 MB/s 的速度顺序读取 +* 以 100 MB/s 从 1 Gbps 的以太网顺序读取 +* 从 SSD 以 1 GB/s 的速度读取 +* 以 4 GB/s 的速度从主存读取 +* 每秒能绕地球 6-7 圈 +* 数据中心内每秒有 2,000 次往返 + +#### 延迟数可视化 + +![](https://camo.githubusercontent.com/77f72259e1eb58596b564d1ad823af1853bc60a3/687474703a2f2f692e696d6775722e636f6d2f6b307431652e706e67) + +#### 来源及延伸阅读 + +* [每个程序员都应该知道的延迟数 — 1](https://gist.github.com/jboner/2841832) +* [每个程序员都应该知道的延迟数 — 2](https://gist.github.com/hellerbarde/2843375) +* [关于建设大型分布式系统的的设计方案、课程和建议](http://www.cs.cornell.edu/projects/ladis2009/talks/dean-keynote-ladis2009.pdf) +* [关于建设大型可拓展分布式系统的软件工程咨询](https://static.googleusercontent.com/media/research.google.com/en//people/jeff/stanford-295-talk.pdf) + +### 其它的系统设计面试题 + +> 常见的系统设计面试问题,给出了如何解决的方案链接 + +| 问题 | 引用 | +| ----------------------- | ---------------------------------------- | +| 设计类似于 Dropbox 的文件同步服务 | [youtube.com](https://www.youtube.com/watch?v=PE4gwstWhmc) | +| 设计类似于 Google 的搜索引擎 | [queue.acm.org](http://queue.acm.org/detail.cfm?id=988407)
[stackexchange.com](http://programmers.stackexchange.com/questions/38324/interview-question-how-would-you-implement-google-search)
[ardendertat.com](http://www.ardendertat.com/2012/01/11/implementing-search-engines/)
[stanford.edu](http://infolab.stanford.edu/~backrub/google.html) | +| 设计类似于 Google 的可扩展网络爬虫 | [quora.com](https://www.quora.com/How-can-I-build-a-web-crawler-from-scratch) | +| 设计 Google 文档 | [code.google.com](https://code.google.com/p/google-mobwrite/)
[neil.fraser.name](https://neil.fraser.name/writing/sync/) | +| 设计类似 Redis 的建值存储 | [slideshare.net](http://www.slideshare.net/dvirsky/introduction-to-redis) | +| 设计类似 Memcached 的缓存系统 | [slideshare.net](http://www.slideshare.net/oemebamo/introduction-to-memcached) | +| 设计类似亚马逊的推荐系统 | [hulu.com](http://tech.hulu.com/blog/2011/09/19/recommendation-system.html)
[ijcai13.org](http://ijcai13.org/files/tutorial_slides/td3.pdf) | +| 设计类似 Bitly 的短链接系统 | [n00tc0d3r.blogspot.com](http://n00tc0d3r.blogspot.com/) | +| 设计类似 WhatsApp 的聊天应用 | [highscalability.com](http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html) | +| 设计类似 Instagram 的图片分享系统 | [highscalability.com](http://highscalability.com/flickr-architecture)
[highscalability.com](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html) | +| 设计 Facebook 的新闻推荐方法 | [quora.com](http://www.quora.com/What-are-best-practices-for-building-something-like-a-News-Feed)
[quora.com](http://www.quora.com/Activity-Streams/What-are-the-scaling-issues-to-keep-in-mind-while-developing-a-social-network-feed)
[slideshare.net](http://www.slideshare.net/danmckinley/etsy-activity-feeds-architecture) | +| 设计 Facebook 的时间线系统 | [facebook.com](https://www.facebook.com/note.php?note_id=10150468255628920)
[highscalability.com](http://highscalability.com/blog/2012/1/23/facebook-timeline-brought-to-you-by-the-power-of-denormaliza.html) | +| 设计 Facebook 的聊天系统 | [erlang-factory.com](http://www.erlang-factory.com/upload/presentations/31/EugeneLetuchy-ErlangatFacebook.pdf)
[facebook.com](https://www.facebook.com/note.php?note_id=14218138919&id=9445547199&index=0) | +| 设计类似 Facebook 的图表搜索系统 | [facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-building-out-the-infrastructure-for-graph-search/10151347573598920)
[facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-indexing-and-ranking-in-graph-search/10151361720763920)
[facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-the-natural-language-interface-of-graph-search/10151432733048920) | +| 设计类似 CloudFlare 的内容传递网络 | [cmu.edu](http://repository.cmu.edu/cgi/viewcontent.cgi?article=2112&context=compsci) | +| 设计类似 Twitter 的热门话题系统 | [michael-noll.com](http://www.michael-noll.com/blog/2013/01/18/implementing-real-time-trending-topics-in-storm/)
[snikolov .wordpress.com](http://snikolov.wordpress.com/2012/11/14/early-detection-of-twitter-trends/) | +| 设计一个随机 ID 生成系统 | [blog.twitter.com](https://blog.twitter.com/2010/announcing-snowflake)
[github.com](https://github.com/twitter/snowflake/) | +| 返回一定时间段内次数前 k 高的请求 | [ucsb.edu](https://icmi.cs.ucsb.edu/research/tech_reports/reports/2005-23.pdf)
[wpi.edu](http://davis.wpi.edu/xmdv/docs/EDBT11-diyang.pdf) | +| 设计一个数据源于多个数据中心的服务系统 | [highscalability.com](http://highscalability.com/blog/2009/8/24/how-google-serves-data-from-multiple-datacenters.html) | +| 设计一个多人网络卡牌游戏 | [indieflashblog.com](http://www.indieflashblog.com/how-to-create-an-asynchronous-multiplayer-game.html)
[buildnewgames.com](http://buildnewgames.com/real-time-multiplayer/) | +| 设计一个垃圾回收系统 | [stuffwithstuff.com](http://journal.stuffwithstuff.com/2013/12/08/babys-first-garbage-collector/)
[washington.edu](http://courses.cs.washington.edu/courses/csep521/07wi/prj/rick.pdf) | +| 添加更多的系统设计问题 | [贡献](#贡献) | + +### 真实架构 + +> 关于现实中真实的系统是怎么设计的文章。 + +

+ +
+ Source: Twitter timelines at scale +

+ +**不要专注于以下文章的细节,专注于以下方面:** + +* 发现这些文章中的共同的原则、技术和模式。 +* 学习每个组件解决哪些问题,什么情况下使用,什么情况下不适用 +* 复习学过的文章 + +| 类型 | 系统 | 引用 | +| --------------- | ---------------------------------------- | ---------------------------------------- | +| Data processing | **MapReduce** - Google的分布式数据处理 | [research.google.com](http://static.googleusercontent.com/media/research.google.com/zh-CN/us/archive/mapreduce-osdi04.pdf) | +| Data processing | **Spark** - Databricks 的分布式数据处理 | [slideshare.net](http://www.slideshare.net/AGrishchenko/apache-spark-architecture) | +| Data processing | **Storm** - Twitter 的分布式数据处理 | [slideshare.net](http://www.slideshare.net/previa/storm-16094009) | +| | | | +| Data store | **Bigtable** - Google 的列式数据库 | [harvard.edu](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) | +| Data store | **HBase** - Bigtable 的开源实现 | [slideshare.net](http://www.slideshare.net/alexbaranau/intro-to-hbase) | +| Data store | **Cassandra** - Facebook 的列式数据库 | [slideshare.net](http://www.slideshare.net/planetcassandra/cassandra-introduction-features-30103666) | +| Data store | **DynamoDB** - Amazon 的文档数据库 | [harvard.edu](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/decandia07dynamo.pdf) | +| Data store | **MongoDB** - 文档数据库 | [slideshare.net](http://www.slideshare.net/mdirolf/introduction-to-mongodb) | +| Data store | **Spanner** - Google 的全球分布数据库 | [research.google.com](http://research.google.com/archive/spanner-osdi2012.pdf) | +| Data store | **Memcached** - 分布式内存缓存系统 | [slideshare.net](http://www.slideshare.net/oemebamo/introduction-to-memcached) | +| Data store | **Redis** - 能够持久化及具有值类型的分布式内存缓存系统 | [slideshare.net](http://www.slideshare.net/dvirsky/introduction-to-redis) | +| | | | +| File system | **Google File System (GFS)** - 分布式文件系统 | [research.google.com](http://static.googleusercontent.com/media/research.google.com/zh-CN/us/archive/gfs-sosp2003.pdf) | +| File system | **Hadoop File System (HDFS)** - GFS 的开源实现 | [apache.org](https://hadoop.apache.org/docs/r1.2.1/hdfs_design.html) | +| | | | +| Misc | **Chubby** - Google 的分布式系统的低耦合锁服务 | [research.google.com](http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/archive/chubby-osdi06.pdf) | +| Misc | **Dapper** - 分布式系统跟踪基础设施 | [research.google.com](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36356.pdf) | +| Misc | **Kafka** - LinkedIn 的发布订阅消息系统 | [slideshare.net](http://www.slideshare.net/mumrah/kafka-talk-tri-hug) | +| Misc | **Zookeeper** - 集中的基础架构和协调服务 | [slideshare.net](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) | +| | 添加更多 | [贡献](#贡献) | + +### 公司的系统架构 + +| Company | Reference(s) | +| -------------- | ---------------------------------------- | +| Amazon | [Amazon 的架构](http://highscalability.com/amazon-architecture) | +| Cinchcast | [每天产生 1500 小时的音频](http://highscalability.com/blog/2012/7/16/cinchcast-architecture-producing-1500-hours-of-audio-every-d.html) | +| DataSift | [每秒实时挖掘 120000 条 tweet](http://highscalability.com/blog/2011/11/29/datasift-architecture-realtime-datamining-at-120000-tweets-p.html) | +| DropBox | [我们如何缩放 Dropbox](https://www.youtube.com/watch?v=PE4gwstWhmc) | +| ESPN | [每秒操作 100000 次](http://highscalability.com/blog/2013/11/4/espns-architecture-at-scale-operating-at-100000-duh-nuh-nuhs.html) | +| Google | [Google 的架构](http://highscalability.com/google-architecture) | +| Instagram | [1400 万用户,达到兆级别的照片存储](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html)
[是什么在驱动 Instagram](http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances) | +| Justin.tv | [Justin.Tv 的直播广播架构](http://highscalability.com/blog/2010/3/16/justintvs-live-video-broadcasting-architecture.html) | +| Facebook | [Facebook 的可扩展 memcached](https://cs.uwaterloo.ca/~brecht/courses/854-Emerging-2014/readings/key-value/fb-memcached-nsdi-2013.pdf)
[TAO: Facebook 社交图的分布式数据存储](https://cs.uwaterloo.ca/~brecht/courses/854-Emerging-2014/readings/data-store/tao-facebook-distributed-datastore-atc-2013.pdf)
[Facebook 的图片存储](https://www.usenix.org/legacy/event/osdi10/tech/full_papers/Beaver.pdf) | +| Flickr | [Flickr 的架构](http://highscalability.com/flickr-architecture) | +| Mailbox | [在 6 周内从 0 到 100 万用户](http://highscalability.com/blog/2013/6/18/scaling-mailbox-from-0-to-one-million-users-in-6-weeks-and-1.html) | +| Pinterest | [从零到每月数十亿的浏览量](http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html)
[1800 万访问用户,10 倍增长,12 名员工](http://highscalability.com/blog/2012/5/21/pinterest-architecture-update-18-million-visitors-10x-growth.html) | +| Playfish | [月用户量 5000 万并在不断增长](http://highscalability.com/blog/2010/9/21/playfishs-social-gaming-architecture-50-million-monthly-user.html) | +| PlentyOfFish | [PlentyOfFish 的架构](http://highscalability.com/plentyoffish-architecture) | +| Salesforce | [他们每天如何处理 13 亿笔交易](http://highscalability.com/blog/2013/9/23/salesforce-architecture-how-they-handle-13-billion-transacti.html) | +| Stack Overflow | [Stack Overflow 的架构](http://highscalability.com/blog/2009/8/5/stack-overflow-architecture.html) | +| TripAdvisor | [40M 访问者,200M 页面浏览量,30TB 数据](http://highscalability.com/blog/2011/6/27/tripadvisor-architecture-40m-visitors-200m-dynamic-page-view.html) | +| Tumblr | [每月 150 亿的浏览量](http://highscalability.com/blog/2012/2/13/tumblr-architecture-15-billion-page-views-a-month-and-harder.html) | +| Twitter | [Making Twitter 10000 percent faster](http://highscalability.com/scaling-twitter-making-twitter-10000-percent-faster)
[每天使用 MySQL 存储2.5亿条 tweet](http://highscalability.com/blog/2011/12/19/how-twitter-stores-250-million-tweets-a-day-using-mysql.html)
[150M 活跃用户,300K QPS,22 MB/S 的防火墙](http://highscalability.com/blog/2013/7/8/the-architecture-twitter-uses-to-deal-with-150m-active-users.html)
[可扩展时间表](https://www.infoq.com/presentations/Twitter-Timeline-Scalability)
[Twitter 的大小数据](https://www.youtube.com/watch?v=5cKTP36HVgI)
[Twitter 的行为:规模超过 1 亿用户](https://www.youtube.com/watch?v=z8LU0Cj6BOU) | +| Uber | [Uber 如何扩展自己的实时化市场](http://highscalability.com/blog/2015/9/14/how-uber-scales-their-real-time-market-platform.html) | +| WhatsApp | [Facebook 用 190 亿美元购买 WhatsApp 的架构](http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html) | +| YouTube | [YouTube 的可扩展性](https://www.youtube.com/watch?v=w5WVu624fY8)
[YouTube 的架构](http://highscalability.com/youtube-architecture) | + +### 公司工程博客 + +> 你即将面试的公司的架构 +> +> 你面对的问题可能就来自于同样领域 + +* [Airbnb Engineering](http://nerds.airbnb.com/) +* [Atlassian Developers](https://developer.atlassian.com/blog/) +* [Autodesk Engineering](http://cloudengineering.autodesk.com/blog/) +* [AWS Blog](https://aws.amazon.com/blogs/aws/) +* [Bitly Engineering Blog](http://word.bitly.com/) +* [Box Blogs](https://www.box.com/blog/engineering/) +* [Cloudera Developer Blog](http://blog.cloudera.com/blog/) +* [Dropbox Tech Blog](https://tech.dropbox.com/) +* [Engineering at Quora](http://engineering.quora.com/) +* [Ebay Tech Blog](http://www.ebaytechblog.com/) +* [Evernote Tech Blog](https://blog.evernote.com/tech/) +* [Etsy Code as Craft](http://codeascraft.com/) +* [Facebook Engineering](https://www.facebook.com/Engineering) +* [Flickr Code](http://code.flickr.net/) +* [Foursquare Engineering Blog](http://engineering.foursquare.com/) +* [GitHub Engineering Blog](http://githubengineering.com/) +* [Google Research Blog](http://googleresearch.blogspot.com/) +* [Groupon Engineering Blog](https://engineering.groupon.com/) +* [Heroku Engineering Blog](https://engineering.heroku.com/) +* [Hubspot Engineering Blog](http://product.hubspot.com/blog/topic/engineering) +* [High Scalability](http://highscalability.com/) +* [Instagram Engineering](http://instagram-engineering.tumblr.com/) +* [Intel Software Blog](https://software.intel.com/en-us/blogs/) +* [Jane Street Tech Blog](https://blogs.janestreet.com/category/ocaml/) +* [LinkedIn Engineering](http://engineering.linkedin.com/blog) +* [Microsoft Engineering](https://engineering.microsoft.com/) +* [Microsoft Python Engineering](https://blogs.msdn.microsoft.com/pythonengineering/) +* [Netflix Tech Blog](http://techblog.netflix.com/) +* [Paypal Developer Blog](https://devblog.paypal.com/category/engineering/) +* [Pinterest Engineering Blog](http://engineering.pinterest.com/) +* [Quora Engineering](https://engineering.quora.com/) +* [Reddit Blog](http://www.redditblog.com/) +* [Salesforce Engineering Blog](https://developer.salesforce.com/blogs/engineering/) +* [Slack Engineering Blog](https://slack.engineering/) +* [Spotify Labs](https://labs.spotify.com/) +* [Twilio Engineering Blog](http://www.twilio.com/engineering) +* [Twitter Engineering](https://engineering.twitter.com/) +* [Uber Engineering Blog](http://eng.uber.com/) +* [Yahoo Engineering Blog](http://yahooeng.tumblr.com/) +* [Yelp Engineering Blog](http://engineeringblog.yelp.com/) +* [Zynga Engineering Blog](https://www.zynga.com/blogs/engineering) + +#### 来源及延伸阅读 + +* [kilimchoi/engineering-blogs](https://github.com/kilimchoi/engineering-blogs) + +## 正在完善中 + +有兴趣加入添加一些部分或者帮助完善某些部分吗?[加入进来吧](#贡献)! + +* 使用 MapReduce 进行分布式计算 +* 一致性哈希 +* 直接存储器访问(DMA)控制器 +* [贡献](#贡献) + +## 致谢 + +整个仓库都提供了证书和源 + +特别鸣谢: + +* [Hired in tech](http://www.hiredintech.com/system-design/the-system-design-process/) +* [Cracking the coding interview](https://www.amazon.com/dp/0984782850/) +* [High scalability](http://highscalability.com/) +* [checkcheckzz/system-design-interview](https://github.com/checkcheckzz/system-design-interview) +* [shashank88/system_design](https://github.com/shashank88/system_design) +* [mmcgrana/services-engineering](https://github.com/mmcgrana/services-engineering) +* [System design cheat sheet](https://gist.github.com/vasanthk/485d1c25737e8e72759f) +* [A distributed systems reading list](http://dancres.github.io/Pages/) +* [Cracking the system design interview](http://www.puncsky.com/blog/2016/02/14/crack-the-system-design-interview/) + +## 联系方式 + +欢迎联系我讨论本文的不足、问题或者意见。 + +可以在我的 [GitHub 主页](https://github.com/donnemartin)上找到我的联系方式 + +## 许可 + + Creative Commons Attribution 4.0 International License (CC BY 4.0) + + http://creativecommons.org/licenses/by/4.0/ From 5517013458814e8f7cdd66173a1292a2f2d0b2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A0=B9=E5=8F=B7=E4=B8=89?= Date: Mon, 17 Apr 2017 05:49:15 +0800 Subject: [PATCH 43/44] zh-cn: Rename README-zh-Hant.md to README-zh-Hans.md (#64) --- README-zh-Hant.md => README-zh-Hans.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README-zh-Hant.md => README-zh-Hans.md (100%) diff --git a/README-zh-Hant.md b/README-zh-Hans.md similarity index 100% rename from README-zh-Hant.md rename to README-zh-Hans.md From 5072dfe96c4428aac53db0500d713baac1986c60 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 16 Apr 2017 15:06:31 -0700 Subject: [PATCH 44/44] Update translation links (#65) Move the list of completed and in-progress translations to the top of the README. Add a translate link to the Contributing section. --- README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d725ee0b..25793518 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +*[English](README.md) ∙ [简体中文](README-zh-Hans.md) | [Brazilian Portuguese](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Turkish](https://github.com/donnemartin/system-design-primer/issues/39) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* + # The System Design Primer

@@ -5,14 +7,6 @@

-## Translations - -Interested in [translating](https://github.com/donnemartin/system-design-primer/issues/28)? Translations in progress: - -* [Brazilian Portuguese translation](https://github.com/donnemartin/system-design-primer/issues/40) -* [Simplified Chinese translation](https://github.com/donnemartin/system-design-primer/issues/38) -* [Turkish translation](https://github.com/donnemartin/system-design-primer/issues/39) - ## Motivation > Learn how to design large-scale systems. @@ -84,6 +78,7 @@ Feel free to submit pull requests to help: * Fix errors * Improve sections * Add new sections +* [Translate](https://github.com/donnemartin/system-design-primer/issues/28) Content that needs some polishing is placed [under development](#under-development).